Receiving legacy webhooks

After you have configured legacy webhooks for the event types that you want, you must be ready to receive the webhook. Optionally, for security purposes, you can verify the webhook signature before acting on the webhook.

In order to receive and use webhook responses for your site, do the following:

  1. Listen for Nexio's POST requests on the URL you provided in step 3 of the Configuring legacy webhooks tutorial.

    The body of the request includes the eventType and a data object, with information about the event.

  2. Save the JSON as a string called body.

    Example
    var body = '
    {
      "eventType": "TRANSACTION_AUTHORIZED",
      "data": {
        "id": "2eruYW1lIjoidXNhZXBheSIZYXABCiOiIxMDAwMzkiLCJyZWZOdW1iZXIiOiZYXABCcmFuZG9tIjowLCJjdXJyZW5jeSI6InVzZCJ9",
        "shouldUpdateCard": true,
        "merchantId": "100039",
        "transactionDate": "2019-12-23T20:50:23.060Z",
        "authCode": "458399",
        "transactionStatus": "pending",
        "amount": 1.15,
        "transactionType": "sale",
        "currency": "USD",
        "gatewayResponse": {...},
        "data": {
            "amount": 1.15,
            "currency": "USD",
            "settlementCurrency": "USD",
            "customFields": {...},
            "customer": {...},
            "cart": {...},
            "lodging": {...}
        },
        "card": {...},
        "kountResponse": {...},
        "token": {...}
      }
    }';
    

    If you configured the merchant secret (step 5 of the Configuring legacy webhooks tutorial), the request will include a header, which you will use to to verify the merchant signature. Continue to step 3.

    If you did not configure a merchant secret, skip to step 4.

  3. Verify the signature by doing the following:

    a. Copy the signature and timestamp from the header.

    Example Signature Header
    Nexio-signature: t=1554146049,v1=f66f6c47e7288e4922629ffe87819678b793944c60668d8695804e4a2b9f90d1
    

    b. Split the header string at the , character.

    c. Split each of the two strings at the = characters.

    d. Save the data following the t= as a variable called timestamp.

    Example
    var timestamp = 1554146049;
    

    e. Save the data following the s= as a variable called signature.

    Example
    var signature = 'f66f6c47e7288e4922629ffe87819678b793944c60668d8695804e4a2b9f90d1';
    

    f. Concatenate the timestamp and body (from step 2) with a . character in between and save it as a variable called payload.

    Example
    var payload = ${timestamp}.${body};
    

    g. Re-create the expected signature by creating an HMAC using the SHA256 hash function. Use the merchant secret as the key and the payload as the message.

    This is the expected signature.

    Note: If you did not save the secret when you configured the legacy webhook (step 5), you can retrieve it again by sending a GET request to the View merchant secret endpoint.

    h. Compare the expected signature from step 2h with the signature you received from the webhook.
    (The signature from step 2e.)

    The following example uses Node.js to verify the signature:

    Node.js Example
    import crypto from 'crypto';
    
    function verifyHMACSignature(payload, signature, sharedSecret) {
      //Create an HMAC using the SHA256 hash function
      const hmac = crypto.createHmac('sha256', sharedSecret);
      hmac.update(payload);
    
      const mySig = hmac.digest().toString('hex');
    
      //Compare the expected signature with the signature you received
      return mySig.length === signature.length
        && crypto.timingSafeEqual(Buffer.from(mySig, 'hex'), Buffer.from(signature, 'hex'));
    }
    
    function verifyNexioSignature(body, signatureHeader, sharedSecret) {
      //Split the Nexio-Signature on the comma to get the timestamp field and the signature field
      const [timeStampField, signatureField] = signatureHeader.split(',');
    
      //Split each of the two strings on the equals signs and save them as variables
      const timestamp = timeStampField.split('=')[1];
      const signature = signatureField.split('=')[1];
    
      //Recreate the payload that was signed by Nexio
      const payload = `${timestamp}.${body}`;
    
      return verifyHMACSignature(payload, signature, sharedSecret);
    }
    

    i. If the signatures match, then the webhook is valid and you can continue to step 3.


  4. From the string you saved as body (step 2), use the eventType and a data object to determine what action, if any, to take as a result of this webhook. For more details about possible body content, see the Legacy webhook body examples page.


Did this page help you?