Skip to main content

Integration

This guide walks you through embedding the Alipay button on your page. The flow is:

  1. Load the component script.
  2. Add a container element.
  3. Define event handlers.
  4. Build the paymentData object.
  5. Call init(options).

For a copy-paste-ready end-to-end snippet, jump to the Full Example.

Step 1: Add the Alipay Component script

Include the component bundle in the <head> of your HTML page.

Sandbox / Test:

<script src='https://test-pay.dnapayments.com/components/alipay-wechat-pay/alipay-wechat-pay-component.js'></script>

Production:

<script src='https://pay.dnapayments.com/components/alipay-wechat-pay/alipay-wechat-pay-component.js'></script>

The script exposes window.DNAPayments.AlipayComponent.

Step 2: Create the container element

<div id='alipay-btn-container' style='width: 100%; height: 46px;'></div>

Apply the desired width and height to the container: the button takes the container's dimensions.

Step 3: Define event handlers

Provide callbacks via the events object passed to init(). The full list is in the Events section. The most common four are shown here.

function onClick() {
console.log('Alipay button has been clicked');
}

function onError(error) {
// error is { code, message, additionalInfo? }, see the Handling Error Codes page
console.error('Alipay error:', error);
}

function onCancel() {
console.log('Payment was cancelled by the user');
}

function onPaymentSuccess(result) {
console.log('Payment processed successfully', result);
// redirect to a success page, persist invoiceId, etc.
}

const events = {
onClick,
onError,
onCancel,
onPaymentSuccess,
};

Step 4: Build paymentData

paymentData carries the order details. Top-level fields and nested structures are described in paymentData reference.

const paymentData = {
amount: 24,
currency: 'GBP',
invoiceId: 'YOUR_INVOICE_ID',
description: 'Shoes',
paymentSettings: {
terminalId: 'YOUR_TERMINAL_ID',
callbackUrl: 'https://example.com/callback',
failureCallbackUrl: 'https://example.com/failure-callback'
},
customerDetails: {
accountDetails: { accountId: 'uuid000001' },
billingAddress: {
firstName: 'John', lastName: 'Doe',
addressLine1: 'Fulham Rd',
postalCode: 'SW6 1HS', city: 'London', country: 'GB'
},
email: 'example@email.com',
mobilePhone: '+441234567890'
},
orderLines: [{
name: 'Running shoe',
quantity: 1,
unitPrice: 24,
taxRate: 20,
totalAmount: 24,
totalTaxAmount: 4,
imageUrl: 'https://www.example.com/logo.png',
productUrl: 'https://www.example.com/AD6654412.html'
}]
};

Step 5: Initialize the button

Pass the container, paymentData, events and your access token to init():

async function renderAlipay() {
window.DNAPayments.AlipayComponent.init({
containerElement: document.getElementById('alipay-btn-container'),
paymentData,
events,
token: 'YOUR_ACCESS_TOKEN',
});
}

window.addEventListener('load', renderAlipay);
Access token

The OAuth token endpoint returns an object (access_token, expires_in, token_type, ...). Pass only the access_token string to the component. See Authentication for the token flow and the scopes required for the seamless component.

Payment flow

Alipay is QR-based. The flow looks like this:

  1. The customer taps the Alipay button.
  2. The component opens a modal with the Alipay QR code and a countdown driven by paymentTimeoutInSeconds (default 15 minutes).
  3. The customer scans the QR with their Alipay app and completes the payment on their phone.
  4. On success, onPaymentSuccess fires and the modal closes.
  5. If the customer closes the modal before scanning, onCancel fires.
  6. If the countdown runs out before the payment completes, onError({ code: 1006 }) fires.
  7. If anything else goes wrong during the flow (network failure, invalid paymentData, expired token, backend rejection), onError({ code, message, additionalInfo? }) fires with the relevant code from Handling Error Codes.

API reference

The component exposes the following functions on window.DNAPayments.AlipayComponent:

MethodDescription
init(options)Render the button and return the component instance.
create(...)⚠️ Deprecated: use init() instead.

init(options)

const component = await window.DNAPayments.AlipayComponent.init(options);

Renders the Alipay button into containerElement and returns the initialized component instance.

options fields

PropertyTypeRequiredDescription
containerElementHTMLElementDOM node where the button is rendered.
eventsobjectEvent handler map, see Events.
paymentDataobjectPayment request, see paymentData reference. Must include at least amount, currency and paymentSettings.terminalId.
tokenstringOAuth2 access token (the access_token string returned by Authentication).
languagestring-Language of the QR modal UI. Allowed values: 'en', 'is', 'pt', 'es', 'de'. Defaults to 'en'.
paymentTimeoutInSecondsnumber-How long the QR code stays valid. Defaults to 900 (15 minutes).
environmentstring-Either 'sandbox' or 'production'. Optional, defaults to the environment baked into the bundle.

create(...) (deprecated)

Deprecated

create() is kept for backwards compatibility and will be removed in a future version. Use init(options) instead.

Migration:

// Before: positional arguments
window.DNAPayments.AlipayComponent.create(container, events, payload);

// After: single options object
window.DNAPayments.AlipayComponent.init({
containerElement: container,
events,
paymentData: payload.paymentData,
token: payload.token,
language: payload.language,
paymentTimeoutInSeconds: payload.paymentTimeoutInSeconds,
});

Events

The component emits the following events. All handlers are attached via the events map passed to init().

EventSignatureFires when
onClick() => voidThe user taps the Alipay button, before the QR modal is shown.
onLoad() => voidFires after the button has been rendered and mounted into containerElement.
onBeforeProcessPaymentasync () => { paymentData?, token?, paymentTimeoutInSeconds? }Fires after the click but before the QR is requested. The handler may return refreshed paymentData, token and paymentTimeoutInSeconds: this is the canonical CMS pattern where the order (and invoiceId) is created server-side at this moment. Locked fields (amount, currency, delivery address) must match the init() values, otherwise the component fires 1011. See Deferred values via onBeforeProcessPayment.
onPaymentSuccess(result) => voidThe payment has been processed successfully on the Alipay side. See onPaymentSuccess payload.
onCancel() => voidThe user closed the QR modal before completing the payment.
onError(error) => voidAny error during initialization or processing. See onError payload and Handling Error Codes.

Deferred values via onBeforeProcessPayment

onBeforeProcessPayment fires after the customer taps the button and before the QR is requested. The handler can return { paymentData, token, paymentTimeoutInSeconds } to swap in server-side values (typically invoiceId and a freshly issued access token):

const events = {
onBeforeProcessPayment: async () => {
const { invoiceId, token } = await fetch('/api/create-order-and-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: paymentData.amount, currency: paymentData.currency })
}).then(r => r.json());

return {
paymentData: { ...paymentData, invoiceId },
token,
paymentTimeoutInSeconds: 600 // optional override
};
}
};

Locked fields (amount, currency, delivery address) must match the values passed at init(). Returning a paymentData whose locked fields differ fires 1011 PAYMENT_DATA_MISMATCH. Use onBeforeProcessPayment to add server-side fields, not to change the displayed total. If the cart amount can change, re-initialize the component instead.

Returning values from onClick is deprecated

Earlier versions allowed returning { paymentTimeoutInSeconds } from onClick. This path still works but is deprecated and logs a console.warn in the SDK. Return refreshed values from onBeforeProcessPayment instead.

onPaymentSuccess payload

{
id: string,
reference: string,
success: boolean
}

The object may include additional fields when applicable.

onError payload

{
code: number,
message: string,
additionalInfo?: any
}

additionalInfo carries the underlying cause when available (the original exception, or the response body from the DNA Payments backend), useful for logging and debugging. See Handling Error Codes for the full list of code values.

paymentData reference

The most commonly used fields of paymentData:

FieldRequiredDescription
amountTotal transaction amount as a decimal number.
currency-ISO 4217 currency code (e.g. 'GBP'). Defaults to 'GBP'.
invoiceId-Your internal order / invoice identifier.
description-Human-readable description shown on receipts.
paymentSettings.terminalIdYour DNA Payments terminal ID.
paymentSettings.callbackUrl-Server-to-server success callback.
paymentSettings.failureCallbackUrl-Server-to-server failure callback.
customerDetails.accountDetails.accountId-Stable customer ID on your side.
customerDetails.email-Customer email.
customerDetails.mobilePhone-Customer phone.
customerDetails.billingAddress-Billing address object (firstName, lastName, addressLine1, postalCode, city, country, ...).
customerDetails.deliveryDetails.deliveryAddress-Shipping address object (same shape as billingAddress).
orderLines-Array of line items (name, quantity, unitPrice, taxRate, totalAmount, totalTaxAmount, imageUrl, productUrl).