---
updatedAt: 2026-07-21T15:12:08.000Z
agentTools:
  projectIndex: https://docs.neonomics.io/llms.txt
---

# Pay by Bank

# Types of payments supported by Neonomics

Neonomics supports six types of payments: Domestic Payment, Domestic Scheduled Payment, SEPA Payment, SEPA Scheduled Payment, Batch Transfer, and Danish Payment Slip.

* **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.
* **Danish Payment Slip** is a domestic payment made against a Danish GIRO or FI/FIK payment slip ("indbetalingskort"), initiated through the same domestic payment endpoint. Instead of a normal creditor account, you pay against the creditor number and "kortart" code printed on the slip. Currently only supported for Lunar.

<br />

> ⚠️ 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](https://docs.neonomics.io/docs/development-quickstart) and the customer [consent guide](https://docs.neonomics.io/docs/consent-authorization-and-sca) 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
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 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](https://docs.neonomics.io/reference) for the respective payment types.

<br />

## Domestic Payment Request Example

```json
{
  "debtorAccount": {
    "bban": "12032202452"
  },
  "debtorName": "Mike",
  "creditorAccount": {
    "bban": "12257989702"
  },
  "creditorName": "Kim",
  "instrumentedAmount": "1",
  "currency": "NOK",
  "remittanceInformationUnstructured": "Neonomics test",
  "endToEndIdentification": "Neonomics test",
  "paymentMetadata": {}
}
```
```
```

## Danish GIRO/FIK Payment Slip Request Example

To pay a Danish GIRO or FI/FIK payment slip, use the same `/payments/domestic-transfer/` endpoint as a regular domestic payment, but include `paymentMetadata.countryMetadata.DK.paymentSlipType` set to the "kortart" code printed on the slip (GIRO: `"01"`, `"04"`, `"15"`; FI/FIK: `"71"`, `"73"`, `"75"`). When this field is set:

* `creditorAccount.bban` must be the slip's creditor number (max 8 characters), not a regular Danish BBAN
* `debtorAccount.bban` is required
* Currently only supported for Lunar

```json
{
  "debtorAccount": {
    "bban": "12345678901"
  },
  "debtorName": "John Doe",
  "creditorAccount": {
    "bban": "12345678"
  },
  "creditorName": "Jane Doe",
  "instrumentedAmount": "250.00",
  "currency": "DKK",
  "remittanceInformationUnstructured": "Invoice 12345",
  "endToEndIdentification": "Neonomics test",
  "paymentMetadata": {
    "countryMetadata": {
      "DK": {
        "paymentSlipType": "71"
      }
    }
  }
}
```

## Domestic Scheduled Payment Request Example

```json
{
  "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

```json
{
    "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"
        }
    ]
}
```
```
```

<Callout icon="💡" theme="default">
  ### 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
</Callout>

# 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**

```json
{
    "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**

```json
{
    "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`

<Callout icon="💡" theme="default">
  ### 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
</Callout>

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
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:**

```json
{
  "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

![](https://files.readme.io/57d3a21-image.png)

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.

<br />

For Individual Payments:

![](https://files.readme.io/1dd78bb212624c74636e2521341826ddb9d439a0c9673c2e139860720cd19855-image.png)

For Batch Payments:

![](https://files.readme.io/d023e465cf9f8cb3ae20e6511ca7333f92c63d0ba20c52b19e30658bbc34764b-Screenshot_2025-09-10_at_12.44.17.png)

# 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
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):**

```json
{  
  "paymentId": "b3f1a7cb-d85a-4db5-90ab-2e38b45922c4",  
  "status": "ACTC",  
  "creationDateTime": "2019-12-03T14:19:41.855+01:00"  
}
```

**Response (Batch Payment):**

```json
{
    "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 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
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
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):**

```curl
# 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:**

```json
{
  "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

<Callout icon="💡" theme="default">
  ### 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.
</Callout>

<Callout icon="🕒" theme="default">
  ### 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.
</Callout>

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

<Callout icon="📊" theme="default">
  ### 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.
</Callout>

## 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

<br />

Fantastic! You have now completed your first payment 🌟