Skip to main content

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-Signature header.
  • Flutterwave: Check the verify-hash header.

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 event field (or similar, e.g., eventType) indicating the type of event.
  • A data field 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).