From a6f6fef7504ea3789342ffe80e516069443baf86 Mon Sep 17 00:00:00 2001 From: weiping-awx Date: Tue, 16 Jun 2026 18:16:07 +0800 Subject: [PATCH] doc: documentation for public API --- .../AirwallexPaymentFlutterPlugin.swift | 3 +- .../AirwallexSdk.swift | 7 +++- lib/airwallex.dart | 41 +++++++++++++++++++ lib/types/apple_pay_options.dart | 11 +++++ lib/types/card.dart | 6 +++ lib/types/google_pay_options.dart | 10 +++++ lib/types/merchant_trigger_reason.dart | 5 +++ lib/types/next_triggered_by.dart | 1 + lib/types/payment_consent.dart | 5 +++ lib/types/payment_result.dart | 9 ++++ lib/types/payment_session.dart | 13 ++++++ lib/types/payment_sheet_configuration.dart | 5 +++ lib/types/shipping.dart | 2 + 13 files changed, 116 insertions(+), 2 deletions(-) diff --git a/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexPaymentFlutterPlugin.swift b/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexPaymentFlutterPlugin.swift index 4ba2289..11b4fba 100644 --- a/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexPaymentFlutterPlugin.swift +++ b/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexPaymentFlutterPlugin.swift @@ -19,7 +19,8 @@ public class AirwallexPaymentFlutterPlugin: NSObject, FlutterPlugin { case "initialize": sdk = AirwallexSdk() let arguments = call.arguments as! NSDictionary - sdk?.initialize(environment: arguments["environment"] as! String) + let saveLogToLocal = (arguments["saveLogToLocal"] as? Bool) ?? false + sdk?.initialize(environment: arguments["environment"] as! String, saveLogToLocal: saveLogToLocal) result(nil) case "presentEntirePaymentFlow": let arguments = call.arguments as! NSDictionary diff --git a/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexSdk.swift b/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexSdk.swift index 0ed5a12..1ffeaca 100644 --- a/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexSdk.swift +++ b/ios/airwallex_payment_flutter/Sources/airwallex_payment_flutter/AirwallexSdk.swift @@ -6,10 +6,15 @@ class AirwallexSdk: NSObject { private var paymentConsentID: String? private var paymentSessionHandler: PaymentSessionHandler? - func initialize(environment: String) { + func initialize(environment: String, saveLogToLocal: Bool) { let mode = AirwallexSDKMode.from(environment) Airwallex.setMode(mode) AWXAPIClientConfiguration.shared() + if saveLogToLocal { + Airwallex.enableLocalLogFile() + } else { + Airwallex.disableLocalLogFile() + } AnalyticsLogger.shared().bindExtraCommonData(["framework": "flutter", "frameworkVersion": "0.3.0"]) } diff --git a/lib/airwallex.dart b/lib/airwallex.dart index a439d2f..d4c8d73 100644 --- a/lib/airwallex.dart +++ b/lib/airwallex.dart @@ -13,6 +13,11 @@ import '/types/payment_sheet_configuration.dart'; import 'airwallex_payment_flutter_platform_interface.dart'; class Airwallex { + /// Initializes the Airwallex SDK. Call this once at app startup before invoking any other payment method. + /// + /// @param environment - The Airwallex environment to connect to. Defaults to `Environment.production`. + /// @param enableLogging - When `true`, the SDK emits logs to the console. Android only. Defaults to `true`. + /// @param saveLogToLocal - When `true`, logs are also persisted to a local file for debugging. Defaults to `false`. static void initialize({ Environment environment = Environment.production, bool enableLogging = true, bool saveLogToLocal = false}) { if (enableLogging && kDebugMode) { @@ -21,6 +26,12 @@ class Airwallex { AirwallexPaymentFlutterPlatform.instance.initialize(environment, enableLogging, saveLogToLocal); } + /// Presents the full Airwallex payment sheet, letting the customer pick any supported payment method + /// (cards, wallets, redirect methods) and complete the payment. + /// + /// @param session - The payment session describing the intent, amount, currency, and customer. + /// @param configuration - Optional UI configuration for the payment sheet (e.g. layout). + /// @returns The result of the payment attempt. Future presentEntirePaymentFlow( BaseSession session, { PaymentSheetConfiguration? configuration, @@ -29,6 +40,12 @@ class Airwallex { .presentEntirePaymentFlow(session, configuration: configuration); } + /// Presents the card-only payment sheet. Use this when the merchant wants to restrict checkout + /// to card payments and skip the payment-method selection screen. + /// + /// @param session - The payment session describing the intent, amount, currency, and customer. + /// @param supportedBrands - Optional list of card brands to accept. When `null`, all supported brands are accepted. + /// @returns The result of the payment attempt. Future presentCardPaymentFlow( BaseSession session, { List? supportedBrands, @@ -37,24 +54,48 @@ class Airwallex { .presentCardPaymentFlow(session, supportedBrands: supportedBrands); } + /// Pays with raw card details collected by the merchant's own UI. The merchant is responsible + /// for PCI compliance when using this method. + /// + /// @param session - The payment session describing the intent, amount, currency, and customer. + /// @param card - The card details to charge. + /// @param saveCard - When `true`, the card is saved as a payment consent for future use. + /// @returns The result of the payment attempt. Future payWithCardDetails(BaseSession session, Card card, bool saveCard) { return AirwallexPaymentFlutterPlatform.instance .payWithCardDetails(session, card, saveCard); } + /// Pays using an existing payment consent (a previously saved card). + /// + /// @param session - The payment session describing the intent, amount, currency, and customer. + /// @param consent - The payment consent to charge. + /// @returns The result of the payment attempt. Future payWithConsent(BaseSession session, PaymentConsent consent) { return AirwallexPaymentFlutterPlatform.instance .payWithConsent(session, consent); } + /// Starts a Google Pay payment flow. Android only. + /// + /// @param session - The payment session. Must include `googlePayOptions` for the merchant configuration. + /// @returns The result of the payment attempt. Future startGooglePay(BaseSession session) { return AirwallexPaymentFlutterPlatform.instance.startGooglePay(session); } + /// Starts an Apple Pay payment flow. iOS only. + /// + /// @param session - The payment session. Must include `applePayOptions` for the merchant configuration. + /// @returns The result of the payment attempt. Future startApplePay(BaseSession session) { return AirwallexPaymentFlutterPlatform.instance.startApplePay(session); } + /// Sets the tint color used by the native payment UI on iOS. + /// On Android, override the `airwallex_tint_color` resource instead. + /// + /// @param color - The tint color to apply. static void setTintColor(Color color) { AirwallexPaymentFlutterPlatform.instance.setTintColor(color); } diff --git a/lib/types/apple_pay_options.dart b/lib/types/apple_pay_options.dart index 1bdf603..637b2e8 100644 --- a/lib/types/apple_pay_options.dart +++ b/lib/types/apple_pay_options.dart @@ -2,6 +2,10 @@ import 'package:json_annotation/json_annotation.dart'; part 'apple_pay_options.g.dart'; +/// Apple Pay configuration. Required on a `PaymentSession` when invoking +/// `startApplePay`, or when offering Apple Pay through `presentEntirePaymentFlow` on iOS. +/// +/// `merchantIdentifier` must match the Apple Pay merchant ID configured in the app's entitlements. @JsonSerializable(explicitToJson: true) class ApplePayOptions { String merchantIdentifier; @@ -27,6 +31,7 @@ class ApplePayOptions { Map toJson() => _$ApplePayOptionsToJson(this); } +/// Card networks the merchant is willing to accept through Apple Pay. enum ApplePaySupportedNetwork { visa, masterCard, @@ -37,6 +42,7 @@ enum ApplePaySupportedNetwork { maestro } +/// Payment-processing capabilities the merchant supports. `supports3DS` is required by Apple Pay. enum ApplePayMerchantCapability { supports3DS, supportsCredit, @@ -44,6 +50,7 @@ enum ApplePayMerchantCapability { supportsEMV, } +/// Contact fields the merchant requires from the customer during Apple Pay checkout. enum ContactField { emailAddress, name, @@ -52,6 +59,8 @@ enum ContactField { postalAddress, } +/// An additional line item displayed in the Apple Pay summary +/// (e.g. tax, shipping, discount) on top of the session amount. @JsonSerializable() class CartSummaryItem { String label; @@ -69,6 +78,8 @@ class CartSummaryItem { Map toJson() => _$CartSummaryItemToJson(this); } +/// Whether a `CartSummaryItem` amount is final or still pending +/// (e.g. shipping not yet calculated). enum CartSummaryItemType { finalType, pendingType, diff --git a/lib/types/card.dart b/lib/types/card.dart index 4348eee..ddde820 100644 --- a/lib/types/card.dart +++ b/lib/types/card.dart @@ -2,6 +2,12 @@ import 'package:json_annotation/json_annotation.dart'; part 'card.g.dart'; +/// Card details. When used as input to `payWithCardDetails`, the merchant +/// supplies `number`, `expiryMonth`, `expiryYear`, `cvc`, and optionally `name`. +/// +/// The remaining fields (`bin`, `last4`, `brand`, `fingerprint`, `cvcCheck`, +/// `avsCheck`, etc.) are populated by Airwallex when a Card is returned as part of +/// a saved payment method on a `PaymentConsent`. @JsonSerializable(fieldRename: FieldRename.snake, includeIfNull: false) class Card { String? cvc; diff --git a/lib/types/google_pay_options.dart b/lib/types/google_pay_options.dart index cc5805f..14469c1 100644 --- a/lib/types/google_pay_options.dart +++ b/lib/types/google_pay_options.dart @@ -2,6 +2,8 @@ import 'package:json_annotation/json_annotation.dart'; part 'google_pay_options.g.dart'; +/// Google Pay configuration. Required on a `PaymentSession` when invoking +/// `startGooglePay`, or when offering Google Pay through `presentEntirePaymentFlow` on Android. @JsonSerializable(explicitToJson: true) class GooglePayOptions { List? allowedCardAuthMethods; @@ -44,6 +46,7 @@ class GooglePayOptions { Map toJson() => _$GooglePayOptionsToJson(this); } +/// Controls how the customer's billing address is collected via Google Pay. @JsonSerializable() class BillingAddressParameters { Format? format; @@ -59,11 +62,16 @@ class BillingAddressParameters { Map toJson() => _$BillingAddressParametersToJson(this); } +/// How much of the billing address Google Pay should return. +/// +/// - `min` — postal code and country only (sufficient for most card validation). +/// - `full` — full address. enum Format { min, full, } +/// Controls how the customer's shipping address is collected via Google Pay. @JsonSerializable() class ShippingAddressParameters { List? allowedCountryCodes; @@ -79,6 +87,8 @@ class ShippingAddressParameters { Map toJson() => _$ShippingAddressParametersToJson(this); } +/// The set of card networks Airwallex supports through Google Pay. Useful as a default value +/// for `GooglePayOptions.allowedCardNetworks` when the merchant has no preference. List googlePaySupportedNetworks() { return [ "AMEX", diff --git a/lib/types/merchant_trigger_reason.dart b/lib/types/merchant_trigger_reason.dart index 8bebff8..fbeb047 100644 --- a/lib/types/merchant_trigger_reason.dart +++ b/lib/types/merchant_trigger_reason.dart @@ -1,3 +1,8 @@ +/// Why the merchant is triggering a charge against a saved payment consent. +/// Only meaningful when `NextTriggeredBy` is `merchant`. +/// +/// - `scheduled` — fixed-interval billing the customer has agreed to (e.g. monthly subscription). +/// - `unscheduled` — merchant-initiated charge at an unpredictable time (e.g. account top-up, usage overage). enum MerchantTriggerReason { unscheduled, scheduled, diff --git a/lib/types/next_triggered_by.dart b/lib/types/next_triggered_by.dart index 76f8cf7..78c9e0d 100644 --- a/lib/types/next_triggered_by.dart +++ b/lib/types/next_triggered_by.dart @@ -1,3 +1,4 @@ +/// Who initiates the next charge against a saved payment consent. enum NextTriggeredBy { merchant, customer, diff --git a/lib/types/payment_consent.dart b/lib/types/payment_consent.dart index 6542239..1a2bdb9 100644 --- a/lib/types/payment_consent.dart +++ b/lib/types/payment_consent.dart @@ -6,6 +6,9 @@ import 'package:airwallex_payment_flutter/types/shipping.dart'; part 'payment_consent.g.dart'; +/// A reusable payment authorization tied to a customer and a payment method. +/// Created during a `RecurringSession` / `RecurringWithIntentSession` flow, +/// and later passed to `payWithConsent` to charge without re-prompting the customer. @JsonSerializable(explicitToJson: true, fieldRename: FieldRename.snake, includeIfNull: false) class PaymentConsent { String? id; @@ -45,6 +48,8 @@ class PaymentConsent { Map toJson() => _$PaymentConsentToJson(this); } +/// The payment instrument attached to a `PaymentConsent` — typically a saved card, +/// along with its billing details. @JsonSerializable(explicitToJson: true, fieldRename: FieldRename.snake, includeIfNull: false) class PaymentMethod { String? id; diff --git a/lib/types/payment_result.dart b/lib/types/payment_result.dart index 6937052..2158c44 100644 --- a/lib/types/payment_result.dart +++ b/lib/types/payment_result.dart @@ -1,8 +1,14 @@ +/// The outcome of a payment flow. Discriminated by `status`: +/// `'success'`, `'inProgress'`, or `'cancelled'`. +/// +/// Errors are not represented here — they are surfaced by the returned `Future` failing. abstract class PaymentResult { final String status; PaymentResult(this.status); } +/// The payment completed successfully. If a payment consent was created during the +/// flow, its id is returned in `paymentConsentId`. class PaymentSuccessResult extends PaymentResult { final String? paymentConsentId; @@ -10,10 +16,13 @@ class PaymentSuccessResult extends PaymentResult { : super('success'); } +/// The payment has been submitted but its final outcome is not yet known. +/// The merchant should poll the payment intent or wait for a webhook to confirm the result. class PaymentInProgressResult extends PaymentResult { PaymentInProgressResult() : super('inProgress'); } +/// The customer cancelled the payment flow before it completed. class PaymentCancelledResult extends PaymentResult { PaymentCancelledResult() : super('cancelled'); } \ No newline at end of file diff --git a/lib/types/payment_session.dart b/lib/types/payment_session.dart index e1d17fd..1c07ac9 100644 --- a/lib/types/payment_session.dart +++ b/lib/types/payment_session.dart @@ -7,6 +7,14 @@ import 'merchant_trigger_reason.dart'; part 'payment_session.g.dart'; +/// Base class for every payment session. A session bundles the authentication +/// (`clientSecret`), amount and currency, customer details, and optional wallet +/// configuration into the single value passed to every payment flow method. +/// +/// Pick a concrete subclass based on what the merchant wants to do: +/// - `OneOffSession` — charge the customer once. +/// - `RecurringSession` — save a payment method for future recurring charges, without charging now. +/// - `RecurringWithIntentSession` — charge now AND save the payment method for future recurring charges. abstract class BaseSession { String type; String? customerId; @@ -42,6 +50,7 @@ abstract class BaseSession { Map toJson(); } +/// A one-off payment against a payment intent. @JsonSerializable(explicitToJson: true) class OneOffSession extends BaseSession { String paymentIntentId; @@ -70,6 +79,8 @@ class OneOffSession extends BaseSession { Map toJson() => _$OneOffSessionToJson(this); } +/// A session that sets up a payment consent for future recurring charges +/// without charging the customer right now. @JsonSerializable(explicitToJson: true) class RecurringSession extends BaseSession { NextTriggeredBy nextTriggeredBy; @@ -96,6 +107,8 @@ class RecurringSession extends BaseSession { Map toJson() => _$RecurringSessionToJson(this); } +/// A session that charges a payment intent now and sets up a payment consent +/// for future recurring charges in a single step. @JsonSerializable(explicitToJson: true) class RecurringWithIntentSession extends BaseSession { String paymentIntentId; diff --git a/lib/types/payment_sheet_configuration.dart b/lib/types/payment_sheet_configuration.dart index d4dd3db..690a060 100644 --- a/lib/types/payment_sheet_configuration.dart +++ b/lib/types/payment_sheet_configuration.dart @@ -1,5 +1,10 @@ +/// How payment methods are arranged on the payment sheet. +/// +/// - `tab` — payment methods shown as horizontally-scrollable tabs. +/// - `accordion` — payment methods stacked vertically, expanding on tap. enum PaymentLayout { tab, accordion } +/// Optional UI configuration for the payment sheet shown by `presentEntirePaymentFlow`. class PaymentSheetConfiguration { final PaymentLayout layout; diff --git a/lib/types/shipping.dart b/lib/types/shipping.dart index 9975f5c..57434fe 100644 --- a/lib/types/shipping.dart +++ b/lib/types/shipping.dart @@ -2,6 +2,8 @@ import 'package:json_annotation/json_annotation.dart'; part 'shipping.g.dart'; +/// Customer shipping (and billing, when reused via `PaymentMethod.billing`) details +/// pre-filled into the payment sheet. @JsonSerializable(explicitToJson: true) class Shipping { String? firstName;