📃Webhook Integration
Overview
The PayLater 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 events.
⚠️ Important: To activate webhooks, merchants must share their Webhook Endpoint URL with PayLater 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.
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:
- 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
 
- Validate Signature: - Use HMAC SHA-256 with your - merchantWebhookSecret
- Hash the - txHashvalue
- Compare the result with the - signaturefield 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"]);
}Last updated
