Outbound Wires
Send wires with the WIRE_OUTBOUND workflow and settle them on the Fed's reply
Overview
An outbound wire is a WIRE_OUTBOUND workflow execution. You create it, Twisp generates its pacs.008, and the Fed's reply settles or rejects it.
generateFile pacs.002 ACSC pacs.004
CREATE ───────────────> SUBMIT ─────────────> SETTLE ─────────> RETURN
│ │
│ CANCEL │ pacs.002 RJCT / admi.002
▼ ▼
CANCEL REJECT (also from CREATE)
The funds are held in the customer account's pending layer from CREATE until the wire settles or is released.
Create a Wire
Execute CREATE with Mutation.workflow.execute() and code WIRE_OUTBOUND:
mutation SendWire {
workflow {
execute(
input: {
executionId: "7c1d4e2a-0f3b-4c5d-8e9f-1a2b3c4d5e6f"
code: "WIRE_OUTBOUND"
task: "CREATE"
params: {
configId: "5d1c6a0e-8b7f-4e2a-9c3d-2e1f0a9b8c7d"
accountId: "6b879478-27e0-4fde-9038-ef81b028bb51"
amount: "25000.00"
debtorName: "Jane Debtor"
debtorAccount: "123456789"
debtorAddress: "{\"streetName\":\"Main St\",\"buildingNumber\":\"1\",\"townName\":\"Springfield\",\"countrySubDivision\":\"IL\",\"postCode\":\"62701\",\"country\":\"US\"}"
creditorName: "John Creditor"
creditorAccount: "987654321"
creditorRoutingNumber: "021000021"
remittance: "Invoice 42"
}
}
) {
executionId
output {
state
}
}
}
}
CREATE Parameters
| Parameter | Required | Description |
|---|---|---|
configId | Yes | The wire configuration. |
accountId | Yes | The customer account to debit. It cannot be one of the configuration's accounts. |
amount | Yes | Decimal dollars, at most two fraction digits, from 0.01 to 9999999999.99. |
debtorName | Yes | The originator's name. |
debtorAccount | No | The originator's account number. |
debtorAddress | No | The originator's address, as JSON (see below). |
creditorName | Yes | The beneficiary's name. |
creditorAccount | Yes | The beneficiary's account number, up to 34 characters. |
creditorAddress | No | The beneficiary's address, as JSON. |
creditorRoutingNumber | Yes | The beneficiary bank's ABA routing number. |
creditorAgentName | No | The beneficiary bank's name, up to 140 characters. |
creditorAgentAddress | No | The beneficiary bank's address, as JSON. |
remittance | No | Remittance information, up to 140 characters. |
endToEndId | No | Your reference, up to 35 characters. Defaults to the UETR without hyphens. |
instructionId | No | Your instruction id (InstrId), up to 35 characters. |
effective | No | Effective date of the transactions. Defaults to the Fedwire business day. |
metadata, entryMetadata | No | JSON for the transaction and entry metadata. |
The debtor agent's name and address, the charge bearer and the account scheme come from the configuration.
An address is a JSON object with any of streetName, buildingNumber, postCode, townName, countrySubDivision, country (ISO 3166 alpha-2) and lines (up to three unstructured lines of 35 characters).
CREATE:
- Builds the wire's pacs.008 and checks it against the Fed usage guidelines. Every problem with the parameters is returned together as
BAD_REQUEST. - Sets the wire's UETR. It is derived from the execution id, so it is stable, and it is returned in the execution context as
uetr. - Posts
SYS_WIRE_OUTBOUND_PENDING_DR, holding the amount in the customer's pending layer. Velocity controls on the account apply: a control that rejects the posting declines the wire, andCREATEfails. - Queues the wire for the next
generateFile.
Tasks
| Task | From | Parameters | Ledger |
|---|---|---|---|
CREATE | — | See above | Posts SYS_WIRE_OUTBOUND_PENDING_DR |
SUBMIT | CREATE | msgId, messageId | None. Records the generated message. Run by generateFile. |
SETTLE | SUBMIT | effective, metadata, entryMetadata | Voids the hold (SYS_WIRE_OUTBOUND_PENDING_VOID_CR), posts SYS_WIRE_OUTBOUND_SETTLE_DR |
REJECT | CREATE, SUBMIT | reasonCode, reasonInfo | Voids the hold |
CANCEL | CREATE | — | Voids the hold. generateFile skips the wire. |
RETURN | SETTLE | amount, reasonCode, reasonInfo | Posts SYS_WIRE_OUTBOUND_RETURN_CR |
All parameters are optional except where noted for CREATE and SUBMIT. A parameter a task does not accept is BAD_REQUEST. A task that does not follow the wire's current state fails with INVALID_STATE_TRANSITION and changes nothing.
RETURN may return part of the wire: amount defaults to the wire's amount and cannot exceed it. A partial return is recorded in the execution context as returnAmount.
You normally run only CREATE and, before generation, CANCEL. Twisp runs SUBMIT during generation and the other tasks when it processes the Fed's replies.
Replies From the Fed
Process each reply file with Mutation.wire.processFile(). Twisp finds the wire by UETR, or by message id for an admi.002, and runs the task:
| Reply | Matched by | Task |
|---|---|---|
pacs.002 with ACSC or ACCC | OrgnlUETR, then OrgnlMsgId | SETTLE |
pacs.002 with RJCT | OrgnlUETR, then OrgnlMsgId | REJECT, with the status reason (such as E433) as reasonCode |
| pacs.002 with another status | — | Recorded as IGNORED |
| admi.002 | RltdRef/Ref, the rejected message's IMAD | REJECT, with the reject reason |
| pacs.004 | OrgnlUETR, then OrgnlMsgId | RETURN, with the returned amount and reason |
A reply that matches no wire is recorded as IGNORED. The exception is a pacs.004: returned funds have arrived, so a pacs.004 that matches no wire is credited to the configuration's exception account as an inbound wire.
A reply that does not apply to the wire's state, such as a second pacs.002 for a settled wire, is recorded as IGNORED and changes nothing.
Balances
For a $25,000.00 wire from a customer account:
| Step | Customer pending | Customer settled |
|---|---|---|
CREATE | −25,000.00 | 0 |
SUBMIT | −25,000.00 | 0 |
SETTLE | 0 | −25,000.00 |
RETURN of $10,000.00 | 0 | −15,000.00 |
or REJECT / CANCEL instead of SETTLE | 0 | 0 |
Postings after the Fed has acted (SETTLE, REJECT, RETURN) are not blocked by velocity controls.