Transaction Lifecycle

How a Treasury transaction moves from creation to settlement, and how to track it.

Every Treasury money movement, a payout, a collection, or a transfer, is a transaction that follows the same lifecycle. This is the shared reference for the statuses, the flow, and how to track a transaction. The method pages (Pay via ACH, Collect via ACH, Transfer funds, and the wire and BOOK pages) link here instead of repeating it.

The flow

You submit a transaction, we validate it, and it moves through processing to a terminal state. You're notified of each change by webhook.

sequenceDiagram
    participant You as Your application
    participant PCE
    participant Rail as Rail / counterparty
    You->>PCE: POST /transaction (unique externalId)
    PCE->>PCE: Validate request
    PCE-->>You: status SCHEDULED
    PCE->>Rail: Process over the method's rail, PROCESSING
    Rail-->>PCE: Settlement result
    PCE-->>You: Webhook, COMPLETED (or PENDING / FAILED / CANCELLED)

How long the middle takes depends on the method. Every Treasury money movement follows this lifecycle. Pick a method below for its scenarios, fields, and rail-specific detail.

Payment methods

Pay out, to a third party

MethodSettlement
Pay via ACHNext business day, or same day before cutoff
Pay via Wire (Domestic)Same day
Pay via International WireVaries by destination
Pay via CheckOn mail delivery
Pay via BOOKInstant, to another account inside the system

Collect / fund in

MethodSettlement
Collect via ACHNext business day; funds held for the good-funds period
Pull Funds via WireSame day

Transfer your own money

MethodSettlement
Transfer fundsBy rail, instant (BOOK), next business day (ACH), or same day (wire)
🚧

PENDING-PUBLISH: settlement timing for Check and International Wire (shown here as generic; verify the specifics).

Statuses

StatusDescriptionTypical reasons
SCHEDULEDCreated and queued.ON_USER_REQUEST
PENDINGOn hold, a source/destination account is inactive or blocked, funds are insufficient, or a compliance check is pending.EXTERNAL_ACCOUNT_BLOCKED, EXTERNAL_ACCOUNT_INACTIVE, ACCOUNT_INACTIVE, ACCOUNT_BLOCKED, ACCOUNT_CLOSURE_INITIATED, ACCOUNT_CLOSED, CUSTOMER_SUSPENDED, OFAC_STATUS_NOT_VERIFIED
PROCESSINGPicked up and in transit.PROCESSING_IN_TRANSIT
COMPLETEDFunds settled and credited to the destination (after the good-funds period, for inbound ACH).PROCESSED_BY_SYSTEM, ACH direct collect processed
FAILEDCouldn't be completed, a processing failure, a bank return, or the collection interval lapsed.INSUFFICIENT_FUNDS, OFAC_VERIFICATION_FAILED, EXTERNAL_ACCOUNT_BLOCKED, EXTERNAL_ACCOUNT_INACTIVE, Collect processing interval lapsed, <return-description> (<return-code>)
CANCELLEDCancelled before processing completed.ON_USER_REQUEST, ON_CUSTOMER_REQUEST, INCORRECTLY_CREATED, OTHERS

The exact reasons depend on the method (for example, ACH return codes apply to ACH, not BOOK). For the specific codes and how to resolve each, see Error Codes and Messages.

Good-funds period (inbound ACH)

An ACH debit can be returned by the payer's bank even after it settles, for insufficient funds, a closed account, or an unauthorized debit. To cover that risk, PCE holds inbound funds for a good-funds period (also called the realization interval) before treating them as final.

  • During the window, the transaction stays in PROCESSING.
  • Once the interval passes without a return, funds are realized and the transaction moves to COMPLETED.
  • If the bank returns the debit within the window, or the interval lapses without realization, it moves to FAILED.

Don't treat inbound funds as spendable until the transaction is COMPLETED. This applies to collections and funding pulls; it does not apply to payouts (money leaving) or instant BOOK transfers.

🚧

PENDING-PUBLISH: the exact good-funds / realization interval, and whether it varies by program configuration, rail, or amount.

Track a transaction

Two ways, no polling required:

  1. GET /v1/customer/id/{id}/transaction/id/{id} (or externalId), retrieve the current state.
  2. Webhooks, subscribe to transaction events and react to each status change.

A webhook wraps the transaction resource in payload[], the same fields you'd get from a GET. ACH events are transaction.ach.create (on create) and transaction.ach.update (on each status change); wire is transaction.wire.*.

{
  "id": 65817044,
  "eventType": "transaction.ach.update",
  "eventTimeStamp": "06/30/2026 09:40:55",
  "eventId": "0001709618091430044",
  "eventCreated": 1782810724000,
  "payload": [
    {
      "resourceName": "transaction",
      "url": "/v1/customer/id/4225975/transaction/id/230492021",
      "id": 230492021,
      "externalId": "your-ref-001",
      "status": "COMPLETED",
      "statusDate": "06/30/2026 09:40:55",
      "amount": 300,
      "method": "ACH",
      "statusReason": "Processed By System"
    }
  ]
}

For the full event catalog and payloads, see Webhook Event Types. For every transaction, store the returned id and your externalId, you'll need them for tracking, reconciliation, and follow-up actions.

🚧

PENDING-PUBLISH: whether inbound ACH (collections/pulls) emit transaction.ach.* or a debit-specific event such as externaltransaction.ach.debit.*.

Idempotency

For Treasury, PCE uses the request-body externalId as the idempotency key; there's no separate header. Send a unique externalId per transaction; retrying with the same value never creates a duplicate.

See also

.readme-logo { display: none !important; }