Skip to main content

Overview

Webhooks notify your server when payment events occur. Set the webhookUrl when creating a payment, and Ebioro will POST to that URL whenever the payment status changes.

Webhook Payload

{
  "data": {
    "type": "transaction_updated",
    "id": "pt_ABC123",
    "status": "paid",
    "settlement_status": "paid",
    "amount": {
      "value": 1000,
      "currency": "USD"
    },
    "settlement_amount": 1000,
    "settlement_currency": "USDC",
    "settlement_fee": 25,
    "amount_paid": 1000,
    "amount_received": 1000,
    "amount_remaining": 0,
    "history": [
      {
        "time": 1714124827333,
        "status": "success",
        "description": "Payment created"
      },
      {
        "time": 1714124900000,
        "status": "success",
        "description": "Customer paid"
      }
    ],
    "metadata": {}
  }
}

Event Types

TypeWhen
transaction_createdPayment order created
transaction_updatedPayment status changed (paid, underpaid, settled)
transaction_failedPayment processing failed

Verifying Webhooks

Every webhook includes an X-WEBHOOK-AUTH header containing an HMAC-SHA256 signature. Always verify this signature before processing the webhook.
const crypto = require('crypto');

function verifyWebhook(body, signature, secretKey) {
  const expected = crypto
    .createHmac('sha256', secretKey)
    .update(JSON.stringify(body))
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// In your webhook handler:
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-auth'];

  if (!verifyWebhook(req.body, signature, YOUR_API_SECRET_KEY)) {
    return res.status(401).send('Invalid signature');
  }

  const { type, status, id } = req.body.data;
  // Process the webhook...

  res.status(200).send('OK');
});

Requirements

  • Webhook URL must use HTTPS in production
  • Your endpoint must respond with a 200 status code
  • Respond within 10 seconds or the request will time out

Retry Policy

If your endpoint returns a non-200 status code or times out, the webhook is not retried. Make sure your endpoint is reliable.
Always verify the X-WEBHOOK-AUTH signature. Without verification, an attacker could send fake webhook events to your endpoint.