Card Vault Pre-Auth
Pre-Auth Request
Request to place a pre-authorisation hold on a customer's vaulted card(s). Funds are reserved on the cardholder's account but not settled until captured. By default the customer's default card is attempted first, cascading through the remaining active cards in priority order until an authorisation succeeds or all cards are exhausted. Pass card_id to authorise a specific card only (no cascade).
Pre-auths are processed as merchant-initiated transactions (MIT) — no 3DS challenge is presented. The 3DS authentication from the original card storage (see Card Vault Link) provides the authentication reference for scheme compliance.
A successful pre-auth returns a transaction_id (tra_), which is then used to capture or reverse the hold. Holds that are neither captured nor reversed expire automatically at expires_at (7 days by default) and the funds are released.
Path
POST /card-vault/{customer_id}/pre-auth
| Path Parameter | Type | Description | Example |
|---|---|---|---|
| customer_id | String(32) | The customer whose stored cards will be authorised — see customers | cus_abc123... |
Example (Basic)
Basic example to pre-authorise the customer. The default card is attempted first, then the remaining active cards in priority order.
{
"item": {
"amount": "349.00" // amount to place on hold
},
"reference": "INV-2026-00042" // your reference; appears on statements and reporting
}
Example (Specific card)
Pre-authorise one specific stored card only. The cascade is disabled — if this card declines, the pre-auth fails.
{
"item": {
"amount": "349.00"
},
"reference": "INV-2026-00042",
"card_id": "crd_SFq2E9LskQimPkf2mRqnV" // authorise this card only; obtain card IDs from the card vault webhooks or the customer's card list
}
Example (Advanced)
Advanced example with all options, including cascade controls and hold duration.
{
"item": {
"amount": "349.00",
"title": "Booking deposit", // [optional] carried through as the default invoice line when the hold is captured with an invoice
"description": "Room 12, 3 nights" // [optional]
},
"currency": "ZAR", // [optional] default "ZAR"
"reference": "INV-2026-00042", // your reference; appears on statements and reporting
"expires_in_days": 7, // [optional] default 7 — days before an uncaptured hold is automatically released (1–30, scheme limits apply)
"signature": "secret-key-for-payload", // [optional] shared-secret signature for the payload, see the signature section below
// [optional] catalog invoice lines, carried through as the default lines when the hold is captured with an invoice —
// overrides the default single line from item; can be overridden at capture
"items": [
{
"product_id": "pro_abc123...",
"qty": 2 // default 1 when omitted
},
{
"product_id": "pro_xyz789...",
"price_excl": 300.23 // override the default product amount
}
],
// Cascade behaviour — ignored when card_id is passed
"cascade": {
"is_enabled": true, // [optional] default true — when false, only the default card is attempted
"max_attempts": 3, // [optional] cap on the number of cards tried; defaults to all ACTIVE cards
"card_order": [ // [optional] explicit order override; defaults to: default card first, then by priority
"crd_SFq2E9LskQimPkf2mRqnV",
"crd_9kLmXw3RtYqPz8vNcE2aB"
],
"skip_codes": ["DO_NOT_HONOUR"] // [optional] additional decline codes that abort the cascade; hard declines (e.g. SUSPECTED_FRAUD, STOLEN_CARD, PICKUP_CARD) always abort and cannot be overridden
},
"notification": {
"email": "me@my-email.co.za", // [optional] email notification on the pre-auth outcome
"webhook_url": "https://merchant.example/webhooks/payments" // webhook on preauth.successful / preauth.failed / preauth.captured / preauth.reversed / preauth.expired
},
"metadata": {
"order_id": "ord_98765" // [optional] custom key/value pairs returned on the pre-auth and webhooks
}
}
Request Parameters
Fields below appear in the request body examples on this page. Y = required for all requests, C = required or applicable depending on usage.
Field | Required | Type | Description | Example |
|---|---|---|---|---|
| item | Y | Object | Hold amount and payer-facing details | See basic example |
| item.amount | Y | String | Amount to place on hold | 349.00 |
| item.title | N | String | Line item title, carried through as the default invoice line when the hold is captured with an invoice; defaults to reference when omitted | Booking deposit |
| item.description | N | String | Optional longer line item description | Room 12, 3 nights |
| currency | N | String(3) | ISO 4217 currency code. Default ZAR | ZAR |
| reference | Y | String(35) | Your reference for this pre-auth; appears on statements and reporting. Must be unique per pre-auth to support idempotent retries | INV-2026-00042 |
| card_id | C | String(32) | Authorise this specific card only; the cascade is disabled. Omit to authorise the customer with cascade | crd_SFq2E9LskQimPkf2mRqnV |
| expires_in_days | N | Integer | Days before an uncaptured hold is automatically released (1–30; card scheme limits apply). Default 7 | 7 |
| items | N | Array | Invoice line items from your catalog, carried through as the default lines when the hold is captured with an invoice; overrides the default single line from item. Can be overridden at capture — see products | See advanced example |
| items.product_id | Y | String | Catalog product for this line | pro_abc123... |
| items.qty | N | Integer | Quantity for this line item (default 1) | 2 |
| items.price_excl | N | Number | Override the default product amount (excluding tax) | 300.23 |
| cascade | N | Object | Cascade behaviour; ignored when card_id is passed | See advanced example |
| cascade.is_enabled | N | Boolean | When false, only the default card is attempted. Default true | true |
| cascade.max_attempts | N | Integer | Cap on the number of cards tried; defaults to all ACTIVE cards | 3 |
| cascade.card_order | N | Array | Explicit card order override; defaults to the default card first, then by priority | [crd_SFq2..., crd_9kLm...] |
| cascade.skip_codes | N | Array | Additional decline codes that abort the cascade instead of trying the next card. Hard declines (SUSPECTED_FRAUD, STOLEN_CARD, PICKUP_CARD) always abort and cannot be overridden — see lookups | [DO_NOT_HONOUR] |
| signature | N | String | Optional passphrase signature for verifying the payload | secret-key-for-payload |
| notification.email | N | String | Email address to notify on the pre-auth outcome | me@my-email.co.za |
| notification.webhook_url | N | String | Webhook URL for the pre-auth lifecycle events | https://merchant.example/webhooks/payments |
| metadata | N | Object | Custom key/value metadata returned on the pre-auth and webhooks | {"order_id": "ord_98765"} |
Response Body
A pre-auth (pre_) wraps one or more card transactions (tra_). Every attempt — including declines — is a real transaction with its own identifier, listed in attempts in the order they were tried. The transaction_id of the successful attempt is the identifier you pass to the capture and reverse endpoints.
Example where the default card declined and the second card was authorised:
{
"status": true,
"result": {
"id": "pre_Wt5RmK2xPqLv9nYcE7aBz",
"customer_id": "cus_abc123...",
"amount": "349.00",
"currency": "ZAR",
"reference": "INV-2026-00042",
"pre_auth_status": "AUTHORISED",
"card_id": "crd_9kLmXw3RtYqPz8vNcE2aB",
"transaction_id": "tra_pr6CvR_4pvWwmgQ4y3dtY",
"attempts": [
{
"sequence": 1,
"card_id": "crd_SFq2E9LskQimPkf2mRqnV",
"is_default": true,
"transaction_id": "tra_x9YtRw2QpLmN8vKcE3aBz",
"transaction_status": "DECLINED",
"error": {
"code": "INSUFFICIENT_FUNDS",
"message": "The transaction was declined due to insufficient funds"
}
},
{
"sequence": 2,
"card_id": "crd_9kLmXw3RtYqPz8vNcE2aB",
"is_default": false,
"transaction_id": "tra_pr6CvR_4pvWwmgQ4y3dtY",
"transaction_status": "AUTHORISED"
}
],
"expires_at": "2026-07-13T10:15:30Z",
"created_at": "2026-07-06T10:15:30Z"
}
}
Example where all cards declined:
{
"status": false,
"result": {
"id": "pre_Rk8NwT4yQmXz2pLvE9aBc",
"customer_id": "cus_abc123...",
"amount": "349.00",
"currency": "ZAR",
"reference": "INV-2026-00042",
"pre_auth_status": "FAILED",
"card_id": null,
"transaction_id": null,
"attempts": [
{
"sequence": 1,
"card_id": "crd_SFq2E9LskQimPkf2mRqnV",
"is_default": true,
"transaction_id": "tra_x9YtRw2QpLmN8vKcE3aBz",
"transaction_status": "DECLINED",
"error": {
"code": "INSUFFICIENT_FUNDS",
"message": "The transaction was declined due to insufficient funds"
}
},
{
"sequence": 2,
"card_id": "crd_9kLmXw3RtYqPz8vNcE2aB",
"is_default": false,
"transaction_id": "tra_z2QpLvE9aBcRk8NwT4yQm",
"transaction_status": "DECLINED",
"error": {
"code": "EXPIRED_CARD",
"message": "The transaction was declined because the card has expired"
}
}
],
"created_at": "2026-07-06T10:15:35Z"
}
}
Response Parameters
Field | Type | Description | Example |
|---|---|---|---|
| status | Boolean | Whether the pre-auth succeeded | true |
| result.id | String(32) | Unique pre-auth identifier wrapping all cascade attempts | pre_Wt5RmK2xPqLv9nYcE7aBz |
| result.customer_id | String(32) | Associated customer ID | cus_abc123... |
| result.amount | String | Amount placed on hold | 349.00 |
| result.currency | String(3) | ISO 4217 currency code | ZAR |
| result.reference | String(35) | Your reference for this pre-auth | INV-2026-00042 |
| result.pre_auth_status | ENUM | Overall pre-auth state: AUTHORISED, FAILED, CAPTURED, REVERSED, or EXPIRED, see lookups | AUTHORISED |
| result.card_id | String(32) | The card that was ultimately authorised; null when the pre-auth failed | crd_9kLmXw3RtYqPz8vNcE2aB |
| result.transaction_id | String(32) | The authorised transaction — pass this to the capture and reverse endpoints; null when the pre-auth failed | tra_pr6CvR_4pvWwmgQ4y3dtY |
| result.attempts | Array | Every card attempt in the order tried, including declines | ... |
| result.attempts.sequence | Integer | Position of this attempt in the cascade | 1 |
| result.attempts.card_id | String(32) | Card attempted | crd_SFq2E9LskQimPkf2mRqnV |
| result.attempts.is_default | Boolean | Whether this card was the customer's default at the time of the pre-auth | true |
| result.attempts.transaction_id | String(32) | Transaction identifier for this attempt | tra_x9YtRw2QpLmN8vKcE3aBz |
| result.attempts.transaction_status | ENUM | Transaction status, see lookups | DECLINED |
| result.attempts.error.code | ENUM | Decline code when the attempt failed, see lookups | INSUFFICIENT_FUNDS |
| result.attempts.error.message | String | Human-readable decline reason | The transaction was declined due to insufficient funds |
| result.expires_at | String | ISO timestamp when the uncaptured hold is automatically released | 2026-07-13T10:15:30Z |
| result.created_at | String | ISO timestamp when the pre-auth was created | 2026-07-06T10:15:30Z |
Capture Request
Capture (settle) a previously authorised hold by passing the transaction_id returned by the pre-auth request. The full held amount is captured by default; pass amount for a partial capture — any remaining held funds are automatically released. A pre-auth can be captured once, and only while its status is AUTHORISED.
Path
POST /card-vault/pre-auth/{transaction_id}/capture
| Path Parameter | Type | Description | Example |
|---|---|---|---|
| transaction_id | String(32) | The authorised transaction returned by the pre-auth request | tra_pr6CvR_4pvWwmgQ4y3dtY |
Example (Full capture)
Capture the full held amount. An empty body (or {}) is valid.
{
"reference": "INV-2026-00042-CAP" // [optional] defaults to the pre-auth reference
}
Example (Partial capture with invoice)
Capture part of the hold; the remainder is released back to the cardholder.
When generating an invoice, the line items default to the item / items supplied on the pre-auth request. Pass a single item object or an items array here to override them — see Checkout Link for the same pattern. Overriding is recommended on partial captures so the invoice lines match the captured amount. When no item.title or items were supplied on either call, the invoice shows a single line using the pre-auth reference.
{
"amount": "299.00", // [optional] must be <= the held amount; omit to capture in full
"reference": "INV-2026-00042-CAP", // [optional] defaults to the pre-auth reference
"signature": "secret-key-for-payload", // [optional] shared-secret signature for the payload, see the signature section below
// Invoice line items — overrides the item / items supplied on the pre-auth;
// pass item for a single free-form line, or items for catalog lines (mutually exclusive)
"items": [
{
"product_id": "pro_abc123...",
"qty": 2 // default 1 when omitted
},
{
"product_id": "pro_xyz789...",
"price_excl": 300.23 // override the default product amount
}
],
// Issue and optionally email an invoice for the captured amount
"invoice": {
"is_generate": true,
"is_send": true // send paid invoice to the customer when true
},
"notification": {
"email": "me@my-email.co.za", // [optional] email notification on the capture outcome
"webhook_url": "https://merchant.example/webhooks/payments" // [optional] overrides the webhook URL supplied on the pre-auth
}
}
Request Parameters
Field | Required | Type | Description | Example |
|---|---|---|---|---|
| amount | N | String | Amount to capture; must be less than or equal to the held amount. Omit to capture the full hold. Any uncaptured remainder is released | 299.00 |
| reference | N | String(35) | Your reference for the capture; defaults to the pre-auth reference | INV-2026-00042-CAP |
| item | N | Object | Single free-form invoice line when generating an invoice; overrides the lines supplied on the pre-auth. Mutually exclusive with items | {"title": "Booking deposit"} |
| item.title | C | String | Line item title shown on the invoice | Booking deposit |
| item.description | N | String | Optional longer line item description | Room 12, 3 nights |
| items | N | Array | Invoice line items from your catalog when generating an invoice; overrides the lines supplied on the pre-auth. Mutually exclusive with item — see products | See partial capture example |
| items.product_id | Y | String | Catalog product for this line | pro_abc123... |
| items.qty | N | Integer | Quantity for this line item (default 1) | 2 |
| items.price_excl | N | Number | Override the default product amount (excluding tax) | 300.23 |
| signature | N | String | Optional passphrase signature for verifying the payload | secret-key-for-payload |
| invoice.is_generate | N | Boolean | Whether to generate an invoice for the captured amount | true |
| invoice.is_send | N | Boolean | Whether to send the paid invoice to the customer | true |
| notification.email | N | String | Email address to notify on the capture outcome | me@my-email.co.za |
| notification.webhook_url | N | String | Webhook URL for the capture outcome; overrides the URL supplied on the pre-auth | https://merchant.example/webhooks/payments |
Response Body
{
"status": true,
"result": {
"id": "pre_Wt5RmK2xPqLv9nYcE7aBz",
"customer_id": "cus_abc123...",
"transaction_id": "tra_pr6CvR_4pvWwmgQ4y3dtY",
"card_id": "crd_9kLmXw3RtYqPz8vNcE2aB",
"pre_auth_status": "CAPTURED",
"amount": "349.00",
"captured_amount": "299.00",
"released_amount": "50.00",
"currency": "ZAR",
"reference": "INV-2026-00042-CAP",
"invoice_id": "inv_k2Jd8sLqPz...",
"captured_at": "2026-07-08T09:20:00Z"
}
}
Response Parameters
Field | Type | Description | Example |
|---|---|---|---|
| status | Boolean | Whether the capture succeeded | true |
| result.id | String(32) | The pre-auth this capture belongs to | pre_Wt5RmK2xPqLv9nYcE7aBz |
| result.customer_id | String(32) | Associated customer ID | cus_abc123... |
| result.transaction_id | String(32) | The captured transaction | tra_pr6CvR_4pvWwmgQ4y3dtY |
| result.card_id | String(32) | The card the funds were captured from | crd_9kLmXw3RtYqPz8vNcE2aB |
| result.pre_auth_status | ENUM | CAPTURED on success, see lookups | CAPTURED |
| result.amount | String | Original held amount | 349.00 |
| result.captured_amount | String | Amount settled | 299.00 |
| result.released_amount | String | Remainder of the hold released back to the cardholder | 50.00 |
| result.currency | String(3) | ISO 4217 currency code | ZAR |
| result.reference | String(35) | Reference used for the capture | INV-2026-00042-CAP |
| result.invoice_id | String(32) | Invoice identifier; present when invoice.is_generate was true | inv_k2Jd8sLqPz... |
| result.captured_at | String | ISO timestamp when the capture completed | 2026-07-08T09:20:00Z |
Reverse Request
Release a previously authorised hold without settling any funds, by passing the transaction_id returned by the pre-auth request. The full held amount is returned to the cardholder's available balance. A pre-auth can only be reversed while its status is AUTHORISED; expired holds are released automatically.
Path
POST /card-vault/pre-auth/{transaction_id}/reverse
| Path Parameter | Type | Description | Example |
|---|---|---|---|
| transaction_id | String(32) | The authorised transaction returned by the pre-auth request | tra_pr6CvR_4pvWwmgQ4y3dtY |
Example
An empty body (or {}) is valid.
{
"reason": "Booking cancelled by customer", // [optional] recorded against the reversal for reporting
"signature": "secret-key-for-payload", // [optional] shared-secret signature for the payload, see the signature section below
"notification": {
"email": "me@my-email.co.za", // [optional] email notification on the reversal outcome
"webhook_url": "https://merchant.example/webhooks/payments" // [optional] overrides the webhook URL supplied on the pre-auth
}
}
Request Parameters
Field | Required | Type | Description | Example |
|---|---|---|---|---|
| reason | N | String | Optional reason recorded against the reversal for reporting | Booking cancelled by customer |
| signature | N | String | Optional passphrase signature for verifying the payload | secret-key-for-payload |
| notification.email | N | String | Email address to notify on the reversal outcome | me@my-email.co.za |
| notification.webhook_url | N | String | Webhook URL for the reversal outcome; overrides the URL supplied on the pre-auth | https://merchant.example/webhooks/payments |
Response Body
{
"status": true,
"result": {
"id": "pre_Wt5RmK2xPqLv9nYcE7aBz",
"customer_id": "cus_abc123...",
"transaction_id": "tra_pr6CvR_4pvWwmgQ4y3dtY",
"card_id": "crd_9kLmXw3RtYqPz8vNcE2aB",
"pre_auth_status": "REVERSED",
"amount": "349.00",
"released_amount": "349.00",
"currency": "ZAR",
"reference": "INV-2026-00042",
"reversed_at": "2026-07-08T09:20:00Z"
}
}
Response Parameters
Field | Type | Description | Example |
|---|---|---|---|
| status | Boolean | Whether the reversal succeeded | true |
| result.id | String(32) | The pre-auth this reversal belongs to | pre_Wt5RmK2xPqLv9nYcE7aBz |
| result.customer_id | String(32) | Associated customer ID | cus_abc123... |
| result.transaction_id | String(32) | The reversed transaction | tra_pr6CvR_4pvWwmgQ4y3dtY |
| result.card_id | String(32) | The card the hold was released from | crd_9kLmXw3RtYqPz8vNcE2aB |
| result.pre_auth_status | ENUM | REVERSED on success, see lookups | REVERSED |
| result.amount | String | Original held amount | 349.00 |
| result.released_amount | String | Amount released back to the cardholder | 349.00 |
| result.currency | String(3) | ISO 4217 currency code | ZAR |
| result.reference | String(35) | Your reference from the original pre-auth | INV-2026-00042 |
| result.reversed_at | String | ISO timestamp when the reversal completed | 2026-07-08T09:20:00Z |
Signature creation
When creating API keys on the dashboard you can download a passphrase key, use it to generate your signature and send it in the signature parameter. The canonicalization and HMAC-SHA256 process is identical across all endpoints — see Checkout Link — Signature creation for Node.js, PHP, C#, Java, and Python examples.
Webhook
Webhooks are delivered to notification.webhook_url for each pre-auth lifecycle event when that field was supplied. Broader platform webhooks are configured separately if applicable. Webhooks fire once per pre-auth outcome, not per cascade attempt.
Possible event values include preauth.successful, preauth.failed, preauth.captured, preauth.reversed, and preauth.expired, listed under Webhook events.
Webhook Payload
{
// preauth.successful · preauth.failed · preauth.captured · preauth.reversed · preauth.expired
"event": "preauth.captured",
"data": [
{
"pre_auth": {
"id": "pre_Wt5RmK2xPqLv9nYcE7aBz",
"customer_id": "cus_abc123...",
"amount": "349.00",
"captured_amount": "299.00", // present on preauth.captured
"released_amount": "50.00", // present on preauth.captured / preauth.reversed / preauth.expired
"currency": "ZAR",
"reference": "INV-2026-00042-CAP",
"pre_auth_status": "CAPTURED",
"card_id": "crd_9kLmXw3RtYqPz8vNcE2aB",
"transaction_id": "tra_pr6CvR_4pvWwmgQ4y3dtY",
"attempts": [
{
"sequence": 1,
"card_id": "crd_SFq2E9LskQimPkf2mRqnV",
"is_default": true,
"transaction_id": "tra_x9YtRw2QpLmN8vKcE3aBz",
"transaction_status": "DECLINED",
"error": {
"code": "INSUFFICIENT_FUNDS",
"message": "The transaction was declined due to insufficient funds"
}
},
{
"sequence": 2,
"card_id": "crd_9kLmXw3RtYqPz8vNcE2aB",
"is_default": false,
"transaction_id": "tra_pr6CvR_4pvWwmgQ4y3dtY",
"transaction_status": "CAPTURED"
}
],
"invoice_id": "inv_k2Jd8sLqPz...",
"metadata": {
"order_id": "ord_98765"
},
"expires_at": "2026-07-13T10:15:30Z",
"completed_at": "2026-07-08T09:20:00Z"
}
}
],
"created_at": "2026-07-08T09:20:00Z"
}
Webhook Payload Parameters
Field | Type | Description | Example |
|---|---|---|---|
| event | String | Type of webhook event that occurred | preauth.captured |
| data | Array | Array containing pre-auth data | ... |
| data.pre_auth.id | String(32) | Unique pre-auth identifier | pre_Wt5RmK2xPqLv9nYcE7aBz |
| data.pre_auth.customer_id | String(32) | Associated customer ID | cus_abc123... |
| data.pre_auth.amount | String | Original held amount | 349.00 |
| data.pre_auth.captured_amount | String | Amount settled; present on preauth.captured | 299.00 |
| data.pre_auth.released_amount | String | Amount released back to the cardholder; present on preauth.captured, preauth.reversed, and preauth.expired | 50.00 |
| data.pre_auth.currency | String(3) | ISO 4217 currency code | ZAR |
| data.pre_auth.reference | String(35) | Reference for this pre-auth or capture | INV-2026-00042-CAP |
| data.pre_auth.pre_auth_status | ENUM | Pre-auth state after the event, see lookups | CAPTURED |
| data.pre_auth.card_id | String(32) | The card that was authorised; null on failure | crd_9kLmXw3RtYqPz8vNcE2aB |
| data.pre_auth.transaction_id | String(32) | The authorised transaction; null on failure | tra_pr6CvR_4pvWwmgQ4y3dtY |
| data.pre_auth.attempts | Array | Every card attempt in the order tried, including declines | ... |
| data.pre_auth.invoice_id | String(32) | Invoice identifier when invoice.is_generate was true on capture | inv_k2Jd8sLqPz... |
| data.pre_auth.metadata | Object | Custom key/value metadata supplied on create | {"order_id": "ord_98765"} |
| data.pre_auth.expires_at | String | ISO timestamp when the uncaptured hold is automatically released | 2026-07-13T10:15:30Z |
| data.pre_auth.completed_at | String | ISO timestamp when the pre-auth reached the status for this event | 2026-07-08T09:20:00Z |
| created_at | String | ISO timestamp when webhook was created | 2026-07-08T09:20:00Z |
Webhook Events
| Event | Description | Trigger Condition | Data Included |
|---|---|---|---|
preauth.successful | A hold was placed on one of the customer's cards | When any cascade attempt (or the specified card_id) is authorised | Pre-auth details, authorised transaction, full attempt history, hold expiry |
preauth.failed | The pre-auth failed on all attempted cards | When all cascade attempts decline, a hard decline aborts the cascade, or the specified card_id declines | Pre-auth details, full attempt history with decline codes |
preauth.captured | The hold was settled in full or in part | When a capture request completes | Pre-auth details, captured and released amounts, invoice when generated |
preauth.reversed | The hold was released without settlement | When a reverse request completes | Pre-auth details, released amount |
preauth.expired | The hold expired and was released automatically | When expires_at passes without a capture or reversal | Pre-auth details, released amount |
Webhook Security
All webhooks are sent with the following headers for verification:
X-Signature: HMAC-SHA256 signature of the payloadX-Timestamp: Unix timestamp of when the webhook was sentUser-Agent:Kwik-Webhooks/1.0
Webhook Response
Your endpoint should respond with a 200 status code to acknowledge receipt. Failed webhooks will be retried up to 3 times with exponential backoff.
Card Vault Charge
Charge a customer's stored cards server-to-server. Attempts the default card first with automatic cascade to fallback cards, or targets a specific card. Supports merchant-initiated (MIT) scheme compliance, invoice issuance, and webhook notifications.
Payouts
Send money to customer bank accounts and manage outbound transfers. Create single or batch payouts with real-time status tracking, beneficiary management, and comprehensive transaction reporting.