Webhooks & callbacks
How payment and logistics providers notify your store, and the browser payment callback.
Webhooks are server-to-server notifications the API receives from providers.
You don't call them — they're documented here so you understand the moving parts
behind payments and delivery. They live at the root (no /v1, no store key);
each is authenticated by the provider's own scheme.
Payment webhook — POST /webhook/phonepe
The payment provider calls this to authoritatively settle a transaction, independent of the shopper's browser redirect.
- Authenticated by a per-store username/password (HTTP basic via the
Authorizationheader) plus anX-Store-Idheader. - On success: marks the transaction and order paid, and clears the customer's cart.
This is why an order can settle even if the shopper closes the tab before the return page loads — the webhook is the source of truth.
Logistics webhook — POST /webhook/logistics/shiprocket
The delivery provider calls this to push tracking updates.
- Authenticated by an
x-api-keyheader (HMAC secret). - Updates the order's delivery fields (
deliveryStatus,deliveryPartner,estimatedDelivery,deliveredAt,trackingUrl) and transitions the order toout_for_deliveryordelivered.
These fields then show up on the order via
customer.orders.get().
Browser payment callback — GET /payment/callback
This is not a webhook — it's where the payment provider redirects the shopper's browser after payment. The API resolves your storefront's origin and then redirects to:
<your-storefront>/payment/callback?orderId=<id>&status=<success|failed|pending>Your app handles that page and confirms the order — see
Payments. The storefront origin is resolved from the
order's storefrontUrl (set from your STOREFRONT_URL), falling back to the
store's registered domain.
You implement the return page, not the callback
The /payment/callback route belongs to the API. Your job is the page it
redirects to on your origin (/payment/callback), which the SDK's
usePaymentConfirmation() hook drives.