Airwallex logo

Save and reuse payment details

Copy for LLMView as Markdown

Both Airwallex iOS SDK and Airwallex Android SDK support recurring payments with certain payment methods.

Recurring payments involves three types of payment flows:

  • Save payment details
  • Subsequent customer-initiated transaction (CIT)
  • Subsequent merchant-initiated transaction (MIT)

See integration steps for each scenario, and use tabs for platform-specific steps.

Save payment details

iOS Recurring first time

Prepare payment session

Follow Prepare payment session to create a customer, payment intent, and payment session.

You must set PaymentConsentOptions when creating the payment session to save payment method for future payment.

swift
1let paymentConsentOptions = PaymentConsentOptions(
2 nextTriggeredBy: .customer, // or .merchant
3 merchantTriggerReason: .unscheduled // or .scheduled
4)
5
6let session = Session(
7 paymentIntent: paymentIntent,
8 countryCode: "Your country code",
9 paymentConsentOptions: paymentConsentOptions, // Required for recurring
10 returnURL: "myapp://payment/return"
11)

Present payment flow

Present the payment flow using AWXUIContext:

swift
1let configuration = AWXUIContext.Configuration()
2configuration.layout = .tab // or .accordion
3configuration.launchStyle = .push // or .present
4
5AWXUIContext.launchPayment(
6 from: "hosting view controller which also handles AWXPaymentResultDelegate",
7 session: session,
8 configuration: configuration
9)

Handle authentication result

In AWXPaymentResultDelegate, handle authentication result to present it to the shopper:

swift
1func paymentViewController(_ controller: UIViewController?, didCompleteWith status: AirwallexPaymentStatus, error: Error?) {
2 // call back for status success / in progress / failure / cancel
3}

If the payment consent is created during payment process, you can implement this optional function to get the ID of this payment consent for future use:

swift
1func paymentViewController(_ controller: UIViewController?, didCompleteWithPaymentConsentId paymentConsentId: String) {
2 // Store consent ID for future payments
3}

Retrieve the Payment Intent API from your server to query payment result and pass it to client app.

Android Recurring first time

  1. Create a customer object and pass it to your server if it is a new customer. Recurring payment requires a customer ID to be initiated.

    From your server, Create a Customer API with customer data received from client app and save the Customer ID returned.

  2. (Optional) If the shopper wishes to pay for the first order

    Your client app will need a PaymentIntent to form a payment session for Airwallex SDK to present payment flow.

    From your server, access Airwallex API to Create a Payment Intent API and pass the PaymentIntent returned to client app.

  3. Call AirwallexStarter.presentPaymentFlowto present the payment flow or the authentication flow to the shopper.

    a. PaymentIntent was created

    Call AirwallexStarter.presentPaymentFlow with an AirwallexRecurringWithIntentSession and a PaymentResultListener to present payment flow to the shopper. See sample code below for parameters required to create an AirwallexRecurringWithIntentSession.

    Java
    1val session = AirwallexRecurringWithIntentSession.Builder(
    2 paymentIntent = requireNotNull(
    3 paymentIntent,
    4 { "PaymentIntent is required" }
    5 ),
    6 customerId = requireNotNull(
    7 paymentIntent.customerId,
    8 { "CustomerId is required" }
    9 ),
    10 nextTriggerBy = nextTriggerBy,
    11 countryCode = Settings.countryCode
    12 )
    13 .setRequireCvc(requiresCVC)
    14 .setMerchantTriggerReason(if (nextTriggerBy == PaymentConsent.NextTriggeredBy.MERCHANT) PaymentConsent.MerchantTriggerReason.SCHEDULED else PaymentConsent.MerchantTriggerReason.UNSCHEDULED)
    15 .setReturnUrl(Settings.returnUrl)
    16 .setAutoCapture(Settings.autoCapture)
    17 .build()
    18AirwallexStarter.presentPaymentFlow(this, session,
    19 object : Airwallex.PaymentResultListener {
    20
    21 override fun onCompleted(status: AirwallexPaymentStatus) {
    22
    23 }
    24 }
    25 )

    b. NO payment is required here

    Call AirwallexStarter.presentPaymentFlow with an AirwallexRecurringSession and a PaymentResultListener to present the authentication flow to the shopper. See sample code below for parameters required to create an AirwallexRecurringWithIntentSession.

    Java
    1val session = AirwallexRecurringSession.Builder(
    2 customerId = customerId,
    3 currency = currency,
    4 amount = orderAmount,
    5 nextTriggerBy = nextTriggerBy,
    6 countryCode = countryCode // Alpha-2 country code of shopper region
    7)
    8 .setShipping(shipping)
    9 .setRequireCvc(requiresCVC)
    10 .setMerchantTriggerReason(if (nextTriggerBy == PaymentConsent.NextTriggeredBy.MERCHANT) PaymentConsent.MerchantTriggerReason.SCHEDULED else PaymentConsent.MerchantTriggerReason.UNSCHEDULED)
    11 .setReturnUrl(Settings.returnUrl)
    12 .build()
    13
    14AirwallexStarter.presentPaymentFlow(this, session,
    15 object : Airwallex.PaymentResultListener {
    16
    17 override fun onCompleted(status: AirwallexPaymentStatus) {
    18
    19 }
    20 }
    21)
  4. In your PaymentFLowListener, handle the authentication result returned from SDK and present it to the shopper.

    If PaymentIntent was created earlier, in onSuccess function above, ask your server to retrieve the payment result. From your server, retrieve the Payment Intent API after SDK has confirmed it with Airwallex API, and pass the payment result to your client app.

Subsequent customer-initiated transaction (CIT)

iOS Recurring CIT (card)

For subsequent payments where the customer initiates the transaction using a saved payment method.

Prepare payment session

Follow Prepare payment session to create a payment intent and payment session.

For subsequent one-off transactions, leave paymentConsentOptions as nil when creating the payment session.

swift
1let session = Session(
2 paymentIntent: paymentIntent,
3 countryCode: "Your country code",
4 // paymentConsentOptions is nil for one-off transactions
5 returnURL: "myapp://payment/return"
6)

Present payment flow

Present the payment flow using AWXUIContext. The SDK will automatically display saved cards for the customer:

swift
1let configuration = AWXUIContext.Configuration()
2configuration.layout = .tab // or .accordion
3configuration.launchStyle = .push // or .present
4
5AWXUIContext.launchPayment(
6 from: "hosting view controller which also handles AWXPaymentResultDelegate",
7 session: session,
8 configuration: configuration
9)

Handle payment result

After the PaymentIntent is confirmed by SDK, this delegate will be called by the SDK automatically:

swift
1func paymentViewController(_ controller: UIViewController?, didCompleteWith status: AirwallexPaymentStatus, error: Error?) {
2 // call back for status success / in progress / failure / cancel
3}

A completed flow does NOT imply a successful transaction. You need to query the payment result afterwards through your server to know whether the order is paid or not. Inside AWXPaymentResultDelegate, ask your server to retrieve the PaymentIntent.

On your server, retrieve the Payment Intent API, get the payment result within it and pass it to client app.

Android Recurring CIT (card)

  1. Create a Payment Intent with Customer ID to request payment for this order. You will get Payment Intent ID and client_secret returned.

  2. Call AirwallexStarter.presentPaymentFlow with an AirwallexSession and a PaymentResultListener to present payment flow to the shopper.

    Java
    1
    2val session = AirwallexPaymentSession.Builder(
    3 paymentIntent = paymentIntent,
    4 countryCode = Settings.countryCode
    5 )
    6 .setReturnUrl(Settings.returnUrl)
    7 .setAutoCapture(Settings.autoCapture)
    8 .build()
    9 AirwallexStarter.presentPaymentFlow(this, session,
    10 object : Airwallex.PaymentResultListener {
    11
    12 override fun onCompleted(status: AirwallexPaymentStatus) {
    13
    14 }
    15 }
    16 )
    17
  3. Retrieve the Payment Intent API in onSuccess function above to get the payment result from the PaymentIntent after the SDK has confirmed it with Airwallex API.

Subsequent merchant-initiated transaction (MIT)

MIT (card & E-wallet)

For merchant-initiated transactions (subscriptions, auto-debit), the payment is processed entirely on the server side.

  1. From your server, Create a Payment Intent API to request for a subsequent payment.

  2. Confirm the Payment Intent API with reference to Payment Consent ID of the stored Payment Consent.

MIT (card & E-wallet)

  1. From your server, Create a Payment Intent API to request for a subsequent payment.

  2. Confirm the Payment Intent API with reference to Payment Consent ID of the stored Payment Consent

Was this page helpful?