GuidesGet StartedStash WebhooksWebhook Listener

Webhook Listener

Begin by creating a webhook listener on your backend. A webhook listener is a server-side program that receives incoming Stash webhook requests at a designated URL, verifies their authenticity (checking the signature), and responds appropriately (if needed) to the Stash.

Example webhook

Purchase Succeeded Webhook Payload
{
  "type": "PURCHASE_SUCCEEDED",
  "purchaseSucceeded": {
    "timeMillis": 1753993257000,
    "orderId": "8ZVBabLrnCMm9zPdu9QpfCWzNaA",
    "currency": "usd",
    "userId": "user_id",
    "items": [
      {
        "id": "item_id",
        "quantity": 1,
        "price": "199"
      }
    ],
    "tax": "0",
    "total": "199",
    "regionCode": "US",
    "source": "StashPay"
  }
}

Each webhook payload includes a type field that indicates the event type enum (ex: PURCHASE_SUCCEEDED). The payload also contains a corresponding object with event-specific details. For a complete overview of all available webhook event types and their payload structures, refer to the webhook event list.

Signature verification

To ensure secure data transmission, you must verify that each webhook was actually sent from Stash and has not been tampered with in transit. Stash uses an HMAC SHA-256 signature to sign every webhook request. You should generate your own signature using your project’s secret key and compare it to the signature provided in the Stash-Hmac-Signature header of the incoming request. If the signatures match, you can trust the webhook is authentic.

Verification steps:

  1. Retrieve the signature:
    Extract the signature from the Stash-Hmac-Signature header of the incoming Stash webhook request. The header format is:

    Stash-Hmac-Signature myp5FsYU7FpC1R6Dk4MUMOdB+boKgeIrffqFBaim0Wo=
  2. Obtain the request body:
    Read the raw JSON payload of the webhook request exactly as received (do not parse and re-serialize, as this may change whitespace or formatting).

  3. Generate your own signature:

    • Concatenate the raw request body (as a string) with your Stash webhook secret key (do not add any separators).
    • Compute the HMAC SHA-256 hash of this concatenated string, using your secret key as the HMAC key.
    • Encode the resulting hash as a lowercase hexadecimal string.

    Example in pseudocode:

    signature = HMAC_SHA256(secret_key, raw_request_body + secret_key)
  4. Compare signatures:
    Compare your generated signature to the value from the Stash-Hmac-Signature header. If they match, the webhook is valid and can be processed safely.

Note:

  • Always use the exact raw request body as received for signature calculation.
  • Never expose your webhook secret key in client-side code or logs.
  • If the signatures do not match, reject the request and do not process the webhook.

For additional security, you may also want to validate the request’s timestamp or IP address, depending on your backend’s requirements.

Reference implementation

Webhook debugging

Was this page helpful?