This notification is not sent by the Facade API, which does not implement webhooks. It is sent by the referenced payments platform, and it is configured at the platform level during onboarding with the TapiPay team: there is no endpoint to create or change the URL. The requests come from that platform’s IPs, not from the Facade API host, and they are handed to you during onboarding.
Configuration
You define the full URL (host and path) TapiPay will send notifications to. You provide two:
TapiPay does not impose a route. Any reachable path works:
/api/webhooks/confirm-payment, /tapi/callback, /notifications, /payment/status.
Requirements for your endpoint
required
Reachable from the TapiPay source IPs handed to you during onboarding.
required
Return any 2xx HTTP code to acknowledge receipt. TapiPay does not read your response body, only the status code, so you can respond empty.
required
If you take longer, the request is treated as failed and enters retries. If you need heavy processing, queue it and respond first.
The payload
POST with Content-Type: application/json to the endpoint you defined.
additionalData is dynamic
Example
The fields insideadditionalData are illustrative: they show what a client might send, not a contract.
Validating the request comes from TapiPay
Your endpoint is public, so anyone can call it. TapiPay offers five mechanisms, configured during onboarding. You can enable one or combine several.Retries and idempotency
The right order in your handler is: validate the origin, respond 2xx quickly, and only then process.alreadyProcessed and markProcessed must rely on persistent storage (a table with a unique operationId, or Redis), not process memory: if you restart the server between the original attempt and the retry, an in-memory mark is lost and the payment is processed again.How to test it
TapiPay cannot reach yourlocalhost, so you need a public URL. Two approaches, depending on what you want to verify.
- Inspect the payload
- Test your code
To see the real payload without writing code, use a public receiver such as webhook.site and provide that URL as your staging endpoint. Every notification is logged with its headers and body.This is how you confirm what arrives in
additionalData for your specific case, which is the part that cannot be documented in advance.operationId: it is the fastest way to confirm your idempotency works before going to production.
