Periodic Payments Sandbox
Test standing orders end-to-end against the open-finance-sandbox provider, using dedicated debtor accounts that resolve to each standing-order status defined by the spec.
A periodic payment (standing order) instructs the bank to repeat a payment on a schedule — for example, paying rent on the 1st of every month until an end date. Before going live against a real bank, you can validate your full integration against the open-finance-sandbox provider.
The sandbox is deterministic: the debtor account you pay from decides the standing order's outcome. Each sandbox debtor account is wired to a specific standing-order status, so you can reproduce every flow — an active standing order, a rejection, a cancellation, a pending state, or a multi-level-SCA partial — just by changing one field in your request. No real money moves and no real bank is contacted.
Unlike single payments (which enter the sandbox asRCVDand are advanced later), a periodic payment adopts its final status immediately at creation. Thestatusyou get back from the create call is the standing-order status the chosen debtor account maps to.
How it works
- You create a periodic payment with
providerId: "open-finance-sandbox"andincludeFakeProviders: true. - You set
periodicPaymentInformation.debtorAccountNumberto one of the sandbox accounts in the status table below. - On creation, the payment is saved with the status that account maps to, and a notification/webhook is fired.
- You read the status back with Get payment status, or override it for further testing with Update sandbox status.
Sandbox debtor accounts
Pick the debtor account that matches the outcome you want to test. The standing order is created directly in that status. These accounts are specific to periodic payments — using any other account returns 400 Debtor account is not a periodic-payment sandbox account.
Debtor account (debtorAccountNumber) | Status | Group | Meaning |
|---|---|---|---|
IL070311140000000435694 | ACTC | Active | Accepted — technical validation passed. The standing order is active. This is the documented end status for periodic payments. |
IL630310640000000406821 | ACWC | Active | Accepted with change (for example the bank shifted the execution date). The standing order is active. |
IL060311140000000436488 | PATC | In progress | Partially accepted — a multi-level SCA is required and some, but not all, approvals are done. |
IL120311140000000436283 | RCVD | In progress | Received, awaiting processing. |
IL490311240000000272604 | RJCT | Terminal | The bank rejected the standing order (also the result if SCA is not completed in time). |
IL060311140000000436682 | CANC | Terminal | The standing order was cancelled. |
debtorAccountTypemust be"iban"for theopen-finance-sandboxprovider, and the creditor account must differ from the debtor account.
Create a periodic payment
Send an authenticated POST to /pay/open-banking-init with periodicPaymentInformation. The call requires the create:payments scope.
curl --request POST \
--url https://api.open-finance.ai/v2/pay/open-banking-init \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"providerId": "open-finance-sandbox",
"includeFakeProviders": true,
"psuId": "000000000",
"periodicPaymentInformation": {
"amount": 250,
"currency": "ILS",
"description": "Monthly rent",
"debtorAccountType": "iban",
"debtorAccountNumber": "IL070311140000000435694",
"creditorAccountType": "iban",
"creditorAccountNumber": "IL900311140000000111111",
"creditorName": "Landlord Ltd",
"startDate": "2030-01-01",
"endDate": "2031-01-01",
"frequency": "Monthly",
"dayOfExecution": "1"
}
}'const res = await fetch("https://api.open-finance.ai/v2/pay/open-banking-init", {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
providerId: "open-finance-sandbox",
includeFakeProviders: true,
psuId: "000000000",
periodicPaymentInformation: {
amount: 250,
currency: "ILS",
description: "Monthly rent",
debtorAccountType: "iban",
debtorAccountNumber: "IL070311140000000435694", // -> ACTC (active)
creditorAccountType: "iban",
creditorAccountNumber: "IL900311140000000111111",
creditorName: "Landlord Ltd",
startDate: "2030-01-01",
endDate: "2031-01-01",
frequency: "Monthly",
dayOfExecution: "1",
},
}),
});
const { paymentId, status } = await res.json();
// status === "ACTC"The response returns the created payment id and its standing-order status:
{
"paymentId": "01J9X8Z2K4P7QF0V2N6M3B5A1C",
"status": "ACTC",
"scaOAuth": "https://.../?state=01J9X8Z2K4P7QF0V2N6M3B5A1C"
}Swap debtorAccountNumber for IL490311240000000272604 and the same request returns "status": "RJCT" instead — that is the whole point of the sandbox.
Required & notable fields
providerId, includeFakeProviders, and psuId are top-level. Every other field below lives inside the periodicPaymentInformation object.
| Field | Notes |
|---|---|
providerId (top level) | Use "open-finance-sandbox". |
includeFakeProviders (top level) | Must be true — the sandbox is a test provider. |
amount | Greater than 0. |
currency | "ILS". |
description | Required. |
debtorAccountNumber / debtorAccountType | Required. Use a periodic sandbox account with type "iban". |
creditorAccountNumber + creditorName, or merchantId | Provide the creditor explicitly or resolve it from a merchant. Must differ from the debtor account. |
startDate | ISO date, tomorrow or later (the start date must be strictly in the future). |
endDate | Optional. If omitted the standing order is open-ended. When provided it must be at least one full frequency period after startDate (Monthly → +1 month, Quarterly → +3 months, Annual → +1 year), so the order always spans at least two occurrences. |
frequency | One of Monthly, Quarterly, Annual. |
dayOfExecution | Optional, 1–31 (31 means the last day of the month — ultimo). |
executionRule | Optional, following or preceding — how to shift an execution that lands on a weekend or bank holiday. |
Check the status
Read the standing order back at any time with GET /payments/{paymentId}/status (scope read:payments). For sandbox payments this returns the stored payment as-is.
curl --request GET \
--url https://api.open-finance.ai/v2/payments/01J9X8Z2K4P7QF0V2N6M3B5A1C/status \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Override the status
To walk a standing order through additional transitions (for example RCVD → ACTC, or PATC → ACTC once all SCAs complete), update it directly with PATCH /payments/sandbox/{paymentId} (scope create:payments). This endpoint only works on sandbox payments.
curl --request PATCH \
--url https://api.open-finance.ai/v2/payments/sandbox/01J9X8Z2K4P7QF0V2N6M3B5A1C \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{ "status": "ACTC" }'Standing-order status reference
These are the transaction statuses a standing order can carry, per the spec (see Spec alignment).
| Status | Group | Description |
|---|---|---|
RCVD | In progress | Received by the bank, not yet processed. |
PATC | In progress | Partially accepted, technically correct — multi-level SCA, some but not all approvals done. |
ACTC | Active | Accepted, technical validation passed — the standing order is set up. The typical end status for periodic payments. |
ACWC | Active | Accepted with change (for example a changed execution date). |
RJCT | Terminal | Rejected by the bank (also when a required SCA is not completed in time). |
CANC | Terminal | Cancelled. |
Spec alignment
The statuses above are the subset of the ISO 20022 / Berlin Group transaction statuses that the Bank of Israel "Open Banking IL" Implementation Guidelines v1.8 (NextGenPSD2 XS2A Framework) permit for standing orders:
- The end status of a periodic payment initiation is
ACTC(§4.14.1 — periodic payments are not executed immediately, so they finish technical validation rather than settlement).ACCPis mentioned by the framework but is not used in Israel. CANCis explicitly valid for future-dated and recurring/standing payments (§14.13).- A standing order that does not complete its required SCA (including multi-level SCA) becomes
RJCT(§5.4).
Statuses intentionally not offered for periodic payments:
PART— used only for bulk payments (§14.13).PDNG/PENDING,ACCP,ACWP— not used in Israel (§14.13).ACSC,ACSP,ACCC,ACFC— settlement/funds-check statuses of an executed transfer, not of a standing-order initiation.
Next steps
- Repeat the create call with each periodic sandbox debtor account to cover every status your integration must handle.
- Point your webhook/notification handler at the sandbox to confirm you receive the status you expect.
- When your flows pass against the sandbox, switch
providerIdto a real bank and dropincludeFakeProviders.
