Receiving payment notifications with webhooks
Listen for payment notifications across the payment's lifecycle to automatically trigger reactions.
Webhooks are used to listen to payment notifications across a payment's lifecycle.
How receiving payment notifications with webhooks works
1. Supported scenarios
Scenario  | Notes  | 
|---|---|
Pay with Setel code scan (Not supported)  | Webhook is not supported.  | 
Pay with Setel online  | Webhook can be set upon creation of the checkout session.  | 
Considerations for webhooks
Due to network issues, there might be cases where the webhook requests might not be received by integrators. A retry query using the retrieve a checkout session API is recommended for this situation.
Multiple webhook requests for a single order might be sent. Please ensure there is an implementation to verify which request is the latest.
2. Subscribing to a webhook
You will need to define the webhook URL when creating a checkout session. This URL will be used to receive updates on the payment sessions.
2.1 Webhook request payload
"headers": {
    "Content-Type": "application/json",
    "signature": "random string"
    }{
    'id': 'test-id',
     'createdAt': '2021-06-09T10:09:37.927Z',
     'updatedAt': '2021-06-09T10:09:37.927Z',
     'apiKey': 'test-x-api-key',
     'paymentIntentId': 'test-payment-intent-id',
     'paymentIntentStatus': 'succeeded',
     'amount': '10',
      'referenceId': 'test-reference-id',
}3. Signature
A signature is used to verify the identity of the request/data sent. This is needed to prevent information from being stolen or received from the wrong entity.
3.1 How to generate a signature
- Step 1: Get the 
secretHashfromx-api-secret. - Step 2: Calculate 
databy concatenating fields in above order. - Step 3: Get 
signatureby hmac('sha256',secretHash)(data). 
3.2 Sample code in NodeJS
const { createHmac, createHash } = require('crypto');
const secret = 'test-x-api-secret';
const secretHash = createHash('sha256').update(secret).digest('hex');
console.log(secretHash);
// secretHash: 874d70d91c89cfa556797c1754ea186e060a189a0cc398b000f94630c1b1674e
const body = {
    'id': 'test-id',
    'createdAt': '2021-06-09T10:09:37.927Z',
    'updatedAt': '2021-06-09T10:09:37.927Z',
    'apiKey': 'test-x-api-key',
    'paymentIntentId': 'test-payment-intent-id',
    'paymentIntentStatus': 'succeeded',
    'amount': '10',
    'referenceId': 'test-reference-id',
};
const fields = [
    'id',
    'createdAt',
    'updatedAt',
    'apiKey',
    'paymentIntentId',
    'paymentIntentStatus',
    'amount',
    'referenceId',
];
let data = '';
fields.forEach(field => data += body[field] || '');
console.log(data);
// data: test-id2021-06-09T10:09:37.927Z2021-06-09T10:09:37.927Ztest-x-api-keytest-payment-intent-idsucceeded10test-reference-id
const hmac = createHmac('sha256', secretHash).update(data).digest('hex');
console.log(hmac);
// hmac: 77b928780f10a0d2339d93be7319eda4dda4472d5a9fdf7bcc53768a2a61faf03.3 Sample input and output
3.3.1 Input
Name  | Value  | 
|---|---|
x-api-secret  | test-x-api-secret  | 
body  | {  | 
3.3.2 Output
77b928780f10a0d2339d93be7319eda4dda4472d5a9fdf7bcc53768a2a61faf0Updated 5 months ago
