API ReferenceTopups

Webhooks

How top-up status changes are surfaced - polling, email notifications, and the planned webhook events

Outbound client webhooks for top-ups are not yet wired. Voucher orders already fire order.delivered / order.partially_delivered / order.failed / order.cancelled events (plus wallet.credited / wallet.debited) to your registered webhook URL, but the equivalent topup.* events have not yet been rolled out. Until they ship, use the two patterns below.

How to Track Top-Up Status Today

1. Poll the order endpoint

GET /api/v1/topups/orders/:id refreshes the latest status on each call for in-flight orders. A reasonable poll loop:

# Pseudo-shell: poll every 5s for the first minute, then 30s for a few minutes
# An order that's still PENDING after that is Octopus Cards retrying transient
# fulfilment issues — stop foreground polling and lean on notifications.
delay=5
elapsed=0
while [ "$elapsed" -lt 660 ]; do
  status=$(curl -s "$HOST/api/v1/topups/orders/$ORDER_ID" \
    -H "Authorization: Bearer $TOKEN" | jq -r '.data.status')

  case "$status" in
    DELIVERED|FAILED|CANCELLED) echo "Terminal: $status"; break ;;
  esac

  sleep $delay
  elapsed=$((elapsed + delay))
  [ "$elapsed" -ge 60 ] && delay=30
done

Top-ups typically resolve within 5–30 seconds. The retry cron handles slower fulfilment paths in the background, so your poll will eventually see a terminal status even if the first attempt hung.

2. Attach a notification email

PATCH /api/v1/topups/orders/:id/notification-email registers an email address that is sent a templated receipt on terminal transitions:

  • DELIVERED → success email with the variant name and reference
  • FAILED → failure email with the customer-safe failure_reason
  • CANCELLED → cancellation email with refund confirmation

Email notifications fire at the same terminal points where webhook events will fire once they ship. They are server-driven (no polling needed) but only useful for end-user-facing flows where you actually have a customer email.

Planned Webhook Events

When outbound topup webhooks land, the envelope will match the voucher webhook shape (see Voucher Webhooks for the established pattern):

{
  "id": "evt_topup_abc123",
  "type": "topup.delivered",
  "created_at": "2026-05-15T14:31:12Z",
  "data": {
    "id": 9123456,
    "client_reference": "RECHARGE_REQ_4391",
    "status": "DELIVERED",
    "product_name": "PUBG Mobile UC",
    "variant_name": "325 UC",
    "amount": 4.7405,
    "currency": "USD",
    "completed_at": "2026-05-15T14:31:12Z"
  }
}

Expected event types:

EventTrigger
topup.deliveredOrder moved to DELIVERED. Final.
topup.failedOrder moved to FAILED. Wallet auto-refunded. Final. failure_code / failure_reason / is_user_fixable will be in data.
topup.cancelledOrder cancelled administratively. Wallet refunded. Final.

In-flight sub-statuses will not fire webhooks — events only fire at terminal transitions. This matches the voucher webhook contract.

For shared HMAC verification mechanics, see Signature Verification.

On this page