Corgi BankDocumentation
OpenAPI

States and notifications

A wire moves through the states below, and its changes of state are published as events. This page lists the states as the code writes them and says which events to act on.

The states

The state is the status of the Wire Transfer object. reason says in words why a wire is held, queued, failed or unapplied.

StatusDirectionMeaning
pendingoutboundRecorded with its funds on hold, about to be sent.
held_for_reviewbothWaiting for a person. Outbound: screening was not clear, the fraud rules held it, the account refused the debit as the wire was about to leave, or it is a bank transfer waiting for its second operator. Inbound: the screening of a party on the message was not clear, and the funds wait on the transit account.
queuedoutboundFedwire is closed to customer transfers. queued_until is the next opening and value_date the cycle date it will settle on. The hold stays.
sendingoutboundClaimed for sending. A wire stays here, with the reason, when the service gave no answer.
sentoutboundThe service answered PDNG. Its final status report settles or fails the wire.
settledoutboundThe service answered ACSC. The debit is posted, the hold released and omad set.
failedoutboundThe service rejected the message. The hold is released.
rejectedoutboundRefused at review. The hold is released.
receivedinboundCredited to the beneficiary's account. A bank transfer is booked to the transit account instead, until operations classify it.
unappliedinboundNo open account has the beneficiary account number, or a return matches no wire the bank sent. The funds wait on the transit account until the wire is applied or returned.
applyinginboundClaimed by an operator who is applying it.
blockedinboundRefused at review. The funds stay on the transit account.
returnedbothThe wire has gone back: a return arrived for a wire the bank sent, or the returns the bank sent add up to the wire it received.

Claim before send

A wire is claimed before its message is built. The claim moves it to sending in one statement, and only from pending, queued or held_for_review, so two approvers, or an approver and the queue release, produce one message. The caller that loses is answered 409 conflict with the state it found. A wire under an open fraud review cannot be claimed by anyone: the answer is payments.fraud_review_open until that review is decided. The claim itself publishes no event.

When the service does not answer

If the send fails in transit, the bank cannot know whether the message arrived. The wire stays sending with its IMAD and its message, the hold stays, and the create call answers 503 payments.rail_unavailable. A scheduler routine sends the same message again once it has gone two minutes unanswered. The resend carries the same IMAD, and the service answers it with the original outcome, so the wire settles once. Retry the request with the same idempotency key, or read the wire. Do not send a second wire under a new key.

Review

POST /transfers/wire/{id}/review takes decision (approve or reject) and actor. The reviewer recorded is the token's verified subject. The Idempotency-Key is optional here: with one, a retry replays the recorded decision. A wire that is not held answers payments.not_reviewable.

  • Outbound, approve: the wire is claimed and sent. A customer wire that screening held is judged by the fraud rules first and can stay held. A bank transfer approved while Fedwire is closed is queued.
  • Outbound, reject: the wire is rejected and the hold released.
  • Inbound, approve: the funds move from the transit account to the beneficiary's account and the wire is received. With no account to credit it becomes unapplied.
  • Inbound, reject: the wire is blocked.

Events

Each state is an event type: payments.wire.pending, .queued, .held_for_review, .rejected, .sending, .sent, .settled, .failed, .received, .unapplied, .applying, .blocked and .returned. The event is written in the same database transaction as the state, and its data is the wire. Subscribe a webhook endpoint to payments.wire.*, or read GET /events. Events and webhooks covers delivery.

  • Sending: payments.wire.settled means the debit is posted. payments.wire.failed and payments.wire.rejected mean the funds are back on the account. payments.wire.held_for_review and payments.wire.queued mean nothing has left yet.
  • Receiving: payments.wire.received with an account_id is a credit to that account. payments.wire.unapplied and payments.wire.held_for_review need an operator.
  • payments.wire.returned arrives on the original wire. The return is a wire of its own, with kind return and original_wire_id.
  • A state can be published more than once: failed and rejected are written again when the hold comes off. Treat a repeated state as already handled.

Return requests publish their own types, payments.wire_return_request.*. See Returns and return requests.

Testing

The simulated service reads the beneficiary's name. A name that contains REJECTWIRE is rejected, and the wire ends failed. A name that contains PENDINGWIRE is answered PDNG, which leaves the wire sent.

to move to open esc to close