Release candidate

v2.2-rc2 is not ratified and MUST NOT be used for production. Current: v2.1. Changelog

This is v2.2-rc2 — a release candidate for the v2.2 standards, published for review and not yet ratified. It MUST NOT be used as the basis for a production implementation. For the current standards, switch to v2.1 using the version selector. See the v2.1 → v2.2-rc2 changelog for every change in this version.

Service Initiation · Domestic Payments · Timing

Payment Timing 6 min read

This page sets out what your TPP receives after it calls POST/payments on the API Hub, and when. It applies to Single Instant Payment and to every multi-payment type.

A domestic payment moves through three statuses. Pending comes back on the 201. AcceptedSettlementCompleted follows within 3 seconds of the LFI’s 201, once the LFI has handed the payment to the rail. The terminal status follows when the rail responds. The LFI-side obligations behind this timeline are in the LFI Integration Guide Payment Timing page.

01 Timeline

The timeline at a glance

Sequence diagramDomestic payment timing — TPPClick to expand
#StageWhenWhat your TPP receivesStatus
1Submit the paymentSynchronous201 on POST /payments, or an error responsePending
2Handed to the railWithin 3 seconds of the LFI’s 201, plus API Hub relay timeA payment status eventAcceptedSettlementCompleted
3Rail outcomeWhen the rail responds — set by the AANI or UAEFTS scheme rulesA payment status eventAcceptedWithoutPosting, AcceptedCreditSettlementCompleted, or Rejected

A payment between two accounts at the same LFI is booked on that LFI’s own ledger, so it has no rail and no hand-off. Its first status after Pending is the terminal AcceptedCreditSettlementCompleted, which arrives within the same 3-second window.

02 Stage 1 · Synchronous

Submitting POST /payments

The POST /payments request is validated in two places before your TPP receives a response. Either can reject it synchronously, in which case no payment resource is created:

Validated byChecks
API HubThe access token, the consent status, the payment against the consent’s control parameters (ConsentId, Instruction.Amount, PaymentPurposeCode, references, OpenFinanceBilling), and the request against the OpenAPI schema
LFIDecryption and schema of the payment PII, the creditor against the creditor authorised on the consent, available funds, and the state of the debtor account. Some payment types add checks — for example x-fapi-customer-ip-address on Single Instant Payment, or a duplicate in-flight check on the on-demand types

If both pass, your TPP receives 201 Created with Status: Pending and the LFI-assigned PaymentId. PaymentRail and PaymentTransactionId may be absent at this point, because the LFI routes the payment after it responds.

If the response never arrives

If your TPP does not receive a response to POST /payments — because of a network error or a timeout — do not submit a new payment with a new x-idempotency-key. Look the payment up with GET/payments and the same x-idempotency-key. If a payment was created, the response points to it.

03 Stage 2 · Within 3 seconds

AcceptedSettlementCompleted: handed to the rail

Within 3 seconds of returning its 201 to the API Hub, the LFI MUST complete its fraud screening, transaction monitoring and AML checks, submit the payment to AANI or UAEFTS, and PATCH AcceptedSettlementCompleted to the API Hub. The API Hub relays that status to your TPP as a payment status event and returns it on GET/payments/{PaymentId}.

The 3-second figure is measured at the LFI, from its 201 to the API Hub. Your TPP receives the event after the API Hub has relayed it, so allow for that relay time when you set expectations or timeouts.

AcceptedSettlementCompleted means the payment has cleared the LFI’s checks and been handed to the rail. From this point PaymentRail and PaymentTransactionId are present. It is not terminal: the rail’s outcome follows, and the payment can still be rejected at that stage. Your TPP SHOULD present the payment to the customer as submitted or in progress, not as completed.

payment status event — decrypted, abridgedjson
{
  "Data": {
    "PaymentId": "5ff155ea-853f-480c-ac74-1eaed7c1201f",
    "PaymentRail": "AANI",
    "PaymentTransactionId": "OFP7d2c1e9a4b6f4c0e8a1b",
    "Status": "AcceptedSettlementCompleted"
  }
}
04 Stage 3 · Rail-dependent

The terminal status

The LFI PATCHes the terminal status as soon as the rail responds. How long the rail takes is set by the AANI and UAEFTS scheme rules, not by the Open Finance standards, so there is no fixed upper bound on this stage.

PaymentRailSuccessFailure
AANIAcceptedWithoutPostingRejected, RejectReasonCode in the AANI. namespace
FTSAcceptedCreditSettlementCompletedRejected, RejectReasonCode in the FTS. namespace
LFIAcceptedCreditSettlementCompletedRejected, RejectReasonCode in the LFI. namespace

Only Rejected means the payment failed. Your TPP SHOULD NOT treat a payment as failed because it is still at AcceptedSettlementCompleted after some time. The payment is with the rail, and a customer prompted to pay again could pay twice.

payment status event — decrypted, abridgedjson
{
  "Data": {
    "PaymentId": "5ff155ea-853f-480c-ac74-1eaed7c1201f",
    "PaymentRail": "AANI",
    "PaymentTransactionId": "OFP7d2c1e9a4b6f4c0e8a1b",
    "Status": "AcceptedWithoutPosting"
  }
}

What each status means, and the full set of reject reason codes, are in Payment Status.

05 Receiving Status

Events and polling against the timeline

With a webhook registered on the consent, the API Hub sends a payment status event each time the LFI PATCHes a new status: once for AcceptedSettlementCompleted, and once for the terminal status. See the Payment Status Event API Guide.

If your TPP polls instead, align the polling with the timeline:

  • Make the first poll about 3 seconds after the 201. The payment will normally be at AcceptedSettlementCompleted, or at its terminal status if it was booked on the LFI’s own ledger.
  • After that, back off. The remaining wait depends on the rail.
  • Stop polling once the payment reaches AcceptedWithoutPosting, AcceptedCreditSettlementCompleted, or Rejected. A terminal status does not change.