Mobile app
Accept Pay-easy payments from your mobile app on your shopper's Android or iOS phone by loading the Pay-easy payment page in a WebView. You will also need to handle pop-up windows in the WebView in order to process payments for Pay-easy.
Step 1. Initialize a Payment Intent
Create a PaymentIntent object with a request_id, amount, currency and a merchant_order_id from your backend server.
1curl -X POST https://api-demo.airwallex.com/api/v1/pa/payment_intents/create \2 -H 'Content-Type: application/json' \3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \4 -d '{5 "request_id": "ed11e38a-7234-11ea-aa94-7fd44ffd1b89",6 "amount": 20,7 "currency": "JPY",8 "merchant_order_id": "85d7b0e0-7235-11ea-862e-9f6aa1adfca6",9 "return_url": "https://www.airwallex.com"10 }'
Step 2. Confirm the intent to obtain the redirect URL
When a shopper selects to pay with Pay-easy on their mobile app, call the following API endpoint to get the URL which you can use to load the Pay-easy payment page in a WebView.
Request:
1curl -X POST https://api-demo.airwallex.com/api/v1/pa/payment_intents/{{PAYMENT_INTENT_ID}}/confirm \2 -H 'Content-Type: application/json' \3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \4 -d '{5 "request_id": "ed11e38a-7234-11ea-aa94-7fd44ffd1b89",6 "payment_method": {7 "type": "payeasy",8 "payeasy": {9 "shopper_name": "xxxxxx",10 "shopper_email": "[email protected]",11 "shopper_phone": "0104568978"12 }13 }14 }'
Response: Use the value of url to load the Pay-easy payment page in a WebView.
1{2 "next_action": {3 "type": "redirect",4 "method": "GET",5 "url": "https://r2.girogate.de/econtext/T1122/I?tx=915232725&rs=mmj4dQl8Bc448SAR2kfhfakE7hHONeVd&cs=8f96414821982946640f4799474c73d9819e747a7faffe9d247c3aad8e6ff9b4"6 }7}
Step 3. (Optional) Handle the redirect URL in WebView
When loading the Pay-easy payment page in your app's WebView, you may need to handle pop-up windows. The Pay-easy payment page may open new windows for bank authentication or payment confirmation. Without proper pop-up handling, these windows will fail to open and the payment flow will break.
iOS
To handle pop-up windows in WKWebView on iOS, implement the WKUIDelegate protocol. When the payment page requests a new window (for example, for bank authentication), targetFrame will be nil. You need to create a new WKWebView to display the pop-up content and dismiss it when the pop-up calls window.close().
1// MARK: - WKUIDelegate (Popup support in WebView)2extension YourWebViewController: WKUIDelegate {34 func webView(5 _ webView: WKWebView,6 createWebViewWith configuration: WKWebViewConfiguration,7 for navigationAction: WKNavigationAction,8 windowFeatures: WKWindowFeatures9 ) -> WKWebView? {10 // Only handle popup requests (when targetFrame is nil)11 guard navigationAction.targetFrame == nil else { return nil }1213 let popupWebView = WKWebView(frame: .zero, configuration: configuration)1415 let popupViewController = YourWebViewController(webView: popupWebView)16 popupViewController.isPopupWebView = true17 present(popupViewController, animated: true)1819 return popupWebView20 }2122 func webViewDidClose(_ webView: WKWebView) {23 if let presentingViewController {24 presentingViewController.dismiss(animated: true)25 } else if let navigationController {26 navigationController.popViewController(animated: true)27 }28 }29}
Key points for iOS:
- Ensure
javaScriptCanOpenWindowsAutomaticallyis set totrueon yourWKWebViewConfigurationand assign theuiDelegateon yourWKWebView. - Implement
createWebViewWithto intercept pop-up requests (whentargetFrameisnil) and present a new view controller with the pop-up content. - Implement
webViewDidCloseto dismiss the pop-up view controller when the page callswindow.close().
Android
To handle pop-up windows in WebView on Android, set a WebChromeClient that overrides onCreateWindow. By default, Android WebView does not handle window.open() calls. You need to enable multi-window support in the WebView settings and provide a WebChromeClient to create and manage the pop-up WebView.
Enable multi-window support in your WebView settings and set a WebChromeClient that handles onCreateWindow:
1// Enable popup support in your WebView settings2webView.settings.apply {3 javaScriptEnabled = true4 domStorageEnabled = true5 setSupportMultipleWindows(true)6 javaScriptCanOpenWindowsAutomatically = true7}89// Set a WebChromeClient to handle popup windows10webView.webChromeClient = object : WebChromeClient() {11 override fun onCreateWindow(12 view: WebView?,13 isDialog: Boolean,14 isUserGesture: Boolean,15 resultMsg: Message?16 ): Boolean {17 val popupWebView = WebView(context).apply {18 settings.javaScriptEnabled = true19 settings.domStorageEnabled = true20 webViewClient = WebViewClient()21 }2223 // Display the popup in a Dialog24 val dialog = Dialog(context).apply {25 setContentView(popupWebView)26 window?.setLayout(27 ViewGroup.LayoutParams.MATCH_PARENT,28 ViewGroup.LayoutParams.MATCH_PARENT29 )30 setOnDismissListener { popupWebView.destroy() }31 show()32 }3334 // Handle window.close() from the popup35 popupWebView.webChromeClient = object : WebChromeClient() {36 override fun onCloseWindow(window: WebView?) {37 dialog.dismiss()38 }39 }4041 val transport = resultMsg?.obj as? WebView.WebViewTransport42 transport?.webView = popupWebView43 resultMsg?.sendToTarget()44 return true45 }4647 override fun onCloseWindow(window: WebView?) {48 // Handle window.close() on the main WebView if needed49 }50}
Key points for Android:
- Call
setSupportMultipleWindows(true)andjavaScriptCanOpenWindowsAutomatically = trueon theWebSettingsto enable pop-up support. - Set a
WebChromeClientand overrideonCreateWindowto create a newWebViewfor the pop-up content. UseWebView.WebViewTransportto pass the newWebViewback to the system. - Override
onCloseWindowto dismiss the pop-up dialog when the page callswindow.close(). - Clean up the pop-up
WebViewinsetOnDismissListenerto prevent memory leaks.
Step 4. Query the payment result status
To get the payment result, we suggest you poll the status of the Payment Intent via the Retrieve a Payment Intent API API. You may start polling the Payment Intent status after the shopper is redirected back to your website or mobile app, i.e., the return_url passed when creating the Payment Intent.
In addition, Airwallex will notify you of the payment result asynchronously via the webhooks. Please refer to the webhook documentation to set up your webhook accordingly. Although subscribing to webhook events is optional, it is recommended to subscribe to the payment_intent.succeeded webhook which indicates that the shopper has paid the order.