Documentation Index
Fetch the complete documentation index at: https://docs.config.money/llms.txt
Use this file to discover all available pages before exploring further.
Webhooks
Config.money sends webhook events to notify you of important payment lifecycle events. Configure your webhook endpoint in your merchant dashboard to receive these events.
Endpoint
POST https://your-domain.com/webhook
Each webhook request includes the following headers:
Content-Type: application/json
X-Config-Signature: t=1679580000,v1=5257a869e7eaea848cde13e1358682c04f21cf0c
The X-Config-Signature header contains a timestamp and signature that you can use to verify the webhook’s authenticity.
Event Types
Schedule Events
schedule.setup_success
Sent when a customer successfully sets up a collection schedule.
{
"event": "schedule.setup_success",
"data": {
"schedule_id": "sched_123456789",
"customer_id": "cust_123456789",
"amount": {
"value": 2000,
"currency": "GBP"
},
"frequency": {
"type": "monthly",
"day": 1
},
"created_at": "2024-03-20T10:00:00Z"
}
}
schedule.setup_failed
Sent when a customer fails to set up a collection schedule.
{
"event": "schedule.setup_failed",
"data": {
"schedule_id": "sched_123456789",
"customer_id": "cust_123456789",
"error": {
"code": "consent_denied",
"message": "Customer denied consent for the schedule"
},
"created_at": "2024-03-20T10:00:00Z"
}
}
Collection Events
collection.success
Sent when a collection is successfully made from the customer’s account to your merchant wallet.
{
"event": "collection.success",
"data": {
"payment_id": "pay_123456789",
"schedule_id": "sched_123456789",
"amount": {
"value": 2000,
"currency": "GBP"
},
"completed_at": "2024-03-20T10:00:00Z"
}
}
collection.failed
Sent when a collection fails.
{
"event": "collection.failed",
"data": {
"payment_id": "pay_123456789",
"schedule_id": "sched_123456789",
"amount": {
"value": 2000,
"currency": "GBP"
},
"error": {
"code": "insufficient_funds",
"message": "Insufficient funds in customer account"
},
"failed_at": "2024-03-20T10:00:00Z"
}
}
Settlement Events
settlement.success
Sent when funds are successfully settled from your merchant wallet to your destination account.
{
"event": "settlement.success",
"data": {
"settlement_id": "set_123456789",
"amount": {
"value": 2000,
"currency": "GBP"
},
"destination_account": {
"account_number": "12345678",
"sort_code": "123456"
},
"completed_at": "2024-03-21T10:00:00Z"
}
}
settlement.failed
Sent when a settlement fails.
{
"event": "settlement.failed",
"data": {
"settlement_id": "set_123456789",
"amount": {
"value": 2000,
"currency": "GBP"
},
"destination_account": {
"account_number": "12345678",
"sort_code": "123456"
},
"error": {
"code": "invalid_account",
"message": "Invalid destination account details"
},
"failed_at": "2024-03-21T10:00:00Z"
}
}
Response
Your webhook endpoint should return a 200 OK response to acknowledge receipt of the webhook. If we don’t receive a 200 OK response, we’ll retry the webhook delivery.
Retry Policy
If your webhook endpoint is unavailable or returns an error, we’ll retry the delivery with the following schedule:
- 1 minute after the first failure
- 5 minutes after the second failure
- 15 minutes after the third failure
- 30 minutes after the fourth failure
- 1 hour after the fifth failure
After 5 failed attempts, we’ll stop retrying and you’ll need to check the events in your dashboard.
Security
To verify the authenticity of webhooks, you should:
- Check the timestamp in the signature header to ensure the webhook is recent
- Verify the signature using your webhook secret
Example verification code:
import hmac
import hashlib
import time
def verify_webhook_signature(payload, signature_header, webhook_secret):
# Extract timestamp and signature
timestamp, signature = signature_header.split(',')
timestamp = int(timestamp.split('=')[1])
signature = signature.split('=')[1]
# Check if the webhook is recent (within 5 minutes)
if time.time() - timestamp > 300:
return False
# Calculate expected signature
expected_signature = hmac.new(
webhook_secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature)