Airwallex logo

Mobile app

Copy for LLMView as Markdown

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.

Shell
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:

Shell
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.

JSON
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().

swift
1// MARK: - WKUIDelegate (Popup support in WebView)
2extension YourWebViewController: WKUIDelegate {
3
4 func webView(
5 _ webView: WKWebView,
6 createWebViewWith configuration: WKWebViewConfiguration,
7 for navigationAction: WKNavigationAction,
8 windowFeatures: WKWindowFeatures
9 ) -> WKWebView? {
10 // Only handle popup requests (when targetFrame is nil)
11 guard navigationAction.targetFrame == nil else { return nil }
12
13 let popupWebView = WKWebView(frame: .zero, configuration: configuration)
14
15 let popupViewController = YourWebViewController(webView: popupWebView)
16 popupViewController.isPopupWebView = true
17 present(popupViewController, animated: true)
18
19 return popupWebView
20 }
21
22 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 javaScriptCanOpenWindowsAutomatically is set to true on your WKWebViewConfiguration and assign the uiDelegate on your WKWebView.
  • Implement createWebViewWith to intercept pop-up requests (when targetFrame is nil) and present a new view controller with the pop-up content.
  • Implement webViewDidClose to dismiss the pop-up view controller when the page calls window.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:

Kotlin
1// Enable popup support in your WebView settings
2webView.settings.apply {
3 javaScriptEnabled = true
4 domStorageEnabled = true
5 setSupportMultipleWindows(true)
6 javaScriptCanOpenWindowsAutomatically = true
7}
8
9// Set a WebChromeClient to handle popup windows
10webView.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 = true
19 settings.domStorageEnabled = true
20 webViewClient = WebViewClient()
21 }
22
23 // Display the popup in a Dialog
24 val dialog = Dialog(context).apply {
25 setContentView(popupWebView)
26 window?.setLayout(
27 ViewGroup.LayoutParams.MATCH_PARENT,
28 ViewGroup.LayoutParams.MATCH_PARENT
29 )
30 setOnDismissListener { popupWebView.destroy() }
31 show()
32 }
33
34 // Handle window.close() from the popup
35 popupWebView.webChromeClient = object : WebChromeClient() {
36 override fun onCloseWindow(window: WebView?) {
37 dialog.dismiss()
38 }
39 }
40
41 val transport = resultMsg?.obj as? WebView.WebViewTransport
42 transport?.webView = popupWebView
43 resultMsg?.sendToTarget()
44 return true
45 }
46
47 override fun onCloseWindow(window: WebView?) {
48 // Handle window.close() on the main WebView if needed
49 }
50}

Key points for Android:

  • Call setSupportMultipleWindows(true) and javaScriptCanOpenWindowsAutomatically = true on the WebSettings to enable pop-up support.
  • Set a WebChromeClient and override onCreateWindow to create a new WebView for the pop-up content. Use WebView.WebViewTransport to pass the new WebView back to the system.
  • Override onCloseWindow to dismiss the pop-up dialog when the page calls window.close().
  • Clean up the pop-up WebView in setOnDismissListener to 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.

Was this page helpful?