For the complete documentation index, see llms.txt. This page is also available as Markdown.

Overview & Verification

Webhooks allow you to set up a notification system that can be used to receive updates on certain requests made to the Startbutton API.

With webhooks, Startbutton sends updates to your server when the status of your request changes. You will typically listen to these events on your webhook URL - a POST endpoint, the URL needs to parse a JSON request and return a 200 OK.

We send webhooks for the following transaction types:

  1. Collections

  2. Transfers

  3. Conversions

  4. Refunds

  5. Disputes

Webhook Verification

To ascertain that the request you received on your webhook is legit and not a bad actor, it's recommended that the webhook response is verified.

Events sent from Startbutton carry the following header:

Header
Value

x-startbutton-signature

HMAC SHA512 signature of the event payload signed using your secret key

Verify the header signature before processing the event.

Here is a sample code showing the webhook verification

var crypto = require('crypto'); 
var secret = process.env.MERCHANT_SECRET_KEY; 
// Using Express 
app.post("/my/webhook/url", function(req, res) { 
    //validate event 
    const hash = crypto.createHmac('sha512', secret).update(JSON.stringify(req.body)).digest('hex'); 
    if (hash == req.headers['x-startbutton-signature']) { 
    // Retrieve the request's body 
    const event = req.body; 
    // Do something with event  
    } 
    res.send(200); 
});
using System; 
using System.Text; 
using System.Security.Cryptography; 
using Microsoft.AspNetCore.Mvc; 
using Microsoft.AspNetCore.Http; 
using Newtonsoft.Json; 

public class WebhookController : ControllerBase 
{ 
    private readonly string secret = Environment.GetEnvironmentVariable("MERCHANT_SECRET_KEY"); 

    [HttpPost("/my/webhook/url")] 
    public IActionResult HandleWebhook([FromBody] WebhookData requestBody) 
    { 
        // Convert the request body to JSON 
        string jsonBody = JsonConvert.SerializeObject(requestBody); 

        // Validate the event 
        string hash = CalculateHash(jsonBody); 

        if (hash == Request.Headers["x-startbutton-signature"]) 
        { 
            // Request is valid, process the event 
            // You can access the JSON data in 'requestBody' 
            // Do something with the event 
        } 

        return Ok(); 
    } 

    private string CalculateHash(string data) 
    { 
        using (var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(secret))) 
        { 
            byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(data)); 
            return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); 
        } 
    } 
    
    
    public class WebhookData 
    { 
        public string @event { get; set; } 
        public WebhookDataObj data { get; set; } 
    } 


    public class WebhookDataObj 
    { 
        public WebhookTransaction transaction { get; set; } 
        public string authorizationCode { get; set; } 
    } 

    public class WebhookTransaction 
    { 
        public string _id { get; set; } 
        public string transType { get; set; } 
        public string status { get; set; } 
        public string merchantId { get; set; } 
        public string transactionReference { get; set; } 
        public string customerEmail { get; set; } 
        public string paymentPartnerId { get; set; } 
        public string paymentCode { get; set; } 
        public string userTransactionReference { get; set; } 
        public bool isRecurrent { get; set; } 
        public string postProcess { get; set; } 
        public string createdAt { get; set; } 
        public string updatedAt { get; set; } 
        public int feeAmount { get; set; } 
        public int amount { get; set; } 
        public string currency { get; set; } 

}
}

Final Notes

To wrap up your webhook implementation, here is the ideal flow your webhook endpoint should follow

  1. Verify request is from us using secret key and payload sent

  2. Send 200 status back immediately and handle complex logic on your end

  3. Ensure webhook responses are idempotent. Save the response and ensure value isn't give twice since you can get multiple calls for a transaction.

Last updated