> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.thepennyinc.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.thepennyinc.com/_mcp/server.

# Simulation Scenarios

Every simulated transaction starts with one creation call and, optionally, moves through its lifecycle via `POST /transaction/update`. Which creation call you use depends on what you're simulating.

## Creating a transaction

Each simulated transaction kind has its own creation endpoint:

| Endpoint                    | Simulates                                                                      |
| --------------------------- | ------------------------------------------------------------------------------ |
| `POST /transaction/card`    | A card purchase, funded from the card's Capital Account.                       |
| `POST /transaction/payment` | A payment between a linked account and a Capital Account, in either direction. |

> **Info**
>
> Neither endpoint simulates card refunds or transfers between two of your own Capital Accounts. `POST /transaction/card` produces an outbound purchase only, and `POST /transaction/payment` exchanges with a linked account only. Use `POST /accounts/capital/transfer` on Penny Banking for transfers.

### Card purchases

`POST /transaction/card` takes these fields:

| Field      | Required | Description                                                                        |
| ---------- | -------- | ---------------------------------------------------------------------------------- |
| `card_id`  | Yes      | The card making the purchase.                                                      |
| `amount`   | Yes      | Decimal string in major units, greater than zero, such as `"25.00"` for \$25.00.   |
| `currency` | Yes      | `USD`.                                                                             |
| `merchant` | Yes      | Where the purchase is made. See the merchant fields below.                         |
| `acquirer` | Yes      | The acquiring bank submitting the purchase: `id` (required) and `name` (optional). |
| `force`    | No       | Defaults to `false`. See below.                                                    |

The `merchant` object:

| Field           | Required | Description                                                                                                                                                                                          |
| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`          | Yes      | The merchant's display name.                                                                                                                                                                         |
| `category_code` | Yes      | The four-digit merchant category code (MCC) as a string, such as `"5411"` for grocery stores. [Merchant rules](/spend-controls/merchant-rules) match on this value.                                  |
| `merchant_id`   | No       | The network's identifier for the merchant. Reuse the same value to simulate repeat purchases at one merchant. When omitted, Penny derives a stable identifier from the merchant's name and location. |
| `city`          | No       | The merchant's city.                                                                                                                                                                                 |
| `zip_code`      | No       | The merchant's postal or ZIP code.                                                                                                                                                                   |
| `country`       | No       | ISO 3166-1 alpha-2 country code, such as `US`. [Geographic rules](/spend-controls/geographic-rules) match on this value.                                                                             |
| `subdivision`   | No       | ISO 3166-2 code of the merchant's state or province, such as `US-NY`. Must belong to `country` when both are sent.                                                                                   |

The `force` flag controls authorization:

* **`force: false` (default)** — runs the purchase through Penny's authorization: account and card eligibility, available funds, spend controls, and any configured live decisioning callback. Penny records its decision (`transaction.request.approved` or `transaction.request.declined`), and the simulator then confirms it the way a card network would (`transaction.approved` or `transaction.declined`). You do not trigger that confirmation step. A decline is still a *successful* simulation response that contains a declined transaction.
* **`force: true`** — bypasses authorization and records the transaction as settled (`transaction.settled`), modeling an offline or store-and-forward capture that arrives with no prior authorization.

See [Simulating a Card Purchase](/simulation/simulating-a-card-purchase) for a worked example.

### Linked account payments

`POST /transaction/payment` takes `linked_account_id`, `capital_account_id`, `amount`, and `currency` (`USD`), all required, plus:

* **`direction`** (default `inbound`) — `inbound` for a payment received from the linked account, `outbound` for a payment sent to it.
* **`settle`** (default `false`) — `true` settles the payment immediately; `false` leaves it approved until you send a `transaction.settled` event with `POST /transaction/update`.

## Transaction events

Once a transaction exists, `POST /transaction/update` advances it with one of four events:

| Event                    | Use                                                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `transaction.settled`    | Partial, repeated, or full settlement. `amount` required and positive.                                                   |
| `transaction.adjustment` | A signed change to the pending amount — negative for a reduction. `amount` required and non-zero.                        |
| `transaction.cancelled`  | Releases the pending hold. `amount` optional — omit it to release the full pending amount.                               |
| `transaction.expired`    | Expires the authorization under Penny's lifecycle rules. `amount` optional — omit it to release the full pending amount. |

An optional `reason` string is recorded on the event for any of these.

> **Info**
>
> Only the four events above are accepted by `POST /transaction/update`. The request and approval events happen automatically when a card transaction is created (see above), and any other event value is rejected with `400`.

Settlement and adjustment amounts are **deltas**, not cumulative totals. Send a second settlement event with its own amount to exercise multi-part settlement. To model a reversal, send a negative `transaction.adjustment`, or a separate payment in the opposite direction.

Penny validates each event against the transaction's current state, as it does for real activity. An event that is not valid from the transaction's current state is rejected with `422`.

## Reading a simulated transaction back

Read a simulated transaction through Penny Banking's `GET /transactions/{transaction_id}` endpoint, or through a transaction list scoped to its card or account. See [Transactions](/banking/transactions).

## Idempotency

`POST /transaction/card`, `POST /transaction/payment`, and `POST /transaction/update` accept an `Idempotency-Key` header. It is optional, but strongly advised. Use a new key for each intended event, and reuse the same key, with the same body, only when retrying that exact event. A request still being processed under the same key returns `409`. See [Retries & Idempotency](/get-started/idempotency).