# Webhook Integration

## Overview

The [PayLater ](https://paylaterapp.com/)system sends real-time webhook notifications to your backend when key events occur, such as transaction status updates. This ensures your platform stays in sync with the latest [PayLater ](https://paylaterapp.com/)events.

⚠️ **Important:** To activate webhooks, merchants must share their **Webhook Endpoint URL** with [PayLater](https://paylaterapp.com/) and request their unique **Webhook Secret** from their account manager.

## 📥 Webhook Request

Webhook events are delivered as an HTTP `POST` request with a JSON payload.

## Endpoint

You must expose a public POST endpoint to receive these requests.&#x20;

## Headers

* `Content-Type: application/json`

## Request Body

```
{
  "merchantId": "<merchant_id>",
  "orderId": "<order_id>",
  "paylaterRef": "PL1746499849330726",
  "status": "<status>",
  "timestamp": "<timestamp>",
  "signature": "<signature>",
  "txHash": "<tx_hash>",
  "comments": "<comments>"
}
```

### Parameter Descriptions

| Field      | Type   | Description                                                                                      |
| ---------- | ------ | ------------------------------------------------------------------------------------------------ |
| merchantId | String | Unique identifier for the merchant                                                               |
| orderId    | String | Unique identifier for the order                                                                  |
| status     | String | Status of the order (e.g., `success`, `failed`, `pending`)                                       |
| timestamp  | Long   | Epoch timestamp of the request                                                                   |
| signature  | String | HMAC SHA-256 signature generated using `txHash` and the webhook secret                           |
| txHash     | String | MD5 hash of the concatenated payload (merchantId + orderId + orderstatus + timestamp + comments) |
| comments   | String | Optional comments or metadata                                                                    |

## 🔐 Security & Validation

To validate the webhook and ensure it's sent by PayLater:

1. **Reconstruct the Data String:**
   * Concatenate `merchantId + orderId + status + timestamp + comments`
   * Convert the whole string to uppercase
   * Generate an MD5 hash of this string and compare it with the provided `txHash`
2. **Validate Signature:**
   * Use HMAC SHA-256 with your `merchantWebhookSecret`
   * Hash the `txHash` value
   * Compare the result with the `signature` field from the request

## ✅ Sample Node.js Verification

```
const crypto = require('crypto');

const verifyWebhook = (req) => {
  const { merchantId, orderId, status, timestamp, txHash, signature, comments } = req.body;
  const data = `${merchantId}${orderId}${status}${timestamp}${comments}`.toUpperCase();
  const computedTxHash = crypto.createHash('md5').update(data).digest('hex');
  if (computedTxHash !== txHash) return false;
  const computedSignature = crypto.createHmac('sha256', process.env.WEBHOOK_SECRET)
                                  .update(txHash)
                                  .digest('hex');
  return computedSignature === signature;
};
```

## ✅ Sample PHP Verification

```
$MERCHANT_SECRET = "your_webhook_secret";
$request = json_decode(file_get_contents("php://input"), true);
$dataString = strtoupper($request['merchantId'] . $request['orderId'] . $request['status'] . $request['timestamp'] . $request['comments']);
$computedTxHash = md5($dataString);
$computedSignature = hash_hmac("sha256", $computedTxHash, $MERCHANT_SECRET);
if ($computedSignature === $request['signature']) {
  http_response_code(200);
  echo json_encode(["message" => "Webhook received successfully"]);
} else {
  http_response_code(403);
  echo json_encode(["message" => "Invalid signature"]);
}
```

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://paylater.gitbook.io/paylater-docs/getting-started/quickstart/webhook-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
