> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compago.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Charge a Saved Card

> Charge a customer's saved payment method on demand via API.

Once a customer has [saved their card](/payment-method/save-card) and the payment method status is `ACTIVE`, you can charge it at any time by calling the charge endpoint. No customer interaction is required. The charge is processed entirely server-side.

## Overview

Charging a saved card allows you to:

* Bill customers for subscriptions, memberships, or recurring services
* Charge after service delivery (on-demand services, freight, freelance work)
* Process payments when orders ship or milestones are reached

## Prerequisites

Before charging a saved card:

* The payment method must have a status of `ACTIVE`
* You must have the payment method `id` (returned when [creating the payment method](/payment-method/save-card))
* The card must not be expired or revoked

## Creating a Charge

### Endpoint

```
POST /api/payment-method/{id}/payment
```

**API reference:** [`POST /payment-method/{id}/payment`](/api-reference/payment-method/charge)

### Authentication

Include your API key in the request headers:

```
x-api-key: YOUR_API_KEY
Content-Type: application/json
```

### Path Parameters

<ParamField path="id" type="string" required>
  The unique identifier of the payment method to charge (UUID).
</ParamField>

### Request Body

```json theme={null}
{
  "amount": 500,
  "currency": "MXN",
  "description": "Monthly subscription - January 2025"
}
```

### Field Descriptions

| Field         | Type   | Required | Description                                      |
| ------------- | ------ | -------- | ------------------------------------------------ |
| `amount`      | number | Yes      | Amount to charge in MXN. Must be at least 1 MXN. |
| `currency`    | string | No       | Currency code. Defaults to `"MXN"`.              |
| `description` | string | No       | Description of the charge.                       |

### Response

```json theme={null}
{
  "id": "11111111-2222-3333-4444-555555555555",
  "status": "CONFIRMED",
  "amount": 500,
  "currency": "MXN"
}
```

| Field      | Type   | Description                                                                                         |
| ---------- | ------ | --------------------------------------------------------------------------------------------------- |
| `id`       | string | Unique identifier of the payment.                                                                   |
| `status`   | string | Current status of the payment (`NOT_INITIALIZED`, `PENDING`, `CONFIRMED`, `CANCELLED`, `REFUNDED`). |
| `amount`   | number | The charged amount.                                                                                 |
| `currency` | string | Currency code.                                                                                      |

### Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.harmony.compago.com/api/payment-method/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/payment \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "amount": 500,
      "currency": "MXN",
      "description": "Monthly subscription - January 2025"
    }'
  ```

  ```javascript Node.js theme={null}
  const paymentMethodId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';

  const response = await fetch(
    `https://api.harmony.compago.com/api/payment-method/${paymentMethodId}/payment`,
    {
      method: 'POST',
      headers: {
        'x-api-key': process.env.COMPAGO_API_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        amount: 500,
        currency: 'MXN',
        description: 'Monthly subscription - January 2025'
      })
    }
  );

  const payment = await response.json();
  console.log('Payment ID:', payment.id);
  console.log('Status:', payment.status);
  ```

  ```python Python theme={null}
  import requests
  import os

  payment_method_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'

  response = requests.post(
      f'https://api.harmony.compago.com/api/payment-method/{payment_method_id}/payment',
      headers={
          'x-api-key': os.environ['COMPAGO_API_KEY'],
          'Content-Type': 'application/json'
      },
      json={
          'amount': 500,
          'currency': 'MXN',
          'description': 'Monthly subscription - January 2025'
      }
  )

  payment = response.json()
  print('Payment ID:', payment['id'])
  print('Status:', payment['status'])
  ```

  ```php PHP theme={null}
  <?php
  $paymentMethodId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';

  $ch = curl_init("https://api.harmony.compago.com/api/payment-method/{$paymentMethodId}/payment");
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'x-api-key: ' . getenv('COMPAGO_API_KEY'),
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
      'amount' => 500,
      'currency' => 'MXN',
      'description' => 'Monthly subscription - January 2025'
  ]));

  $response = curl_exec($ch);
  $payment = json_decode($response, true);
  curl_close($ch);

  echo 'Payment ID: ' . $payment['id'] . PHP_EOL;
  echo 'Status: ' . $payment['status'] . PHP_EOL;
  ?>
  ```

  ```ruby Ruby theme={null}
  require 'net/http'
  require 'json'
  require 'uri'

  payment_method_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
  uri = URI("https://api.harmony.compago.com/api/payment-method/#{payment_method_id}/payment")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Post.new(uri)
  request['x-api-key'] = ENV['COMPAGO_API_KEY']
  request['Content-Type'] = 'application/json'
  request.body = {
    amount: 500,
    currency: 'MXN',
    description: 'Monthly subscription - January 2025'
  }.to_json

  response = http.request(request)
  payment = JSON.parse(response.body)

  puts "Payment ID: #{payment['id']}"
  puts "Status: #{payment['status']}"
  ```
</CodeGroup>

## Checking Payment Status

After creating a charge, you can check its status at any time:

```
GET /api/payment-method/{id}/payment/{paymentId}
```

**API reference:** [`GET /payment-method/{id}/payment/{paymentId}`](/api-reference/payment-method/get-payment)

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.harmony.compago.com/api/payment-method/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/payment/11111111-2222-3333-4444-555555555555 \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    `https://api.harmony.compago.com/api/payment-method/${paymentMethodId}/payment/${paymentId}`,
    {
      headers: { 'x-api-key': process.env.COMPAGO_API_KEY }
    }
  );

  const payment = await response.json();
  console.log('Payment status:', payment.status);
  ```

  ```python Python theme={null}
  response = requests.get(
      f'https://api.harmony.compago.com/api/payment-method/{payment_method_id}/payment/{payment_id}',
      headers={'x-api-key': os.environ['COMPAGO_API_KEY']}
  )

  payment = response.json()
  print('Payment status:', payment['status'])
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.harmony.compago.com/api/payment-method/{$paymentMethodId}/payment/{$paymentId}");
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'x-api-key: ' . getenv('COMPAGO_API_KEY')
  ]);

  $response = curl_exec($ch);
  $payment = json_decode($response, true);
  curl_close($ch);

  echo 'Payment status: ' . $payment['status'] . PHP_EOL;
  ?>
  ```

  ```ruby Ruby theme={null}
  uri = URI("https://api.harmony.compago.com/api/payment-method/#{payment_method_id}/payment/#{payment_id}")
  request = Net::HTTP::Get.new(uri)
  request['x-api-key'] = ENV['COMPAGO_API_KEY']

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }
  payment = JSON.parse(response.body)

  puts "Payment status: #{payment['status']}"
  ```
</CodeGroup>

## Important Business Rules

<Warning>
  **Payment method must be ACTIVE.** You can only charge payment methods with an `ACTIVE` status. Attempting to charge a `PENDING`, `EXPIRED`, or `REVOKED` payment method will result in a 400 error.
</Warning>

<Warning>
  **Card expiration.** If the customer's card has expired since it was saved, the charge will fail. In this case, you'll need to create a new payment method and have the customer save an updated card.
</Warning>

<Note>
  **Currency restriction.** Only **MXN (Mexican Peso)** is currently supported. Charges in other currencies will be rejected.
</Note>

## Error Handling

| Status Code | Error                     | Solution                                                      |
| ----------- | ------------------------- | ------------------------------------------------------------- |
| 400         | Payment method not ACTIVE | Verify the payment method status is `ACTIVE` before charging. |
| 400         | Invalid amount            | Ensure the amount is at least 1 MXN.                          |
| 400         | Currency not supported    | Use `"MXN"` as the currency.                                  |
| 401         | Unauthorized              | Check your API key is valid and included in headers.          |
| 404         | Payment method not found  | Verify the payment method ID is correct.                      |

## Next Steps

<CardGroup cols={2}>
  <Card title="Process Refunds" icon="rotate-left" href="/payment-method/refund">
    Issue full refunds for charges made against saved cards.
  </Card>

  <Card title="Manage Payment Methods" icon="list" href="/payment-method/manage">
    List, retrieve, and revoke payment methods and view payment history.
  </Card>
</CardGroup>
