Airwallex logo

Drop-in integration

The Drop in integration enables Merchants to accept payments when they wish to partially delegate the responsibility of handling their payments but they still aim to control the overall look and feel of their payments page. Note that a limited PCI-DSS certification is required for this integration

The following steps will guide you through our integrations.

  1. Initially you need to create a Payment Intent. The payment intent captures the details of your checkout and includes the currency and amount you wish to charge your customer.
curl https://pci-api.airwallex.com/api/v1/pa/payment_intents/create \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer your_bearer_token \
  -d '{
    "request_id": "ed11e38a-7234-11ea-aa94-7fd44ffd1b89",
    "amount": 100,
    "currency": "CNY",
    "merchant_order_id": "85d7b0e0-7235-11ea-862e-9f6aa1adfca6"
  }'

The response of the Payment Intent creation looks as below and contains a client_secret, it represents your payment session and you need to use it to request the URL where you will redirect your client

  1. In order to leverage the components that Airwallex has built on your behalf, you will need to leverage our frontend scripts.

Load the Airwallex checkout JavaScript in your front end and initialize it accordingly with the information you received.

In order to do so you can get the airwallex-payment-elements yarn or npm package

yarn add airwallex-payment-elements
npm install airwallex-payment-elements

You can also embed the code directly in your HTML client.

<!-- Step #1: Load Checkout Universal Module Definition (UMD) bundle js-->
<script src="https://checkout-staging.airwallex.com/assets/bundle.0.0.xx.min.js"></script>

Initialize it with

// Step #2: Initialize the Airwallex global context for event communication
Airwallex.init({
 env: 'demo', // Setup which env('staging' | 'demo' | 'prod') you would like to integrate with
 origin: window.location.origin, // Setup your event target to receive the browser events message
});

Pay attention to the following parameters:

  • env: Required setup which env('staging' | 'demo' | 'prod') you would like to integrate with
  • origin: Required setup your event target to receive the browser events message

  • options [Optional] you can provide additional parameters to customize your checkout following the below interface.

/**
* Global font option config for Airwallex integration methods
*/
export interface FontOptions {
 /**
  * The font-family property
  * https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
  */
 family?: string;
 /**
  * The font source url
  * https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face
  */
 src?: string;
 /**
  * The font-weight property
  * https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
  */
 weight?: string | number;
}
/**
* Indicate which airwallex integration env your merchant site would like to connect with
*/
export type AirwallexEnv = 'dev' | 'preview' | 'qa' | 'staging' | 'demo' | 'prod';
/**
* Global init option config for Airwallex javascript SDK
*/
export interface InitOptions {
 /**
  * Indicate which airwallex integration env your merchant site would like to connect with
  * If not provide default will be prod which point to [Airwallex Checkout](https://checkout.airwallex.com)
  */
 env?: AirwallexEnv;
 /**
  * Your checkout website origin url, aka merchant checkout page's 'window.location.origin' field
  */
 origin?: string;
 /**
  * i18n localization config
  */
 locale?: 'en' | 'zh';
 /**
  * Global font options
  */
 font?: FontOptions;
}
  1. It is time to create the elements that will help you to capture the payment details. You can further customize those with the Style interface:
/**
* The definition mapping of supported integration element type with it's props options used to customize the element, merchant can check on each element options type for details
*/
export interface ElementOptionsTypeMap {
 /**
  * Define card number input element type and it's mapped option type, apply to split card element integration
  * Using together with `expiry` and `cvc` element to gain maximum customization
  */
 cardNumber: CardNumberElementOptions;
 /**
  * Define expiry input element type and it's mapped option type, apply to split card element integration
  * Using together with `cardNumber` and `cvc` element to gain maximum customization
  */
 expiry: ExpiryDateElementOptions;
 /**
  * Define cvc input element type and it's mapped option type, apply to split card element integration
  * Using together with `cardNumber` and `expiry` element to gain maximum customization
  */
 cvc: CvcElementOptions;
 /**
  * Define W3C payment request API element type and it's mapped option type
  */
 paymentRequestButton: PaymentRequestButtonOptions;
 /**
  * Define card element type and it's mapped option type, this integration make the card PCI input (card number / cvc / expiry) behavior like a single input
  */
 card: CardElementOptions;
 /**
  * Define WeChat element type and it's mapped option type
  */
 wechat: WechatElementOptions;
 /**
  * Define dropIn element type and it's mapped option type, this integration make integrate with Airwallex supported card and APM (alternative payment method like WeChat etc.) payment method like a single widget
  */
 dropIn: DropInElementOptions;
 /**
  * Define full featured card element type and it's mapped option type, this integration make integrate with Airwallex supported card payment method like a single widget
  */
 fullFeaturedCard: FullFeaturedCardElementOptions;
}

/**
* Element integration `step #2`
* Create payment element for checkout
*/
export declare function createElement<T extends ElementType>(
 type: T,
 options?: ElementOptionsTypeMap[T],
): Element | null;
/**
* The payment intent you would like to checkout
* Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Payment_Intents/Intro)
*
* ***Hint***:
* This interface only contain the necessary information when shopper checkout
* For the detail meaning of each field you can refer to above api document
*/
export interface Intent {
 /**
  * Id of intent
  */
 id: string;
 /**
  * client_secret of intent
  */
 client_secret?: string;
 /**
  * Your request id when create payment intent
  */
 request_id?: string;
 amount?: number;
 currency?: string;
 merchant_order_id?: string;
 customer_id?: string;
 status?: string;
 created_at?: string;
 updated_at?: string;
}
 /**
* Supported customized pseudo css style for `cardNumber` | `expiry` | `cvc` elements
* https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
*/
type PseudoClasses = ':hover' | ':focus' | '::placeholder' | '::selection' | ':disabled';
/**
* Pseudo-classes object
*/
type PseudoClassStyle = { [K in PseudoClasses]?: Properties };

/**
* Customize the the element using CSS properties
* 1. Reference: https://github.com/frenic/csstype
* 2. Extend with element variations for `hpp` | `card` | `dropIn`, following the best practices of https://material-ui.com/api/input-base/
* 3. To support customized Popup overlay width and height
*/
export interface Style extends PseudoClassStyle, Properties {
 /**
  * Input variation for `hpp` | `card` | `dropIn` integration
  */
 variant?: 'outlined' | 'filled' | 'standard' | 'bootstrap';
 /**
  * Customized Popup overlay width like 3DS payment flow
  */
 popupWidth?: number;
 /**
  * Customized Popup overlay height like 3DS payment flow
  */
 popupHeight?: number;
}

/**
* Config options for element integration, support using for ElementType
*/
export interface ElementOptions {
 /**
  * Element css style camelcase option, default style by Chrome browser default
  */
 style?: Style;
 /**
  * Your checkout website origin url, aka merchant checkout page's 'window.location.origin' field
  */
 origin?: string;
}
export interface DropInElementOptions extends ElementOptions {
 /**
  * The payment intent you would like to checkout
  * Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Payment_Intents/Intro)
  *
  */
 intent?: Intent;
 /**
  * The payment method component your website would like to integrate with
  */
 component?: 'default' | 'card' | 'wechatpay';
 /**
  * Indicate whether to capture immediate when authentication success
  */
 autoCapture?: boolean;
 /**
  * Indicate to improve 3DS experience, indicate if the payment form will collect billing info from shopper
  */
 withBilling?: boolean;
}

/**
* Supported integration element type
*/
export type ElementType =
 | 'cardNumber'
 | 'expiry'
 | 'cvc'
 | 'paymentRequestButton'
 | 'card'
 | 'wechat'
 | 'dropIn'
 | 'fullFeaturedCard';

/**
* Functions and external fields can be using in your integration flow with airwallex element
*
* Two ways to get elements, by call createElement function or getElement
*
* ***IMPORTANT***
*
* Once element destroy by call function destroyElement, the element reference should not be using anymore
*/
export interface Element {
 /**
  * Refer to the options when call createElement
  */
 options?:
   | CardElementOptions
   | CardNumberElementOptions
   | ExpiryDateElementOptions
   | CvcElementOptions
   | FullFeaturedCardElementOptions
   | DropInElementOptions
   | WechatElementOptions
   | PaymentRequestButtonOptions;
 /**
  * The iframe element after mount to the DOM
  */
 iframe: HTMLIFrameElement | null;
 /**
  * Refer to the DOM element you call mount function
  */
 domElement: string | HTMLElement;
 /**
  * Element integration `step #3`
  * Mount payment element to your HTML DOM element for checkout
  */
 mount(domElement: string | HTMLElement): void;
 /**
  * Using this function to blur the input html element
  */
 blur(): void;
 /**
  * Using this function to focus the input html element
  * https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/blur
  */
 focus(): void;
 /**
  * Using this function to unmount the element, opposite to mount function
  * https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus
  */
 unmount(): void;
 /**
  * Using this function to update the element option after create the element
  */
 update(
   options?:
     | CardElementOptions
     | CardNumberElementOptions
     | ExpiryDateElementOptions
     | CvcElementOptions
     | FullFeaturedCardElementOptions
     | DropInElementOptions
     | WechatElementOptions
     | PaymentRequestButtonOptions,
 ): void;
}

Once your customization is complete, you need to create the elements:

// Step #3: Create 'dropIn' element
const dropIn = Airwallex.createElement('dropIn', {
 intent: { // Required, dropIn use intent Id and client_secret to prepare checkout
   id: 'replace-with-your-intent-id',
   client_secret: 'replace-with-your-client-secret'
 }
});
// Step #4: Mount 'dropIn' element
dropIn.mount('dropIn');
window.addEventListener('onSuccess', (event) => {
 // Handle event
 alert(JSON.stringify(event.detail));
})

The drop-in element will render the available payment methods and enable the customer to select the most applicable for him. Both Local Payment Methods and Card payments are available for the customer to choose.

  1. Place the drop-in element on your checkout page the way suits your website. You can use the snippet below to fulfill this task
<div id="dropin"></div>

Once the element is mounted, the drop-in element will take care of the rest. Upon completion of the checkout (with a success or fail result) you will get an event notification that you must listen to.

  1. You must listen to the events of the drop-in component to appropriately react to those during your checkout. The following interface defines the data you can collect from an event
/**
* Define of error code when failed to validate user input or failed to request
* [Error codes](https://www.airwallex.com/docs/payments__error-codes)
*/
export type ERROR_CODE =
 | 'required'
 | 'invalid'
 | 'un_support'
 | 'expired'
 | 'validation_error'
 | 'duplicate_request'
 | 'resource_not_found'
 | 'resource_already_exists'
 | 'state_invalid_for_operation'
 | 'service_unavailable'
 | 'processor_unavailable'
 | 'processor_busy'
 | 'processor_declined'
 | 'amount_above_limit'
 | 'frequency_above_limit'
 | 'transaction_blocked'
 | 'payment_blocked'
 | 'unsupported_operation_on_payment_method'
 | 'capture_amount_above_limit'
 | 'refund_amount_above_limit'
 | 'insufficient_available_funds'
 | 'insufficient_incoming_funds'
 | 'processor_user_account_abnormal'
 | 'processor_refund_period_expired'
 | 'processor_refund_offline_required';

/**
* Event code supported value by element when shopper interact with the checkout element
*
* `onReady`: The event fires when a given element resource has loaded.
*
* `onSubmit`: The event is raised when confirm the intent. It fires after the click Pay button or calling confirmPaymentIntent function.
*
* `onSuccess`: The event fires when a intent is confirm with Airwallex
*
* `onError`: Error events are fired at various targets for different kinds of errors with shopper interaction, refer to `ElementError` interface.
*
* `onCancel`: The event fires when shopper click cancel button when interact with the payment form.
*
* `onFocus`: The event is raised when the shopper sets focus on an input by click or tab switch interaction.
*
* `onBlur`: The event is raised when an input in element loses focus.
*
* `onChange`: The events fire when the user commits a value change to a input. This may be done, for example, by clicking outside of the input or by using the Tab key to switch to a different input.
*
* `onClick`: The event is raised when the user clicks on an input element.
*
* `onDynamicCurrencyConversion`: The events fire when merchant enable Dynamic Currency Conversion (DCC) feature and shopper is confirm payment with an intent which match DCC scenario
*/
export type EventCode =
 | 'onReady'
 | 'onSubmit'
 | 'onDynamicCurrencyConversion'
 | 'onSuccess'
 | 'onError'
 | 'onCancel'
 | 'onFocus'
 | 'onBlur'
 | 'onChange'
 | 'onClick';

/**
* Return error when failed to validate user input or failed to request
*/
export interface ElementError {
 /**
  * Feel text message in english
  */
 message: string;
 /**
  * String code, will support in the future
  */
 code?: ERROR_CODE;
}

/**
* Event detail, field define by CustomEvent, we fully leverage it to communicate the event payload
*/
export interface EventDetail {
 /**
  * Type of element which fire the event
  */
 type: ElementType;
 /**
  * Indicate if the element input is validate format
  */
 complete?: boolean;
 /**
  * Indicate if the element input is empty or not
  */
 empty?: boolean;
 /**
  * Indicate the brand of card, only apply for card payment method
  */
 brand?: string;
 /**
  * Indicate the confirm response when integrate with `paymentRequestButton` | `card` | `wechat` | `dropIn` element
  */
 intent?: Intent;
 /**
  * Response error when failed to call interact with shopper input
  */
 error?: ElementError;
}

/**
* The event object your checkout page can listen to by below implementation:
*
* Using html [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent)
*
* window.addEventListener(code: EventCode, (event: { detail: ElementEvent }) => /* Your code here *\/ );
*/
export interface ElementEvent {
 /**
  * Event type code
  * https://developer.mozilla.org/en-US/docs/Web/API/Event/type
  */
 type: EventCode;
 /**
  * Event detail of CustomEvent
  * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail
  */
 detail: EventDetail;
}
window.addEventListener('onSuccess', (event) => {
  /*
    ... Your custom to handle success event
  */
}