---
title: Directly charge a credit card
slug: directly-charge-a-credit-card
createdAt: 2026-02-19T22:49:27.478Z
---

:::hint{type="warning"}
To enable card-on-file features such as this one, you must contact [Jetpay support ](mailto\:jetpay@baselinepayments.com)directly.
:::

Charge a saved card with a single request from your backend.

This flow is designed for applications where users maintain an account and store payment methods for reuse. A typical example is a logged-in user selecting a saved card from a dropdown and completing payment without re-entering card details.

If you need to collect card details **at the time of payment**, for example, guest checkout or one-time payments, use the [Collect payment method at checkout](docId\:LNP1ZGF7yBPWuvS3G5URF) flow instead.

***

## Prerequisites

- [Jetpay API Key](docId:_zgmIm7QKrrAoX9JjaQrL)
- Your [company bank account ID](docId\:aEx0SSFndR_XgalXG2_ZF) where funds will be deposited
- [Tokenized contact credit card](docId:_5zW0FS71q4rn5rY5IFPj)

Before you charge a saved card, the customer must exist as a Contact in Jetpay and have at least one tokenized payment method attached.

If you have not yet created a contact or collected card details, complete the [Create a contact](docId\:BzwF0wyOoqBKGSFuGEnH0) and [Tokenize a contact credit card](docId:_5zW0FS71q4rn5rY5IFPj) guides first. Once a payment method is stored, you can charge it directly.

***

## Flow Overview

```mermaid
sequenceDiagram
    autonumber
    participant Platform
    participant Jetpay
    participant CardNetwork as Card Network

    Platform->>Jetpay: POST /contact/{contact_id}/creditCards/{credit_card_id}/charge
    Jetpay->>CardNetwork: Authorize & capture
    CardNetwork-->>Jetpay: Response (approved / declined)
    Jetpay-->>Platform: Charge created (status: paid)
    Jetpay-->>Platform: Webhook (completed / failed)
```

***

## Implementation details

### Charge the contact credit card

Endpoint: [`POST /contact/{contact_id}/creditCards/{credit_card_id}/charge`](https://extapi.jetpay.baselinepayments.com/docs#tag/Contacts-\(v0\)/operation/charge_contact_credit_card_contact__contact_id__creditCards__credit_card_id__charge_post)

:::CodeblockTabs
```curl
curl https://extapi.demo.jetpay.baselinepayments.com/contact/contact_123/creditCards/cc_456/charge \
  -X POST \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 100.50,
    "to_bank_account_id": "<your_bank_account_id>",
    "statement": "Test Statement",
    "note": "Test Note"
  }'
```

```python
import requests

url = "https://extapi.demo.jetpay.baselinepayments.com/contact/contact_123/creditCards/cc_456/charge"

headers = {
    "Authorization": "Bearer <YOUR_API_TOKEN>",
    "Content-Type": "application/json"
}

payload = {
    "amount": 100.50,
    "to_bank_account_id": "<your_bank_account_id>",
    "statement": "Test Statement",
    "note": "Test Note"
}

response = requests.post(url, json=payload, headers=headers)

print(response.status_code)
print(response.json())
```

```nodejs
const fetch = require("node-fetch");

const url = "https://extapi.demo.jetpay.baselinepayments.com/contact/contact_123/creditCards/cc_456/charge";

const payload = {
  amount: 100.50,
  to_bank_account_id: "<your_bank_account_id>",
  statement: "Test Statement",
  note: "Test Note"
};

fetch(url, {
  method: "POST",
  headers: {
    "Authorization": "Bearer <YOUR_API_TOKEN>",
    "Content-Type": "application/json"
  },
  body: JSON.stringify(payload)
})
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));
```
:::

### Handle the response

If the card is successfully charged, a response will be returned with an HTTP status code of 200 and the following response body:

```json
{
  "debit_id": "debit_123",
  "amount": 100.50,
  "statement": "Test Statement",
  "note": "Test Note",
  "to_bank_account_id": "your_bank_account_id",
  "contact_id": "contact_123",
  "from_credit_card_id": "cc_456",
  "transaction_state": "paid"
}
```

You should store the returned `debit_id` so that it can be cross referenced against the webhook events that we send. Final transaction outcomes (such as `completed` or `failed`) are delivered via [payment event webhooks](docId:-bnN6n5bf_AFNEr-9SDdr).

### Track status updates via events/webhooks

As the transaction moves through its lifecycle, an **Event** is created for each state update. The most efficient way to track these updates in your system is to register for webhooks. If you are not yet familiar with our webhooks system, please review the [Events and webhooks](docId:79a4CGVETAChOLkpJYd5C) guide.
