Skip to content

Instantly share code, notes, and snippets.

@blisssan
Created February 16, 2021 14:16
Show Gist options
  • Save blisssan/9a58357f912b54ed0911f240353b66de to your computer and use it in GitHub Desktop.
Save blisssan/9a58357f912b54ed0911f240353b66de to your computer and use it in GitHub Desktop.
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, PaymentResultDelegate,WKNavigationDelegate {
var flutterResult: FlutterResult?
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let navigationController = UINavigationController(rootViewController: controller);
navigationController.navigationBar.barTintColor = hexStringToUIColor(hex: "#ff6000");
navigationController.navigationBar.tintColor = .white;
navigationController.setNavigationBarHidden(true, animated: false);
self.window = UIWindow(frame: UIScreen.main.bounds);
self.window?.rootViewController = navigationController;
self.window?.makeKeyAndVisible();
let platform = FlutterMethodChannel(name: "com.ebb.app/payment",
binaryMessenger: controller.binaryMessenger)
platform.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
self.flutterResult = result
guard call.method == "initiatePayment" else {
result(FlutterMethodNotImplemented)
return
}
guard let argument = call.arguments as? Dictionary<String,Any> else {
result(FlutterError(code: "INVALID_ARGUMENTS", message: "No Valid argument found", details: ""))
return
}
guard let argumentData = argument["data"] as? String else {
result(FlutterError(code: "INVALID_ARGUMENTS", message: "No Valid argument found", details: ""))
return
}
let jsonData = argumentData.data(using: .utf8)!
let data = try! JSONDecoder().decode(Data.self, from: jsonData)
self.initiatePayment(result: result, application: application, data: data)
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func initiatePayment(result: @escaping FlutterResult, application: UIApplication, data: Data) {
if let nav = self.rootController() as? UINavigationController {
nav.setNavigationBarHidden(false, animated: true);
}
let ipaySdk: Ipay = Ipay()
ipaySdk.delegate = self
let payment: IpayPayment = IpayPayment()
payment.paymentId = ""
payment.merchantKey = data.merchant_key
payment.merchantCode = data.merchant_code
payment.refNo = data.order_no
payment.amount = data.amount
payment.currency = "MYR"
payment.prodDesc = "Payment for \(data.order_no)"
payment.userName = data.name
payment.userEmail = data.email
payment.userContact = "9090909090"
payment.country = "MY"
payment.backendPostURL = data.backend_post_url
payment.remark = ""
DispatchQueue.main.async {
guard let paymentView = ipaySdk.checkout(payment) as? WKWebView else {
if let nav = self.rootController() as? UINavigationController {
nav.setNavigationBarHidden(true, animated: true);
}
result(FlutterError(code: "SDKERROR", message: "payment view not available", details: nil))
return
}
guard let topViewController = AppDelegate.topViewController() else {
if let nav = self.rootController() as? UINavigationController {
nav.setNavigationBarHidden(true, animated: true);
}
result(FlutterError(code: "SDK_VIEW_ERROR", message: "top view controller view not available", details: nil))
return
}
let doneButton = UIBarButtonItem(title: "Close", style: UIBarButtonItem.Style.plain, target: self, action: #selector(self.buttonTapped));
doneButton.tintColor = .white;
topViewController.navigationItem.rightBarButtonItem = doneButton;
paymentView.tag = 100
paymentView.navigationDelegate = self
paymentView.frame = CGRect(x: 0, y: 50, width: paymentView.frame.size.width, height: paymentView.frame.size.height - 50)
paymentView.configuration.preferences.javaScriptEnabled = true
paymentView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
topViewController.view.addSubview(paymentView)
}
}
@objc func buttonTapped(sender : UIButton) {
//Write button action here
guard let topViewController = AppDelegate.topViewController() else {
return
}
if let viewWithTag = topViewController.view.viewWithTag(100){
viewWithTag.removeFromSuperview()
}
if let nav = self.rootController() as? UINavigationController {
nav.setNavigationBarHidden(true, animated: true);
}
}
private func rootController() -> UIViewController?{
return UIApplication.shared.keyWindow?.rootViewController;
}
class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
let moreNavigationController = tab.moreNavigationController
if let top = moreNavigationController.topViewController, top.view.window != nil {
return topViewController(base: top)
} else if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
/*
WebView Delegates
*/
func webView(_ webView: WKWebView, didFinish: WKNavigation!){
}
func webView(_ webView: WKWebView, didFail: WKNavigation!, withError: Error){
}
func webView(_ webView:WKWebView, didFailProvisionalNavigation: WKNavigation!, withError: Error){
}
func webView(_ webView:WKWebView, didCommit: WKNavigation!){
}
func webView(_ webView:WKWebView, didReceiveServerRedirectForProvisionalNavigation: WKNavigation!){
}
/*
Payment SDK Protocol
*/
func paymentSuccess(_ refNo: String!, withTransId transId: String!, withAmount amount: String!, withRemark remark: String!, withAuthCode authCode: String!) {
sendStatus(withTransId: transId, withOrderNo: refNo, withStatus: "SUCCESS", withExtra: authCode)
}
func paymentFailed(_ refNo: String!, withTransId transId: String!, withAmount amount: String!, withRemark remark: String!, withErrDesc errDesc: String!) {
sendStatus(withTransId: transId, withOrderNo: refNo, withStatus: "FAILED", withExtra: errDesc)
}
func paymentCancelled(_ refNo: String!, withTransId transId: String!, withAmount amount: String!, withRemark remark: String!, withErrDesc errDesc: String!) {
sendStatus(withTransId: transId, withOrderNo: refNo, withStatus: "CANCELLED", withExtra: errDesc)
}
func requerySuccess(_ refNo: String!, withMerchantCode merchantCode: String!, withAmount amount: String!, withResult result: String!) {
}
func requeryFailed(_ refNo: String!, withMerchantCode merchantCode: String!, withAmount amount: String!, withErrDesc errDesc: String!) {
}
func sendStatus(withTransId transId:String, withOrderNo orderNo:String, withStatus status:String, withExtra extra:String){
do{
let paymentResponse = PaymentResponse(status: status, trans_id: transId, order_no: orderNo, extra: extra)
let jsonData = try JSONEncoder().encode(paymentResponse)
let jsonString = String(data: jsonData, encoding: .utf8)!
if(self.flutterResult != nil && jsonString != ""){
self.flutterResult?(jsonString)
}
}catch _{
if(self.flutterResult != nil){
self.flutterResult?(FlutterError(code: "INVALID_RESPONSE", message: "Invalid Response Check Status in My Orders", details: ""))
}
}
if let nav = self.rootController() as? UINavigationController {
nav.setNavigationBarHidden(true, animated: true);
}
}
func hexStringToUIColor (hex:String) -> UIColor {
var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if (cString.hasPrefix("#")) {
cString.remove(at: cString.startIndex)
}
if ((cString.count) != 6) {
return UIColor.gray
}
var rgbValue:UInt64 = 0
Scanner(string: cString).scanHexInt64(&rgbValue)
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}
}
struct Data: Codable {
var name:String
var email:String
var order_no:String
var amount: String
var backend_post_url:String
var merchant_key:String;
var merchant_code:String;
}
struct PaymentResponse: Codable{
var status:String
var trans_id:String
var order_no: String
var extra:String
init(status: String, trans_id: String, order_no: String, extra: String) {
self.status = status
self.trans_id = trans_id
self.order_no = order_no
self.extra = extra
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment