---
title: Credit card checkout example
slug: credit-card-checkout-example
createdAt: 2026-02-21T00:51:36.990Z
---

This example shows a full credit card payment flow using hosted tokenization. It covers creating a contact, creating a debit, generating the card collection URL, and completing payment through the secure iframe.

Unlike EFT, the debit is paid as part of the card collection flow. Use this as a reference for implementing a complete card checkout experience.

## Flow diagram

```mermaid
sequenceDiagram
    participant Backend as Platform Backend
    participant Frontend as Platform Frontend
    actor Customer
    participant Jetpay as Jetpay API

    Backend->>Jetpay: Create contact
    Jetpay-->>Backend: contact_id

    Backend->>Jetpay: Create debit
    Jetpay-->>Backend: debit_transaction_id

    Backend->>Jetpay: Request payment URL
    Jetpay-->>Backend: payment_url

    Backend-->>Frontend: payment_url

    Frontend->>Customer: Render hosted iframe
    Customer->>Jetpay: Enter card details and submit

    Jetpay-->>Backend: Webhook (payment result)
```

## Code sample

:::CodeblockTabs
```curl
# --------------------------------------------
# Configuration
# --------------------------------------------

BASE_URL="https://extapi.demo.jetpay.baselinepayments.com"
API_TOKEN="<YOUR_API_TOKEN>"

# --------------------------------------------
# 1. Create Contact
# --------------------------------------------

curl -X PUT "$BASE_URL/contact" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "name": "Jane Doe",
    "tags": [],
    "language": "en"
  }'

# → Save the returned contact_id (e.g., contact_123)


# --------------------------------------------
# 2. Create Debit
# --------------------------------------------

curl -X PUT "$BASE_URL/debit" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "statement": "Test Statement",
    "note": "Test Note",
    "to_bank_account": "platform_bank_abc",
    "contact_id": "contact_123",
    "preauthorize": false
  }'

# → Save the returned debit_transaction_id (e.g., debit_456)


# --------------------------------------------
# 3. Get Hosted Credit Card Payment URL
# --------------------------------------------

# IMPORTANT:
# You must request a hosted payment URL from Jetpay.
# This URL must be rendered in an iframe on your frontend.
# The customer will enter their card details securely within that iframe.

curl -X POST "$BASE_URL/transaction/debit_456/pay-debit/url" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "allow_credit_card_tokenization": false
  }'

# → Save the returned payment_url


# --------------------------------------------
# 4. Display Hosted Payment Page (Frontend)
# --------------------------------------------

# Your backend sends the payment_url to your frontend.
# Your frontend renders it in an iframe.
# The customer enters their credit card details.
# The debit is paid immediately upon successful authorization.
#
# There is NO separate /pay-debit call for credit cards.


# --------------------------------------------
# 5. Listen for Webhook
# --------------------------------------------

# Implement webhooks to receive confirmation of:
# - successful payment
# - failed payment
# - authorization errors
#
# The webhook event confirms the final transaction state.
```

```python
import requests

BASE_URL = "https://extapi.demo.jetpay.baselinepayments.com"
API_TOKEN = "<YOUR_API_TOKEN>"

headers = {
    "Authorization": f"Bearer {API_TOKEN}",
    "Content-Type": "application/json"
}

# --------------------------------------------
# 1. Create Contact
# --------------------------------------------

contact_response = requests.put(
    f"{BASE_URL}/contact",
    headers=headers,
    json={
        "email": "jane@example.com",
        "name": "Jane Doe",
        "tags": [],
        "language": "en"
    }
)

contact_id = contact_response.json()["identifier"]

# --------------------------------------------
# 2. Create Debit
# --------------------------------------------

debit_response = requests.put(
    f"{BASE_URL}/debit",
    headers=headers,
    json={
        "amount": 10000,
        "statement": "Test Statement",
        "note": "Test Note",
        "to_bank_account": "platform_bank_abc",
        "contact_id": contact_id,
        "preauthorize": False
    }
)

debit_id = debit_response.json()["identifier"]

# --------------------------------------------
# 3. Get Hosted Credit Card Payment URL
# --------------------------------------------

payment_url_response = requests.post(
    f"{BASE_URL}/transaction/{debit_id}/pay-debit/url",
    headers=headers,
    json={
        "allow_credit_card_tokenization": False
    }
)

payment_url = payment_url_response.json()["url"]

print("Render this URL in an iframe on your frontend:")
print(payment_url)

# --------------------------------------------
# IMPORTANT
# --------------------------------------------

# Your frontend must render the payment_url in an iframe.
# The customer enters their card details securely in that hosted component.
# The debit is paid immediately upon successful authorization.
#
# There is NO separate /pay-debit call for credit cards.
# Implement webhooks to receive final transaction status updates.
```

```nodejs
const BASE_URL = "https://extapi.demo.jetpay.baselinepayments.com";
const API_TOKEN = "<YOUR_API_TOKEN>";

const headers = {
  "Authorization": `Bearer ${API_TOKEN}`,
  "Content-Type": "application/json"
};

async function runCreditCardFlow() {
  // --------------------------------------------
  // 1. Create Contact
  // --------------------------------------------

  const contactRes = await fetch(`${BASE_URL}/contact`, {
    method: "PUT",
    headers,
    body: JSON.stringify({
      email: "jane@example.com",
      name: "Jane Doe",
      tags: [],
      language: "en"
    })
  });

  const contactData = await contactRes.json();
  const contactId = contactData.identifier;

  // --------------------------------------------
  // 2. Create Debit
  // --------------------------------------------

  const debitRes = await fetch(`${BASE_URL}/debit`, {
    method: "PUT",
    headers,
    body: JSON.stringify({
      amount: 10000,
      statement: "Test Statement",
      note: "Test Note",
      to_bank_account: "platform_bank_abc",
      contact_id: contactId,
      preauthorize: false
    })
  });

  const debitData = await debitRes.json();
  const debitId = debitData.identifier;

  // --------------------------------------------
  // 3. Get Hosted Credit Card Payment URL
  // --------------------------------------------

  const urlRes = await fetch(
    `${BASE_URL}/transaction/${debitId}/pay-debit/url`,
    {
      method: "POST",
      headers,
      body: JSON.stringify({
        allow_credit_card_tokenization: false
      })
    }
  );

  const urlData = await urlRes.json();
  const paymentUrl = urlData.url;

  console.log("Render this URL in an iframe on your frontend:");
  console.log(paymentUrl);

  // --------------------------------------------
  // IMPORTANT
  // --------------------------------------------

  // Your frontend must render the paymentUrl in an iframe.
  // The customer enters their card details securely in that hosted component.
  // The debit is paid immediately upon successful authorization.
  //
  // There is NO separate /pay-debit call for credit cards.
  // Implement webhooks to receive final transaction status updates.
}

runCreditCardFlow();
```
:::

