Corgi BankDocumentation
OpenAPI

Returns and return requests

Money that arrived by wire goes back as a payment return (pacs.004). Money the bank sent can only be asked back, with a return request (camt.056) that the receiver may refuse. The writes on this page are operator actions: they need a staff or service identity, and a customer's token is answered forbidden.

Return a wire the bank received

POST /transfers/wire/{id}/returns returns an inbound wire that is received or unapplied. Any other wire answers payments.wire_not_returnable. The body takes reason_code, operator, and optionally reason and amount.

  • reason_code is an ISO 20022 return reason from the set the bank uses, among them AC03, AC04, AC06, AG01, AM05, CUST, DUPL, FOCR, FRAD, NARR, RR04, TECH and UPAY.
  • amount may be less than the wire: a partial return leaves the remainder returnable. Without it, the whole remainder goes back.
  • The money comes from the customer's account, under a pending_debit hold, when the wire was credited there. It comes from the transit account when the wire was never applied.

The return is a new wire with kind return, direction outbound and original_wire_id. It is queued, sent and settled like any outbound wire. When the returns settled against the original add up to its amount, the original becomes returned.

Ask for a wire back

POST /transfers/wire/{id}/return-requests sends a camt.056 about a wire the bank sent. The wire must be settled, or the answer is payments.transfer_not_settled. reason_code is one of DUPL, FRAD, TECH, UPAY, CUST, AGNT, AM09, CURR or CUTA. The request is stored with its message before it leaves. If the service cannot be reached the call answers payments.rail_unavailable, and a scheduler routine sends the message again until it is acknowledged.

The result is a Wire Return Request. GET /transfers/wire/{id}/return-requests lists the requests on a wire, sent and received.

StatusDirectionMeaning
requestedoutboundSent. The service has not acknowledged it yet.
acknowledgedoutboundThe service acknowledged it (admi.007) and omad is set.
acceptedoutboundThe receiver answered camt.029 CNCL: a return will follow.
rejectedoutboundThe receiver answered RJCR. response_reason_code and response_reason say why.
returnedoutboundThe pacs.004 arrived. return_wire_id names it, the original wire is returned, and the money is back on the account or GL it left.
receivedinboundAnother participant asked for a wire the bank received. It waits for a decision.
decidinginboundAn operator's answer is on its way.
honouredinboundThe bank answered CNCL and sent the return. return_wire_id names it.
refusedinboundThe bank answered RJCR with a reason.
failedbothThe service rejected the request, or the bank's answer to one.

A camt.029 PDCR records the response and leaves the state as it was. An accepted request means a return will follow. The funds are back only at returned.

Decide a request the bank received

A camt.056 about a wire the bank received is recorded with direction inbound and acknowledged to the sender. One that matches no received wire is answered with a message reject. An operator decides it with POST /wire-return-requests/{id}/respond:

  • "decision": "refuse" sends RJCR with a reason_code: LEGL, CUST, AGNT, NOOR, ARDT, AC04, AM04, NOAS or PTNA. CUST is the default.
  • "decision": "honour" sends CNCL and then returns the wire with reason FOCR. If the wire is already returned, the answer is RJCR with ARDT and the request ends refused.

The request is claimed before the answer leaves, so two operators deciding it together send one answer and make one return. A request that is not received answers payments.return_request_not_open.

Apply an unapplied wire

An inbound wire whose beneficiary account number matches no open account is unapplied, and its funds sit on the transit account, GL 2320. POST /transfers/wire/{id}/apply with account_id and operator moves them to an open account and sets the wire received. The wire is claimed first: of two operators applying it to two accounts, one wins and the other is answered conflict. A wire in any other state answers payments.wire_not_applicable. The alternative is to return it.

Events and testing

A request publishes payments.wire_return_request.* with its status as the last part, and the wires on either side publish the events in States and notifications. In the sandbox, POST /simulate/transfers/wire/return plays the receiver returning a wire the bank sent, and POST /simulate/transfers/wire/return-request plays the sender asking for a wire the bank received. The simulated receiver honors every return request the bank sends except one with reason CUST, which it refuses.

to move to open esc to close