Skip to main content

What are UniBee webhooks?

UniBee sends outbound webhook events to merchant-configured HTTPS endpoints when billing state changes, for example:
  • payment.success
  • invoice.created
  • subscription.auto_renew.success
  • subscription.activated
These are not payment-gateway callbacks into UniBee. Stripe, PayPal, and similar inbound gateway webhooks are configured separately in payment gateway setup. Use webhooks when your backend must react to billing events as soon as UniBee generates them. You can also inspect deliveries and resend failed attempts in the Admin Portal under Configuration → Webhooks.

Configure an endpoint

Admin Portal

  1. Open Configuration → Webhooks.
  2. Click + to add an endpoint.
  3. Enter the webhook URL.
  4. Select the events you want.
  5. Confirm.
Webhook URL requirements
  • Publicly reachable from the internet
  • HTTPS only
  • Accepts HTTP POST with JSON body
For local testing, use a staging server or an HTTPS tunnel such as ngrok or localtunnel. Keep the URL stable while testing.

Merchant API

You can manage endpoints programmatically:
CapabilityAPI reference
List subscribable eventsWebhook event list
Create / update / delete endpointsNew, Update, Delete
List endpointsGet webhook endpoint list
Get webhook secretGet webhook secret
View delivery logsGet webhook endpoint log list
Resend a deliveryResent webhook
Subscribe only to events returned by the event list. The full catalog and trigger notes are in Webhook events. In non-production environments, each merchant can configure up to 16 sandbox endpoints.

Delivery format

HTTP request

  • Method: POST
  • Content-Type: application/json
  • Body: business payload with these top-level fields injected before send:
    • eventType
    • eventId
    • msgId
    • datetime (2006-01-02T15:04:05+08:00)

Request headers

HeaderDescription
Content-Typeapplication/json
AuthorizationBearer {merchant.ApiKey}
EventTypeEvent name
EventIdSame as body eventId
Msg-idSame as body msgId
DatetimeSame as body datetime
X-Signature-Algorithmhmac
X-SignatureHMAC-SHA256 of the raw JSON body string, Base64-encoded, using the merchant API key as the secret
Use eventId or msgId for idempotency. Retries for the same business action may use new IDs.

Verify webhook requests

UniBee signs each delivery with HMAC-SHA256 over the full JSON body string. Verify X-Signature with your merchant API key before processing the payload. GET /get_webhook_secret can return or generate a webhook secret for endpoint management workflows. Current outbound webhook signatures use the merchant API key as the HMAC secret. You can also check that Authorization matches Bearer {API_KEY} as an additional guard.
const crypto = require('crypto');

app.post('/webhooks/unibee', express.raw({ type: 'application/json' }), async (req, res) => {
  const signature = req.headers['x-signature'];
  const algorithm = req.headers['x-signature-algorithm'];
  const eventType = req.headers['eventtype'];
  const rawBody = req.body.toString();

  if (!signature || algorithm !== 'hmac') {
    return res.status(401).send('Missing signature');
  }

  const expectedSignature = crypto
    .createHmac('sha256', process.env.UNIBEE_API_KEY)
    .update(rawBody)
    .digest('base64');

  const signatureBuffer = Buffer.from(signature);
  const expectedSignatureBuffer = Buffer.from(expectedSignature);

  if (
    signatureBuffer.length !== expectedSignatureBuffer.length ||
    !crypto.timingSafeEqual(signatureBuffer, expectedSignatureBuffer)
  ) {
    return res.status(401).send('Invalid signature');
  }

  const payload = JSON.parse(rawBody);

  switch (payload.eventType || eventType) {
    case 'subscription.activated':
      await handleSubscriptionActivated(payload);
      break;
    case 'invoice.paid':
      await handleInvoicePaid(payload);
      break;
    default:
      break;
  }

  res.status(200).send('success');
});
Verification notes
  • Verify the raw body string before JSON parsing.
  • Compare signatures with crypto.timingSafeEqual() or an equivalent constant-time compare.
  • See Webhook events for the event catalog and payload samples.

Acknowledgement, retries, and idempotency

Your endpoint must return HTTP 200 with a response body of exactly success after trimming whitespace. Any other body, including other 2xx responses, is treated as failure and queued for retry. UniBee retries failed deliveries up to about 8 attempts. Intervals usually increase from about 1 minute to about 7 minutes. Process events idempotently with eventId or msgId. Do not reuse the same idempotency key for recurring tracking events such as subscription.track*.

Webhook logs

  1. Open Configuration → Webhooks.
  2. Select an endpoint to view deliveries.
  3. Inspect request body and response.
  4. Use Resend to replay a delivery when needed.
Each log includes timestamp, URL, Msg-id, event name, response, retry count, and the JSON payload.

Testing

  1. Point integrations at the sandbox API (https://api-sandbox.unibee.top).
  2. Configure a public HTTPS webhook URL.
  3. Trigger billing flows and confirm deliveries in the Admin Portal.
  4. Verify signature checks and idempotency handling.
Before production:
  • HTTPS endpoint
  • HMAC verification implemented
  • Idempotency on eventId / msgId
  • Response body is exactly success
  • Monitoring for failed deliveries
  • Subscribed events tested end to end
For payment-related tests, see Testing cards.