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:

URLMethodPost DataResponseFunction
relay/payPOSTPayment ResponsePayment ReplySubmit payment tx
relay/statusPOSTStatus QueryStatus ReplyQuery 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.

Payment Response

This is the wallet's response to the original Payment Request.

{
    "id": "PID-123",                // Relay-unique Payment ID from Connect Payment
	"tx": "489c47f8a3ba3293737..",  // Hex-encoded signed dogecoin transaction
    "refund": "DKY8dUTQthSX..",     // Dogecoin address for refunds (RECOMMENDED)
}

Payment Reply

This is the Payment Relay's reply from the pay URL.

{
    "id": "PID-123",       // Relay-unique Payment ID from Connect Payment
	"status": "accepted",  // One of: accepted | confirmed | declined
    "reason": "",          // Reason for decline (message, optional)
    "required": 5,         // Number of block confirmations required (risk analysis)
    "confirmed": 0,        // Current number of block confirmations on-chain
    "due_sec": 300,        // Estimated time in seconds until 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.

If the transaction is malformed, or does not pay the requested amounts to the requested addresses, the POST will be rejected with a 400 Bad Request http response. This represents a programming error in the wallet. A bad request should not be retried.

Payments may also be rejected with a declined status, in the case that the Vendor or their nominated Relay believes the transaction is too risky. This represents a customer-specific problem. A declined request should not be retried.

Wallets should also be prepared to handle 500 and 503 http errors, and other spurious errors, which indicate a temporary Relay or network problem. Wallets should retry the request a few times (with a small random delay) to increase reliability.

The final three fields, required, confirmed and due_sec are in common with the Status Reply below.

Status Query

This allows the wallet to query the current status of a payment.

{
    "id": "PID-123"  // Relay-unique Payment ID from Connect Payment
}

Status Reply

This is the Payment Relay's reply from the status URL.

{
    "id": "PID-123",        // Relay-unique Payment ID from Connect Payment
	"status": "accepted",   // unpaid | accepted | confirmed
    "required": 5,          // Number of block confirmations required
    "confirmed": 4,         // Current number of block confirmations on-chain
    "due_sec": 30,          // Estimated time in seconds until confirmed
}

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.

When the payment status is confirmed, the confirmed field is always greater or equal to required, and the due_sec field is alway zero.

Note: there are some edge-cases where the confirmed count can reduce, i.e. during a short-term blockchain fork.