# Payment Updates

## Event Types

| Event | Fired when |
| --- | --- |
| `payment.created` | A payment has been created in Tesser's system |
| `payment.quote_created` | Route planning is complete; execution steps are created with exchange rate info |
| `payment.balance_updated` | Balance check result is available (`reserved` or `awaiting_funds`) |
| `payment.risk_updated` | Risk status has changed. See [Risk Statuses and Webhooks](/overviews/wallet-risk-screening#risk-statuses-and-webhooks) for the six `risk_status` values and what each one means |
| `payment.updated` | General notification that a field on the payment has been updated. |
| `payment.expired` | The payment reached its expiration date-time and is no longer actively processing |

For a detailed breakdown of what each event means in the context of a payout, see [Funds Movement Lifecycle and Data Model](/overviews/funds-movement-lifecycle-and-data-model#lifecycle-phases).

## Step Events

Once steps are created (`payment.quote_created`), individual step lifecycle events fire as each step progresses:

| Event | Fired when |
| --- | --- |
| `step.signature_requested` | Tesser has prepared an unsigned transaction and is waiting for your signature. The payload carries it as `unsigned_transaction` |
| `step.signed` | Step has been cryptographically signed |
| `step.submitted` | Step has been submitted for execution |
| `step.confirmed` | Step execution is confirmed on-chain or by the partner |
| `step.completed` | Step finished successfully |
| `step.failed` | Step encountered an error and could not complete |
| `step.updated` | General notification that a field on the step has been updated |

The `data.object` for Payment step events is a [PaymentStep](/api/~schemas#payment-step) resource.

`step.signature_requested` and `step.signed` fire only for steps your organization signs — on-chain steps out of a self-custodial wallet, where `provider_key` is `turnkey`. Steps executed by a custodian or liquidity provider go straight to `step.submitted`. To sign, see [Sign a Wallet Step](/how-tos/sign-a-wallet-step) and [Payout Step Signing](/how-tos/send-a-stablecoin-payout/create-a-payout-from-a-wallet#payout-step-signing-stepsignature_requested).

## Expiration

When a payment reaches `expires_at` before completing, its unfinished steps are resolved and two kinds of event fire:

- `step.failed`, one per step still in `created` or `signature_requested` — the only two statuses expiration fails. Each carries `failed_at` and a `status_reasons` entry with `error_code` [`transfers-9204`](/overviews/errors#transfers) ("The transfer expired before it could be executed"). A step that has reached `signed`, `submitted`, or `confirmed` is in flight on-chain, so expiration leaves it to resolve on its own outcome instead of failing it.
- `payment.expired`, carrying the final state of the payment.

No `payment.updated` follows `payment.expired` — the expiration event itself carries the final top-level values, including whatever the `actual` overlay settled to. Steps never emit an event of their own for expiration; it is a property of the payment, and a failed step's outcome surfaces as `step.failed`.

For how the payment's fields look at expiration, see [Expiration](/overviews/funds-movement-lifecycle-and-data-model#expiration).

## Inbound Payments

The events above describe an outbound payout. Inbound payments — funds arriving at one of your managed wallets from an external sender — use the same event types, with these differences:

- **No planning events.** There is no quote and no `PATCH`, so `payment.quote_created` never fires. `payment.created` arrives with the `estimated` overlay already populated from the observed on-chain transaction.
- **No signing events.** The external sender signed and broadcast the transaction, so `step.signature_requested` and `step.signed` never fire.
- **One step.** The payment has exactly one `transfer` step, created in `confirmed` status, which moves to `completed` when the block finalizes.
- **Risk screening targets the sender and does not gate the credit.** `payment.risk_updated` reports the screening outcome for the sending wallet. It runs in parallel with on-chain finalization, so it can arrive before or after `step.completed`, and the receiving wallet's available balance updates on finalization regardless of the outcome.

For the full inbound event sequence and payloads at each stage, see [Receive an Inbound Payment to a Wallet](/how-tos/receive-an-inbound-payment-to-a-wallet).

## Payload

The `data.object` for each top-level Payment event contains the full payment resource, including its steps. See [General](./general#example-payloads) for the envelope shape and an example payload, and the [Payment schema](/api/~schemas#payment) for the full field reference.

Three arrays on the payment carry compliance output. They are populated by the time `payment.risk_updated` fires and are repeated on every later payment event:

| Field | Carries | Reference |
| --- | --- | --- |
| `risk_status_reasons[]` | The findings behind the current `risk_status`, each marked decisive or not | [Reading risk_status_reasons[]](/overviews/wallet-risk-screening#reading-risk_status_reasons) |
| `participants[]` | The parties Tesser identified in the flow of funds, each with the record it was reconciled to and the reconciliation outcome | [Payment Participants](/overviews/payment-participants) |
| `provider_metadata[]` | The raw wallet screening and Travel Rule responses the decision was based on | [Raw Screening Data](/overviews/wallet-risk-screening#raw-screening-data) |

## Key Status Fields

For details on how `risk_status` and `balance_status` evolve through a payout, see [Risk Statuses](/overviews/funds-movement-lifecycle-and-data-model#risk-statuses) and [Balance Statuses](/overviews/funds-movement-lifecycle-and-data-model#balance-statuses).
