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, and .googlePay.


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://api.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'
secureTokenThe secure_token from your checkout session
paymentMethodsArray of payment method handlers to enable

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


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.

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 ]
10 });
11
12 // Now you can accept any of these payment methods
13 paymentKit.submit({
14 paymentMethod: 'card', // or 'paypal' or 'google_pay'
15 fields: { /* customer info */ },
16 onSuccess: (result) => { /* handle success */ },
17 onError: (errors) => { /* handle errors */ }
18 });
19</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. The following fields are required for card payments:

FieldDescription
customer_nameCustomer’s full name (4-40 characters)
customer_emailCustomer’s email address
customer_countryTwo-letter country code (e.g., US, GB)
customer_zip_codePostal or ZIP code

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.