> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sapiom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Sapiom Pay is for platforms whose agent shops for many end users. Each end user is a buyer with their own Sapiom key and saved cards.
> Use the buyer's key for every call made on that buyer's behalf. Never use one buyer's key for another user, and never give the agent the platform key.
> Agents call the hosted MCP tools at https://api.sapiom.ai/v1/mcp. Backends call the REST API at https://api.sapiom.ai/v1. Both take the key in an x-api-key header.
> Never ask a buyer for a card number, expiry date or CVV in chat. Buyers enter card details only on Sapiom's hosted pages.
> Follow the nextAction in each transaction result. Action links are secrets for the intended buyer only.
> Use one idempotencyKey per transaction. After a timeout, retry with the same key. Never start a new transaction to escape an uncertain outcome.
> Report an order as placed only when order.outcome is confirmed. If it is unknown, stop and hand off to a person.

# Confirm the order and recovery

> Read the transaction until the merchant confirms the order, refresh the checkout when asked, and retry without buying twice.

After checkout submits, keep reading the transaction until `order.outcome` is final. Only `confirmed` means the buyer has an order.

## Read the transaction

```json theme={null}
{
  "name": "sapiom_get_transaction",
  "arguments": {
    "transactionId": "00000000-0000-4000-8000-000000000003",
    "since": "<last version you saw>",
    "waitSeconds": 20
  }
}
```

`waitSeconds` (0 to 22) holds the call open until something changes. `since` is the `version` from your last read. Reading never pays and never contacts the merchant.

| `order.outcome` | Meaning | What to do |
| - | - | - |
| `confirmed` | The merchant completed the checkout. | Tell the buyer their order is placed. |
| `not_confirmed` | No order yet. | Follow `nextAction`. |
| `unknown` | The order may or may not exist. | Keep this transaction and follow `nextAction`. Never buy again. |

## Refresh the checkout

When `nextAction.type` is `reconcile_checkout`, Sapiom needs a fresh look at the merchant's checkout. Your backend calls the refresh route with the buyer's key, then your agent reads the transaction again:

```bash theme={null}
curl --request POST \
  "https://api.sapiom.ai/v1/transactions/$TRANSACTION_ID/ucp/checkout/refresh" \
  -H "x-api-key: $SAPIOM_BUYER_KEY"
```

## Recover without buying twice

| Situation | Do this |
| - | - |
| A request timed out, or `nextAction.type` is `resend_request` | Send the same request with the same key. |
| You have a `transactionId` but the outcome is uncertain | Keep reading and refreshing that transaction. Never start another. |
| `idempotency_conflict` | That key belongs to a different request. Check the original merchant, checkout and card. |
| An error before the merchant opened checkout | Follow the error's `nextStep`. Some fixes need a corrected request and a new key. |
| Browser Pay reported `refused`, `failed` or `relayed_unfulfilled` | Keep reading and refreshing the same transaction. |
| An update or cancel timed out | Stop. Your team reconciles it with the merchant, using the original key. |

Error formats and codes are in [Errors](https://docs.sapiom.ai/api-reference/errors.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.