Webhooks & Redirects

Real-time notifications, signature verification, IP whitelisting, retries, and timeouts for both APIs

View as Markdown

Both the Payments API and the Disbursement API support asynchronous, real-time notification via a callback_webhook_url, in addition to (or instead of) polling Get Transactions.

Webhook notifications — also known as real-time payment notifications or callbacks — are automated messages sent to your server when a payment or disbursement event occurs. They let you instantly update your system (e.g., credit a user’s account) without polling or manual intervention.

When an event is processed, a POST request with a JSON payload is sent to your specified callback_webhook_url, so your backend can handle the result immediately and reliably.

The mechanics below (signature algorithm, data format, IP addresses, payload shape, and status values) differ between the two APIs. Don’t reuse Payments API webhook-verification code for Disbursement API webhooks, or vice versa.

Redirects (Payments API only)

Generate Transaction additionally accepts two optional browser-redirect fields, which have no Disbursement API equivalent since a disbursement has no customer browser involved:

FieldPurpose
success_redirect_urlWhere the customer’s browser is redirected after a successful payment.
failure_redirect_urlWhere the customer’s browser is redirected if the payment fails or is cancelled.

The redirect URLs are a browser-side experience — they only fire if the customer’s browser is still open on the payment page. The webhook is a server-side notification that fires regardless of what the customer’s browser is doing, which makes it the more reliable mechanism for updating your system’s records.

Example Webhook Payloads

Example webhook payload
1{
2 "message": "Transaction has been updated.",
3 "data": {
4 "reference_no": "TESTQRZLXXX2OPGV",
5 "amount": 1,
6 "status": "completed",
7 "signature": "6c37ddeea4503d2a526a300fe00d0d745caca989edcf4fcc226ae08414f061c8",
8 "transaction": {
9 "subtotal_amount": 1,
10 "service_fee": 0,
11 "total_amount": 1,
12 "reference_no": "TESTQRZLXXX2OPGV",
13 "provider_reference_no": "a1138921-3291-4783-8fa1-7041e6c98ae2",
14 "status": "completed",
15 "link_url": null,
16 "is_expired": false,
17 "expires_at": "2025-07-19T20:03:04+08:00",
18 "date": "2025-07-18T20:03:04+08:00",
19 "channel": {
20 "name": "GCash",
21 "desciption": null,
22 "slug": "gcash-direct"
23 },
24 "sub_biller": null,
25 "extra": null
26 }
27 }
28}

Note the payload is flatter at the top level (data.amount, data.reference_no, data.status, data.signature) with a nested data.transaction object carrying the full transaction detail.

Possible Status Values

Both APIs use the same three status values: pending, cancelled, and completed.

StatusMeaning
pendingPayment has been initiated but is not yet completed. The customer may still be in the process of paying.
cancelledPayment was either failed, expired, or manually canceled. No funds were received.
completedPayment was successfully processed and confirmed. Funds have been received.

Always use these values to determine how your system should respond to an update — don’t infer status from HTTP response codes alone.

Webhook Signature Verification

To ensure that incoming webhook notifications are truly from your payment provider and not a malicious third party, both APIs sign the payload with a signature — a cryptographic hash that acts as a tamper-proof seal. Even if someone intercepts the webhook, they cannot fake a valid signature without access to the secret key.

The two APIs use different HMAC algorithms and different data formats to compute the signature. Verify against the correct one for the webhook you received.

Uses HMAC-SHA256.

  • Data format: amount + "@" + reference_no Example: 100@EPLKZT2OH319WBEF
  • Signature key: provided by your payment facilitator. For sandbox/staging (test-merchant credentials), use the Signature Key from the Create Token section: 9XAgVZzU4WhqrXA6jEvMtkF85j8wKZZhQ5RE2hsDPwa5rjPT7RpCmJceu8jNt4Wy
  • HMAC output: hexadecimal string
1const crypto = require('crypto');
2const signatureKey = 'your_signature_key';
3const data = '100@EPLKZT2OH319WBEF';
4const signature = crypto
5 .createHmac('sha256', signatureKey)
6 .update(data)
7 .digest('hex');
8console.log(signature);

IP Whitelisting

IP whitelisting limits incoming requests to only those from approved, trusted sources, reducing the risk of spoofed webhooks or unauthorized actions. This works in tandem with HMAC signature verification — together, they ensure the webhook is both authentic and coming from the correct origin.

Do not process any webhook request unless the HMAC signature is verified and the request originates from one of the whitelisted IP addresses below. Checking only one of the two can lead to spoofed or fraudulent transactions being processed.

Sandbox/Staging: 43.198.4.7

Production:

  • 18.166.179.109
  • 18.166.252.124

Both APIs share the same sandbox/staging IP (43.198.4.7), but each has its own, distinct pair of production IPs. Whitelist the correct set for the API you’re integrating.

Webhook Retry Mechanism

If your server responds with a 4xx or 5xx status code (or doesn’t respond in time), the system automatically retries delivery using a backoff schedule. This behavior is identical for both APIs.

  • Webhook delivery is retried up to 17 times over a span of roughly 7 days.
  • Retries follow this interval schedule (in minutes):
1[2, 10, 10, 60, 120, 360, 900]
  • Retry #1 — after 2 minutes
  • Retry #2 — after 10 minutes
  • Retry #3 — after another 10 minutes
  • Retry #4 — after 60 minutes
  • Retry #5 — after 120 minutes
  • Retry #6 — after 360 minutes (6 hours)
  • Retry #7 — after 900 minutes (15 hours)
  • Retry #8 to #17 — every 900 minutes (15 hours)

The retry count resets only when a 2xx response is received from your callback_webhook_url.

Webhook Timeout & Latency Guidelines

These are also identical for both APIs:

  • Up to 3000ms (3 seconds) is allowed for your server to respond.
  • If your server doesn’t respond within this window, the attempt is considered failed and will be retried.
  • Keep your webhook processing latency below 300ms to account for network overhead, JSON parsing, and response handling.

Best practice: acknowledge the webhook immediately (return a 200 OK), then process the payload asynchronously in the background — don’t do slow work before responding.

Testing Webhook Notifications

For testing and debugging, you can temporarily use webhook.site as your callback_webhook_url for either API. This lets you:

  • Instantly see the actual JSON payload sent by the system.
  • Inspect and verify the HMAC signature.
  • Debug your integration before going live.

This is the same approach shown in the collection’s own example requests, and works for both payment and disbursement flows without needing to stand up your own server endpoint first.

Quick Comparison

Payments APIDisbursement API
Redirect URLsYes (success_redirect_url, failure_redirect_url)No — backend-only flow
Signature algorithmHMAC-SHA256HMAC-SHA512
Signature data formatamount + "@" + reference_noMinified JSON of data (excluding signature)
Payload shapeFlat top-level fields + nested data.transactionFlat — no nested transaction object
Status valuespending, cancelled, completedpending, cancelled, completed
Sandbox IP43.198.4.743.198.4.7
Production IPs18.166.179.109, 18.166.252.12416.162.178.209, 18.167.239.15
Retry schedule17 retries over ~7 days17 retries over ~7 days
Timeout3000ms3000ms