***
title: PaymentKit.js
subtitle: >-
Accept payments directly on your website with secure, PCI-compliant payment
elements powered by PaymentKit.js.
----------------------------------
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](/guides/payment-orchestration)
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:
A complete working example showing card payments, PayPal, and Google Pay integration.
***
# 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):**
```html
```
**jsDelivr:**
```html
```
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`.
```bash
npm install @payment-kit-js/vanilla
```
```bash
yarn add @payment-kit-js/vanilla
```
```bash
pnpm add @payment-kit-js/vanilla
```
***
# How it works
Accepting a payment with PaymentKit.js involves three steps:
```mermaid
sequenceDiagram
participant Server as Your Server
participant PaymentKit as PaymentKit
participant Customer as Customer
Server->>PaymentKit: 1. Create checkout session
PaymentKit-->>Server: { secureToken }
Server->>Customer: 2. Initialize PaymentKit.js
Customer->>PaymentKit: 3. Customer enters payment details
PaymentKit-->>Server: Payment confirmed
```
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.
```bash
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:
```json
{
"id": "cs_dev_abc123",
"secure_token": "tok_abc123xyz789",
"state": "open",
"success_url": "https://yoursite.com/success",
"return_url": "https://yoursite.com/cancel",
"line_items": [
{
"price_id": "price_dev_x7k9m2n4",
"quantity": 1
}
]
}
```
***
# Step 2: Initialize PaymentKit
Import PaymentKit and the payment methods you want to support, then initialize with your configuration:
```html
```
The CDN bundle includes all payment methods pre-loaded. Access them via `PaymentKit.PaymentMethods`.
```typescript
import PaymentKit from '@payment-kit-js/vanilla';
import CardPaymentMethod from '@payment-kit-js/vanilla/payment-methods/card';
const paymentKit = PaymentKit({
environment: 'production',
secureToken: 'aBcDeFgHiJkLmNoPqRsTuVwXyZ123456', // From your backend
paymentMethods: [CardPaymentMethod]
});
```
| Parameter | Description |
| ---------------- | ----------------------------------------------------- |
| `environment` | The environment to use: `'sandbox'` or `'production'` |
| `secureToken` | The `secure_token` from your checkout session |
| `paymentMethods` | Array 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
Accept credit and debit cards with PCI-compliant inputs and automatic 3D Secure handling.
Let customers pay with their PayPal account using a popup-based authentication flow.
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:
```html
```
```typescript
import PaymentKit from '@payment-kit-js/vanilla';
import CardPaymentMethod from '@payment-kit-js/vanilla/payment-methods/card';
import PayPalPaymentMethod from '@payment-kit-js/vanilla/payment-methods/paypal';
import GooglePayPaymentMethod from '@payment-kit-js/vanilla/payment-methods/google-pay';
const paymentKit = PaymentKit({
environment: 'production',
secureToken: 'aBcDeFgHiJkLmNoPqRsTuVwXyZ123456',
paymentMethods: [CardPaymentMethod, PayPalPaymentMethod, GooglePayPaymentMethod]
});
// Now you can accept any of these payment methods
paymentKit.submit({
paymentMethod: 'card', // or 'paypal' or 'google_pay'
fields: { /* customer info */ },
onSuccess: (result) => { /* handle success */ },
onError: (errors) => { /* handle errors */ }
});
```
***
# 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.
```typescript
paymentKit.submit({
fields: {
customer_name: 'Jane Smith',
customer_email: 'jane@example.com',
customer_country: 'US',
customer_zip_code: '94102'
},
paymentMethod: 'card',
onSuccess: (result) => {
console.log('Payment successful:', result.paymentIntentId);
// Redirect to success page or show confirmation
},
onError: (errors) => {
console.error('Payment failed:', errors);
// Display errors to the customer
}
});
```
## Customer fields
PaymentKit collects customer information to help with fraud prevention and compliance. The following fields are required for card payments:
| Field | Description |
| ------------------- | ------------------------------------------ |
| `customer_name` | Customer's full name (4-40 characters) |
| `customer_email` | Customer's email address |
| `customer_country` | Two-letter country code (e.g., `US`, `GB`) |
| `customer_zip_code` | Postal or ZIP code |
## Success response
When a payment succeeds, the `onSuccess` callback receives a result object:
```typescript
{
id: 'cca_dev_abc123',
checkoutAttemptId: 'ca_dev_abc123',
checkoutSessionId: 'cs_dev_xyz789',
paymentIntentId: 'pi_dev_def456',
state: 'checkout_succeeded'
}
```
***
# Handling errors
Payment errors are returned to the `onError` callback as an object with field-specific error codes:
```typescript
onError: (errors) => {
// Field validation errors
if (errors.customer_email === 'required') {
showFieldError('email', 'Email is required');
}
if (errors.customer_email === 'invalid') {
showFieldError('email', 'Please enter a valid email');
}
// Payment method errors
if (errors.card_pan) {
showFieldError('card', getCardErrorMessage(errors.card_pan));
}
// General errors
if (errors.root) {
showGeneralError(errors.root);
}
}
```
## Error types
### Form field errors
| Error field | Possible values | Description |
| ------------------- | --------------------- | --------------------------------------------------------- |
| `customer_name` | `required`, `invalid` | Customer name validation failed (must be 4-40 characters) |
| `customer_email` | `required`, `invalid` | Email validation failed |
| `customer_country` | `required`, `invalid` | Country code validation failed |
| `customer_zip_code` | `required`, `invalid` | ZIP code validation failed |
### Card input errors
| Error field | Possible values | Description |
| ----------- | -------------------------------------- | --------------------- |
| `card_pan` | `required`, `invalid`, `unknown_error` | Card number error |
| `card_exp` | `required`, `invalid`, `unknown_error` | Expiration date error |
| `card_cvc` | `required`, `invalid`, `unknown_error` | Security code error |
### Payment method errors
| Error field | Possible values | Description |
| ------------ | --------------- | ------------------------- |
| `paypal` | String message | PayPal-specific error |
| `google_pay` | String message | Google Pay-specific error |
| `apple_pay` | String message | Apple Pay-specific error |
| `root` | String message | General payment error |
***
# Cleaning up
When your checkout component unmounts or the user navigates away, always clean up PaymentKit resources to prevent memory leaks:
```typescript
// Call cleanup when done
paymentKit.cleanup();
```
In React, use a cleanup function in your effect:
```jsx
useEffect(() => {
const pk = PaymentKit({ /* config */ });
return () => {
pk.cleanup(); // Clean up on unmount
};
}, [secureToken]);
```
Failing to call `cleanup()` can leave orphaned iframes and event listeners, which may cause issues if the user returns to checkout.