curl --request GET \
--url https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/statusimport requests
url = "https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status")
.asString();require 'uri'
require 'net/http'
url = URI("https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"payment_id": "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f",
"status": "pending",
"transactions": {
"deposit": {
"transaction_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"chain_id": "eip155:42161",
"block_number": 61234567
},
"fulfillment": {
"transaction_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"chain_id": "eip155:42161",
"block_number": 61234567
}
},
"updated_at": "2023-11-07T05:31:56Z",
"quote_id": "0x9a3b...e8d4",
"fulfillment_quote": {},
"fulfillment_confirmation": {
"payment_id": "0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f",
"request_id": "req_123456789",
"source_chain_id": "eip155:1",
"destination_chain_id": "eip155:42161",
"source_tx_hash": "0xa1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
"destination_tx_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"fulfillment_timestamp": "2023-11-07T05:31:56Z",
"source_block_number": 123,
"destination_block_number": 123
},
"error": {
"code": "SETTLEMENT_FAILED",
"message": "No quotes received within the auction window",
"domain": "PAYMENT_GATEWAY",
"docs_url": "<string>",
"retry_classification": "RECONCILE_THEN_DECIDE",
"request_id_reusable": false,
"blockchain_context": {
"chain_id": "<string>",
"transaction_hash": "<string>",
"block_number": 123,
"contract_address": "<string>",
"revert_reason": "<string>",
"gas_used": "<string>",
"estimated_gas_needed": "<string>"
}
},
"requested_count": 8,
"decline_summary": [
{
"reason": "INSUFFICIENT_LIQUIDITY",
"count": 4,
"retry_classification": "RETRY_AFTER_DELAY",
"docs_url": "https://docs.atum.xyz/decline-reasons#insufficient-liquidity"
}
]
}{
"code": "INVALID_SOURCE_ASSET",
"message": "The source asset identifier is not a valid CAIP-19 asset.",
"request_id": "req_123456789",
"payment_id": "0xc7108e200d11580e7e75185991084b42a535af588ba8267cd0d1e7df089e5c9c",
"docs_url": "<string>",
"domain": "PAYMENT_GATEWAY",
"retry_classification": "RECONCILE_THEN_DECIDE",
"request_id_reusable": false
}{
"code": "INVALID_SOURCE_ASSET",
"message": "The source asset identifier is not a valid CAIP-19 asset.",
"request_id": "req_123456789",
"payment_id": "0xc7108e200d11580e7e75185991084b42a535af588ba8267cd0d1e7df089e5c9c",
"docs_url": "<string>",
"domain": "PAYMENT_GATEWAY",
"retry_classification": "RECONCILE_THEN_DECIDE",
"request_id_reusable": false
}Get payment status
Poll a payment’s current status by payment_id: pending, completed, or failed.
curl --request GET \
--url https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/statusimport requests
url = "https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status")
.asString();require 'uri'
require 'net/http'
url = URI("https://payment-gw.production-mainnet.atum.xyz/v1/payments/{paymentId}/status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"payment_id": "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f",
"status": "pending",
"transactions": {
"deposit": {
"transaction_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"chain_id": "eip155:42161",
"block_number": 61234567
},
"fulfillment": {
"transaction_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"chain_id": "eip155:42161",
"block_number": 61234567
}
},
"updated_at": "2023-11-07T05:31:56Z",
"quote_id": "0x9a3b...e8d4",
"fulfillment_quote": {},
"fulfillment_confirmation": {
"payment_id": "0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f",
"request_id": "req_123456789",
"source_chain_id": "eip155:1",
"destination_chain_id": "eip155:42161",
"source_tx_hash": "0xa1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
"destination_tx_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"fulfillment_timestamp": "2023-11-07T05:31:56Z",
"source_block_number": 123,
"destination_block_number": 123
},
"error": {
"code": "SETTLEMENT_FAILED",
"message": "No quotes received within the auction window",
"domain": "PAYMENT_GATEWAY",
"docs_url": "<string>",
"retry_classification": "RECONCILE_THEN_DECIDE",
"request_id_reusable": false,
"blockchain_context": {
"chain_id": "<string>",
"transaction_hash": "<string>",
"block_number": 123,
"contract_address": "<string>",
"revert_reason": "<string>",
"gas_used": "<string>",
"estimated_gas_needed": "<string>"
}
},
"requested_count": 8,
"decline_summary": [
{
"reason": "INSUFFICIENT_LIQUIDITY",
"count": 4,
"retry_classification": "RETRY_AFTER_DELAY",
"docs_url": "https://docs.atum.xyz/decline-reasons#insufficient-liquidity"
}
]
}{
"code": "INVALID_SOURCE_ASSET",
"message": "The source asset identifier is not a valid CAIP-19 asset.",
"request_id": "req_123456789",
"payment_id": "0xc7108e200d11580e7e75185991084b42a535af588ba8267cd0d1e7df089e5c9c",
"docs_url": "<string>",
"domain": "PAYMENT_GATEWAY",
"retry_classification": "RECONCILE_THEN_DECIDE",
"request_id_reusable": false
}{
"code": "INVALID_SOURCE_ASSET",
"message": "The source asset identifier is not a valid CAIP-19 asset.",
"request_id": "req_123456789",
"payment_id": "0xc7108e200d11580e7e75185991084b42a535af588ba8267cd0d1e7df089e5c9c",
"docs_url": "<string>",
"domain": "PAYMENT_GATEWAY",
"retry_classification": "RECONCILE_THEN_DECIDE",
"request_id_reusable": false
}Path Parameters
The ID of the payment to query
Response
Payment status retrieved successfully
The payment ID you're checking status for.
"0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f"
Where your payment is in its lifecycle. One payment reads the same however you ask about it.
pending: accepted and in progress. Nothing has reached the recipient yet.finalizing: the transaction paying your recipient is on chain and is accruing the confirmations its chain requires. NOT FINAL, see below.completed: delivered, with the required confirmations behind it.failed: did not complete. Any funds held in escrow are returned, anderrordescribes what went wrong.
completed and failed are final and will not change afterwards. pending and
finalizing will.
Do not treat finalizing as delivered. It says the payment has been made on
chain but is not yet irreversible, much as a card authorization is not yet a
settlement. It normally becomes completed, and it can still become failed if
the transaction never reaches the confirmation depth its chain requires. Acting on
finalizing — releasing goods, crediting an account — means accepting that risk
deliberately, at whatever threshold suits you rather than the one we wait for.
finalizing is about paying the recipient. While your own funds are still being
committed on the source chain the payment is pending, because nothing has reached
the recipient yet.
pending, finalizing, completed, failed "pending"
The transactions a payment has produced, one entry per stage, added as each becomes known. A stage absent here has produced no transaction yet.
These are the two movements that decide whether your payment happened: your funds
being committed, and your recipient being paid. Present on every outcome, so a
payment that did not complete can still be traced on chain.
fulfillment_confirmation is not a substitute: it is written only once a payment
completes, and describes the finished delivery rather than progress towards it.
Where a stage is attempted more than once, the entry describes the attempt that counts — the one that succeeded, or the last one if none did.
Show child attributes
Show child attributes
When the status was last updated
The winning quote's ID. Present once a quote has been awarded for this payment;
absent while the payment is still collecting or awarding. Cross-references the
quote_id returned by GET /v1/payments/quote-requests/{quoteRequestId}.
"0x9a3b...e8d4"
The settler-signed FulfillmentQuote for the winning quote, returned verbatim as an
opaque signed document (structurally the canonical FulfillmentQuote/v1 declaration at
https://schemas.atum.xyz/declarations/FulfillmentQuote/v1). Present once a quote has
been awarded — including after the payment completes and fulfillment_confirmation is
populated, since that is precisely when a consumer verifies.
This is the PREIMAGE of the quote_hash committed on-chain in the escrow deposit and
reserve witnesses. On-chain we commit only the hash, so a quote-selector consumer
recomputes quote_hash over these bytes and compares it against the on-chain commitment
to confirm the payment settled against the quote it selected ("trust but verify"), and
verifies the settler signature over the same bytes.
quote_hash is canonicalization-based (URDNA2015), so it is stable across JSON key-order/whitespace normalization and across JSON string-escaping differences. The returned bytes are hash-equivalent to, but not necessarily byte-identical with, what the settler emitted (quotes are stored as JSONB, which normalizes on write). The gateway still never re-serializes the quote through a typed struct (that renormalizes timestamp values and WOULD change quote_hash), so the Go binding exposes it as a raw JSON passthrough.
Confirmation details after a payment has been successfully delivered. Contains proof of delivery and transaction details for both source and destination chains.
Show child attributes
Show child attributes
Why a payment failed. Present only when status is failed, and identical
however you ask about the payment.
code is the stable, machine-readable identity of the failure — branch on it
rather than on message, which is written for a person and may be reworded.
docs_url points at the page describing that code.
Show child attributes
Show child attributes
How many settler agents this payment's auction was broadcast to. Absent means unknown, never zero.
8
Why the payment drew few or no quotes. Read from the same settler reports as the quote-request endpoints, keyed by this payment, so a payment that failed on an expired quote deadline can say WHY nobody funded it instead of only that nobody did.
Every declining agent is counted exactly once under its most recent reason. Empty means no agent declined against this payment, absent means the breakdown could not be read. A payment awarded out of a quote-request batch was bid on at quote time, so its declines are keyed to that batch and are read from the batch's status endpoint rather than here. As on the quote-request endpoints, the free-form decline detail is never relayed.
Show child attributes
Show child attributes