Webhooks are the authoritative event stream for card activity, master-account ledger movements, and deposit status events.
Delivery Contract #
| Header | Value | Notes |
|---|---|---|
Content-Type |
application/json |
Always UTF-8 JSON. |
x-client-id |
Your tenant ID | Mirrors the API credential. |
x-signature |
HMAC-SHA256 | Lowercase hexadecimal digest computed with the client secret. |
x-idempotency-key |
Optional | Propagated when the source API call had one. |
Compute x-signature over the exact HTTP request body bytes. The header contains
the bare 64-character hexadecimal digest, without a sha256= prefix.
Payload schema:
{
"event": "card_transaction",
"data": {
"id": "5b2fa934-1f1d-4b71-8d5a-a3e2f61ac1af",
"cardId": "0b1e9c6e-5d87-4f90-8c4d-0ad6f4ce4be5",
"transactionAmount": "12.34",
"transactionCurrency": "USD",
"type": "authorization",
"referenceId": "c8de3ebf-5b2d-4020-a7bb-65f88c3a37ce",
"timestamp": "2025-06-02T11:24:12Z"
}
}
Recommended Ingestion Flow #
- Verify
x-signaturebefore parsing payload. - Persist raw payload keyed by
data.id. - Handle duplicates idempotently.
- Return
204 No Contentquickly. - Process business logic asynchronously.
Event Types #
| Event | Fired When | Key Fields |
|---|---|---|
card_transaction |
Authorizations, settlements, adjustments, refunds, declines, card lifecycle events | cardId, type, referenceId, linkedId |
account_transaction |
Master-account ledger entries (holds, releases, fees, transfers) | accountId, type, subtype, amount, referenceId |
account.deposit.* |
A deposit completed, failed, cancelled, expired, entered manual review, was refunded, or was charged back | id, status, accountId, chargedAmount, creditedAmount |
Join card and account events by referenceId for full flow reconciliation. Deposit webhooks use the deposit data.id as their stable business identifier.
Deposit Webhooks #
Register deposit deliveries separately with type: deposit. The event names are:
account.deposit.completedaccount.deposit.failedaccount.deposit.cancelledaccount.deposit.expiredaccount.deposit.refundedaccount.deposit.chargebackaccount.deposit.manual_review
Example:
{
"event": "account.deposit.completed",
"data": {
"id": "f99bc4a6-604f-47a8-941b-6b02d4963504",
"status": "completed",
"method": "card",
"accountId": "4a40c2a9-b145-4335-bf19-f302b9b72062",
"amount": "20.00",
"currency": "USD",
"chargedAmount": "22.00",
"creditedAmount": "20.00",
"paycaFee": "2.00",
"createdAt": "2026-08-13T10:30:00Z",
"completedAt": "2026-08-13T13:30:00Z"
}
}
No deposit webhook is sent for created, awaiting_payment, or processing; retrieve the deposit while it is in flight. A completed deposit may later emit refunded or chargeback.
Replay Strategy #
If your endpoint was unavailable, replay failed deliveries:
curl -X POST "$PAYCA_BASE_URL/v1/webhooks/resend?fromDate=2025-06-01T00:00:00Z" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET"
Recommendations:
- Replay in chronological order.
- Rate-limit replay processing to avoid
429. - Monitor replay completion and remaining failures.
- Use response counters (
account,card,deposit,total) to validate scope.
Client-Side Storage Recommendations #
Store at least these fields from every webhook:
- Envelope:
event, receive timestamp, HTTP headers (x-client-id,x-idempotency-key). - Data object:
id,referenceId,type,subtype,status,amount,currency,cardId,accountId(when present).
This is sufficient for replay, audit, and financial reconciliation.
Alerting & Security #
- Alert when webhook failures spike or replay backlog grows.
- Track end-to-end webhook latency.
- Serve webhook endpoints over HTTPS (TLS 1.2+).
- Rotate secrets regularly and support overlap during key rotation.
Continue with Webhook Balance Effects for event-by-event balance impact.