Skip to main content
Cresora Commerce
Transaction Types

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:

VOIDAUTH_REVERSAL
What it isOffline, ledger-only cancel — no processor message is sentA rails-level processor message (0420-equivalent) that releases the issuer hold
Valid againstAUTHORIZED, or CAPTURED but not yet SETTLEDAUTHORIZED or CAPTURED, pre-settlement
Cardholder seesThe hold lingers until the issuer expires it on its own scheduleThe hold is actively released
amountIgnored (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.