Pay by Bank
Types of payments supported by Neonomics
Neonomics supports five types of payments: Domestic Payment, Domestic Scheduled Payment, SEPA Payment, SEPA Scheduled Payment, and Batch Transfer.
- Domestic Payment is a transfer of money between two bank accounts in the same country using the domestic currency. An example of a domestic payment would be £50 from one British bank account to another British bank account.
- Domestic Scheduled Payment is a transfer of money between two bank accounts in the same country using the domestic currency, set to be executed on a specific date. For example, initiating a payment of £10 from one British bank account to another British bank account to be executed on the 11th of March 2021.
- SEPA Payment (Single Euro Payments Area) is a transfer of money from one bank account to another within the 36 SEPA countries. The currency used for these payments is the euro. An example of a SEPA payment would be €10 from a Finnish bank account to a French bank account.
- SEPA Scheduled Payment is a SEPA payment set to be executed on a specific date.
- Batch Transfer is a transfer of multiple payments in a single transaction with a shared debtor account. You can combine immediate domestic payments and domestic scheduled payments in one batch, with up to 20 creditors per batch.
Current LimitationsBatch payments currently support domestic and domestic scheduled payments only. SEPA batch payments will be added in future releases.
InfoYou need to complete the development quickstart and the customer consent guide before starting this guide. A valid
access_token
andsessionId
are needed to follow the payments.
How to make a payment using the Neonomics API
To make a payment, complete these four steps in sequence:
Individual Payments:
- Initiate the payment to create a payment object in Neonomics so that the end-user can authorize the payment. This step will require consent from the end-user if no valid consent exists for the account.
- Handle the response from payment initiation to determine how to proceed. If the payment is exempt from SCA, the initiation will already be complete in step 1. Otherwise, you need to execute the following steps.
- Authorize the payment by obtaining a URL from the end-user's bank to complete a payment authorization. This step is omitted if the payment is exempt from SCA.
- Complete the payment initiation to queue the payment for execution in the bank. This step is omitted if the payment is exempt from SCA.
- Get the final payment status to verify the payment was processed successfully.
Batch Payments:
- Initiate the batch payment with multiple creditors in a single request
- Handle the batch response to determine authorization requirements
- Authorize the batch payment using the batchId (if required)
- Complete the batch payment initiation to queue all payments
- Verify individual payment status for each payment in the batch
When the payment initiation is complete, the debtor bank will execute the payment in accordance with its procedures for cut-off time and settlement.
Step 1: Initiate a payment
To initiate a payment, make a curl POST
request below and follow these instructions:
For Individual Payments:
- Replace
<PAYMENT_TYPE>
with the payment type you want to initiate. The possible payment types are/payments/domestic-transfer/
,/payments/domestic-scheduled-transfer/
,/payments/sepa-credit/
, or/payments/sepa-scheduled-credit/
For Batch Payments:
-
Use
/payments/batch-transfer/
as the payment type -
The request body must contain all creditors in a single batch
-
The request body must contain all required parameters in the
<PAYMENT_BODY>
. -
In cases where you need to apply a Redirect URL, include the
x-redirect-url
parameter in the request header. -
Remember to include the
x-psu-id
header if it is required by the bank. -
Replace
<ACCESS_TOKEN>
and<SESSION_ID>
with theaccess_token
andsessionId
generated in the Development quickstart. -
Please note that the bank details used in this document are test details, only used in the sandbox.
curl -X POST https://sandbox.neonomics.io/ics/v3/payments/<PAYMENT_TYPE> \
-H "Authorization:Bearer <ACCESS_TOKEN>" \
-H "x-device-id:example_id_for_quickstart" \
-H "Content-Type:application/json" \
-H "Accept:application/json" \
-H "x-session-id:<SESSION_ID>" \
-H "x-psu-ip-address: 109.74.179.3" \
-d '{<PAYMENT_BODY>
}'
Account numbers
When initiating a payment, creditor and debtor account info is required. This info consists of two parts:
- The actual account number, which is also called the account identifier, e.g., 'DE89370400440532013000'.
- The account scheme is also called account number type. The table below shows what account schemes can be used in what markets.
Account scheme | Name | Where used |
---|---|---|
IBAN | International Bank Account Number | All markets |
BBAN | Base Bank Account Number | All markets |
PGNR | PlusGironummer | Sweden |
BGNR | Bankgironummer | Sweden |
The rules for what account schemes are valid in a payment initiation request body depend on the payment type. Those rules are described for each payment type in the payment guides here as well as in API References for the respective payment types.
Domestic Payment Request Example
{
"debtorAccount": {
"bban": "12032202452"
},
"debtorName": "Mike",
"creditorAccount": {
"bban": "12257989702"
},
"creditorName": "Kim",
"instrumentedAmount": "1",
"currency": "NOK",
"remittanceInformationUnstructured": "Neonomics test",
"endToEndIdentification": "Neonomics test",
"paymentMetadata": {}
}
Domestic Scheduled Payment Request Example
{
"debtorAccount": {
"accountScheme": "BBAN",
"identifier": "12032202452"
},
"debtorName": "Debtor",
"creditorAccount": {
"accountScheme": "IBAN",
"identifier": "NO2712073650567"
},
"creditorName": "Kim",
"instrumentedAmount": "10",
"currency": "NOK",
"remittanceInformationUnstructured": "Neonomics test",
"endToEndIdentification": "Neonomics test",
"requestedExecutionDate": "2025-09-20",
"paymentMetadata": {}
}
Batch Payment Request Example
{
"debtorName": "John Doe",
"debtorAccount": {
"accountScheme": "IBAN",
"identifier": "NO1234567890123"
},
"currency": "NOK",
"endToEndIdentification": "BATCH_001",
"creditors": [
{
"creditorName": "Supplier A",
"referenceId": "REF001",
"creditorAccount": {
"accountScheme": "IBAN",
"identifier": "NO9876543210987"
},
"instrumentedAmount": "1500.00",
"remittanceInformationUnstructured": "Invoice 001"
},
{
"creditorName": "Supplier B",
"referenceId": "REF002",
"creditorAccount": {
"accountScheme": "BBAN",
"identifier": "12073650567"
},
"instrumentedAmount": "2500.00",
"remittanceInformationUnstructured": "Invoice 002",
"requestedExecutionDate": "2025-12-25"
}
]
}
Key Batch Payment Features
- Shared Debtor: All payments use the same debtor account
- Mixed Types: Combine immediate and scheduled payments in one batch
- Reference Tracking: Optional
referenceId
for each creditor to track payments- Limit: Maximum 20 creditors per batch
Step 2: Handle the response
You can usually expect one of the three responses described below when you initiate a payment. Handle any other response as an error situation.
-
Status code
201
with message "Payment created", which means that the bank accepted the payment straight away. The response contains the payment'sstatus
andpaymentId
(orbatchId
for batch payments), which you can use later in a Get Payment by ID call to follow up on the payment's status. After a201
response, omit calling Authorize payment and Complete Payment, because the payment initiation is already complete. -
Status code
510
together with error code1426
, which means that end-user consent is required. The next step is to call Get Consent API to initiate Strong Customer Authentication. When that is successfully completed, initiate the payment again. -
Status code
510
together with error code1428
, which means that payment authorization is required. The next step is to call Authorize Payment API to initiate Strong Customer Authentication. When that is successfully completed, call Complete Payment.
Error Code Details
- Error 1426: This resource needs to initialize consent. You must call the consent endpoint first.
- Error 1428: Payment authorization required. You must call
/ics/v3/payments/{paymentProduct}/{paymentId}/authorize
to get authorization URL. For batch payments, use the batchId in place of paymentId.
Batch Payment Error Response Example (1426 - Consent Required)
Response
{
"id": "f807a7f3de2cb6b9ae58594e27c4f330",
"errorCode": "1426",
"message": "This resource needs to initialise consent. Please use the URL provided to continue. The consent Url will provide the bank authentication url. You can consume this resource after authenticating.",
"source": "C",
"type": "CONSENT",
"timestamp": 1757502239430,
"links": [
{
"type": "GET",
"rel": "consent",
"href": "https://development-api.neonomics.io/ics/v3/consent/a3bf620f-33b6-43d7-8914-bee85e8cc18b?scope=payments",
"meta": {
"id": "a3bf620f-33b6-43d7-8914-bee85e8cc18b"
}
}
]
}
Batch Payment Error Response Example (1428 - Authorization Required)
Response
{
"id": "f2af98f8bf608846c79a5be32e95bcc3",
"errorCode": "1428",
"message": "This payment requires Strong Customer Authentication (SCA). Please use the authorization URL provided to continue, then call the payment complete endpoint after authorising.",
"source": "C",
"type": "CONSENT",
"timestamp": 1756917584443,
"links": [
{
"type": "GET",
"rel": "payment",
"href": "https://api.neonomics.io/ics/v3/payments/batch-transfer/e4e5d367-539d-4e96-9569-cfd0a2c1df2b/authorize",
"meta": {
"id": "e4e5d367-539d-4e96-9569-cfd0a2c1df2b",
"batchPayments": [
{
"paymentId": "3768f547-af00-4ccf-adab-17214046c7be",
"referenceId": "REF001"
},
{
"paymentId": "3f07c82b-05d7-49d2-a17d-fce263b6bfe0",
"referenceId": "REF002"
}
]
}
}
]
}
Link object
Neonomics API errors can contain an array of link objects. The error shown above contains a link object with the following attributes:
href
- This can contain two types of links. The first type is the URL for a Neonomics API request, as in the example above. The second type is a link to the bank's website so the end-user can complete a consent request or a customer payment authorization.rel
- The Neonomics API operation related to the link. For error 1426, this will be "consent". For error 1428, this will be "payment".type
- If thehref
is a link to a request to the Neonomics API, then this is the type of HTTP RESTful request method required:POST
,GET
,DELETE
,PUT
, orPATCH
.meta
- Contains important identifiers:- Error 1426: Contains the sessionId needed for consent flow
- Error 1428 (Individual payments): Contains the paymentId
- Error 1428 (Batch payments): Contains the batchId and a
batchPayments
array that maps yourreferenceId
to the generatedpaymentId
Important for Batch PaymentsIn batch payment error responses (1428), the
batchPayments
array in the meta object is crucial. It shows you:
- The mapping between your
referenceId
and the generatedpaymentId
- Individual payment IDs you'll use later to check payment status
- The batchId (in meta.id) you'll use for authorization and completion
Save the href
you received from the request above, as you will need it in step 3.
Step 3: Authorize the payment
Now that you have initiated a payment, the end-user usually has to authorize the payment API. However, some payment types are exempt from authorization. In those cases, there will be no error.
To authorize a payment, you will need to obtain the bank's authorization URL by using the curl GET
request below.
You will need the URL you obtained in the error object in step one. Replace <AUTHORIZATION_URL>
with the href obtained in step one. Replace <ACCESS_TOKEN>
and <SESSION_ID>
with your access_token
and sessionId
. Remember to include the x-psu-id
header if it is required by the bank.
Authorization Endpoints
- Individual Payments: Use the paymentId in the authorization URL
- Batch Payments: Use the batchId (from the meta.id field) in the authorization URL
- After Error 1426: First complete the consent flow using the consent URL, then retry the payment initiation
Request:
curl -X GET \<AUTHORIZATION_URL>
-H "Authorization:Bearer \<ACCESS_TOKEN>"
-H "Accept:application/json"
-H "x-device-id:example_id_for_quickstart"
-H "x-psu-ip-address:109.74.179.3"
-H "x-session-id:\<SESSION_TOKEN>"
Below is the response returned from the request above.
Response:
{
"paymentId": "<PAYMENT_ID_OR_BATCH_ID>",
"message": "Please use the Authorization Url to continue.",
"links": [
{
"type": "GET",
"rel": "Authorization URL",
"href": "https://openbanking.sbanken.no/tap-sandbox/9710/?route_secesb_id=2&flow=psd2&state=8cda5e87-1fbc-4d82-8f5b-c13351d8c911&context=PRIVATE"
}
]
}
This response contains an array of links
with one object. The href
in this object is a link that will take you to the decoupled authorization page.
In this example, you can simulate the end-user authorization of the payment. Save the paymentId
(or batchId
for batch payments), as this is required in step 4.
Copy the href
URL and open it in your internet browser. Below is the bank's payment authorization webpage. You will be asked to enter a 'Personnummer'. Use this number: 01078900497

You will then be taken to the Neonomics webpage shown below. However, if a custom Redirect URL was applied in the authorization request, the page specified in x-redirect-url
will appear instead.
For Individual Payments:

For Batch Payments:

Step 4: Complete the payment initiation
After the end-user has authorized the payment, it's required to complete the payment initiation API. This needs to be done without delay since payment tokens issued by banks are only valid for a limited time.
Use the curl POST
request below. Replace \<PAYMENT_ID>
with the paymentId
(or batchId
for batch payments) that was returned in the authorization response in step 3. Replace \<ACCESS_TOKEN>
and \<SESSION_ID>
with your access_token
and sessionId
. Remember to include the x-psu-id
header if it is required by the bank.
Complete Payment Endpoints
- Individual Payments: Use
/ics/v3/payments/<PAYMENT_TYPE>/<PAYMENT_ID>/complete
- Batch Payments: Use
/ics/v3/payments/batch-transfer/<BATCH_ID>/complete
Request:
curl -X POST <https://sandbox.neonomics.io/ics/v3/payments/><PAYMENT_TYPE/>\<PAYMENT_ID>/complete
-H "Authorization:Bearer \<ACCESS_TOKEN>"
-H "accept: application/json"
-H "content-type: application/json"
-H "x-device-id:example_id_for_quickstart"
-H "x-psu-ip-address:109.74.179.3"
-H "x-session-id:\<SESSION_ID>"
-H "content-length: 0"
This is the returned object for individual payments:
Response (Individual Payment):
{
"paymentId": "b3f1a7cb-d85a-4db5-90ab-2e38b45922c4",
"status": "ACTC",
"creationDateTime": "2019-12-03T14:19:41.855+01:00"
}
Response (Batch Payment):
{
"batchId": "aa00a560-cdd0-448a-9bc5-6fb109a82ced",
"status": "ACTC",
"creationDateTime": "2025-01-15T10:30:00Z"
}
Batch Payment Status Values
Status Code | Description |
---|---|
RCVD | Received |
ACTC | Accepted Technical Validation |
PATC | Partially Accepted Technical Validation |
RJCT | Rejected |
Step 5: Get the final payment status
Regardless if the final payment status (successful or failed) was returned in a previous step, we strongly recommend calling the Get Payment by ID endpoint for all payments. Only if the response of the Get Payment by ID call is final should the end-user be informed about the outcome of the payment.
If the payment is scheduled, a final payment status may only be returned on the due date. Note that in some cases, banks will retry the payments for some days if the user does not have sufficient funds in their account on the due date. It is therefore recommended to continue polling the Get Payment by ID until a final payment status is returned.
Use the curl GET
request below. Replace \<PAYMENT_ID>
with the paymentId
that was returned in the authorization response in step 3.
Important Note for Batch PaymentsUse the individual
paymentId
(notbatchId
) to check status of payments that were part of a batch. This returns individual payment details, not batch details. You can find the individual payment IDs in thebatchPayments
array from the authorization response.Payment Product Options for Batch Payments:
- Option 1: Use
batch-transfer
as the payment product- Option 2: Use the specific payment product (
domestic-transfer
ordomestic-scheduled-transfer
) if you know the actual payment typeBoth approaches work and return the same individual payment details.
For Individual Payments:
curl -X GET <https://sandbox.neonomics.io/ics/v3/payments/><PAYMENT_TYPE/>\<PAYMENT_ID>
-H 'accept: application/json'
For Batch Payments (Option 1 - Using batch-transfer):
curl -X GET https://sandbox.neonomics.io/ics/v3/payments/batch-transfer/3768f547-af00-4ccf-adab-17214046c7be
-H 'accept: application/json'
For Batch Payments (Option 2 - Using specific payment type):
# For an immediate domestic payment from batch
curl -X GET https://sandbox.neonomics.io/ics/v3/payments/domestic-transfer/3768f547-af00-4ccf-adab-17214046c7be
-H 'accept: application/json'
# For a domestic scheduled payment from batch
curl -X GET https://sandbox.neonomics.io/ics/v3/payments/domestic-scheduled-transfer/3f07c82b-05d7-49d2-a17d-fce263b6bfe0
-H 'accept: application/json'
This is the returned object. If the payment is successful then the attribute status
will be ACSC
, this is an ISO 20022 standard code. The ISO Codes page explains the codes used by the Neonomics API.
Response Type Field for Batch PaymentsFor payments that were part of a batch, the
type
field in the response will show the actual payment product type:
"domestic-transfer"
for immediate domestic payments"domestic-scheduled-transfer"
for domestic scheduled paymentsThis is true regardless of whether you used
batch-transfer
or the specific payment product in your GET request URL.
Response:
{
"paymentId": "3768f547-af00-4ccf-adab-17214046c7be",
"status": "ACPT",
"creationDateTime": "2024-03-07T11:01:20.820Z",
"debtorAccount": {
"iban": "NO1234567890123",
"bban": "string",
"sortCodeAccountNumber": "string"
},
"creditorAccount": {
"iban": "NO9876543210987",
"bban": "string",
"sortCodeAccountNumber": "string"
},
"remittanceInformationUnstructured": "Invoice 001",
"instrumentedAmount": "1500.00",
"currency": "NOK",
"type": "domestic-transfer",
"remittanceInformationStructured": {
"reference": "string",
"referenceType": "string",
"referenceIssuer": "string"
}
}
Note: In this example, even though the payment was initiated as part of a batch via /batch-transfer
, the type
field shows "domestic-transfer"
because this specific payment was an immediate domestic payment (no requestedExecutionDate
was provided for this creditor).
Key Implementation Notes for Batch Payments
Reference ID MappingUse the
batchPayments
array from authorization response to map your reference IDs to generated payment IDs. This allows you to track which payment corresponds to which of your internal references.
Mixed Execution DatesWithin a single batch:
- Creditors without
requestedExecutionDate
= immediate domestic payments- Creditors with
requestedExecutionDate
= domestic scheduled paymentsThis allows you to combine different payment types in one authorization flow.
Error HandlingIf any payment in the batch fails validation, the entire batch may be rejected. Ensure all payment details are correct before submitting.
Status MonitoringCheck individual payment status using the specific
paymentId
, not thebatchId
. Each payment in the batch gets its own unique ID for tracking.
Required Headers
Header | Value | Required |
---|---|---|
Authorization | Bearer {access_token} | ✅ Yes |
x-session-id | {session_id} | ✅ Yes |
x-device-id | {device_id} | ✅ Yes |
Content-Type | application/json | ✅ POST requests |
Optional Headers
Header | Description | Values |
---|---|---|
x-redirect-url | Custom callback URL | Any valid URL |
x-psu-ip-address | End-user IP address | IPv4 or IPv6 |
x-psu-id | End-user identifier (required for some banks) | Base64 encoded |
domestic-payment-type | Payment speed for supported banks | instant or same-day |
Current Limitations
Current Limitations
- Batch SEPA Payments: Not yet supported (coming in future releases)
- Maximum Batch Size: 20 creditors per batch
- Mixed Currencies: All payments in a batch must use the same currency
- Same Debtor: All payments in a batch must use the same debtor account
Benefits of Batch Payments
- 🚀 Efficiency: Process multiple payments in a single API call
- 🔐 Reduced Authorization: One SCA flow for multiple payments
- 🏷️ Reference Tracking: Map your internal references to payment IDs
- ⚡ Flexibility: Mix immediate and scheduled payments in one batch
- 💰 Cost Optimization: Reduce API calls and processing overhead
Fantastic! You have now completed your first payment 🌟
Updated 5 days ago