Webhooks
Receive real-time notifications when events happen at your store.
Available events
| Event | Description |
|---|---|
card.activated | A consumer activated a new card at your store |
card.reloaded | A consumer topped up an existing card |
card.transferred_in | Balance was transferred into your store from another store |
card.transferred_out | Balance was transferred out of your store to another store |
card.balance_changed | Any balance change on a card at your store |
card.disabled | A card at your store was permanently disabled |
Webhook payload
{
"event": "card.activated",
"timestamp": "2026-04-05T10:30:00Z",
"data": {
"cardUuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amountCents": 5000,
"currency": "USD",
"newBalanceCents": 5000,
"consumerEmail": "customer@example.com"
}
}Verifying webhooks
Each webhook includes an X-ReloadCard-Signature header containing an HMAC-SHA256 signature of the payload using your webhook secret.
const crypto = require('crypto')
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}Registering webhooks
Configure your webhook URL in the merchant dashboard under Settings → Reload Network, or programmatically via the API.
Create a webhook
POST /api/v1/webhooks
curl -X POST https://merchant.reloadcard.app/api/v1/webhooks \
-H "Authorization: Bearer rc_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yoursite.com/webhooks/reloadcard",
"events": ["card.activated", "card.reloaded", "card.disabled"]
}'Response 201
{
"id": "wh_abc123",
"url": "https://yoursite.com/webhooks/reloadcard",
"events": ["card.activated", "card.reloaded", "card.disabled"],
"secret": "whsec_a1b2c3d4e5f6...",
"created_at": "2026-04-08T10:00:00Z"
}Important: The secret is returned only once at creation. Store it securely — you'll need it to verify webhook signatures.
List webhooks
GET /api/v1/webhooks
curl https://merchant.reloadcard.app/api/v1/webhooks \ -H "Authorization: Bearer rc_live_your_key"
Update a webhook
PATCH /api/v1/webhooks/:id
Update the URL, events, or active status. Only include the fields you want to change.
curl -X PATCH https://merchant.reloadcard.app/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer rc_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"events": ["card.activated", "card.reloaded", "card.transferred_in", "card.disabled"],
"is_active": true
}'Delete a webhook
DELETE /api/v1/webhooks/:id
curl -X DELETE https://merchant.reloadcard.app/api/v1/webhooks/wh_abc123 \ -H "Authorization: Bearer rc_live_your_key"
Delivery details
Webhooks are delivered as POST requests to your registered URL with a JSON body. Each delivery includes:
- HMAC-SHA256 signing — Every request includes an
X-ReloadCard-Signatureheader. Verify it using your webhook secret to ensure the payload is authentic. - 10-second timeout — Your endpoint must respond within 10 seconds with a
2xxstatus code, or the delivery is marked as failed. - Retry policy — Failed deliveries are retried up to 3 times with exponential backoff (1 min, 5 min, 30 min). After 3 consecutive failures, the webhook is automatically disabled and you are notified via email.
Retry policy
| Attempt | Delay |
|---|---|
| 1st retry | ~1 minute |
| 2nd retry | ~5 minutes |
| 3rd retry | ~30 minutes |
| After 3 failures | Webhook disabled, email notification sent |
Re-enable a disabled webhook via the API (PATCH with {"is_active": true}) or from the merchant dashboard.