Route / developers

Execute a payment

Documentation revision 2026-10-07. Mainnet contract 1.44.0-preview; testnet contract 0.10.7-preview.

Use GET /v1/payments/{id}/next-action to decide what your app should present next. The action table is the shared control flow; provider references define exact payloads. The same response envelope covers NEAR, direct protocol payments, CCTP testnet and supported composed workflows. It identifies the next step, the responsible actor and the existing Route operation to call.

This is an observation of saved state. Reading it does not refresh chain evidence, allocate a deposit, request a signature or submit funds. Every mutation still checks current wallet, policy, fee and receipt evidence. A displayed action may become stale before the user acts.

Save a payment#

Choose an unexpired candidate from Compare routes. Persist your business order, network, quote/candidate IDs and a UUID request key before creating the payment.

Create the draft#

Choose a candidate from the quote and send:

{"mode":"prepare","quoteId":"QUOTE_UUID","candidateId":"EXACT_CANDIDATE_ID"}

POST /payments requires a separate UUID Idempotency-Key. It returns a draft with its id, status, version, saved quote evidence, events and readiness. Quotes with unknown checks may be saved for review; quotes with failed checks are rejected. Expired observations, changed provider settings and changed policies require a new quote. A saved draft can subsequently expose newly expired evidence or changed settings in readiness.blockers.

GET /payments/{id} retrieves that same record. status is currently draft or cancelled. executionEnabled reports whether the selected path is released; readiness.ready remains false for an unsigned draft. POST /payments/{id}/cancel takes { "version": 1 }. Cancellation only cancels a draft before a provider preparation is reserved. Once a preparation exists, cancellation returns 409 PREPARATION_EXISTS: cancelling a database record cannot revoke an allocated deposit address or undo a transfer.

Action table#

action.type Actor Your app's behavior
prepare-payment app Prepare or resume the existing payment with the indicated version. Supply paymentIntent when listed; collect sender, recipient, fee budget and any path-specific fields
request-intent-approval app Request the NEAR wallet intent challenge for the saved preparation
sign-intent wallet Review and sign the exact intent challenge, then confirm that proof. This does not transfer tokens
prepare-transaction app Persist a request key, then create the saved transaction authorization. An allowance transaction may precede the source transfer
sign-transaction wallet Independently review the exact payload and obtain a sign-only transaction signature, then save it for the indicated authorization
submit-transaction app After explicit payment authorization, submit the already saved signed transaction for that authorization
confirm-wallet-broadcast app Recover the hash from the wallet and confirm the reserved action. Never automatically repeat a wallet send
renew-source app NEAR: check an expired NEAR Stellar, Solana or Fogo source against current chain and provider evidence, renew the same deposit, then obtain fresh intent consent and a transaction signature. Mainnet Stellar-source protocol payments (Circle CCTP, LayerZero, Axelar): prove that the expired, never-signed burn or transfer has no receipt, its time bound has passed on a closed ledger and its wallet sequence is unused, then prepare a fresh action at the same sequence (with fresh terms) for a new signature; see Stellar source renewal. If the wallet already broadcast the saved transaction itself, renewal is refused and Route tracks that transaction or records it for review. Both use POST /payments/{id}/transaction/renew with authorizationId and a persisted UUID Idempotency-Key.
renew-mint app Check expiry and unused sequence, then prepare the same customer Stellar mint for a fresh signature. POST /payments/{id}/transaction/renew requires an authorizationId and UUID Idempotency-Key.
renew-approval app Mainnet Stellar CCTP only. Prove that the expired approval has no receipt, its time bound has passed on a closed ledger and its wallet sequence is unused. Then prepare a fresh action at the same sequence (one exact approval, or the burn when permission already covers it) for a new signature. POST /payments/{id}/transaction/renew requires an authorizationId and a persisted UUID Idempotency-Key. No funds move. See approval renewal.
close-payment app Mainnet Stellar-source protocol payments only, when the current expired Stellar action cannot be renewed: a signed, submitted or uncertain burn or transfer that was never included, or an approval or never-signed burn or transfer whose renewal cannot run because execution is paused or the payment's saved policy or provider settings changed. Prove the same expiry and unused sequence, then close the unfunded standalone payment: it becomes cancelled, and its wallet sequence, API-key holds and credit hold are released. POST /payments/{id}/transaction/close requires an authorizationId and a persisted UUID Idempotency-Key. Nothing is sent; a new payment needs a fresh quote. closeEnabled also marks an expired approval or unsigned transfer the app may choose to close instead of renewing. See closing an expired Stellar payment.
refresh-review app Renew a supported review on the same payment/action; inspect the new checks and any renewed intent approval
track app Refresh the existing transfer, respecting backoff. This POST can progress an authorized managed destination mint. Do not sign or create a replacement payment
continue-leg app Read the active child's next-action endpoint and follow that transfer. Preserve the parent and child IDs
advance app Prepare the next composed transfer after the verified intermediate receipt. This can allocate the next provider deposit and needs a saved request key
reconcile app Reconcile a captured provider preparation using the same payment; it does not resend funds
completed none Show verified final delivery and stop the execution loop
refunded none Show verified final refund; do not count this as a delivered payment
cancelled none Close the unused payment. This does not imply a previously submitted transfer was reversed
review-required operator Stop automatic signing/submission, display the message and blockers, and follow the recovery playbook. It includes a transaction reported for any action of the payment that Route has not shown to be that action's own transaction or a recognized cancellation (lastError.reason reported-transaction, unclassified-transaction, unclassified-sender-transaction, equivalent-execution, or a wallet-altered copy): Route then submits, hands off and prepares no action of the payment. For a managed Stellar mint whose destinationExecution.lastError.retryAllowed is true, Route itself re-mints once after lastError.remintAfter if the CCTP message is still unminted; background tracking or /refresh continues it. Never repeat the source transfer

For an advance action, apps can first call previewAdvance and explicitly review the returned bounds without allocating a child. Pass that review to advance, then obtain a separate wallet signature. See continuation recovery.

An app actor identifies responsibility, not permission to run unattended. Preparation can reserve a wallet slot or allocate provider instructions. Submission and composed advancement must remain within the authorization your user or account owner granted. See unattended payments.

Read the snapshot#

GET /v1/payments/PAYMENT_UUID/next-action
Authorization: Bearer YOUR_ROUTE_KEY
Route-Network: testnet

Required scope: payments:read. Use the matching environment key. Testnet requires Route-Network: testnet; omit the header or use mainnet for mainnet. The result is the payment_next_action object directly, without a wrapper.

Field How to use it
schemaVersion Currently 1. Pause automatic execution on an unsupported version
network, paymentId Check they match the saved business order and API environment
activePaymentId The active child transfer for a composed workflow; otherwise the payment itself
flow, adapter Identify the underlying payment family; detailed payloads and evidence remain specific to that family
paymentVersion, preparationVersion Separate concurrency versions. Preserve both; do not interchange them
authorizationId The saved transaction authorization, when one exists
status The payment's normalized paymentState, such as AWAITING_ACTION or REQUIRES_ATTENTION (see payment states); use action.type for the next step. Detailed saved states remain on the payment: draft status, composed workflow.state and testnet status
observedAt, expiresAt Snapshot time and relevant review deadline. Neither reserves liquidity nor proves that signed bytes are unusable after expiry
action.type, action.actor What should happen and whether it belongs to your app, a wallet, an operator, or nobody
action.operation Existing endpoint, method, saved request fields, missing caller input and request-key requirement; null for terminal/operator-only steps
action.payload The exact intent challenge or unsigned transaction to review for wallet steps; otherwise null. This is not an accepted signature
action.walletRequirements Optional initial composed-preparation address fields and their networks. Collect customer-controlled intermediate wallets with ETH for their fees; see the BTC → Base → Stellar example
checks, blockers, tracking Saved evidence in its existing flow-specific shape. An empty array does not establish fresh readiness

Operation paths already begin with /v1. Resolve them against your trusted Route origin, not against /v1 again. Never send credentials to a host supplied by an untrusted object. The SDK below uses explicit methods rather than a generic operation dispatcher.

For initial composed preparation, walletRequirements describes the addresses to collect within paymentIntent. The operation still has requiredInput: ["paymentIntent"], body: {"version": <saved version>} and payload: null. Merge the collected intent fields into the top-level /prepare body; do not send a nested paymentIntent object. This metadata is optional and is not permission to fund or sign.

Keep the three approvals separate#

  1. Spending permission: an on-chain token allowance transaction, only when required: ERC-20 approval on EVM, or native-USDC approval for Stellar-source CCTP. It has its own signature and receipt. EVM approval can continue after canonical block inclusion; Stellar approval requires the exact allowance event in a finalized ledger. Sufficient existing allowance skips this step; on Stellar, that allowance must also stay live through the burn’s expiry. An expired Stellar approval offers renew-approval rather than a review refresh. See Stellar CCTP approval. The actual transfer keeps its normal finality requirements.
  2. Payment intent proof: NEAR's wallet signature of the reviewed payment terms. It is separate from ERC-20 allowance and cannot itself broadcast the funding transaction.
  3. Transaction signature: a signature over the exact saved transaction. Saving it is separate from Route submitting it.

Testnet transaction responses now expose authorizationPrepared. A prepared unsigned action can exist before the signing authorization is persisted. Until authorizationPrepared: true, signingEnabled is false and the next action is to prepare the transaction, not ask the wallet to sign. Read GET /payments/{id}/transaction after a lost creation response to recover that authorization.

Use the JavaScript SDK#

Download these files together into the same server-side directory:

import {createRouteSDK} from './route-sdk.mjs';

const route = createRouteSDK({
  baseUrl: 'https://route.click/v1',
  apiKey: process.env.ROUTE_API_KEY,
  network: 'testnet',
});

const next = await route.getNextAction(savedPaymentId);
switch (next.action.actor) {
  case 'wallet':
    // Present the exact payload for independent review; do not auto-sign.
    showWalletReview(next);
    break;
  case 'operator':
    showRecovery(next.action.message, next.blockers);
    break;
  case 'none':
    showOutcome(next.action.type);
    break;
  case 'app':
    // Dispatch only an explicitly supported, authorized business operation.
    showNextStep(next.action.type, next.action.operation);
    break;
}

savedPaymentId, showWalletReview, showRecovery, showOutcome and showNextStep belong to your application. This snippet reads guidance; it is not a payment execution loop. The complete testnet starter demonstrates durable operation storage and restart recovery for its specified CCTP path.

For troubleshooting, await route.getRecovery(savedPaymentId) returns a typed, allowlisted report with the saved outcome, required evidence and reservation observations. It makes one GET and never refreshes or performs a recovery action. INVALID_RECOVERY_REPORT means the response failed version, identity, safe-field or nested-type validation; preserve the existing payment and request review. See the recovery report contract.

The SDK validates the normalized result returned by getNextAction() and throws INVALID_NEXT_ACTION for an unsupported or inconsistent snapshot. Stop automatic execution, retain the payment and read its detailed evidence; do not fall back to guessing an operation. Other mutation responses retain their existing flow-specific envelopes; follow the detailed contract when inspecting those results, or read a fresh next-action snapshot afterwards. The SDK performs no wallet calls, automatic mutations, retries or chain broadcasts on construction or on reads.

Operation SDK method
Prepare payment preparePayment(id, {version, ...intent}, key); mainnet requires a key, testnet uses the payment version without one
Request / confirm NEAR intent requestIntentApproval(id, version, key) / confirmIntentApproval(id, approvalId, signature)
Prepare transaction prepareTransaction(id, {version, approvalId?}, key)
Save exact signature / submit saveSignature(id, authorizationId, signedTransaction) / submit(id, authorizationId)
Renew supported review refreshReview(id, {version?, authorizationId?}, key)
Track / reconcile refresh(id, destinationHash?), or refresh(id, {refundHash}) for a known SwapKit refund / reconcile(id)
Close an unfunded payment closePayment(id, authorizationId, key, cancellationHash?); the hash is required for an expired unsigned EVM action
Preview composition continuation previewAdvance(id)
Advance composition advance(id, key, review?)

paymentIntent in requiredInput means the documented fields for that preparation; it is not a new nested API field. Merge those fields with operation.body without replacing the saved version, approval or authorization IDs. Mainnet NEAR review renewal uses the preparation version and optional authorization ID; protocol approval renewal uses its authorization ID. Use the supplied operation body and the underlying endpoint contract instead of guessing from a status name.

Supply the preparation intent#

paymentIntent is a reminder to supply the fields for the chosen flow, not a nested request property. Preserve operation.body.version and merge the applicable fields:

Flow Initial input and complete contract
NEAR mainnet sender, recipient, refundTo, refundDeadline; minimum received and slippage inherit the saved quote when omitted. NEAR preparation
Direct protocol mainnet sender, recipient. Circle → Stellar customer mode also needs destinationFeePayer and destinationFeeBudget in XLM; managed mode uses Route's configured sponsorship. Protocol preparation
CCTP testnet sender, recipient, maxFee in test USDC and destination execution mode; customer mode needs its Stellar fee payer. Later actions reuse the saved intent. Testnet lifecycle
Composed mainnet Original sender, final recipient and customer-controlled intermediate wallet, with the path's minimum/slippage/refund terms. Resume with the original saved intent and request identity. Composed preparation

Check wallet compatibility early#

The SDK also exports the pure checkWalletCompatibility helper. It checks your declared account type and capabilities; it performs no wallet or network calls and cannot prove that an extension will sign a real action.

import {checkWalletCompatibility} from './route-sdk.mjs';

const result = checkWalletCompatibility({
  family: 'evm',
  flow: 'protocol',
  accountType: 'eoa',
  capabilities: {signOnly: true, evmLegacyTransaction: true},
});
// result.status: compatible | unsupported | unknown
// result.evidence: declared-capabilities-only

Populate capabilities from your reviewed wallet integration; do not hard-code true merely because an account connected. Missing capability information returns unknown. NEAR additionally needs the matching wallet intent proof capability. Inspect requirements, reasons and nextStep, and read the wallet compatibility matrix. EVM wallets that sign and send use the explicit handoff below.

EVM wallet submission#

Choose one submission mode for each saved action. The default is sign-only → saveSignature → submit, where Route broadcasts. Alternatively, a supported EVM wallet can submit the action and your backend reports its hash. This works for NEAR EVM deposits, Circle/Allbridge/LayerZero/Axelar EVM actions and CCTP Ethereum Sepolia actions. Quote-only adapters gain no execution coverage from this option.

  1. Prepare the payment and transaction as usual. NEAR still requires its separate signed intent approval. Read the saved transaction and require walletBroadcastAvailable: true.
  2. Before opening the wallet, call POST /payments/{id}/transaction/broadcast with {"authorizationId":"SAVED_ACTION_ID"}. Persist the response and your intent to open the wallet. The handoff reserves this action for wallet submission, reruns readiness and owner limits, and sends nothing to the network. Retrying this API request returns the same handoff. Once review evidence for any action of this payment is on record (a wallet-altered copy of a call, see step 4, the same payment sent or queued at another nonce, any other transaction reported for it that is neither the action's saved transaction nor a recognized cancellation, whoever signed it, or a reported hash Route could not read yet, from any recovery, confirmation, cancellation or close request), a new handoff returns 409 WALLET_TRANSACTION_REVIEW_REQUIRED with that evidence in error.details before any network read: it reserves nothing and returns no params. An existing handoff is kept and replayed, and nothing is sent, but the response no longer presents the call to send: walletBroadcast.method is null, params is empty and notice asks for review. The saved transaction then reports walletBroadcastAvailable, signingEnabled and submissionEnabled as false; mainnet protocol actions and GET NEAR transaction add actionBlocker.code: "WALLET_TRANSACTION_REVIEW_REQUIRED". Do not open the wallet; review the recorded hash. While a recovery, cancellation or close check for the action is still reading the network, a new handoff returns 409 WALLET_EVIDENCE_CHECK_IN_PROGRESS with details.retryable: true; retry after that request returns. An altered spending approval moves no funds: its handoff is not refused and keeps its params, but Route never submits its saved signature. Any other recorded transaction refuses an approval's handoff too.
  3. With explicit user approval, the app calls its wallet's eth_sendTransaction using walletBroadcast.params. Never open the wallet when params is empty. Verify the connected account/network first. Pass the supplied fields unchanged, including type: "0x0", nonce, gas and gasPrice. If the wallet lowers the gas limit, Route can recognize that broadcast within the original gas ceiling. The gas price, sender, chain, nonce, recipient, value and calldata must still match exactly. Increased gas limits, fee-price editing, nonce rewriting, EIP-1559 conversion and smart-account wrapping are unsupported: Route never attaches such a transaction to the payment (see step 4).
  4. Persist the returned hash immediately. Call POST /payments/{id}/transaction/broadcast-confirm with {"authorizationId":"SAVED_ACTION_ID","transactionHash":"0x..."}. Route checks the transaction's cryptographic signature, network, sender, nonce, amount, destination, calldata and fees. A missing RPC transaction returns 409 WALLET_TRANSACTION_NOT_FOUND: retry confirmation with the same hash, never the wallet send. Route records every reported hash for the payment before it checks it, so until a retry verifies it the payment reads review-required; the wallet's exact original clears that record when it registers. If the wallet changed the nonce, fees or transaction type but kept the exact payment call (sender, contract, calldata, value and chain), confirmation returns 409 WALLET_TRANSACTION_REVIEW_REQUIRED. Its error.details is the recorded evidence: transactionHash, the saved nonce, observedNonce, observedType, observed gas and fee fields, checkedAt and automaticAttachmentAllowed: false. Route keeps the evidence permanently and as the action's lastError, never attaches it, and keeps the saved nonce and every reservation. paymentState becomes REQUIRES_ATTENTION, next-action returns review-required, and mainnet emits payment.requires_attention. For a burn or transfer, that transaction may have moved the funds: a cancellation can no longer close the payment, and confirming the exact original later does not clear the review. An altered spending approval moves no funds; it is flagged the same way, but a finalized cancellation of its saved nonce can still close an otherwise unfunded payment. Do not send replacement funds; review the recorded hash. Other WALLET_TRANSACTION_MISMATCH or WALLET_TRANSACTION_CONFLICT responses also require reconciliation, never a new send.
  5. Read next-action and continue normal receipt tracking. Spending approval still needs one successful canonical inclusion before the next action. Funding and destination settlement retain their existing finality checks.

The SDK exposes beginWalletBroadcast(paymentId, authorizationId) and confirmWalletBroadcast(paymentId, authorizationId, transactionHash). These are backend API methods; neither connects to a wallet nor requests a signature. For checkWalletCompatibility, set submissionMode: "wallet" and explicitly declare evmSignAndSend and evmLegacyTransaction; NEAR also needs evmTypedDataV4.

After the handoff, /transaction/signature, /execute and review renewal are disabled for that action. Until confirmation, its state is submission-unknown. With no recorded review evidence, the normalized next action is confirm-wallet-broadcast. Once a hash is recorded as reported-transaction, next-action returns review-required with no automatic operation. Retry recovery with the same authorizationId and transactionHash used in the original report: payment-wide evidence may come from an earlier action, and a pending cancellation must be checked through recovery rather than payment confirmation. This means the wallet may have submitted; Route has not. API timeouts, wallet rejection, closing the tab or review expiry do not release the nonce or payment/credit holds. Recover the existing hash from wallet activity and confirm it. Use recoverWalletBroadcast(paymentId, authorizationId, transactionHash?) to check the saved nonce and recover an included original transaction. A verified finalized cancellation can close an unfunded standalone payment through cancelWalletBroadcast; see wallet handoff recovery. For a supported composed first source action, verified cancellation closes the unfunded parent and releases unused payment holds; see first-transfer recovery. For a supported composed intermediate action, the same endpoints can close only that cancelled attempt; then review continuation on the parent as described in intermediate cancellation recovery. For supported standalone payments whose signature is already saved, including backend signing, see signed-source cancellation. Never create a replacement payment while the outcome remains uncertain.

Hash confirmation remains available after the review expires, API-key rotation or execution pause, provided the current key has access to the payment. This supports reconciliation of an existing send; it does not extend permission to make a late send. A verified hash records submission, not recipient delivery. Credits and processed USD totals retain their normal verified-outcome rules.

Recovery, versions and request keys#

Persist the order, environment, payment ID, active child ID, both versions, authorization ID, operation body and request key before mutating. The snapshot does not replace that durable record.

  • Use operation.body.version as supplied. Mainnet POST /prepare uses paymentVersion; mainnet POST /transaction and NEAR intent approval use preparationVersion. Testnet preparation and transaction creation both use paymentVersion. They are not interchangeable counters.
  • When idempotencyKeyRequired is true, save a new UUID for a genuinely new operation. Reuse that key and the identical body if its response is lost. A fresh snapshot does not permit changing an in-flight operation's body under its old key.
  • Signature acceptance and execute bind to an existing authorization. Preserve the exact signed bytes privately. A calculated sourceHash does not prove broadcast.
  • submitting, submitted and submission-unknown require tracking the same transfer. Do not interpret review expiry as permission to create another deposit or broadcast from the wallet.
  • On VERSION_CONFLICT, reread payment state and recover existing progress. On 401/403, correct key access without replacing the payment. Honor Retry-After on 429; use bounded 15/30/60-second polling with jitter when tracking. Unknown actions or schemas require a pause.

Use the recovery playbook for lost responses, failed readiness checks, expired signatures and operator escalation. Garden is paused: new quotes and execution are unavailable, including Garden-backed SwapKit paths. SwapKit executes supported simple EVM and native Bitcoin deposits; consult the candidate’s exact execution coverage. Testnet remains the documented CCTP path. Auto-route selects among policy-compatible paths and uses its separate 4× pricing; it does not authorize wallet signatures or turn this snapshot into an autonomous payer.

Approval is specific to the selected route#

An EVM token allowance belongs to a particular source chain, token contract, owner wallet and spender contract. It must cover the required amount. There is no blanket “wallet approved for Route” state. Changing the route, token, sender, chain or amount can change the required allowance. See the ERC-20 allowance specification.

Use the exact approval action returned by Route. Do not guess the spender, use a destination address as the spender, or approve every adapter in advance. Route checks the current allowance, skips unnecessary approvals and requests the exact required amount. If an insufficient nonzero allowance needs resetting, approval-reset and approval are separate transactions with separate signatures and confirmation waits. Route does not request unlimited approval.

The source wallet also needs enough native currency for approval and transfer fees. An approval grants spending permission; it does not send the cross-chain payment or prove recipient delivery. It still costs network fees.

Confirmation and reorganizations#

Across every supported EVM chain, for mainnet approval and approval-reset, canContinue: true means the verified permission transaction is usable for requesting the next action. It is independent of receipt.finalized. The preparation returns nextAction: "prepare-transaction". Do not use the action's submitted state or a wallet's hash alone as the continuation signal.

Route rechecks unfinalized prerequisite approvals before building the next action, saving its signature and submitting it. It also rechecks the current allowance and simulates the exact action. If an approval disappears from the canonical chain, continuation is blocked with APPROVAL_CONFIRMATION_PENDING; call /refresh and track the existing hash. An approval event mismatch or unavailable network verification also blocks progress. Route does not automatically replace or resend transactions. If the transfer was already submitted, track that transfer; do not initiate another payment.

Approval gas is included in subsequent fee checks even before finality. This rule changes only token permissions: burn, bridge and destination-settlement verification retain their finality requirements. Wallets with sufficient existing allowance skip approval as before.

Not every transfer needs a token allowance#

NEAR's current EVM deposit builder transfers tokens directly from the sender to the provider deposit address; it does not use an ERC-20 spender allowance. Its wallet intent approval is an off-chain confirmation of payment details, followed by a separate transaction signature. Do not add a token-approval transaction to that flow.

Native-asset transfers and the supported Stellar, Bitcoin and Solana-family flows have their own wallet checks and signatures. Do not impose an EVM allowance requirement on them. Stellar recipients may need the exact asset trustline; source wallets still need sufficient asset balance and network fees. For composed routes, repeat readiness checks for each leg, including the intermediate wallet's approval and gas needs.

Hosted CCTP testnet uses a different continuation endpoint: after approval_confirmed, call /prepare with the current payment version for the burn, then request its transaction. Follow the testnet lifecycle; do not substitute the mainnet preparation-version sequence.

Mainnet protocol sequence#

After an approval returns canContinue: true, use the current preparation version and a new saved action key to request the next protocol transaction. Route refreshes terms before the transfer review. Protocol execution contains the exact request/sign/submit sequence.

Expiry and pending transactions#

Honor the action's current expiresAt, signing and submission flags. Submitted or uncertain transactions keep their existing payment and hash; review expiry never authorizes another deposit. Use Track and recover for renewal, polling and unresolved outcomes.

Saved SwapKit quote review#

A review-required response can identify a saved provider allocation with changed terms. NEAR EVM- or Aptos-source payments with quoteReviewAvailable: true support explicit review of the saved allocation. Acceptance sets a new standalone minimum and cost ceiling, or retains the original composed final minimum, before separate wallet consent.

For SwapKit: Read GET /payments/{id}/quote-review, show the revised receipt and fees, and obtain explicit payer acceptance before posting the review hash and minimum. This is an interactive decision, not an automatic retry. After acceptance, next-action can return prepare-payment for the same channel while its deadline remains valid. A validated SwapKit channel whose deposit instructions were not attached, for example after a failed wallet check, also returns prepare-payment with the same wallets until providerAllocation.expiresAt. After that time it returns review-required.

Expired Stellar source actions#

renew-source also applies to an eligible unsigned Stellar protocol burn or transfer. A signed expired Stellar source may instead offer close-payment, an explicit application action at POST /payments/{id}/transaction/close with authorizationId and a UUID idempotency key. It verifies non-execution and closes the unfunded standalone payment, preserving evidence and releasing unused holds. Never infer permission from expiry alone. See Stellar protocol recovery.

Links from earlier guides

This section is now in Execute.

This section is now in Execute.

This section is now in Track and recover.