Card Transactions
Card payment types, auth-only via the hosted page, and state transitions.
Card payments in Cresora charge a saved card referenced by its vault token (cvt_…) — see API Direct for the charging surface. Whether a payment captures immediately or authorizes for a later capture is decided when the card is charged on the hosted page, not by a field on POST /transactions.
Immediate capture (sale)
The default. The hosted-page session is created with capture_mode: sale (or the mode omitted), and a direct SALE on a vault token authorizes and captures in one step. Use this for most e-commerce flows.
State path: INITIATED → CAPTURED → SETTLED (SUBMITTED is the ACH in-flight state
and never appears on the card rail — see Transaction lifecycle)
Auth-only (authorize now, capture later)
Authorize the card to hold funds, then capture later. Use this for:
- Hotel and rental holds
- Marketplace settlements after service delivery
- Order fulfillment with uncertain timing
Auth-only is available on the hosted-page rail: create the session with "capture_mode": "authorize" (see the HPP guide). The completed session materialises an AUTHORIZED transaction you capture through the normal capture call below. type: "AUTHORIZATION" on POST /transactions returns 501 — reserved until the vault-token authorize wire shape is vendor-confirmed.
State path: AUTHORIZED → (your capture call) → CAPTURED → SETTLED
There is no Cresora capture deadline
Cresora does not expire authorizations on a timer and does not sweep them. The hold's lifetime belongs to the issuer, and you discover it lazily: a capture against a hold the issuer has already released comes back as a gateway decline — the capture reads state: FAILED with a decline_code; there is no "expired" state or flag. Plan around your issuer's window, not around a platform one.
Capture
curl -X POST https://api.cresoracommerce.ai/api/v1/transactions \
-H "Authorization: Bearer csk_ab12cd34_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem_$(uuidgen)" \
-d '{
"type": "CAPTURE",
"merchant_id": "0190a1b2-c3d4-7e5f-8901-23456789abcd",
"parent_transaction_id": "0190d8a1-2b3c-7d4e-9f12-7a8b9c0d1e2f"
}'CAPTURE takes the parent's full authorized value — an amount in the body is ignored. To capture less, use type: "PARTIAL_CAPTURE" with an amount:
{ "type": "PARTIAL_CAPTURE", "merchant_id": "…", "parent_transaction_id": "…", "amount": "80.00" }The uncaptured remainder is released automatically.
Cancelling before settlement: VOID vs AUTH_REVERSAL
Two distinct operations — you choose which by the type you send, and they do different things:
VOID | AUTH_REVERSAL | |
|---|---|---|
| What it is | Offline, ledger-only cancel — no processor message is sent | A rails-level processor message (0420-equivalent) that releases the issuer hold |
| Valid against | AUTHORIZED, or CAPTURED but not yet SETTLED | AUTHORIZED or CAPTURED, pre-settlement |
| Cardholder sees | The hold lingers until the issuer expires it on its own schedule | The hold is actively released |
amount | Ignored (lifted from the parent) | Omit for a full reversal; send one for a partial reversal (processor-gated) |
{ "type": "VOID", "merchant_id": "…", "parent_transaction_id": "…" }{ "type": "AUTH_REVERSAL", "merchant_id": "…", "parent_transaction_id": "…" }Voidability is gated by "settled at processor", not by a wall-clock window — once the parent is SETTLED, the only remaining operation is a refund. For customer-facing cancellations where the hold matters (debit cards especially), prefer AUTH_REVERSAL: it is the one that actually tells the issuer to let go of the funds.
A partial reversal (amount present, strictly less than the remaining authorized amount) leaves the parent AUTHORIZED for the remainder and records a PARTIAL_AUTH_REVERSAL child. Support is processor-dependent — an unsupported processor declines through the normal decline_code surface.
Refunds
A refund is valid once the parent is SETTLED — before settlement, cancel with VOID/AUTH_REVERSAL instead:
curl -X POST https://api.cresoracommerce.ai/api/v1/transactions \
-H "Authorization: Bearer csk_ab12cd34_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem_$(uuidgen)" \
-d '{
"type": "REFUND",
"merchant_id": "0190a1b2-c3d4-7e5f-8901-23456789abcd",
"parent_transaction_id": "0190d8a1-2b3c-7d4e-9f12-7a8b9c0d1e2f",
"refund_reason": "customer_requested"
}'This refunds the full settled amount (amount is ignored — the platform derives the remainder). For a partial refund, use type: "PARTIAL_REFUND" with an amount; multiple partial refunds can be issued until the full amount is refunded.
State transition on full refund: SETTLED → REFUNDED (partials pass through PARTIALLY_REFUNDED). See Refunds for reason codes and the response shape.