Skip to content

Implementing Webhooks

Introduction

Webhooks are a powerful tool that allows your application to receive real-time notifications from the Senfenico API about specific events that occur, such as payment updates or transaction statuses. This ensures that your system can respond immediately to changes without the need to continually poll the API for updates.

Why Implement Webhooks?

  1. Real-time Notifications: Get instant updates on events such as successful payments, failed transactions, and pending checkouts.
  2. Reduced Latency: Improve the efficiency of your application by eliminating the need to frequently query the API.
  3. Automation: Automate processes based on events, such as sending confirmation emails, updating order statuses, or triggering additional workflows.
  4. Resource Efficiency: Save server resources and bandwidth by reducing the number of API calls.

Setting Up Webhooks

Subscribing to Events

To start receiving notifications, you need to subscribe to events via the Senfenico dashboard:

  1. Log in to your Senfenico account.
  2. Navigate to the Webhooks Subscription Page
  3. Add your webhook endpoint URL and select the events you want to subscribe to.
  4. Copy your webhook secret key from the same dashboard. This key will be used to verify the authenticity of incoming webhook requests.

Importance of Responding with a 200 OK Status

When your application receives a webhook notification from Senfenico, it is crucial to respond with a 200 OK HTTP status code. This indicates to Senfenico that the notification was successfully received and processed. If a 200 OK response is not returned, Senfenico will continue to resend the notification for up to one hour to ensure delivery.

Webhook Payload Structure

All events sent by the Senfenico API have the following structure:

{
    "event": "string representing the event",
    "data": {
        "object representing the event details"
    }
}
{
    "event": "checkout.pending",
    "data": {
        "email": "customer@mail.com",
        "reference": "58e15198-dbee-41b2-8ef6-9b08a84b977c",
        "charge_reference": null,
        "amount": 1000,
        "success_url": "https://yourwebsite.com/",
        "cancel_url": "https://yourwebsite.com/",
        "phone": "",
        "provider": "",
        "live_mode": false,
        "created_at": null,
        "updated_at": null,
        "status": "pending"
    }
}

Implementing Webhooks

Webhook Key

To ensure that the webhook notifications you receive are from Senfenico and have not been tampered with, each notification request includes an X-Webhook-Hash header. This header contains a hash signature that you can use to verify the authenticity of the notification. You will use the webhook secret key to generate this hash and compare it with the received signature.

SDKs for Easier Implementation

Senfenico provides SDKs in PHP and Python to facilitate the integration of webhooks into your application. These SDKs handle much of the boilerplate code required for webhook validation and processing, allowing you to focus on the core logic specific to your business needs.

<?php
require_once 'senfenico-php/init.php';
$payload = file_get_contents('php://input');
$webhook_hash = $_SERVER['HTTP_X_WEBHOOK_HASH'];
$webhook_key = 'your_secret_webhook_key...';

try{
    $webhook = \Senfenico\Webhook::constructEvent($payload, $webhook_hash, $webhook_key);
} catch(\Exception $e) {
    // Invalid payload
    http_response_code(400);
    exit;
}

// Handle the event
switch ($webhook->event) {
    case 'checkout.pending':
        //handle checkout pending event
        break;
    case 'checkout.success':
        //chandle checkout success event
        break;
    // ... handle other event types
    default:
        echo 'Received unknown event type ' . $webhook->event;
}

http_response_code(200);
exit;
$payload = $request->getContent();
$webhook_hash = $request->header('X-Webhook-Hash');
$webhook_key = '9e191505-9637-4c2b-a55e-da813b882732';

try{
    $webhook = \Senfenico\Webhook::constructEvent($payload, $webhook_hash, $webhook_key);
} catch(\Exception $e) {
    Log::debug('Message: ' .$e->getMessage());
    return response()->json(['message' => 'une erreur sest produite'], 400);
}

// Handle the event
switch ($webhook->event) {
    case 'checkout.pending':
        //handle checkout pending event
        break;
    case 'checkout.success':
        //chandle checkout success event
        break;
    // ... handle other event types
    default:
        Log::debug('Received unknown event type ' . $webhook->event);
}

return response()->json(['message' => 'Webhook received'], 200);
webhook_key = 'your_secret_webhook_key...'  # replace with your secret key

@app.route('/webhook', methods=['POST'])
def handle_webhook():    
    # Extract the hash from headers
    received_hash = request.headers.get('X-Webhook-Hash')

    # Get the payload from the body
    payload = request.json
    try:
        webhook = senfenico.Webhook.construct_event(payload, received_hash, webhook_key)
    except ValueError as e:
        print('Invalid payload')
        return jsonify({'error': str(e)}), 400

    if webhook.event == 'checkout.pending':
        print('checkout pending')
    elif webhook.event == 'checkout.success':
        print('checkout completed')
    # ... handle other events
    else:
        print('Unhandled event type {}'.format(webhook.event))

    return jsonify({'message': 'Webhook received successfully'}), 200
webhook_key = 'your_webhook_secret_key...'  # replace with your secret key

@csrf_exempt
def handle_webhook(request):
    # Extract the hash from headers
    received_hash = request.headers.get('X-Webhook-Hash')

    # Get the payload from the body
    payload = request.body
    try:
        webhook = senfenico.Webhook.construct_event(payload, received_hash, webhook_key)
    except ValueError as e:
        print('Invalid payload')
        return HttpResponse(status=400)

    if webhook.event == 'checkout.pending':
        print('checkout pending')
    elif webhook.event == 'checkout.success':
        print('checkout completed')
    # ... handle other events
    else:
        print('Unhandled event type {}'.format(webhook.event))

    return HttpResponse(status=200)

Implementing Webhooks Without SDKs

For developers who prefer not to use the provided SDKs or are working in a language or framework not supported by Senfenico SDKs, here is a guide to implement webhooks from scratch.

General Steps

  1. Create a Webhook Endpoint: Set up an endpoint in your application to receive HTTP POST requests from Senfenico.
  2. Verify the Request: Use the X-Webhook-Hash header and your secret key to verify the authenticity of the request.
  3. Parse the Event: Extract and parse the JSON payload to identify the event and associated data.
  4. Handle the Event: Implement logic to process different types of events based on your application's requirements.
  5. Respond to the Webhook: Return an appropriate HTTP response to acknowledge the receipt of the webhook.

Conclusion

This documentation provides a comprehensive guide to implementing webhooks with the Senfenico API. By subscribing to the necessary events and setting up your webhook endpoint correctly, you can automate and streamline your payment processing workflows. Whether you use our SDKs for ease of integration or implement from scratch, following these instructions ensures that your application can efficiently handle real-time events. Remember to always return a 200 OK response upon receiving a webhook to confirm successful processing and prevent redundant notifications.