Webhooks
Webhooks allow your application to receive real-time updates about transaction events without needing to poll the API.
Setting Up Webhooks
To set up webhooks for your payment providers:
- Go to Settings in the Kipay admin dashboard
- Navigate to the API Keys tab and scroll down to the Webhook Settings section
- Copy the webhook URL for your payment provider (e.g., Paystack, Flutterwave, or Stripe)
- Log in to your payment provider's dashboard and add this URL as a webhook endpoint
- Configure the events you want to receive (usually all payment events)
Webhook URLs
Kipay provides different webhook URLs for each supported payment provider:
- Paystack:
https://kipay.benfex.net/webhook/paystack
- Flutterwave:
https://kipay.benfex.net/webhook/flutterwave
- Stripe:
https://kipay.benfex.net/webhook/stripe
Handling Webhooks in Your Application
Kipay automatically processes webhook events from payment providers and updates transaction statuses accordingly. However, you might want to perform additional actions when events occur.
You can set up your own webhook endpoint to receive forwarded events from Kipay:
- Create a webhook endpoint URL in your application
- Go to Settings > Notifications in the Kipay admin dashboard
- Enter your webhook URL and select the events you want to receive
- Save your settings
Webhook Events
Kipay processes the following webhook events:
Event | Description |
---|---|
charge.success |
When a payment is successful |
charge.failed |
When a payment fails |
transfer.success |
When a transfer is successful |
transfer.failed |
When a transfer fails |
subscription.create |
When a subscription is created |
subscription.disable |
When a subscription is disabled |
invoice.create |
When an invoice is created |
invoice.payment_failed |
When an invoice payment fails |
Webhook Payload Format
The payload format varies depending on the payment provider, but typically includes the following information:
Paystack Webhook Example
{
"event": "charge.success",
"data": {
"id": 123456789,
"reference": "KIPAY12345678",
"amount": 10000,
"status": "success",
"channel": "card",
"currency": "KSH",
"paid_at": "2025-04-10T12:34:56.000Z",
"customer": {
"email": "[email protected]",
"name": "John Doe"
}
}
}
Flutterwave Webhook Example
{
"event": "charge.completed",
"data": {
"id": 123456789,
"tx_ref": "KIPAY12345678",
"amount": 10000,
"status": "successful",
"payment_type": "card",
"currency": "KSH",
"customer": {
"email": "[email protected]",
"name": "John Doe"
}
}
}
Stripe Webhook Example
{
"id": "evt_123456789",
"type": "charge.succeeded",
"data": {
"object": {
"id": "ch_123456789",
"amount": 10000,
"currency": "ksh",
"status": "succeeded",
"payment_method_details": {
"type": "card"
},
"metadata": {
"reference": "KIPAY12345678"
}
}
}
}
Verifying Webhook Signatures
To ensure that webhook events are coming from the actual payment provider, Kipay verifies webhook signatures. Each provider has its own signature verification method:
Paystack
Paystack signs webhook payloads with the X-Paystack-Signature
header.
Flutterwave
Flutterwave includes a verificationHash
in the webhook payload.
Stripe
Stripe signs webhook payloads with the Stripe-Signature
header.
Testing Webhooks
You can test webhooks locally using tools like ngrok:
- Download and install ngrok
- Start your local development server (e.g.,
php -S localhost:8000
) - Start ngrok:
ngrok http 8000
- Copy the ngrok URL (e.g.,
https://1234abcd.ngrok.io
) - Update your webhook URL in the payment provider's dashboard to point to your ngrok URL (e.g.,
https://1234abcd.ngrok.io/webhook/paystack
) - Make a test payment to trigger the webhook
Troubleshooting Webhooks
If you're having issues with webhooks, check the following:
- Verify that the webhook URL is correctly configured in the payment provider's dashboard
- Check the Kipay logs for webhook events in the admin dashboard
- Ensure your server is accessible from the internet
- Check for any firewall or security settings that might be blocking webhook requests
- Verify that your webhook endpoint is returning a 200 OK response, even if it encounters an error