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 Limitations

Batch payments currently support domestic and domestic scheduled payments only. SEPA batch payments will be added in future releases.

📘

Info

You need to complete the development quickstart and the customer consent guide before starting this guide. A valid access_token and sessionId 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:

  1. 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.
  2. 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.
  3. 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.
  4. Complete the payment initiation to queue the payment for execution in the bank. This step is omitted if the payment is exempt from SCA.
  5. Get the final payment status to verify the payment was processed successfully.

Batch Payments:

  1. Initiate the batch payment with multiple creditors in a single request
  2. Handle the batch response to determine authorization requirements
  3. Authorize the batch payment using the batchId (if required)
  4. Complete the batch payment initiation to queue all payments
  5. 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 the access_token and sessionId 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:

  1. The actual account number, which is also called the account identifier, e.g., 'DE89370400440532013000'.
  2. The account scheme is also called account number type. The table below shows what account schemes can be used in what markets.
Account schemeNameWhere used
IBANInternational Bank Account NumberAll markets
BBANBase Bank Account NumberAll markets
PGNRPlusGironummerSweden
BGNRBankgironummerSweden

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's status and paymentId (or batchId for batch payments), which you can use later in a Get Payment by ID call to follow up on the payment's status. After a 201 response, omit calling Authorize payment and Complete Payment, because the payment initiation is already complete.

  • Status code 510 together with error code 1426, 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 code 1428, 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 the href 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, or PATCH.
  • 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 your referenceId to the generated paymentId
💡

Important for Batch Payments

In batch payment error responses (1428), the batchPayments array in the meta object is crucial. It shows you:

  • The mapping between your referenceId and the generated paymentId
  • 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 CodeDescription
RCVDReceived
ACTCAccepted Technical Validation
PATCPartially Accepted Technical Validation
RJCTRejected

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 Payments

Use the individual paymentId (not batchId) 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 the batchPayments 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 or domestic-scheduled-transfer) if you know the actual payment type

Both 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 Payments

For 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 payments

This 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 Mapping

Use 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 Dates

Within a single batch:

  • Creditors without requestedExecutionDate = immediate domestic payments
  • Creditors with requestedExecutionDate = domestic scheduled payments

This allows you to combine different payment types in one authorization flow.

⚠️

Error Handling

If any payment in the batch fails validation, the entire batch may be rejected. Ensure all payment details are correct before submitting.

📊

Status Monitoring

Check individual payment status using the specific paymentId, not the batchId. Each payment in the batch gets its own unique ID for tracking.

Required Headers

HeaderValueRequired
AuthorizationBearer {access_token}✅ Yes
x-session-id{session_id}✅ Yes
x-device-id{device_id}✅ Yes
Content-Typeapplication/json✅ POST requests

Optional Headers

HeaderDescriptionValues
x-redirect-urlCustom callback URLAny valid URL
x-psu-ip-addressEnd-user IP addressIPv4 or IPv6
x-psu-idEnd-user identifier (required for some banks)Base64 encoded
domestic-payment-typePayment speed for supported banksinstant 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 🌟