Skip to main content
POST
Charge a saved payment method

Authorizations

x-api-key
string
header
required

Path Parameters

id
string<uuid>
required

The unique identifier of the payment method to charge

Body

application/json

Request body for charging a saved payment method

amount
number<decimal>
required

The amount to charge in MXN. Must be a positive number.

Required range: x >= 0.01
Example:

500

currency
enum<string>
default:MXN

Currency code. Defaults to MXN.

Available options:
MXN
Example:

"MXN"

description
string

A description of the charge.

Example:

"Monthly subscription - January 2025"

holdFunds
boolean
default:false

When true the funds are only authorized and held, not captured. The payment comes back as HELD, with heldAmount set to the authorized amount, and the money reaches you only when you call the capture endpoint, which can take the full held amount or part of it. Call the release endpoint to give the funds back, otherwise the hold is released automatically at the end of the 7th natural day. The hold window is counted in NATURAL DAYS, not in elapsed hours. The day the hold is placed counts as day 1 and the time of day it was placed is irrelevant: a hold placed Monday 10:00 and one placed Monday 23:29 both expire at the same instant, at the end of the following Sunday. The bank closes its day at 23:30 America/Mexico_City and Compago closes the hold at 23:00, 30 minutes earlier, so the last minute to capture is 22:59 on the last day.

Example:

false

externalId
string

Optional idempotency key for this charge or hold. Your own reference, up to 255 characters, unique across all payments in your organization. Repeating a request with the same value returns the ORIGINAL payment, with the HTTP status the original attempt produced, instead of charging or holding a second time. A DECLINED attempt SPENDS the key: replaying it returns the decline again, so retrying a declined charge or hold requires a NEW externalId. Reusing a key with a different payment method, amount or currency answers 409 EXTERNAL_ID_MISMATCH. An empty string is treated as not supplied. This is NOT the payment method externalId, which identifies the saved card: they are separate namespaces and are never compared with each other.

Maximum string length: 255
Example:

"invoice-2025-01-8842"

Response

Payment created successfully. When holdFunds is true the payment comes back with status HELD, heldAmount set to the authorized amount, and the funds held rather than captured. When the request carried an externalId that was already used, this is the ORIGINAL payment replayed rather than a new one.

Response after charging a payment method, or after placing a hold when holdFunds was true

id
string<uuid>
required

Unique identifier of the payment

Example:

"11111111-2222-3333-4444-555555555555"

status
enum<string>
required

Current status of the payment. A successful hold returns HELD.

Available options:
NOT_INITIALIZED,
PENDING,
CONFIRMED,
CANCELLED,
REFUNDED,
HELD,
HOLD_RELEASED,
HOLD_EXPIRED
Example:

"CONFIRMED"

amount
number<decimal>
required

The money that moved, or that will move. On a hold it equals heldAmount until the hold is captured; after a partial capture it is the amount actually captured.

currency
string
required
Example:

"MXN"

heldAmount
number<decimal> | null

The amount the bank authorized when the hold was placed. Stamped once and never rewritten, so it stays the record of what was blocked on the card even after a partial capture. Null on any payment that was never held.

Example:

null

externalId
string | null

The idempotency key supplied when the payment was created, echoed back so you can map this payment id to your own order reference. Null when none was supplied. Not to be confused with the payment method externalId, which identifies the saved card.

Example:

"invoice-2025-01-8842"

heldAt
string<date-time> | null

When the bank approved the hold. Null on payments that were never held.

Example:

"2026-08-12T10:00:00.000Z"

capturedAt
string<date-time> | null

When the hold was captured. This, and not createdAt, is the settlement date of a captured hold. Null until the hold is captured.

holdReleasedAt
string<date-time> | null

When the hold was released, either by the release endpoint or by the automatic expiry. Null otherwise.

holdExpiresAt
string<date-time> | null

When the hold expires: 23:00 America/Mexico_City on the 7th natural day, counting the day of heldAt as day 1. The hold window is counted in NATURAL DAYS, not in elapsed hours. The day the hold is placed counts as day 1 and the time of day it was placed is irrelevant: a hold placed Monday 10:00 and one placed Monday 23:29 both expire at the same instant, at the end of the following Sunday. The bank closes its day at 23:30 America/Mexico_City and Compago closes the hold at 23:00, 30 minutes earlier, so the last minute to capture is 22:59 on the last day. It keeps being reported once the hold has ended, because it is a fact about the payment. Null on payments that were never held.

Example:

"2026-08-19T05:00:00.000Z"

holdExpired
boolean

Whether the hold window has closed. It flips at 23:00 America/Mexico_City on the last natural day, not 7 times 24 hours after heldAt. False on payments that were never held.

holdDaysRemaining
integer | null

Natural days on which the hold can still be captured, including today when today's 23:00 cutoff has not passed yet: 7 for a hold placed before 23:00 on its placement day, 6 for one placed at or after 23:00 (its placement day is already spent), 1 through the last day, and 0 from 23:00 on the last day. Null unless the payment is currently HELD.

Example:

7