Payment Relay
The Payment Relay base URL is found in the relay field of Connect Payment.
The following Web API must be implemented by a Payment Relay:
| URL | Method | Post Data | Response | Function |
|---|---|---|---|---|
| relay/pay | POST | Payment Submission | Payment Status | Submit payment tx |
| relay/status | POST | Status Query | Payment Status | Query payment status |
Requests and responses are JSON payloads; JSON must be UTF-8 encoded.
All responses must include a Cache-Control: no-store header, to avoid
leaking payment information into caches. Both endpoints additionally use
the POST method to avoid caching edge-cases (e.g. error responses.)
The Relay must implement the pay endpoint with idempotence in
the following way: if the status of payment id is already accepted or
confirmed, it responds to another pay request with that status, ignoring
the supplied tx. This is because wallets will retry their pay request
if they did not receive or process the first reply.
Relay Token
A Relay may include an opaque relay_token in the Connect Payment. If present,
the wallet must echo it back verbatim in the Payment Submission. The token is
opaque to the wallet — it should not attempt to parse or interpret its contents.
The relay token enables stateless validation: the relay can embed whatever parameters it needs inside the token, avoiding additional lookups at submission time.
The token format is entirely up to the relay implementation.
Payment Submission
The wallet’s submission to the relay’s pay endpoint in response to a Connect Payment.
{
"id": "PID-123", // Relay-unique Payment ID from Connect Payment
"tx": "489c47f8a3ba3293737..", // Hex-encoded signed dogecoin transaction
"refund": "DKY8dUTQthSX..", // Dogecoin address for refunds (recommended)
"relay_token": "eyJpZCI6IlBJRC..." // Relay token from Connect Payment, if present
}
Payment Status
Both the pay and status endpoints return a Payment Status response.
200 — Accepted:
{
"id": "PID-123",
"status": "accepted",
"txid": "a1b2c3d4e5..",
"required": 5,
"confirmed": 0,
"due_sec": 300
}
403 — Declined:
{
"id": "PID-123",
"status": "declined",
"reason": "Transaction deemed too risky"
}
The status field is a PaymentStatus enum value. The txid field
contains the hex-encoded transaction ID and is present whenever the
status is accepted or confirmed. The confirmed_at field is an RFC 3339 timestamp indicating when the
submitted transaction reached the required number of block confirmations;
it is only present when the status is confirmed.
The status will be accepted if the Relay requires one or more block
confirmations on the blockchain, reflected in the required field.
The status may be confirmed if the Relay deems the payment low-risk.
The required, confirmed and due_sec fields are present whenever the
status is accepted or confirmed. The required field indicates how many
block confirmations the Relay requires; confirmed is the current count
on-chain; due_sec is the estimated seconds remaining until confirmed.
When the payment status is confirmed, the confirmed field is always
greater or equal to required, and the due_sec field is always zero.
Payments transition from unpaid to accepted after the signed transaction
is submitted to the pay endpoint (provided payment was accepted.) After
the required number of block confirmations have been seen on-chain, the
payment status transitions to confirmed.
Note: there are some edge-cases where the confirmed count can reduce,
i.e. during a short-term blockchain fork.
Error Response
{
"error": "invalid_tx",
"message": "Transaction outputs do not match requested amounts"
}
HTTP Status Codes
pay endpoint
| HTTP | Body | Meaning |
|---|---|---|
| 200 | Payment Status | Accepted or confirmed |
| 400 | Error Response | Programming error (malformed tx, wrong outputs, expired, invalid token) |
| 403 | Payment Status | Declined (status: "declined") |
| 404 | Error Response | Unknown payment ID |
| 500 / 503 | - | Transient server error; retry with backoff |
status endpoint
| HTTP | Body | Meaning |
|---|---|---|
| 200 | Payment Status | Status returned |
| 404 | Error Response | Unknown payment ID |
| 500 / 503 | - | Transient server error; retry with backoff |
A 400 or 403 response indicates a permanent failure; wallets should not retry. A 500 or 503 response is transient — the wallet should assume the relay will recover and retry a few times with exponential backoff and a small random jitter.
Status Query
This allows the wallet to query the current status of a payment.
{
"id": "PID-123" // Relay-unique Payment ID from Connect Payment
}