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

# Reconcile authorization outcomes

> A decision table for the async case — when to commit, cancel, or quarantine.

The hardest part of async spending control is **finality**: knowing whether an external provider actually accepted an action. A local timeout is **not** proof that the provider did nothing. If the provider accepted just before your timeout, releasing the authority can allow two executions.

This guide is a decision table for the async case. It tells you exactly what to do for each possible outcome of an external execution, and when to commit, cancel, or quarantine.

## The rule

> **Commit only after definite acceptance. Cancel only after definite non-acceptance. Reconcile first after an ambiguous result.**

An Attesso authorization is a **reservation**, not proof that execution happened. You must report finality yourself.

## Decision table

| External outcome                                                        | What it means                                     | Action                                                                                                           |
| ----------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **Provider returned success** (charge/booking accepted)                 | Definite acceptance                               | **Commit** with `provider_transaction_reference`                                                                 |
| **Provider returned explicit rejection** (declined, invalid, refused)   | Definite non-acceptance                           | **Cancel** with `reason: EXECUTOR_REJECTED`                                                                      |
| **Provider returned an error before acting** (validation, auth failure) | Definite non-acceptance                           | **Cancel** with `reason: EXECUTION_FAILED`                                                                       |
| **Network error / timeout**                                             | **Ambiguous** — provider may have accepted        | **Reconcile first.** Query the provider by your `external_action_reference`. Do NOT commit or cancel on a guess. |
| **Provider returned success but you lost the response**                 | **Ambiguous** — you don't know if it was accepted | **Reconcile first.** Query the provider.                                                                         |
| **Provider returned an unknown/invalid response**                       | **Ambiguous**                                     | **Reconcile first.** Fail closed — do not execute again.                                                         |
| **You aborted before calling the provider**                             | Definite non-execution                            | **Cancel** with `reason: INTEGRATOR_ABORTED`                                                                     |
| **Security event** (suspected compromise)                               | Definite stop                                     | **Cancel** with `reason: SECURITY_EVENT`                                                                         |

## Reconciliation procedure

When the outcome is ambiguous, do this before deciding:

1. **Query the provider** by your `external_action_reference` (your idempotency key for the PSP call). Stripe: `GET /v1/payment_intents/{id}`. Adyen: `GET /v3/payments/{pspReference}`. Most providers let you look up by your own reference.
2. **Match the result**:
   * Provider shows the action **succeeded** → **Commit**.
   * Provider shows the action **failed/declined** → **Cancel**.
   * Provider shows **no record** of the action → the action never happened → **Cancel** with `execution_disposition: NEVER_BECAME_POSSIBLE`.
   * Provider is **unreachable** or **still processing** → **Quarantine** (below).
3. **Never execute again** while the outcome is ambiguous. The reservation is your guard against double-execution.

## Quarantine

If you cannot determine the outcome (provider unreachable, still processing, or the record is unclear), **do not commit and do not cancel**. Quarantine the authorization:

* Keep the reservation until the provider is reachable or the `execute_before` deadline passes.
* Do not release the authority or retry the action.
* Reconcile again once the provider responds.
* If the deadline passes with no resolution, the reservation expires on its own — but you must still reconcile the provider outcome before treating the action as definitively done or not done.

## Why this matters

* **Double-execution**: if you cancel after a timeout but the provider actually accepted, you release the authority and a retry can execute twice.
* **Stale approvals**: if you commit without provider proof, you record a success that may not have happened.
* **Evidence integrity**: the signed evidence records your `execution_disposition` and the provider reference. An honest reconciliation produces defensible evidence; a guess produces evidence that fails an audit.

## Execution dispositions

When you cancel, you assert how the external capability now stands:

* `NEVER_BECAME_POSSIBLE` — the action could never have executed (e.g. you aborted before calling the provider).
* `NO_LONGER_POSSIBLE` — the action could have executed but no longer can (e.g. the provider rejected it, or the credential is spent).

Choose the disposition that matches the truth. It is part of the signed evidence.
