How to integrate Razorpay in SwiftUI without storyboard

746 views Asked by At

I was looking at integrating the Razorpay checkout feature with iOS in Xcode and found the official documentation at https://razorpay.com/docs/payment-gateway/ios-integration/standard/. The documentation helps with integrating the Razorpay with UIViewController. The iOS app I am building does not make use of the storyboard and is strictly SwiftUI. I have looked at multiple ways of incorporating the UIViewController in SwiftUI which is totally possible with UIViewRepresentable but the code structure uses

struct ComponentName: UIViewRepresentable{}

But Razorpay SDK for iOS wants to implement RazorpayPaymentCompletionProtocol to a class and not struct. How do I go about in using this in a strictly SwiftUI application?

2

There are 2 answers

1
Rudrank Riyam On BEST ANSWER

You can use coordinators to manage the view controllers, and that coordinator will RazorpayPaymentCompletionProtocol.

Example:

struct ComponentName: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> CheckoutViewController {
        .init()
    }

    func updateUIViewController(_ uiViewController: CheckoutViewController, context: Context) { }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, RazorpayPaymentCompletionProtocol {
        let parent: ComponentName
        
        typealias Razorpay = RazorpayCheckout
        var razorpay: RazorpayCheckout!
        
        init(_ parent: ComponentName) {
            self.parent = parent
            
            RazorpayCheckout.initWithKey(razorpayTestKey, andDelegate: self)
        }
        
        func onPaymentError(_ code: Int32, description str: String) {
              print("error: ", code, str)
           //   self.presentAlert(withTitle: "Alert", message: str)
            // parent.alert with message
          }

          func onPaymentSuccess(_ payment_id: String) {
              print("success: ", payment_id)
           //   self.presentAlert(withTitle: "Success", message: "Payment Succeeded")
          }
    }
}

class CheckoutViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        //  self.showPaymentForm()
    }
}
0
Vishal Jadav On

Better version for integrate razorpay in swiftui based project:

import Razorpay
import SwiftUI

struct RazorpayView : UIViewControllerRepresentable {
    
    @State var razorKey : String
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<RazorpayView>) -> RazorViewController {
        let controller = RazorViewController()
        controller.razorKey = self.razorKey
        return controller
    }
    
    func updateUIViewController(_ uiViewController: RazorViewController, context: UIViewControllerRepresentableContext<RazorpayView>) {
        
    }
}

class RazorViewController: UIViewController {
    
    //MARK: - INSTANCE VARIABLES
    private var razorpay:RazorpayCheckout?
    var razorKey = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        razorpay = RazorpayCheckout.initWithKey(razorKey, andDelegateWithData: self)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.setNavigationBarHidden(true, animated: animated)
        
        let options: [String:Any] = [
            "amount" : "15", 
            "description": "test",
            "image": "https://url-to-image.jpg",
            "name": "test",
            "prefill": [
                "contact": "9797979797",
                "email": "[email protected]"
            ],
            "theme": [
                "color": "#F37254"
            ]
        ]
        razorpay?.open(options)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.setNavigationBarHidden(false, animated: animated)
    }
}

extension RazorViewController: RazorpayPaymentCompletionProtocolWithData {
    func onPaymentSuccess(_ payment_id: String, andData response: [AnyHashable : Any]?) {
        let alert = UIAlertController(title: "Paid", message: "Payment Success", preferredStyle: .alert)
        let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        alert.addAction(action)
        self.present(alert, animated: true, completion: nil)
    }
    
    func onPaymentError(_ code: Int32, description str: String, andData response: [AnyHashable : Any]?) {
        let alert = UIAlertController(title: "Error", message: "\(code)\n\(str)", preferredStyle: .alert)
        let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        alert.addAction(action)
        self.present(alert, animated: true, completion: nil)
    }
}