Connecting a cross-border payment API to an ERP or TMS system is not a UI exercise. The integration pattern you choose determines what happens when a payment fails partway through, how reconciliation events reach the ledger, and whether the finance team can trust the positions their system shows without a manual investigation cycle. There are four integration patterns worth understanding. Each involves different tradeoffs on latency, failure handling, and operational complexity. The right choice depends on your ERP's capabilities, your payment volume, and your tolerance for intraday reconciliation ambiguity.
Pattern 1: Synchronous REST with Immediate Status Response
The simplest pattern. Your ERP calls the payment API, waits for a response, and processes the response synchronously before moving on. This works for low-volume, non-time-critical integrations where a brief blocking call is acceptable.
POST /v1/payments
{
"amount": 250000.00,
"currency": "EUR",
"value_date": "2025-11-14",
"beneficiary": {
"account": "DE89370400440532013000",
"bic": "SSKMDEMMXXX",
"name": "Acme Supplier GmbH"
},
"remittance": "INV-2025-00847",
"end_to_end_id": "ERP-20251114-0093"
}
The API responds with a payment_id and an initial status (accepted or rejected). The accepted status means the instruction has been validated and queued. It does not mean the payment has settled. This distinction is where many integrations go wrong: the ERP marks the payable as paid on receipt of accepted, then the payment fails at the correspondent and no automated process updates the ledger.
Synchronous patterns are appropriate for submission and initial validation. They are not appropriate as the sole mechanism for tracking settlement finality.
Pattern 2: Webhook-Driven Status Updates
The webhook pattern inverts the polling problem. Instead of the ERP asking the API for status, the API pushes status events to an endpoint the ERP exposes. This is the correct pattern for settlement confirmation because settlement finality events are asynchronous by nature.
POST https://your-erp.internal/webhooks/birchhill
{
"event_type": "payment.settled",
"payment_id": "pay_9f4a2b1c",
"end_to_end_id": "ERP-20251114-0093",
"settled_at": "2025-11-14T14:22:05Z",
"settlement_system": "TARGET2",
"settled_amount": 250000.00,
"settled_currency": "EUR"
}
Webhook delivery requires your endpoint to be reachable, respond within a timeout window (typically five seconds), and return HTTP 2xx. Events that receive non-2xx responses are retried with exponential backoff. Your integration must handle idempotency: a payment.settled event may be delivered more than once if the initial delivery is uncertain. The payment_id is the idempotency key.
For ERP integrations, the webhook handler posts the settlement event to a staging queue, and a separate process reconciles the ERP's open payables against settled events. This decouples the webhook ingestion latency from the ERP reconciliation write, which is important because some ERP systems process large reconciliation batches slowly.
Pattern 3: Event Stream (Message Queue) Integration
For higher-volume integrations or environments where the ERP and the payment API are both inside a controlled network boundary, a message queue pattern provides more durability than webhooks. Payment events are published to a queue (AMQP, Kafka, or a managed service equivalent) and the ERP subscribes as a consumer.
The key difference from webhooks is consumer-controlled acknowledgment. The ERP processes the event at its own pace and acknowledges consumption only after the ledger write completes. This prevents event loss if the ERP is temporarily unavailable or processing slowly. The tradeoff is operational complexity: you now own a message broker in addition to the integration itself.
This pattern is most appropriate for treasury management systems that have an existing event bus infrastructure, or for integrations where payment event volumes exceed what webhook delivery can handle reliably. For most corporate treasury deployments at the scale of a few hundred payments per day, webhooks are sufficient.
Pattern 4: Batch File Reconciliation
Some ERP environments, particularly older SAP configurations where the S4/HANA API layer is not yet deployed, cannot receive inbound API calls at all. These environments rely on file-based integration: the payment API generates a settlement file in a specified format (ISO 20022 camt.054 credit notifications, or a flat CSV), and the ERP imports the file on a schedule.
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.08">
<BkToCstmrDbtCdtNtfctn>
<GrpHdr>
<MsgId>BHL-20251114-001</MsgId>
<CreDtTm>2025-11-14T17:00:00Z</CreDtTm>
</GrpHdr>
<Ntfctn>
<Ntry>
<Amt Ccy="EUR">250000.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<ValDt><Dt>2025-11-14</Dt></ValDt>
<NtryRef>pay_9f4a2b1c</NtryRef>
<RmtInf><Ustrd>INV-2025-00847</Ustrd></RmtInf>
</Ntry>
</Ntfctn>
</BkToCstmrDbtCdtNtfctn>
</Document>
File-based reconciliation introduces a lag between settlement and ledger update equal to the file import frequency. If the ERP imports files once per day at 19:00, the controller's ledger position is always hours behind actual settlement. This is a structural limitation of the pattern, not a configuration problem. The argument for using this pattern is purely pragmatic: when the ERP cannot support real-time events, a reliable file import is better than nothing.
Failure Handling: The Part That Gets Skipped
Every integration pattern must define what happens when a payment transitions to a terminal failure state: returned, rejected, recalled. In practice, many ERP integrations handle the success path well and leave the failure path as a manual intervention. That creates an operational gap: a returned payment may sit unreconciled for days while a controller waits for a correspondent bank to issue a return advice.
Payment failure events should trigger the same automated reconciliation path as settlement confirmations. The ERP ledger should flip the payable from "in transit" to "failed" and create a reversal entry, without manual data entry. If that path does not exist in the integration design, every failed payment becomes an investigation task rather than an automated reconciliation event.
Building the failure path at design time, rather than retrofitting it after the first returned payment creates confusion, is the difference between an integration that treasury operations trusts and one that requires regular manual clean-up.