Receive Notifications

callback notificationpayment notification

This guide provides an introduction to receiving Spell callback notifications, including how to correctly process notifications.

All callback notifications sent by Spell are delivered to your specified callback address via a POST request. The request content includes:

  • Request Headers
    • Content-Type: application/json.
    • SPELL-Callback-Signature: The request signature for you to verify the authenticity of the request.
  • Request Body
    • callback: Callback notification ID.
    • event: Event ID.
    • order: Order ID.
    • timestamp: Request timestamp.
    • user: User ID.

Verify Signature Validity

To ensure the authenticity of the request and prevent tampering or forgery, Spell signs the information so you can verify it. You need to sign the request body using the corresponding callback secret key for the registered event (recorded during registration, not account API secret) and compare it with the SPELL-Callback-Signature in the request headers. Below are the complete verification steps:

1. Serialize the Data

First, you need to serialize all the fields in the request body into a specific string. This process includes:

  1. Sort by Key: Sort all the fields in the request body alphabetically by their keys.
  2. Format: Convert each field into a string in the format key=value.
  3. Concatenate: Join all the formatted strings using &.

You can use the serializeData() function below to complete this step:

/**
* Serializes a data object to generate a signature string.
* @param data - The data object to be serialized.
* @returns The serialized string in the format key1=value1&key2=value2...
*/
function serializeData(data: Record<string, any>): string {
    return Object.keys(data)
        .sort()
        .map(key => {
            const value = data[key];
            const strValue = typeof value === 'object'
                ? JSON.stringify(value)
                : String(value);
            return `${key}=${strValue}`;
        })
        .join('&');
}

2. Calculate the Signature

Use the crypto module to create an HMAC object and calculate the signature of the serialized data using the SHA-256 algorithm and your secret key.

Below is example code for Node.js:

import * as crypto from 'crypto';

/**
 * Calculates the signature.
 * @param serializedData - The serialized string.
 * @param secretKey - Your callback notification secret key.
 * @returns The signature string in hexadecimal.
 */
function calculateSignature(serializedData: string, secretKey: string): string {
    const hmac = crypto.createHmac('sha256', secretKey);
    hmac.update(serializedData);
    return hmac.digest('hex');
}

3. Compare the Signatures

Finally, compare the signature you calculated with the value of the SPELL-Callback-Signature field in the callback request headers. If they are identical, the request is authentic and valid.

Below is the complete example code:

// Get the signature from the request headers
const cbSignature = request.headers['SPELL-Callback-Signature']; 

// Assume this is the received request body
const requestBody = {
    callback: 'callback_id',
    event: 'event_id',
    order: 'order_id',
    timestamp: 1700000000000,
    user: 'user_id',
};

// Serialize the request body
const serializedData = serializeData(requestBody); 

// Calculate the signature
// CALLBACK_SECRET_KEY is generated during callback registration
const mySignature = calculateSignature(serializedData, CALLBACK_SECRET_KEY); 

// Compare the signatures
if (mySignature === cbSignature) {
    console.log("Signature verification successful! ");
    // Process your business logic
} else {
    console.log("Signature verification failed! You should recreate a callback receiving address.");
    // Ignore the request
}

Handle the Response

To ensure the callback notification is successfully received, Spell will retry at intervals for callbacks that do not receive a success response within a certain time frame. To avoid receiving duplicate notifications from Spell, your server must return an HTTP success response after receiving the notification and confirming the signature is valid.

  • Status Code: 200
  • Response Header: Content-Type: text/plain
  • Response Body: success

    The response body must be the lowercase text success and must not contain any other characters.

©2025 Spell.im All Rights Reserved