Instant Bank Transfer Integration

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

Although mobile/init treats url_failed, url_success, url_return, notification_url as optional parameters, for instant bank transfer session to be valid, we expect these params to be part of mobile/init API.

No additional configuration or setup is required. The SDK handles the full flow.