Skip to main content
Business & GrowthPayment Services252 lines

Checkout Com

Accept payments with Checkout.com. Use this skill when the project needs to integrate Checkout.com for online payments, hosted payment pages, tokenization, subscriptions, payouts, or multi-currency processing. Covers Checkout.com Unified Payments API, Flow (hosted pages), webhooks, and saved cards.

Quick Summary33 lines
You are a payments specialist who integrates Checkout.com into projects.
Checkout.com is a cloud-based payment platform offering direct API access to
card networks, alternative payment methods, and payouts across 150+ currencies.

## Key Points

- Dashboard: `hub.sandbox.checkout.com`
- Approved card: `4242 4242 4242 4242`
- Declined card: `4242 4242 4242 4241`
- 3DS card: `4242 4242 4242 4000`
- Expiry: any future date, CVV: `100`
- Always include `Idempotency-Key` headers on payment requests to prevent duplicates
- Use Frames.js for PCI SAQ-A compliance — card data never touches your server
- Verify webhook signatures using HMAC-SHA256 before processing events
- Store `payment.id` from every transaction for captures, refunds, and reconciliation
- Enable 3D Secure on all card payments for liability shift
- Use separate authorize and capture for physical goods; auto-capture for digital
- Set `metadata` on payments to link back to your internal models

## Quick Example

```bash
npm install checkout-sdk-node
```

```typescript
await cko.payments.capture(paymentId, {
  amount: 2999, // can partial-capture
  reference: `capture-${orderId}`,
});
```
skilldb get payment-services-skills/checkout-comFull skill: 252 lines
Paste into your CLAUDE.md or agent config

Checkout.com Payment Integration

You are a payments specialist who integrates Checkout.com into projects. Checkout.com is a cloud-based payment platform offering direct API access to card networks, alternative payment methods, and payouts across 150+ currencies.

Core Philosophy

Direct API gives full control

Checkout.com exposes raw payment primitives. You control the entire flow — from tokenizing cards client-side with Frames.js to capturing funds server-side. This flexibility suits merchants who need fine-grained control.

Separate authorize and capture

By default, payments are authorized but not captured. This lets you validate orders before taking funds. Use auto-capture or explicit capture depending on your fulfillment model.

Idempotency prevents duplicate charges

Every payment request should include an Idempotency-Key header to safely retry failed requests without double-charging customers.

Setup

Install

npm install checkout-sdk-node

Initialize

import { Checkout } from 'checkout-sdk-node';

const cko = new Checkout(process.env.CKO_SECRET_KEY, {
  pk: process.env.CKO_PUBLIC_KEY,
  environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
});

Key Techniques

Tokenize cards with Frames.js (client-side)

<script src="https://cdn.checkout.com/js/framesv2.min.js"></script>

<form id="payment-form">
  <div class="card-frame"></div>
  <button type="submit">Pay</button>
</form>

<script>
  Frames.init({
    publicKey: 'pk_sbox_xxx',
    localization: 'EN-GB',
  });

  Frames.addEventHandler(Frames.Events.CARD_VALIDATION_CHANGED, (event) => {
    document.querySelector('button').disabled = !Frames.isCardValid();
  });

  document.getElementById('payment-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const { token } = await Frames.submitCard();
    // Send token to your server
    await fetch('/api/pay', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token, amount: 2999 }),
    });
  });
</script>

Request a payment (server-side)

const payment = await cko.payments.request({
  source: {
    type: 'token',
    token: cardToken, // from Frames.js
  },
  amount: 2999, // minor units
  currency: 'USD',
  reference: `order-${orderId}`,
  customer: {
    email: 'shopper@example.com',
    name: 'Alice Smith',
  },
  metadata: { userId, orderId },
  '3ds': { enabled: true },
  capture: false, // authorize only; capture later
}, {
  idempotencyKey: `pay-${orderId}`,
});

if (payment.status === 'Pending') {
  // 3DS redirect required
  return { redirectUrl: payment._links.redirect.href };
}

// payment.id is the payment ID for capture/refund

Capture a payment

await cko.payments.capture(paymentId, {
  amount: 2999, // can partial-capture
  reference: `capture-${orderId}`,
});

Refund a payment

await cko.payments.refund(paymentId, {
  amount: 2999, // can partial-refund
  reference: `refund-${orderId}`,
});

Save a card for future payments

// First payment — request a reusable source
const payment = await cko.payments.request({
  source: { type: 'token', token: cardToken },
  amount: 2999,
  currency: 'USD',
  customer: { email: 'shopper@example.com' },
  metadata: { userId },
  capture: true,
});

// Store payment.source.id (src_xxx) for future charges
const savedSourceId = payment.source.id;

// Subsequent charges — use the stored source
const recurring = await cko.payments.request({
  source: { type: 'id', id: savedSourceId },
  amount: 2999,
  currency: 'USD',
  customer: { email: 'shopper@example.com' },
  payment_type: 'Recurring',
  capture: true,
}, {
  idempotencyKey: `renewal-${Date.now()}`,
});

Hosted payment page (Flow)

const hostedSession = await cko.hostedPayments.create({
  amount: 2999,
  currency: 'USD',
  reference: `order-${orderId}`,
  billing: { address: { country: 'US' } },
  customer: { email: 'shopper@example.com' },
  success_url: 'https://yourdomain.com/success',
  cancel_url: 'https://yourdomain.com/cancel',
  failure_url: 'https://yourdomain.com/failure',
});

// Redirect user to hostedSession._links.redirect.href

Webhook Processing

EventAction
payment_approvedMark order as paid
payment_capturedConfirm funds captured, fulfill order
payment_declinedMark order failed, notify customer
payment_refundedProcess refund in your system
payment_voidedCancel order
payment_capture_declinedRetry capture or escalate
dispute_receivedHandle chargeback
import crypto from 'crypto';

export async function POST(req: Request) {
  const body = await req.text();
  const signature = req.headers.get('cko-signature');

  // Verify signature
  const expected = crypto
    .createHmac('sha256', process.env.CKO_WEBHOOK_SECRET)
    .update(body)
    .digest('hex');

  if (signature !== expected) {
    return new Response('Invalid signature', { status: 401 });
  }

  const event = JSON.parse(body);

  switch (event.type) {
    case 'payment_approved':
      await markOrderPaid(event.data.reference, event.data.id);
      break;

    case 'payment_captured':
      await fulfillOrder(event.data.reference);
      break;

    case 'payment_declined':
      await markOrderFailed(event.data.reference, event.data.response_summary);
      break;

    case 'payment_refunded':
      await processRefund(event.data.reference, event.data.amount);
      break;
  }

  return new Response('OK', { status: 200 });
}

Testing

Checkout.com sandbox environment:

  • Dashboard: hub.sandbox.checkout.com
  • Approved card: 4242 4242 4242 4242
  • Declined card: 4242 4242 4242 4241
  • 3DS card: 4242 4242 4242 4000
  • Expiry: any future date, CVV: 100

Best Practices

  • Always include Idempotency-Key headers on payment requests to prevent duplicates
  • Use Frames.js for PCI SAQ-A compliance — card data never touches your server
  • Verify webhook signatures using HMAC-SHA256 before processing events
  • Store payment.id from every transaction for captures, refunds, and reconciliation
  • Enable 3D Secure on all card payments for liability shift
  • Use separate authorize and capture for physical goods; auto-capture for digital
  • Set metadata on payments to link back to your internal models

Anti-Patterns

  • Relying on the synchronous payment response without webhook confirmation
  • Omitting Idempotency-Key — network retries will duplicate charges
  • Capturing immediately for physical goods before confirming stock/shipping
  • Not handling 3DS redirects — the payment stays in Pending status forever
  • Storing raw card numbers instead of using Frames.js tokenization
  • Ignoring payment_declined webhooks — customer sees no feedback
  • Using the secret key client-side — it must only be used server-side

Install this skill directly: skilldb add payment-services-skills

Get CLI access →

Related Skills

Coinbase Commerce

Accept cryptocurrency payments with Coinbase Commerce. Use this skill when the project needs to integrate Coinbase Commerce for Bitcoin, Ethereum, USDC, or other crypto payments. Covers Coinbase Commerce API, charges, checkout links, webhooks, and payment verification.

Payment Services251L

Creem

Accept payments with Creem as merchant of record. Use this skill when the project needs to integrate Creem for SaaS subscriptions, one-time payments, checkout sessions, global tax compliance, or subscription management. Covers the Creem SDK, checkout sessions, subscription lifecycle, webhooks, and billing portal.

Payment Services139L

Klarna

Accept payments with Klarna. Use this skill when the project needs to integrate Klarna for buy-now-pay-later, installment plans, pay-in-30-days, or direct payments. Covers Klarna Payments API, Klarna Checkout, hosted payment page, order management, webhooks, and settlement.

Payment Services286L

Lemonsqueezy

Accept payments with Lemon Squeezy as merchant of record. Use this skill when the project needs to integrate Lemon Squeezy for SaaS subscriptions, digital product sales, license key management, checkout overlay, tax compliance, or affiliate programs. Covers the Lemon Squeezy API, checkout, subscriptions, license keys, webhooks, and Lemon.js.

Payment Services201L

Mollie

Accept payments with Mollie. Use this skill when the project needs to integrate Mollie for European payments, iDEAL, Bancontact, SEPA, Klarna, subscriptions, payment links, or multi-currency checkout. Covers the Mollie API, payments, subscriptions, mandates, refunds, and webhooks. Popular in Netherlands, Belgium, Germany, and across Europe.

Payment Services170L

Paddle

Accept payments with Paddle as merchant of record. Use this skill when the project needs to integrate Paddle for subscription billing, one-time payments, checkout overlay, tax compliance, invoicing, or global payment processing where Paddle handles tax, compliance, and payouts. Covers Paddle Billing API, checkout, subscriptions, transactions, webhooks, and Paddle.js.

Payment Services213L