PaymentKit.js

Accept payments directly on your website with secure, PCI-compliant payment elements powered by PaymentKit.js.

View as Markdown

PaymentKit.js is a lightweight JavaScript library that lets you securely collect payment information on your website. It renders payment inputs inside isolated iframes, ensuring sensitive card data never touches your servers and keeping you PCI compliant.

Before you begin

To accept payments with PaymentKit.js, you’ll need:

  1. A PaymentKit account with at least one payment processor connected
  2. A backend server to create checkout sessions and handle payment confirmation
  3. Your API keys from the PaymentKit dashboard under Developers > API Keys

Try it out

See PaymentKit.js in action with our demo application:


Installation

Choose your preferred installation method:

Load PaymentKit.js directly from a CDN without any build step. Perfect for HTML-based projects or quick prototyping.

unpkg (recommended):

1<script src="https://unpkg.com/@payment-kit-js/vanilla/dist/cdn/paymentkit.min.js"></script>

jsDelivr:

1<script src="https://cdn.jsdelivr.net/npm/@payment-kit-js/vanilla/dist/cdn/paymentkit.min.js"></script>

The CDN bundle exposes a global PaymentKit object with all payment methods included (~29 KB minified). Access payment methods via PaymentKit.PaymentMethods.card, .paypal, .googlePay, and .applePay.


How it works

Accepting a payment with PaymentKit.js involves three steps:

  1. Create a checkout session on your server to get a secure token
  2. Initialize PaymentKit.js on your frontend with the token
  3. Collect and submit payment details from your customer

Step 1: Create a checkout session

Before collecting payment details, create a checkout session on your server. This generates a secure token that authorizes the frontend to process the payment.

$curl -X POST https://app.paymentkit.com/api/{account_id}/checkout-sessions/ \
> -H "Authorization: Bearer sk_test_..." \
> -H "Content-Type: application/json" \
> -d '{
> "success_url": "https://yoursite.com/success",
> "return_url": "https://yoursite.com/cancel",
> "line_items": [
> {
> "price_id": "price_dev_x7k9m2n4",
> "quantity": 1
> }
> ]
> }'

Replace {account_id} with your account’s external ID (e.g., acc_dev_abc123).

The response includes a secure_token that you’ll pass to PaymentKit.js:

1{
2 "id": "cs_dev_abc123",
3 "secure_token": "tok_abc123xyz789",
4 "state": "open",
5 "success_url": "https://yoursite.com/success",
6 "return_url": "https://yoursite.com/cancel",
7 "line_items": [
8 {
9 "price_id": "price_dev_x7k9m2n4",
10 "quantity": 1
11 }
12 ]
13}

Step 2: Initialize PaymentKit

Import PaymentKit and the payment methods you want to support, then initialize with your configuration:

1<script>
2 // PaymentKit is loaded from CDN and available as a global
3 const paymentKit = PaymentKit.default({
4 environment: 'production',
5 secureToken: 'aBcDeFgHiJkLmNoPqRsTuVwXyZ123456', // From your backend
6 paymentMethods: [
7 PaymentKit.PaymentMethods.card,
8 PaymentKit.PaymentMethods.paypal,
9 PaymentKit.PaymentMethods.googlePay
10 ]
11 });
12</script>

The CDN bundle includes all payment methods pre-loaded. Access them via PaymentKit.PaymentMethods.

ParameterDescription
environmentThe environment to use: 'sandbox' or 'production'. Optional — defaults to 'production'
secureTokenThe secure_token from your checkout session
paymentMethodsArray of payment method handlers to enable
cardTokenizationModeOptional. How card details are tokenized: 'vgs' (card fields are collected in VGS Collect secure iframes) or 'direct'. When omitted, PaymentKit reads the mode from your checkout session automatically
vgsVaultIdOptional. The VGS vault ID from your checkout session. Only used when cardTokenizationMode is 'vgs'
vgsEnvironmentOptional. The VGS environment from your checkout session: 'sandbox' or 'live'. Only used when cardTokenizationMode is 'vgs'

Use 'sandbox' during development and testing. Switch to 'production' when deploying to your live environment.

You typically don’t need to set cardTokenizationMode, vgsVaultId, or vgsEnvironment. When cardTokenizationMode is omitted, PaymentKit fetches your checkout session and configures all three automatically, falling back to 'direct' if the session configuration can’t be loaded. If you explicitly set cardTokenizationMode: 'vgs', you must also provide vgsVaultId and vgsEnvironment — otherwise card fields fall back to 'direct' mode.


Step 3: Collect payment details

How you collect payment details depends on which payment method you’re using. PaymentKit.js supports multiple payment methods that you can enable based on your needs.

Available payment methods

Card payments

Accept credit and debit cards with PCI-compliant inputs and automatic 3D Secure handling.

PayPal

Let customers pay with their PayPal account using a popup-based authentication flow.

Google Pay

Accept Google Pay on supported devices for fast, secure checkout.

Apple Pay

Accept Apple Pay on Safari and iOS devices for fast, secure checkout.

Using multiple payment methods

You can enable multiple payment methods in a single PaymentKit instance. This lets customers choose their preferred way to pay:

1<script>
2 const paymentKit = PaymentKit.default({
3 environment: 'production',
4 secureToken: 'aBcDeFgHiJkLmNoPqRsTuVwXyZ123456',
5 paymentMethods: [
6 PaymentKit.PaymentMethods.card,
7 PaymentKit.PaymentMethods.paypal,
8 PaymentKit.PaymentMethods.googlePay,
9 PaymentKit.PaymentMethods.applePay
10 ]
11 });
12
13 // Now you can accept any of these payment methods
14 paymentKit.submit({
15 paymentMethod: 'card', // or 'paypal', 'google_pay', or 'apple_pay'
16 fields: { /* customer info */ },
17 onSuccess: (result) => { /* handle success */ },
18 onError: (errors) => { /* handle errors */ }
19 });
20</script>

Submitting a payment

Regardless of which payment method you use, payments are submitted using the submit() method. This method validates the payment details, processes the payment, and calls your success or error callbacks.

1paymentKit.submit({
2 fields: {
3 customer_name: 'Jane Smith',
4 customer_email: 'jane@example.com',
5 customer_country: 'US',
6 customer_zip_code: '94102'
7 },
8 paymentMethod: 'card',
9 onSuccess: (result) => {
10 console.log('Payment successful:', result.paymentIntentId);
11 // Redirect to success page or show confirmation
12 },
13 onError: (errors) => {
14 console.error('Payment failed:', errors);
15 // Display errors to the customer
16 }
17});

Customer fields

PaymentKit collects customer information to help with fraud prevention and compliance. All field values are passed as strings. The following fields are required for card payments:

FieldDescription
customer_nameCustomer’s full name (4-40 characters). Split on the first space into first and last name
customer_emailCustomer’s email address (validated for format)
customer_countryTwo-letter country code (e.g., US, GB)
customer_zip_codePostal or ZIP code

Optional billing fields

You can pass additional billing details. They are not validated by the SDK, and the billing address is attached to the payment whenever at least one address field (including customer_country or customer_zip_code) is provided:

FieldDescription
customer_business_nameCustomer’s business or company name
customer_address_line1Billing address line 1
customer_address_line2Billing address line 2
customer_cityBilling address city
customer_stateBilling address state, province, or region
customer_tax_idsCustomer tax IDs, as a JSON-encoded array of strings (see below)

Because all field values are strings, customer_tax_ids must be JSON-encoded:

1fields: {
2 // ...
3 customer_tax_ids: JSON.stringify(['EU123456789', 'GB987654321'])
4}

Values that are not valid JSON, or that decode to an empty array, are silently ignored.

Optional shipping fields

A shipping address is attached to the payment whenever at least one of these fields is provided:

FieldDescription
shipping_address_line1Shipping address line 1
shipping_address_line2Shipping address line 2
shipping_cityShipping address city
shipping_stateShipping address state, province, or region
shipping_zip_codeShipping postal or ZIP code
shipping_countryShipping country code (e.g., US, GB)

Success response

When a payment succeeds, the onSuccess callback receives a result object:

1{
2 id: 'cca_dev_abc123',
3 checkoutAttemptId: 'ca_dev_abc123',
4 checkoutSessionId: 'cs_dev_xyz789',
5 paymentIntentId: 'pi_dev_def456',
6 state: 'checkout_succeeded'
7}

Handling errors

Payment errors are returned to the onError callback as an object with field-specific error codes:

1onError: (errors) => {
2 // Field validation errors
3 if (errors.customer_email === 'required') {
4 showFieldError('email', 'Email is required');
5 }
6 if (errors.customer_email === 'invalid') {
7 showFieldError('email', 'Please enter a valid email');
8 }
9
10 // Payment method errors
11 if (errors.card_pan) {
12 showFieldError('card', getCardErrorMessage(errors.card_pan));
13 }
14
15 // General errors
16 if (errors.root) {
17 showGeneralError(errors.root);
18 }
19}

Error types

Form field errors

Error fieldPossible valuesDescription
customer_namerequired, invalidCustomer name validation failed (must be 4-40 characters)
customer_emailrequired, invalidEmail validation failed
customer_countryrequired, invalidCountry code validation failed
customer_zip_coderequired, invalidZIP code validation failed

Card input errors

Error fieldPossible valuesDescription
card_panrequired, invalid, unknown_errorCard number error
card_exprequired, invalid, unknown_errorExpiration date error
card_cvcrequired, invalid, unknown_errorSecurity code error

Payment method errors

Error fieldPossible valuesDescription
paypalString messagePayPal-specific error
google_payString messageGoogle Pay-specific error
apple_payString messageApple Pay-specific error
rootString messageGeneral payment error

Cleaning up

When your checkout component unmounts or the user navigates away, always clean up PaymentKit resources to prevent memory leaks:

1// Call cleanup when done
2paymentKit.cleanup();

In React, use a cleanup function in your effect:

1useEffect(() => {
2 const pk = PaymentKit({ /* config */ });
3
4 return () => {
5 pk.cleanup(); // Clean up on unmount
6 };
7}, [secureToken]);

Failing to call cleanup() can leave orphaned iframes and event listeners, which may cause issues if the user returns to checkout.


Content Security Policy

If your site uses a Content-Security-Policy header, you must allowlist the following domains in your script-src directive for fraud prevention scripts to load:

EnvironmentDomain
Productionhttps://static.airwallex.com
Sandboxhttps://static-demo.airwallex.com

Example:

1Content-Security-Policy: script-src 'self' https://static.airwallex.com;

If these domains are blocked, PaymentKit.js will log an error to the browser console with the specific domain that needs to be allowlisted.