Webhooks
SkyPay uses webhooks to notify your application about events that happen asynchronously, such as successful payments, failed payments, successful transfers, etc.
POST /api/transactions/webhooks/:processor
Security
It is critical to verify the signature of incoming webhooks before processing them. Each payment processor used by SkyPay (e.g., Paystack, Flutterwave) has its own method for signing webhook requests. You must implement signature verification using the appropriate secret key provided in your SkyPay dashboard.
- Paystack: Check the
X-Paystack-Signatureheader. - Flutterwave: Check the
verify-hashheader.
Failure to verify signatures allows malicious actors to send fake events to your endpoint.
Request Body
The structure of the webhook payload depends entirely on the originating payment processor and the event type.
SkyPay's webhook handler expects a JSON body containing at least:
- An
eventfield (or similar, e.g.,eventType) indicating the type of event. - A
datafield containing the event payload.
Example (Simulated Paystack charge.success)
{
"event": "charge.success",
"data": {
"id": 123456789,
"domain": "test",
"status": "success",
"reference": "SKP-1678886400000-a1b2c3d4", // **** This should be SkyPay's reference ****
"amount": 500000, // Amount in kobo
"message": null,
"gateway_response": "Successful",
"paid_at": "2023-10-27T12:00:00.000Z",
"created_at": "2023-10-27T11:59:00.000Z",
"channel": "card",
"currency": "NGN",
"ip_address": "192.168.1.1",
"metadata": {
"custom_field": "custom_value",
"cart_id": "xyz789"
},
"log": { /* ... */ },
"fees": 5000, // Fee in kobo
"fees_split": null,
"authorization": {
"authorization_code": "AUTH_xxyyzz",
"bin": "408408",
"last4": "4081",
"exp_month": "12",
"exp_year": "2024",
"channel": "card",
"card_type": "visa",
"bank": "Test Bank",
"country_code": "NG",
"brand": "visa",
"reusable": true,
"signature": "SIG_aabbcc",
"account_name": null
},
"customer": {
"id": 98765,
"first_name": "John",
"last_name": "Doe",
"email": "customer@example.com",
"customer_code": "CUS_abc123",
"phone": null,
"metadata": null,
"risk_action": "allow"
},
"plan": null,
"subaccount": null,
"order_id": null,
"paidAt": "2023-10-27T12:00:00.000Z", // Note: Paystack uses both paid_at and paidAt
"requested_amount": 500000
// ... other fields specific to the processor and event
}
}
Response
Your endpoint should respond quickly with a 200 OK status code to acknowledge receipt of the webhook. Any complex processing should be handled asynchronously after sending the response.
Status: 200 OK
Body: Webhook received successfully
If signature verification fails or there's an immediate processing error preventing acknowledgment, respond with an appropriate error status (e.g., 401 Unauthorized for bad signature, 500 Internal Server Error for processing issues).