Skip to main content

Request Lifecycle Overview

Every HTTPayer request progresses through a defined lifecycle, especially when payments or refunds are involved. The lifecycle is divided into five phases:
  1. Discovery
  2. Payment Processing
  3. Upstream Execution
  4. Completion
  5. Refund Handling (if applicable)

Status Reference

HTTPayer uses two layers of status values. See the Status System reference for a full explanation of the mapping between them.

Sync-Response Statuses

These appear in the X-HTTPayer-Status response header and httpayerStatus field on synchronous responses. They are not stored in the webhooks database.

Async / Webhook Statuses

These are stored in the database and returned by GET /webhooks/:id. An initial async_processing record is created when background polling is launched (e.g., after a proxy 502 with webhook_id); it transitions to one of the terminal states below.

In-Flight

Terminal — Success

Terminal — Failure

Upstream Execution

Proxy: upstream payment refused (502)

When the target API returns 402 after all sync retries, HTTPayer returns 502 Bad Gateway with message: "Upstream API refused payment after N attempts". If blockchain polling is active, a webhook_id field is included in the response body — use GET /webhooks/:id to track whether the payment eventually confirmed on-chain. If confirmed, credits are charged; if not, reserved credits are automatically refunded.

SSRF protection (400)

The api_url field is validated before any outbound request is made. Requests targeting private, loopback, or link-local addresses are rejected with 400 Bad Request. Blocked ranges include:
  • Loopback: 127.0.0.0/8, ::1
  • Link-local / cloud metadata: 169.254.0.0/16
  • Private: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
  • Unspecified: 0.0.0.0, ::
Non-http/https schemes (e.g. file://, ftp://) are also rejected.

Refund deduplication

If a refund has already been issued for a relay transaction (status confirmed or pending), any subsequent refund attempt for the same transaction is a no-op — the original refund hash is returned immediately without executing a new blockchain transaction. This prevents double-refunds from retries or concurrent error paths.

Where Statuses Appear

For async flows and refunds, see the Webhooks documentation.