Payment Intents
Create, fetch, update, cancel and validate payment intents on Stellar (SEP-7), Solana (Solana Pay) and Monad (EIP-681).
Stellar only: builds the unsigned envelope paying destination from source on the key's network (a prod key builds for mainnet, a dev key for testnet), plus a second payment to merchantFee.wallet when a merchant fee is set, and answers its XDR, web+stellar:tx URI and QR. memo (a numeric MEMO_ID, generated when omitted) is the idempotency key: a retry with the same memo and terms returns the stored intent, other terms are 409 idempotency_conflict. The intent starts PENDING, emits PAYMENT_INTENT_CREATED, and the on-chain observer settles it when the payment lands.
Requires the payments:write scope. The shared public key may call it.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
application/json- body
Request to create a Stellar SEP-7 tx intent: the payer (source) is known, so the service builds the unsigned transaction for it to sign.
source*stringPayer's Stellar account: the transaction source.
destination*stringPayee's Stellar account.
amount*stringAmount as a decimal string (max 7 decimals).
assetCode?stringAsset code. Omit (or "XLM"/"native") for native lumens.
assetIssuer?stringIssuer account for a non-native asset.
memo?stringMEMO_ID (numeric uint64) for idempotency + on-chain identification. Auto-generated when omitted.
msg?stringSEP-7 msg: shown to the user in their wallet (≤ 300 chars).
callback?stringSEP-7 callback where the wallet POSTs the signed XDR, e.g. url:https://....
checkoutTheme?stringDesign of the hosted checkout page (https://payments.cosmospay.lat/<id>) for this intent. Omit for classic. Cosmetic: it is not part of the payment, so PATCH /v1/payment-intents/{id} can change it later, and a retry with the same memo returns the stored intent with its stored design.
"classic""classic""split""ticket""card"merchantFee?Your own fee on this payment, paid in its asset to wallet (a Stellar account that can receive the asset, not source or destination) by a second payment in the same envelope. paidBy: recipient takes it from amount (the destination receives amount less the fee); payer adds it on top. The intent settles only on a transaction that pays both.
Created
trustline_missing: the destination does not trust the issued asset being paid. The payer signs this transaction and the destination signs nothing, so only the destination account can add the trustline.
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
idempotency_conflict: an intent with this memo already exists for different payment details. Retry with the original request unchanged, or use a new memo (omit memo to have one generated). operation_in_flight: a concurrent create for the same memo changed it while this one was being created; retry the request.
The budget in x-cosmos-rate-limit is spent for this caller. Honour Retry-After.
The ratelimit-* triple rides along on successful responses too, so a client can pace itself instead of being refused. If the counter store itself is unreachable the guard fails closed and answers 503 provider_unavailable.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
provider_unavailable: the provider in x-cosmos-upstream is down or unreachable; the message names it. Retry.
misconfigured: this deployment is missing configuration the route needs (a provider instance, a fee wallet, the plan header the gateway must forward). Retrying will not help; it is an operator problem.
curl -X POST 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents/tx' \ -H 'Content-Type: application/json' \ -d '{ "source": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", "destination": "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO", "amount": "120.1234567"}'{ "id": "clx9z8a1b0000abcd1234efgh", "kind": "TX", "status": "PENDING", "chain": "stellar", "network": "testnet", "source": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", "destination": "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO", "amount": "120.1234567", "asset": "native", "assetIssuer": null, "memo": "123456789", "chainReference": null, "networkFee": null, "merchantFee": { "bps": 150, "fixed": "0.25", "amount": "1.75", "asset": "XLM", "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R", "paidBy": "recipient" }, "msg": "Order #24", "callback": null, "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=", "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…", "qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…", "txHash": null, "reference": null, "checkoutTheme": "classic", "expiresAt": "2026-06-21T13:34:56.000Z", "checkoutSeenAt": null, "checkoutWalletAt": null, "checkoutWalletClosedAt": null, "checkoutSentAt": null, "createdAt": "2026-06-21T12:34:56.000Z", "updatedAt": "2026-06-21T12:34:56.000Z"}Answers a link any wallet can pay and its QR: SEP-7 web+stellar:pay on Stellar (the default chain), Solana Pay on Solana, EIP-681 on Monad, on the key's network (a prod key gets mainnet, a dev key the test networks). Omit amount for an open amount, except on Monad when this deployment has no deposit addresses; with a merchantFee, uri is the hosted checkout on Stellar and a Solana Pay transaction request on Solana. memo (numeric, generated when omitted) is the idempotency key: the same memo and terms return the stored intent, other terms are 409 idempotency_conflict. Emits PAYMENT_INTENT_CREATED; the on-chain observer settles the intent when it finds the payment (a native MON payment without a deposit address needs validate).
Requires the payments:write scope. The shared public key may call it.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
application/json- body
Request to create a pay intent: a payment link any wallet can pay on Stellar (SEP-7), Solana (Solana Pay) or Monad (EIP-681).
chain?stringChain the payment settles on. Omit for Stellar. The network (mainnet or test network) is the one your API key is for, as on Stellar.
"stellar""stellar""solana""monad"destination*stringPayee's account on the chain: Stellar G…, Solana base58, Monad 0x….
amount?stringAmount the destination should receive, in the asset’s own units (XLM, SOL, MON, or the token). Omit to let the user enter it (e.g. donations), but not on Monad, where the amount is part of how the payment is recognised. At most 7 decimals on Stellar; elsewhere, at most the asset’s own decimals.
assetCode?stringAsset code the destination receives. Omit for the chain’s coin (XLM, SOL, MON). For a Solana or Monad token, the ticker it is labelled with, alongside assetIssuer.
assetIssuer?stringStellar: the issuer account. Solana: the SPL mint. Monad: the ERC-20 contract. Omit for the chain’s coin.
memo?stringMEMO_ID (numeric uint64): the idempotency key on every chain, and on Stellar the on-chain identification too (on Solana it is recorded with the SPL Memo program). Auto-generated when omitted.
msg?stringShown to the user in their wallet (≤ 300 chars): SEP-7 msg on Stellar, the Solana Pay message. Not supported on Monad.
callback?stringSEP-7 callback, e.g. url:https://.... Stellar only.
checkoutTheme?stringDesign of the hosted checkout page (https://payments.cosmospay.lat/<id>) for this intent. Omit for classic. Cosmetic: it is not part of the payment, so PATCH /v1/payment-intents/{id} can change it later, and a retry with the same memo returns the stored intent with its stored design.
"classic""classic""split""ticket""card"merchantFee?Only with an amount: your own fee on this payment, paid in its asset to wallet (an account on the link's chain, not destination). paidBy: recipient takes the fee from amount; payer adds it on top. Stellar: a SEP-7 pay link pays one account, so uri is the hosted checkout, which asks for the payer and has POST /v1/payment-links/{id}/transaction build the envelope with both payments. Solana: uri is a Solana Pay transaction request (/v1/payment-links/{id}/solana-pay); a SOL fee goes to an existing account. Monad: needs deposit addresses (merchant_fee_unsupported without them); the deposit address pays the fee (PaymentSplitForwarder) and the link asks for the amount, plus the fee when the payer pays it.
Created
validation_failed: The body, query or headers failed validation
invalid_amount: Not a Stellar amount, or not greater than zero
invalid_memo: The memo is not the type this route requires
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
idempotency_conflict: an intent with this memo already exists for different payment details. Retry with the original request unchanged, or use a new memo (omit memo to have one generated). operation_in_flight: a concurrent create for the same memo changed it while this one was being created; retry the request.
The budget in x-cosmos-rate-limit is spent for this caller. Honour Retry-After.
The ratelimit-* triple rides along on successful responses too, so a client can pace itself instead of being refused. If the counter store itself is unreachable the guard fails closed and answers 503 provider_unavailable.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
The provider named in x-cosmos-upstream refused the request (provider_error) or could not be reached at all (provider_unavailable). Nothing was charged; retry is safe with the same Idempotency-Key.
provider_unavailable: the provider in x-cosmos-upstream is down or unreachable; the message names it. Retry.
misconfigured: this deployment is missing configuration the route needs (a provider instance, a fee wallet, the plan header the gateway must forward). Retrying will not help; it is an operator problem.
The provider in x-cosmos-upstream did not answer in time. Whether it acted on the request is unknown. Retry with the same Idempotency-Key, never with a fresh one.
curl -X POST 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents/pay' \ -H 'Content-Type: application/json' \ -d '{ "destination": "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO"}'{ "id": "clx9z8a1b0000abcd1234efgh", "kind": "PAY", "status": "PENDING", "chain": "stellar", "network": "testnet", "source": null, "destination": "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO", "amount": "120.1234567", "asset": "native", "assetIssuer": null, "memo": "123456789", "chainReference": null, "networkFee": null, "merchantFee": { "bps": 150, "fixed": "0.25", "amount": "1.75", "asset": "XLM", "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R", "paidBy": "recipient" }, "msg": "pay me with lumens", "callback": null, "xdr": null, "uri": "web+stellar:pay?destination=GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO&amount=120.1234567", "qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…", "txHash": null, "reference": null, "checkoutTheme": "classic", "expiresAt": "2026-06-21T13:34:56.000Z", "checkoutSeenAt": null, "checkoutWalletAt": null, "checkoutWalletClosedAt": null, "checkoutSentAt": null, "createdAt": "2026-06-21T12:34:56.000Z", "updatedAt": "2026-06-21T12:34:56.000Z"}Newest first, as { data, total, take, skip } with take up to 100 (default 20). Only intents on the key's network (a prod key lists mainnet intents, a dev key test-network ones), narrowed by status, chain and createdFrom when given.
Requires the payments:read scope.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
status?stringOnly intents in this status. Omit for every status.
"PENDING""SUBMITTED""SUCCEEDED""FAILED""CANCELLED""EXPIRED"chain?stringOnly intents on this chain. Omit for every chain.
"stellar""solana""monad"createdFrom?stringOnly intents created at or after this instant (ISO 8601). Omit for no lower bound. The dashboard uses it for its today / week / month / year views of the list.
date-timetake?numberPage size: how many items to return (1 to 100).
value <= 10020skip?numberHow many items to skip before this page (offset).
0OK
The body, query or path failed validation. message is an array of the individual failures.
Routes that reject a valid request for a reason of their own (an amount, a memo, a state) document the code for it on their own 400.
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
curl -X GET 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents'{ "data": [ { "id": "clx9z8a1b0000abcd1234efgh", "kind": "TX", "status": "PENDING", "chain": "stellar", "network": "testnet", "source": "Greally…56charpublickey", "destination": "GASMERCHANT…56charpublickey", "amount": "25.5", "asset": "native", "assetIssuer": null, "memo": "123456789", "chainReference": null, "networkFee": null, "merchantFee": { "bps": 150, "fixed": "0.25", "amount": "1.75", "asset": "XLM", "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R", "paidBy": "recipient" }, "msg": null, "callback": null, "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=", "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…", "qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…", "txHash": null, "reference": null, "checkoutTheme": "classic", "expiresAt": "2026-06-21T13:34:56.000Z", "checkoutSeenAt": "2026-06-21T12:35:10.000Z", "checkoutWalletAt": null, "checkoutWalletClosedAt": null, "checkoutSentAt": null, "createdAt": "2026-06-21T12:34:56.000Z", "updatedAt": "2026-06-21T12:34:56.000Z" } ], "total": 1, "take": 20, "skip": 0}The intent's audit trail as an array, oldest first: every status change with fromStatus, toStatus, the txHash it carried, its reason and the actor that made it (api, validate, observer or system).
Requires the payments:read scope.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
id*stringOK
The body, query or path failed validation. message is an array of the individual failures.
Routes that reject a valid request for a reason of their own (an amount, a memo, a state) document the code for it on their own 400.
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
No such resource, or it exists and belongs to another consumer. The two are deliberately the same answer: "exists but not yours" is an ownership oracle.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
curl -X GET 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents/string/transitions'[ { "id": "clxtransition0001", "intentId": "clx9z8a1b0000abcd1234efgh", "fromStatus": "PENDING", "toStatus": "SUBMITTED", "txHash": "3389e9f0…", "actor": "api", "reason": {}, "createdAt": "2019-08-24T14:15:22Z" }]One of the consumer’s intents, on any chain, with its QR rebuilt from uri. status moves as the on-chain observer settles or expires the intent, which the PAYMENT_INTENT_* webhooks also report, so polling this route is optional.
Requires the payments:read scope.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
id*stringOK
The body, query or path failed validation. message is an array of the individual failures.
Routes that reject a valid request for a reason of their own (an amount, a memo, a state) document the code for it on their own 400.
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
No such resource, or it exists and belongs to another consumer. The two are deliberately the same answer: "exists but not yours" is an ownership oracle.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
curl -X GET 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents/string'{ "id": "clx9z8a1b0000abcd1234efgh", "kind": "TX", "status": "PENDING", "chain": "stellar", "network": "testnet", "source": "Greally…56charpublickey", "destination": "GASMERCHANT…56charpublickey", "amount": "25.5", "asset": "native", "assetIssuer": null, "memo": "123456789", "chainReference": null, "networkFee": null, "merchantFee": { "bps": 150, "fixed": "0.25", "amount": "1.75", "asset": "XLM", "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R", "paidBy": "recipient" }, "msg": null, "callback": null, "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=", "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…", "qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…", "txHash": null, "reference": null, "checkoutTheme": "classic", "expiresAt": "2026-06-21T13:34:56.000Z", "checkoutSeenAt": "2026-06-21T12:35:10.000Z", "checkoutWalletAt": null, "checkoutWalletClosedAt": null, "checkoutSentAt": null, "createdAt": "2026-06-21T12:34:56.000Z", "updatedAt": "2026-06-21T12:34:56.000Z"}Send only what changes; reference and checkoutTheme are accepted in any status. status: SUCCEEDED needs a txHash and goes through the same on-chain check as validate (400 transaction_rejected when the chain does not confirm it); other status changes follow the transition graph (SUCCEEDED, FAILED and CANCELLED are final, EXPIRED only settles on a verified payment), else 400 invalid_state_transition. A new txHash alone is accepted only while PENDING or SUBMITTED. Emits PAYMENT_INTENT_CANCELLED, PAYMENT_INTENT_SUCCEEDED or PAYMENT_INTENT_FAILED for those statuses and PAYMENT_INTENT_UPDATED otherwise.
Requires the payments:write scope.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
id*stringapplication/json- body
Changes to a payment intent: send only the fields that change.
status?stringThe new status, following the transition graph. SUCCEEDED needs a txHash and is checked on-chain like validate.
"PENDING""SUBMITTED""SUCCEEDED""FAILED""CANCELLED""EXPIRED"txHash?stringThe transaction once it is submitted, in its chain’s own form: a Stellar hash (64 hex), a Solana signature (base58) or a Monad hash (0x + 64 hex). Hex is stored lowercase. A transaction already recorded on another of your payment intents is refused with 409 idempotency_conflict.
^(?:[0-9a-fA-F]{64}|0x[0-9a-fA-F]{64}|[1-9A-HJ-NP-Za-km-z]{80,90})$reference?stringMerchant reference.
checkoutTheme?stringDesign of the hosted checkout page (https://payments.cosmospay.lat/<id>). Accepted in any status, final ones included, alone or with the other fields: it changes nothing about the payment.
"classic""split""ticket""card"OK
validation_failed: The body, query or headers failed validation
invalid_state_transition: The resource cannot move to that state from the one it is in
transaction_rejected: The submitted transaction does not do what the route needs
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
No such resource, or it exists and belongs to another consumer. The two are deliberately the same answer: "exists but not yours" is an ownership oracle.
transaction_already_settled: the transaction already settled, or also pays an older, payment intent of any consumer, and one payment settles at most one intent, the oldest it pays; this intent is not paid by it. idempotency_conflict: the hash is already recorded on another of your intents. operation_in_flight: the status changed under this request; re-read the intent and retry.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
The provider named in x-cosmos-upstream refused the request (provider_error) or could not be reached at all (provider_unavailable). Nothing was charged; retry is safe with the same Idempotency-Key.
provider_unavailable: the provider in x-cosmos-upstream is down or unreachable; the message names it. Retry.
misconfigured: this deployment is missing configuration the route needs (a provider instance, a fee wallet, the plan header the gateway must forward). Retrying will not help; it is an operator problem.
The provider in x-cosmos-upstream did not answer in time. Whether it acted on the request is unknown. Retry with the same Idempotency-Key, never with a fresh one.
curl -X PATCH 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents/string' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "clx9z8a1b0000abcd1234efgh", "kind": "TX", "status": "PENDING", "chain": "stellar", "network": "testnet", "source": "Greally…56charpublickey", "destination": "GASMERCHANT…56charpublickey", "amount": "25.5", "asset": "native", "assetIssuer": null, "memo": "123456789", "chainReference": null, "networkFee": null, "merchantFee": { "bps": 150, "fixed": "0.25", "amount": "1.75", "asset": "XLM", "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R", "paidBy": "recipient" }, "msg": null, "callback": null, "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=", "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…", "qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…", "txHash": null, "reference": null, "checkoutTheme": "classic", "expiresAt": "2026-06-21T13:34:56.000Z", "checkoutSeenAt": "2026-06-21T12:35:10.000Z", "checkoutWalletAt": null, "checkoutWalletClosedAt": null, "checkoutSentAt": null, "createdAt": "2026-06-21T12:34:56.000Z", "updatedAt": "2026-06-21T12:34:56.000Z"}Deletes an intent in any status but SUCCEEDED and emits PAYMENT_INTENT_DELETED. A paid intent is a settled payment and cannot be deleted (400 invalid_state_transition); an intent whose status changes during the delete (it may have just been paid) is 409 operation_in_flight.
Requires the payments:write scope.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
id*stringOK
validation_failed: The body, query or headers failed validation
invalid_state_transition: The resource cannot move to that state from the one it is in
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
No such resource, or it exists and belongs to another consumer. The two are deliberately the same answer: "exists but not yours" is an ownership oracle.
operation_in_flight: the status changed under this delete. The intent may have just been paid. Re-read it before retrying.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
curl -X DELETE 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents/string'{ "id": "clx9z8a1b0000abcd1234efgh", "deleted": true}Looks txHash up on the intent's chain and checks it pays this intent (success, destination, asset, amount, memo or reference, age); a match settles it SUCCEEDED and emits PAYMENT_INTENT_SUCCEEDED. This intent's own payment that failed on-chain marks it FAILED (PAYMENT_INTENT_FAILED); any other mismatch answers valid: false with a reason and leaves the status unchanged. An EXPIRED intent still settles on a verified payment, a SUCCEEDED one answers as it is without asking the chain, and one transaction settles at most one intent of any consumer (the oldest it pays).
Requires the payments:write scope.
apiKeyAuthorizationBearer <API key>Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.
id*stringapplication/json- body
The transaction to check against a payment intent, which settles the intent when it pays it.
txHash*stringThe transaction to validate against this intent, in its chain’s own form: a Stellar hash (64 hex), a Solana signature (base58) or a Monad hash (0x + 64 hex). It must be the one the intent’s chain uses.
OK
validation_failed: The body, query or headers failed validation
transaction_rejected: The submitted transaction does not do what the route needs
invalid_state_transition: The resource cannot move to that state from the one it is in
no_authenticated_consumer: The gateway forwarded no API key identity
insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.
gateway_required: the request did not arrive through APISIX.
No such resource, or it exists and belongs to another consumer. The two are deliberately the same answer: "exists but not yours" is an ownership oracle.
transaction_already_settled: the transaction already settled, or also pays an older, payment intent of any consumer, and one payment settles at most one intent, the oldest it pays; this intent is not paid by it. idempotency_conflict: the hash is already recorded on another of your intents. operation_in_flight: the status changed under this request; re-read the intent and retry.
Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.
The provider named in x-cosmos-upstream refused the request (provider_error) or could not be reached at all (provider_unavailable). Nothing was charged; retry is safe with the same Idempotency-Key.
provider_unavailable: the provider in x-cosmos-upstream is down or unreachable; the message names it. Retry.
misconfigured: this deployment is missing configuration the route needs (a provider instance, a fee wallet, the plan header the gateway must forward). Retrying will not help; it is an operator problem.
The provider in x-cosmos-upstream did not answer in time. Whether it acted on the request is unknown. Retry with the same Idempotency-Key, never with a fresh one.
curl -X POST 'https://api.cosmospay.lat/cosmos-api/v1/payment-intents/string/validate' \ -H 'Content-Type: application/json' \ -d '{ "txHash": "3389e9f0d6b3e3f1c2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9"}'{ "valid": true, "status": "SUCCEEDED", "reason": null, "paymentIntent": { "id": "clx9z8a1b0000abcd1234efgh", "kind": "TX", "status": "PENDING", "chain": "stellar", "network": "testnet", "source": "Greally…56charpublickey", "destination": "GASMERCHANT…56charpublickey", "amount": "25.5", "asset": "native", "assetIssuer": null, "memo": "123456789", "chainReference": null, "networkFee": null, "merchantFee": { "bps": 150, "fixed": "0.25", "amount": "1.75", "asset": "XLM", "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R", "paidBy": "recipient" }, "msg": null, "callback": null, "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=", "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…", "qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…", "txHash": null, "reference": null, "checkoutTheme": "classic", "expiresAt": "2026-06-21T13:34:56.000Z", "checkoutSeenAt": "2026-06-21T12:35:10.000Z", "checkoutWalletAt": null, "checkoutWalletClosedAt": null, "checkoutSentAt": null, "createdAt": "2026-06-21T12:34:56.000Z", "updatedAt": "2026-06-21T12:34:56.000Z" }}