Overview
Card webhooks notify your application when a card changes state or a card transaction occurs. The current card event types are:card.authorizationcard.chargescard.contactless.activationcard.createdcard.created.failedcard.freezedcard.terminatedcard.transactioncard.unfreezedcard.updated
2xx after the event has been accepted for processing.
Verification decision webhooks
Available for asynchronous document verification. These events do not change
the synchronous Nigerian BVN flow or automatically issue a card.
card.verification.approved and
card.verification.rejected using the webhook create or update API. They are
opt-in; an empty or omitted event list does not subscribe to these events.
When updating a webhook, retain any other events you still want in the list.
Subscription
card.verification.approved
event: "card.verification.rejected", status: "REJECTED",
and can_create_card: false. These events apply to asynchronous document
verification for non-Nigerian DEFAULT USD cards, not customer-tier approval.
Verification can finish before a card exists, so the payload identifies the customer rather than a card.
It contains no identity documents, verification tokens, or provider identifiers.
Approval does not create a card or debit the wallet. Before submitting
POST /cards, check the current verification status
and require can_create_card: true. A delivery is a snapshot; subsequent KYC
changes can invalidate eligibility. An approval snapshot can have
can_create_card: false when the saved details have changed.
Verification and retries
These two events retainX-SWERV-SECRET and add:
X-SWERV-Event: event type.X-SWERV-Event-Id: stable delivery ID for this event and webhook endpoint.X-SWERV-Timestamp: Unix timestamp in seconds for this delivery attempt.X-SWERV-Signature:t=<timestamp>,v1=<hex_hmac>.
<timestamp>.<exact raw request body>. Verify using a constant-time comparison,
require the signature timestamp to match X-SWERV-Timestamp, and reject stale
timestamps using a short tolerance such as five minutes. Do not reserialize JSON
before checking the signature.
Use the top-level id as your event idempotency key. The body and event/delivery
IDs remain stable on retry; the signature timestamp is refreshed. Delivery is
at-least-once: acknowledge promptly with 2xx and handle duplicate notifications
without submitting duplicate card requests. Failed deliveries use the existing
retry mechanism and webhook logs; polling remains a fallback if delivery is missed.
Other existing webhook events keep their current authentication protocol.
Created webhook event
This event is fired when a card is created.card.created
Terminated webhook event
This event is fired when a card is terminated.card.terminated
Freeze webhook event
This event is fired when a card is frozen.card.freezed
Unfreeze webhook event
This event is fired when a card is unfrozen.card.unfreezed
Updated webhook event
This event is fired when a card is funded.card.updated
Transaction webhook event
This event is fired when a card transaction is made.Transaction Categories
- FUNDING
- WITHDRAW
- Transaction
Transaction Types
- DEBIT
- CREDIT
Transaction Status
- APPROVED
- DECLINED
- COMPLETED
- FAILED
- REVERSE
card.transaction
Charges webhook event
Thecard.charges event is fired when a card-related fee is debited from the business USD wallet. It is not emitted when the fee is successfully taken directly from the card.
Use charge_type to identify the fee:
CARD_DECLINE_FEE: a declined-card fee that could not be collected from the card.CROSS_BORDER_FEE: a pending cross-border fee passed to the business wallet.
funding_source is BUSINESS_WALLET for this event.
card.charges
Contactless activation webhook event
Thecard.contactless.activation event contains the one-time code needed to add a contactless card to a supported wallet. This confidential event is delivered only after the business explicitly subscribes an eligible webhook.
card.contactless.activation
Verify the signature against the raw request body using the webhook signing key returned when the webhook was created. The signed message is:
NodeJS
2xx promptly. Swervpay attempts confidential delivery up to three times. Activation payloads are redacted from webhook logs and cannot be manually retried through the webhook retry endpoint.