Chargezoom Gateway API reference
A single JSON API for card authorization, capture, void, refund and unreferenced credit, with tokenized storage, idempotent retries and signed webhooks. Everything below is available in sandbox the moment you create an account.
Overview
All endpoints live under a versioned base path and accept and return application/json.
https://chargezoomgateway.com/api/public/gateway/v1
- Environments. Sandbox and live share the same URLs — the environment is determined by the credential you authenticate with. Sandbox routes to a deterministic simulator; live routing is enabled once underwriting approves the merchant.
- Amounts. Send
amountin major units oramountMinorin cents. Responses always report minor units. - Idempotency. Send an
Idempotency-Keyheader on transaction creation. Replaying the same key returns the original transaction instead of charging twice. - Card data. PANs are accepted only at this boundary, encrypted immediately, and never returned. Only brand, expiry and last four are readable afterwards.
Authentication
Every request authenticates with an API login ID and a transaction key. Generate them in the portal under Developers; the transaction key is shown once at creation and stored only as a hash. Revoked credentials and merchants that are not approved are rejected with 401.
Authorization: Basic base64(apiLoginId:transactionKey)
x-api-login-id: 4mTq9Xc2LpVb x-transaction-key: 7f1c...9ba2
Never expose a transaction key in browser or mobile code — call the gateway from your server.
Create a transaction
/api/public/gateway/v1/transactionsRuns a purchase, authorization, account verification or unreferenced credit.
Request body
| Field | Type | Description |
|---|---|---|
| type | "purchase" | "authorize" | "verify" | "credit" | Defaults to "purchase". "authorize" holds funds for a later capture, "verify" performs a zero-amount account check, "credit" pushes an unreferenced credit to the card. |
| amount* | string | number | Major-unit amount, e.g. "24.99". Not required for "verify". |
| amountMinor | integer | Minor units (cents). Takes precedence over amount when both are sent. |
| currency | string(3) | ISO 4217 code. Defaults to the merchant's configured currency. |
| card.number | string | Raw PAN. Send this or card.token. |
| card.expMonth | integer 1-12 | Expiry month, required with card.number. |
| card.expYear | integer | Expiry year, 2 or 4 digits. |
| card.cvv | string(3-4) | Card verification value. Recommended for card-not-present. |
| card.cardholderName | string | Name as printed on the card. |
| card.token | string | A stored instrument token returned by an earlier storeCard request. |
| billing | object | firstName, lastName, address, city, state, postal, country — used for AVS. |
| description | string(255) | Free-form description stored with the transaction. |
| orderReference | string(64) | Your order identifier. |
| invoiceNumber | string(64) | Your invoice identifier. |
| customerEmail | string | Customer email for receipts and reporting. |
| storeCard | boolean | When true and the transaction is approved, the card is tokenized into the vault for reuse. |
Example
curl -X POST https://chargezoomgateway.com/api/public/gateway/v1/transactions \
-u "$API_LOGIN_ID:$TRANSACTION_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1001" \
-d '{
"type": "purchase",
"amount": "24.99",
"currency": "USD",
"orderReference": "order-1001",
"card": {
"number": "4111111111111111",
"expMonth": 12,
"expYear": 2030,
"cvv": "123"
},
"billing": { "postal": "94107", "country": "US" }
}'HTTP/1.1 201 Created
{
"ok": true,
"transaction": {
"id": "8f2c1e34-0b1f-4a90-b3ff-1f2e6c9a77d1",
"type": "purchase",
"status": "captured",
"approved": true,
"amountMinor": 2499,
"currency": "USD",
"authCode": "5JD5FT",
"processor": "fiserv",
"cardBrand": "visa",
"lastFour": "1111",
"avsResult": "Y",
"cvvResult": "M",
"declineReasonCode": null,
"declineReason": null,
"batchId": "1d0a8e21-6f4c-4c65-9a08-2b70a5f0c9ab",
"createdAt": "2026-09-03T17:22:41.019Z"
}
}HTTP/1.1 402 Payment Required
{
"ok": false,
"transaction": {
"id": "c7b2...",
"status": "declined",
"approved": false,
"declineReasonCode": "insufficient_funds",
"declineReason": "Insufficient funds"
}
}Transaction object
| Field | Type | Description |
|---|---|---|
| id | uuid | Chargezoom transaction ID. Use it for capture, void and refund. |
| type | string | The requested transaction type. |
| status | string | pending, authorized, captured, batched, settled, verified, declined, voided, refunded, partially_refunded or error. |
| approved | boolean | True for authorized, captured, batched, settled and verified statuses. |
| amountMinor | integer | Processed amount in minor units. |
| currency | string(3) | Currency of the transaction. |
| authCode | string | null | Acquirer authorization code. |
| processor | string | null | Processor that handled the authorization. |
| processorTransactionId | string | null | Processor-side reference. |
| cardBrand | string | null | visa, mastercard, amex, discover, and so on. |
| lastFour | string | null | Last four digits of the card. |
| avsResult | string | null | Address verification result code. |
| cvvResult | string | null | CVV match result code. |
| declineReasonCode | string | null | Normalized decline code, e.g. insufficient_funds. |
| declineReason | string | null | Human-readable decline explanation. |
| batchId | uuid | null | Settlement batch the capture landed in. |
| createdAt | timestamp | ISO 8601 creation time. |
Status codes
201 approved · 402 declined (the transaction object explains why) · 400 malformed JSON · 401 authentication problem · 422 validation or gateway rule failure · 500 unexpected gateway error.
Follow-up actions
Act on an existing transaction by ID. Omit the amount to act on the full amount, or send a smaller one for a partial capture or refund.
/api/public/gateway/v1/transactions/{id}/captureCaptures a previously authorized transaction and adds it to the open settlement batch.
/api/public/gateway/v1/transactions/{id}/voidCancels an authorization or an unsettled capture before funding.
/api/public/gateway/v1/transactions/{id}/refundReturns funds on a captured, batched or settled transaction, fully or partially.
| Field | Type | Description |
|---|---|---|
| amount | string | number | Optional major-unit amount for a partial action. |
| amountMinor | integer | Optional minor-unit amount. Takes precedence over amount. |
curl -X POST \
https://chargezoomgateway.com/api/public/gateway/v1/transactions/$TRANSACTION_ID/capture \
-u "$API_LOGIN_ID:$TRANSACTION_KEY" \
-H "Content-Type: application/json" \
-d '{ "amount": "18.00" }'Webhooks
Register endpoints in the portal under Developers. Each endpoint subscribes to specific event types or to * for all of them, and receives its own signing secret, shown once.
| Field | Type | Description |
|---|---|---|
| transaction.authorized | event | An authorization was approved and is awaiting capture. |
| transaction.captured | event | Funds were captured and queued into a batch. |
| transaction.verified | event | A zero-amount verification succeeded. |
| transaction.declined | event | A transaction was declined by risk rules or the processor. |
| transaction.voided | event | An authorization or unsettled capture was voided. |
| transaction.refunded | event | A full or partial refund was issued. |
| batch.submitted | event | A settlement batch was closed and submitted to the processor. |
| settlement.funded | event | Funding was reconciled with gross, fee and net amounts. |
Deliveries are POSTed as JSON with the event type and an HMAC-SHA256 signature over {timestamp}.{rawBody}. Failed attempts are retried with exponential backoff, so respond 2xx quickly and process asynchronously. Deduplicate on the transaction ID and event type.
POST /your-endpoint HTTP/1.1
X-Gateway-Event: transaction.captured
X-Gateway-Signature: t=1772822561,v1=9c1f...e07
{
"eventType": "transaction.captured",
"transaction": { "id": "8f2c1e34-...", "status": "captured", "amountMinor": 2499 }
}import crypto from "node:crypto";
export function verifyChargezoomSignature(rawBody, header, signingSecret) {
const parts = Object.fromEntries(
header.split(",").map((piece) => piece.split("=")),
);
const expected = crypto
.createHmac("sha256", signingSecret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(parts.v1),
);
}Errors
Errors use a consistent envelope:
{
"error": {
"code": "validation_failed",
"message": "A positive amount is required."
}
}| Code | HTTP | Meaning |
|---|---|---|
| invalid_json | 400 | The request body was not valid JSON. |
| authentication_required | 401 | No API login ID or transaction key was supplied. |
| authentication_failed | 401 | Credentials are invalid, revoked, or the merchant is not approved. |
| validation_failed | 422 | A field failed validation. The message names the first problem. |
| invalid_amount | 422 | A positive amount is required for this transaction type. |
| invalid_state | 422 | The transaction cannot make that transition, e.g. capturing something already captured. |
| duplicate_transaction | 422 | An identical amount and card was submitted moments ago. |
| unknown_action | 404 | The follow-up action is not capture, void or refund. |
| gateway_error | 500 | Unexpected gateway failure. Safe to retry with the same Idempotency-Key. |
A decline is not an error: it returns 402 with a full transaction object, including declineReasonCode.
Testing
Sandbox credentials route to a deterministic simulator, so the card number decides the outcome. Any future expiry works, and no real network or money movement occurs.
| Card number | Result |
|---|---|
| 4111 1111 1111 1111 | Approved |
| 4000 0000 0000 0002 | Declined — generic_decline |
| 4000 0000 0000 9995 | Declined — insufficient_funds |
| 4000 0000 0000 0069 | Declined — expired_card |
| 4000 0000 0000 0127 | Declined — cvv_mismatch |
| 4000 0000 0000 0010 | Declined — avs_mismatch (AVS returns N) |
| 4000 0000 0000 0119 | Declined — processor_error |
| 4000 0000 0000 0101 | Declined — fraud_suspected |
| 4000 0000 0000 0259 | Declined — pickup_card |
| 4000 0000 0000 0341 | Simulated processor timeout |
You can also run one-off sales without writing code from the virtual terminal in the merchant portal.
