Third parties
The backend talks to three outside services. The frontends never call them directly. Each service also calls back in, through a separate webhook receiver.
How this page was verified
Read on 2026-09-15 from the backend client services, the webhook repo index.js, and the simulator index.js.
The three services
| Service | Role | Backend client | Base-URL env | Inbound webhook (backend) |
|---|---|---|---|---|
| Biteship | delivery / shipment | DeliveriesService (src/deliveries/services/deliveries.service.ts) | DELIVERY_BITESHIP_BASE_URL | webhooks/deliveries |
| DOKU | payment | PaymentsService (src/payments/services/payments.service.ts) | DOKU_BASEURL | webhooks/payments |
| PowerBiz (WMS) | warehouse / stock | WmsService (src/catalogs/services/wms.service.ts) | WMS_ENDPOINT_BASE_URL | webhooks/wms |
All three use @nestjs/axios. Details of each flow are on the feature pages: Delivery, Payment, Stock (WMS).
- Biteship — Bearer
DELIVERY_BITESHIP_API_KEY. Origin is set fromDELIVERY_WAREHOUSE_ZIPCODEand theDELIVERY_ORIGIN_*vars. Calls/v1/couriers,/v1/rates/couriers,/v1/draft_orders(+/confirm),/v1/trackings/:id. - DOKU —
DOKU_CLIENT_IDandDOKU_SECRET_KEY, request signed with HMAC-SHA256 (HMACSHA256=<base64>).DOKU_PAYMENT_DUE_DATE_MINUTEsets the payment window. The backend is created withrawBody: trueso it can verify the DOKU webhook signature. - WMS (PowerBiz) — logs in on boot (
WMS_USERNAME/WMS_PASSWORD) for a bearer token and re-logs in on a 401. Scoped byWMS_BUSINESS_IDandWMS_WAREHOUSE_ID. Methods: inventory lookup, order detail, create/cancel/update order.
The simulator sits in front of them in dev
In dev the backend .env points all three base URLs at https://proxy.exsport.bdt.dev/{biteship,doku,wms}. That proxy is def-exsport-3rdparty-simulator: it forwards to the real APIs and can force errors per service.
- Routes:
/biteship/*→api.biteship.com,/wms/*→open-api.powerbiz.asia,/doku/*→api-sandbox.doku.com(each overridable by env). - An in-memory toggle per service, flipped at
POST /simulate/:service{enable}and shown on the EJS dashboard atGET /. When on, the key endpoint returns HTTP 500: Biteship/v1/draft_orders, WMS/order/create, DOKU any call.
So "payment / delivery / WMS is failing on dev" may just mean error simulation is on. Check the simulator dashboard before you debug the backend.
The webhook receiver fans out to SNS
Inbound callbacks do not hit the backend directly in production; they hit def-exsport-webhook, a small Express app that republishes each payload to an SNS topic:
| Callback | Route | SNS topic env |
|---|---|---|
| WMS / stock | POST /inventory | SNS_TOPIC_WMS_ARN |
| Biteship | POST /delivery | SNS_TOPIC_DELIVERY_ARN |
| DOKU | POST /payment | SNS_TOPIC_PAYMENT_ARN |
The SNS topics and subscriptions are defined in the Pulumi webhook stack. The backend's own webhooks/* REST routes are the handlers that ultimately process these events (directly in dev, via SNS in prod).