Inbound Wires

Decide and post wires received from the Fed, and return them

Overview

When you process a file holding a credit transfer (pacs.008, or pacs.009), Twisp decides which account to credit and posts the wire as a WIRE_INBOUND workflow execution. The execution id is the message id of the file's message.

            decision                    RETURN
(received) ─────────> SETTLE ─────────────────> RETURN
     │                  ▲                         ▲
     │ decision         │ SETTLE                  │ RETURN
     └──────────> PENDING ───────────────────────┘

A Fedwire credit is final when it arrives, so a wire settles at once. There is no settlement date to wait for.

Decisioning

The configuration's decisioning mode decides each wire:

ModeDecision
WEBHOOKYour endpoint answers the create webhook
PENDINGThe wire is credited to the pending account as PENDING
ACCOUNT_LOOKUPTwisp evaluates the src to an externalId and settles the wire to that account. When no account has the externalId, the source fails, or the account is one of the configuration's accounts, the wire is returned with AC03.

Every mode has the webhook contract: it is asked with the webhook request below and answers with a webhook response.

Webhook Request

Twisp POSTs to the configured endpoint, signed with x-twisp-signature like the ACH webhooks:

{
  "workflowTask": "CREATE",
  "workflowName": "WIRE.INBOUND",
  "executionId": "0b9e44a2-6d0c-5b3e-9f1a-2c3d4e5f6a7b",
  "configurationId": "5d1c6a0e-8b7f-4e2a-9c3d-2e1f0a9b8c7d",
  "fileId": "3f1e2d3c-4b5a-6978-8a9b-0c1d2e3f4a5b",
  "messageId": "0b9e44a2-6d0c-5b3e-9f1a-2c3d4e5f6a7b",
  "messageElement": "FedwireFundsCustomerCreditTransfer",
  "creditTransfer": {
    "msgId": "20261009B1QDRCQR000001",
    "creationTime": "2026-10-09T09:00:00-04:00",
    "settlementDate": "2026-10-09T00:00:00Z",
    "uetr": "8a562c67-ca16-48ba-b074-65581be6f011",
    "endToEndId": "Scenario01EtoEId001",
    "amountCents": 51000074,
    "currency": "USD",
    "localInstrument": "CTRC",
    "debtor": {
      "name": "Corporation A",
      "account": "92315266453",
      "address": { "streetName": "Avenue of the Fountains", "townName": "Phoenix", "country": "US" }
    },
    "creditor": {
      "name": "Corporation B",
      "account": "567876543",
      "address": { "streetName": "Desert View Street", "townName": "Bisbee", "country": "US" }
    },
    "debtorAgent": { "routingNumber": "011104238" },
    "creditorAgent": { "routingNumber": "021040078" },
    "instructingAgent": { "routingNumber": "011104238" },
    "instructedAgent": { "routingNumber": "021040078" },
    "remittance": ["Payment for invoice 4562"]
  }
}

creditTransfer is the normalized message. Its fields:

FieldDescription
msgIdThe sender's IMAD
creationTime, settlementDateMessage creation time and interbank settlement date
uetr, endToEndId, instrIdPayment identifiers
amountCents, currencyThe amount in cents, and USD
localInstrumentSuch as CTRC (customer transfer) or BTRS (bank transfer)
debtor, creditorname, account (accountIBAN is true for an IBAN), address; for a pacs.009, routingNumber or bic
debtorAgent, creditorAgent, instructingAgent, instructedAgentBanks: routingNumber, bic, name, address
intermediaryAgentsBanks between the instructed agent and the creditor agent, in order
remittanceUnstructured remittance lines

Fields with empty values are omitted.

Webhook Response

{
  "action": "SETTLE",
  "accountId": "6b879478-27e0-4fde-9038-ef81b028bb51",
  "metadata": { "note": "matched by account number" }
}
FieldDescription
actionSETTLE, PENDING, RETURN or RETRY
accountIdThe account to credit, for SETTLE and PENDING. It cannot be the configuration's settlement, suspense, exception or pending account.
reasonCode, reasonInfoFor RETURN: an ISO return reason code, such as AC03 or AC04, and free text. The code defaults to NARR.
metadata, entryMetadataMetadata for the transaction and the account entry

RETRY, or a webhook that fails, retries the decision.

Account Lookup

An ACCOUNT_LOOKUP source reads the request's creditTransfer as creditTransfer:

Your externalId issrc
The plain account numbercreditTransfer.creditor.account
A string format'dda:' + creditTransfer.creditor.account
A v5 UUID of routing and account numberuuid.NewSHA1(uuid('<your namespace>'), bytes(creditTransfer.creditorAgent.routingNumber + creditTransfer.creditor.account))

A settled wire records the externalId it found as metadata.accountLookup.externalId.

Posting

DecisionLedger
SETTLEPosts SYS_WIRE_INBOUND_SETTLE_CR to the account
PENDINGPosts SYS_WIRE_INBOUND_PENDING_CR to the account's pending layer
RETURNCredits the suspense account (SYS_WIRE_INBOUND_SETTLE_CR), then returns the wire (SYS_WIRE_INBOUND_RETURN_DR)

If the credit cannot post, for example because a velocity control on the account refuses it or the account is locked, the wire is credited to suspense and returned with NARR and the error code as its reason.

The message's detail records the outcome, such as settle or returned AC03 ACCOUNT NOT FOUND.

Resolving PENDING Wires

Settle or return a pending wire with Mutation.workflow.execute() and code WIRE_INBOUND. The execution id is the message id.

mutation SettlePendingWire {
  workflow {
    execute(
      input: {
        executionId: "0b9e44a2-6d0c-5b3e-9f1a-2c3d4e5f6a7b"
        code: "WIRE_INBOUND"
        task: "SETTLE"
        params: { accountId: "6b879478-27e0-4fde-9038-ef81b028bb51" }
      }
    ) {
      executionId
      output {
        state
      }
    }
  }
}
TaskFromParametersLedger
SETTLEPENDINGaccountId (settles to another account), effective, metadata, entryMetadataVoids the pending credit (SYS_WIRE_INBOUND_PENDING_VOID_DR), posts SYS_WIRE_INBOUND_SETTLE_CR
RETURNPENDINGreasonCode, reasonInfoVoids the pending credit
RETURNSETTLEreasonCode, reasonInfoPosts SYS_WIRE_INBOUND_RETURN_DR to the account the wire settled to

Returns

Every RETURN queues the wire. The next generateFile writes a pacs.004 that returns the full amount to the original sender, with the return's reasonCode and reasonInfo. Without a code, the pacs.004 uses NARR.

Only a wire received as a credit transfer (pacs.008 or pacs.009) can be returned, because its pacs.004 is built from that message. RETURN fails with BAD_REQUEST for any other wire, such as an unmatched return credited to the exception account, and changes nothing.

Duplicates and Unmatched Returns

  • A credit transfer whose UETR an earlier inbound wire already has is recorded as IGNORED and does not post.
  • A pacs.004 that matches none of your outbound wires is posted as an inbound wire to the configuration's exception account. Its message detail reads unmatched return credited to the exception account. It has no credit transfer to send back, so RETURN refuses it with BAD_REQUEST. Resolve the funds with your own transactions.
Previous
Outbound Wires