Instant Bank Transfer Integration

This section covers the integration of payabl. Instant Bank Transfer. This feature redirects users to their banking app or browser and returns them to your app via a deep link.

Integrate iOS SDK Instant Bank Transfer button

ViewModel and Delegate Implementation

 class DemoCartViewModel: ObservableObject {
    let backendCheckoutUrl = URL(string: "backend_endpoint/payment_page")!
    var instantBankTransfer: PBLInstantBankTransfer?
    var configuration: PBLConfiguration?
    @Published var pblInstantBankTransferLoaded: Bool = false
    
    func prepareOrder() async -> PBLConfiguration? {
        var request = URLRequest(url: backendCheckoutUrl)
        request.httpMethod = "POST"
        await withCheckedContinuation { [weak self] continuation in
            let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
                guard let data = data,
                      let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]
                else { return }
                let sessionId = json["sessionId"]
                let transactionId = json["transactionId"]
                let ephemeralKey = json["empheralKey"]
                
                self?.configuration = PBLConfiguration(
                    sessionId: sessionId as! String,
                    ephemeralKey: ephemeralKey as! String,
                    customerId: "",
                    environment: .sandbox,
                    transactionId: transactionId as! Int,
                    appleMerchantId: "merchant.payabl.isdk"  // Apple merchant id registered in developer.apple.com
                )
                continuation.resume()
            })
        }
        return self.configuration
    }
    
    func prepareInstantBankTransfer() async -> PBLConfiguration? {
        guard let pblData = await prepareOrder() else { return nil }
        Task { @MainActor in
            pblInstantBankTransferLoaded = true
        }
        return self.configuration
    }
}

extension DemoCartViewModel: PBLInstantBankTransferDelegate {
    func instantBankTransferTapped(onLoadSessionCompleted: @escaping (PayablMerchant.PBLConfiguration) -> Void) {
        Task {
            guard let config = await prepareInstantBankTransfer() else { return }
            onLoadSessionCompleted(config)
        }
    }
    
    func instantBankTransferCompleted(result: PayablMerchant.PBLPaymentResult) {
        print(result)
    }
}

extension DemoCartViewModel: PBLErrorDelegate {
    func errorOccured(error: any Error) {
        print("error from sdk: ", error)
    }
}
📘

Note

PBLPaymentResult.finished indicates that the payment flow has finished, but it does not guarantee a successful transaction. The final transaction status will be confirmed through a server-to-server notification sent to your backend via the notification_url.

SwiftUI View (Custom Button)

struct ContentView: View {
    let cartVM = DemoCartViewModel()
    var body: some View {
        HStack {
            if cartVM.pblInstantBankTransferLoaded {
                cartVM.instantBankTransfer?.button {
                    ZStack {
                        Text("Instant bank transfer")
                            .foregroundStyle(.white)
                    }
                    .background {
                        Color.green
                    }
                }
            }
        }
        .onAppear {
            Task {
                cartVM.instantBankTransfer = PBLInstantBankTransfer(delegate: cartVM, errorDelegate: cartVM)
                cartVM.pblInstantBankTransferLoaded = true
            }
        }
    }
}

Requirements for Instant Bank Transfer

  • Callback URLs: For Instant Bank Transfers, you must define redirect URLs in the initialization request (even if they are marked as optional elsewhere):
    • url_success: Redirect after a successful payment.
    • url_failed: Redirect after a failed or cancelled payment.
    • url_return: Generic Redirect url.
    • notification_url: Server-to-server webhook for final confirmation.
    • app_schema: Required custom URL scheme for deep linking (e.g., "payabl", "yourapp"). If not specified, you may receive an error from the backend. This value should match the android:scheme in your AndroidManifest deep link configuration. Apart from notification_url, all other URLs can be custom schemes or App Links.

Deep Linking (Info.plist)

To handle the redirect back from the Banking App (especially for custom schemes like payabl://), you must register the URL scheme. Add this to your Info.plist: To handle the redirect back from the Banking App (especially for custom schemes like payabl://), you must register the URL scheme. Add this to your Info.plist:


<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>payabl</string>
    </array>
    <key>CFBundleURLName</key>
    <string>Payment Callback</string>
  </dict>
</array>

Examples:


{
  ...
  "app_schema": "payabl"
  "url_failed": "payabl://payment-callback/failed",
  "url_success": "payabl://payment-callback/success",
  "notification_url": "https://your-server.com/api/webhook",
  "url_return": "https://payabl.com/payment-callback/redirect_response.php"
  ...
}