Payment Refund API - details
Payment Refund facilitates client applications to initiate a refund of a credit transfer payment from a Nordea corporate account. There are several conditions and rules to follow when formulating the payment instruction to refund a payment. These details are explained in this API specification.
The consuming client application can use API requests to:
- Create a refund payment instruction - single SEPA credit transfer instructions only
- Track the refund status
Payment Refund is in MVP phase and currently available for Nordea corporate customers with accounts in Finland, with an activated technical user, having received SEPA credit transfers which are to be returned to the original payer. The service is currently limited to Finland, but our ambition is to expand the service to other Nordic countries and currencies.
For further information about the service or the preconditions for onboarding to Payment Refund, please reach out to us via a ticket.
Production access to Payment Refund
To use Payment Refund API in production, you need an active Corporate Cash management agreement (CCM) and a Corporate Netbank Service enabled. The agreement owner needs to enable Premium APIs confirmation rights for a Corporate Netbank administrator. You can integrate Refund API via your technical ERP/TMS vendor or by developing your own system integration to Payment Refund.
To create the technical user in Nordea Corporate Administration for Payment Refund:
As an administrator, you can create the technical user for your company that is needed to use the Payment Refund service.
Sign up for Payment Refund
If you have an active Corporate Cash management agreement (CCM) and a Corporate Netbank Service enabled, you can request access for Payment Refund in production by using this registration webform.
Nordea will respond to your request and guide you through the agreement set up and administrator authorisations for Premium APIs and to finalize the onboarding for Payment Refund.
You can also add additional Premium APIs into your technical API integration, by requesting access via the same registration webform.
Changes from previous version
Version 1.3 - Adjusted test data.
Key changes: Dynamic test data.
- Updated test data (Dynamic Original Date)
Version 1.2 - Fields and test data updates.
Key changes: Input fields, request and response fields.
- Updated RAPI request structure
- Updated RAPI response structure
- Updated test data
Version 1.1 - Available only in Sandbox, fields and test data updates.
Key changes: Input fields, request and response fields.
- Updated scope of input attributes
- Updated RAPI request structure
- Updated RAPI response structure
- Updated test data
- Added information about limitations: up to last 24 months available data
Version 1.0 - Available only in Sandbox
The Payment Refund API is a newly introduced service to support Payments Initiation Services. Refund API provides access to two endpoints:
- Send refund payment instruction
- Get payment status
API endpoints
The prerequisite for integration, is:
- client’s capability to keep track of refund payment ID by which they can query for payer info for given refund payment.
- client’s capability to keep track of payment archive ID which needs to be provided in the refund request, so the original payment can be linked to the refund.
- client needs to be able to provide correct values of required parameters which consist of:
- “payment_archive_id”
- “payment_account”
- “currency”
- “amount”
- “original_payment_date”
- “message”
| Endpoint | Method | Description |
|---|---|---|
| /corporate/payment-refunds/v1/refunds | POST | Send refund payment request to bank. |
| /corporate/payment-refunds/v1/refunds/{id} | GET | Get refund payment status from bank using given payment id. |
Payment confirmation
When Nordea receives refund request through the API, the refund payment is initiated. Before sending the initiated payment for processing, authorization check is done based on technical-user permissions. If technical-user has confirmation permission for refund payment, the payment is sent for processing. Technical-user permissions will be managed using Nordea’s user administration tool.
Note that in Sandbox environment it is not required to create technical-user. Correct technical user is provided in data examples.
Payment Refund API examples
Here you can find examples how to use the Payment Refund API endpoints.
Example: Send refund payment request
This endpoint supports POST HTTP method and URL has the following form:
POST /corporate/payment-refunds/v1/refundsThe following headers must be used:
Content-Type: application/json
X-IBM-Client-Id: {client_id}
X-IBM-Client-Secret: {client_secret}
Digest: {digest}
Signature: {signature}
Technical-user-id: {technical_user_id}
X-Nordea-Originating-Date: {date}
X-Nordea-Originating-Host: {host}The body of the request:
{
"payment_archive_id": "202103152588CEP10005",
"payment_account": "FI9819513119469790",
"amount": "5647",
"original_payment_date": "2024-01-01",
"currency": "EUR",
"message": "Limit of 140 characters"
}- Payment archive id field is a mandatory and must be a valid archive id from received payment.
- Payment account field is mandatory. Value must correspond with the creditor account in the original payment.
- Currency field is optional. But currently RAPI service supports only SEPA payments, so currency field should be provided with “EUR”.
- Amount field is mandatory and must be equal to the original payment amount.
- Original payment date is mandatory and must be equal to the original payment date.
- Message field is optional.
Where the payment request is valid the response will be 201 SUCCESS and formatted like the example below:
{
"group_header": {
"message_identification": "8e1a9c71dcfee8f66152b346a68084b2",
"creation_date_time": "2024-04-11T10:32:37.127421403Z",
"http_code": 201
},
"response": {
"refund_payment": {
"id": "a413ea0a29294c4dae258f39dabe73ea00",
"amount": 5647,
"currency": "EUR",
"message": "Limit of 140 characters",
"debtor": {
"debtor_name": "Mark Webber",
"account": {
"currency": "EUR",
"type": "IBAN",
"value": "FI9819513119469790"
}
},
"payment_status": "PAYMENT_PROCESSING",
"payment_status_reason": "Payment was accepted for execution.",
"status_timestamp": "2024-04-11T10:32:37.120420615Z"
},
"original_payment": {
"archive_id": "202103152588CEP10005",
"amount": 5647.00,
"currency": "EUR"
}
}
}Example: Get refund payment status request
This endpoint supports POST HTTP method and URL has the following form:
GET /corporate/payment-refunds/v1/refunds/{id}The following headers must be used:
X-IBM-Client-Id: {client_id}
X-IBM-Client-Secret: {client_secret}
Signature: {signature}
Technical-user-id: {technical_user_id}
X-Nordea-Originating-Date: {date}
X-Nordea-Originating-Host: {host}Where the status request is valid the response will be 200 SUCCESS and formatted like the example below:
{
"group_header": {
"message_identification": "5f6a6f8409f14f31f726e111f0f7af10",
"creation_date_time": "2024-04-11T10:37:09.238989931Z",
"http_code": 200
},
"response": {
"refund_payment": {
"id": "a7953c56069b42168e173f83170ec0e600",
"amount": 5647.00,
"currency": "EUR",
"message": "Limit of 140 characters",
"debtor": {
"debtor_name": "Mark Webber",
"account": {
"currency": "EUR",
"type": "IBAN",
"value": "FI9819513119469790"
}
},
"payment_status": "PAYMENT_PROCESSING",
"payment_status_reason": "Payment was accepted for execution.",
"status_timestamp": "2024-04-11T10:35:22.394583Z"
},
"original_payment": {
"archive_id": "202103152588CEP10005",
"amount": 5647.00,
"currency": "EUR"
}
}
}Sample test data
Following table provides test data to be used when testing Refund API in Sandbox environment.
When sending refund request in Sandbox archive id must be one of the values listed in the table.
For all requests (POST & GET) use Technical-user-id value according to the table below.
Sent refund payments are cleared from database every midnight in Sandbox env. Please be aware that you can’t request a status update on a refund payment sent during previous days. Please use dynamically updated test data as follow.
| Archive ID | Original Amount | Original Account | Dynamic Original Date | Technical-user-id |
|---|---|---|---|---|
| 202103152588CEP10001 | 50 | FI9820401800063766 | today - 750 days (more than 24 months) | 51014839302 |
| 202103152588CEP10002 | 125 | FI9820006008007885 | today - 5 days | 44420010764772010 |
| 202103152588CEP10003 | 500 | FI2112345600000785 | today - 720 days (almost 24 months) | 51014839302 |
| 202103152588CEP10004 | 650.50 | FI1410093000123458 | today - 5 days | 44420010764772010 |
| 202103152588CEP10005 | 5647 | FI9819513119469790 | today - 5 days | 51014839302 |
| 202103152588CEP10006 | 657 | FI9819112952913632 | today - 5 days | 44420010764772010 |
| 202103152588CEP10007 | 65 | FI9819093000000343 | today - 5 days | 51014839302 |
| 202103152588CEP10008 | 213.20 | FI9817913186076084 | today - 5 days | 44420010764772010 |
| 202103152588CEP10009 | 200.20 | FI9817455200000195 | today - 5 days | 51014839302 |
| 202103152588CEP10010 | 1234 | FI9815723000312512 | today - 5 days | 44420010764772010 |
Additional request examples
Create refund payment (system doesn’t find original payment)
Request URI: localhost:8080/corporate/payment-refunds/v1/refunds
Headers:
Technical-user-id:51014839302
X-IBM-Client-Id:{client_id}
X-IBM-Client-Secret:{secret_id}
Body:
{
"payment_archive_id": "202103152588CEP19999",
"payment_account": "FI9819513119469790",
"amount": "5647",
"original_payment_date": "2024-01-01",
"currency": "EUR",
"message": "Limit of 140 characters"
}Response:
{
"group_header": {
"message_identification": "c29b036853dc6fa4a1fed53024ab2c0a",
"creation_date_time": "2024-04-11T10:42:39.285809753Z",
"http_code": 201
},
"response": {
"refund_payment": {
"id": "d3fed453ddae416b9025b0fa34f1eaa300",
"amount": 5647,
"currency": "EUR",
"message": "Limit of 140 characters",
"debtor": {
"account": {
"currency": "EUR",
"type": "IBAN",
"value": "FI9819513119469790"
}
},
"payment_status": "PAYMENT_PROCESSING",
"payment_status_reason": "Payment was accepted for execution.",
"status_timestamp": "2024-04-11T10:42:39.275402866Z"
}
"original_payment": {
"archive_id": "202103152588CEP19999",
"amount": 5647,
"currency": "EUR"
}
}
}Get refund payment
Request URI: localhost:8080/corporate/payment-refunds/v1/refunds/{id}
the ‘id’ parameter is generated by RAPI during creation of refund payment and should be taken from the response of ‘Create refund payment’ from value of
Headers:
Technical-user-id:51014839302
X-IBM-Client-Id:{client_id}
X-IBM-Client-Secret:{secret_id}
Response:
{
"group_header": {
"message_identification": "a7e378fd7a05867c0f34cdf28850bd85",
"creation_date_time": "2024-04-11T10:47:11.874999194Z",
"http_code": 200
},
"response": {
"refund_payment": {
"id": "d3fed453ddae416b9025b0fa34f1eaa300",
"amount": 5647.00,
"currency": "EUR",
"message": "Limit of 140 characters",
"debtor": {
"account": {
"currency": "EUR",
"type": "IBAN",
"value": "FI9819513119469790"
}
},
"payment_status": "PAYMENT_PROCESSING",
"payment_status_reason": "Payment was accepted for execution.",
"status_timestamp": "2024-04-11T10:42:39.275403Z"
}
"original_payment": {
"archive_id": "202103152588CEP19999",
"amount": 5647.00,
"currency": "EUR"
}
}
}Get refund payment when none is found by provided ID
Request URI: localhost:8080/corporate/payment-refunds/v1/refunds/12345
Headers:
Technical-user-id:51014839302
X-IBM-Client-Id:{client_id}
X-IBM-Client-Secret:{secret_id}
Response:
{
"group_header": {
"message_identification": "2a4844f09d91dbec3d2a3c2cfc738cba",
"creation_date_time": "2024-04-11T10:51:10.781462157Z",
"http_code": 404
},
"error": {
"request": {
"url": "/corporate/payment-refunds/v1/refunds/12345"
},
"failures": [
{
"code": "error.notfound",
"description": "Payment not found based on id: 12345"
}
]
}
}Create refund with data that don’t correspond to the original payment:
Request URI: localhost:8080/corporate/payment-refunds/v1/refunds
Headers:
Technical-user-id:51014839302
X-IBM-Client-Id:{client_id}
X-IBM-Client-Secret:{secret_id}
payment account not matching
Request body:
{
"payment_archive_id": "202103152588CEP10005",
"payment_account": "FI2112345600000785",
"amount": "5647",
"original_payment_date": "2024-01-01",
"currency": "EUR",
"message": "Limit of 140 characters"
}Response:
{
"group_header": {
"message_identification": "6aedff773a42f1d9a3e85e95ae14cc12",
"creation_date_time": "2024-04-11T10:56:15.380374845Z",
"http_code": 400
},
"error": {
"request": {
"url": "/corporate/payment-refunds/v1/refunds"
},
"failures": [
{
"code": "error.validation",
"description": "Request data does not match original payment data. <account>"
}
]
}
}payment amount not matching
Request body:
{
"payment_archive_id": "202103152588CEP10005",
"payment_account": "FI9819513119469790",
"amount": "5647.01",
"original_payment_date": "2024-01-01",
"currency": "EUR",
"message": "Limit of 140 characters"
}Response:
{
"group_header": {
"message_identification": "3411122467b50abe9d4d326529a748af",
"creation_date_time": "2024-04-11T10:59:03.091697151Z",
"http_code": 400
},
"error": {
"request": {
"url": "/corporate/payment-refunds/v1/refunds"
},
"failures": [
{
"code": "error.validation",
"description": "Payment amount: 5647.01 differs from the original amount: 5647.00"
}
]
}
}payment amount wrong format
Request body:
{
"payment_archive_id": "202103152588CEP10005",
"payment_account": "FI9819513119469790",
"amount": "5647.000",
"original_payment_date": "2024-01-01",
"currency": "EUR",
"message": "Limit of 140 characters"
}Response:
{
"group_header": {
"message_identification": "9752b9d2ea1d12c348becdc910ffbb7c",
"creation_date_time": "2024-04-11T11:00:10.354205522Z",
"http_code": 400
},
"error": {
"request": {
"url": "/corporate/payment-refunds/v1/refunds"
},
"failures": [
{
"code": "error.validation",
"description": "has illegal scale (i.e. number of fractional digits) for the given amount",
"path": "amount",
"type": "ValidScale"
}
]
}
}payment date not matching
Request body:
{
"payment_archive_id": "202103152588CEP10005",
"payment_account": "FI9819513119469790",
"amount": "5647",
"original_payment_date": "2024-01-02",
"currency": "EUR",
"message": "Limit of 140 characters"
}Response:
{
"group_header": {
"message_identification": "147a29068971a1160f0e9073f65e7aa6",
"creation_date_time": "2024-04-11T11:16:07.979978528Z",
"http_code": 400
},
"error": {
"request": {
"url": "/corporate/payment-refunds/v1/refunds"
},
"failures": [
{
"code": "error.validation",
"description": "Request data does not match original payment data. <payment date>"
}
]
}
}Technical user id not authorized to view refund payment. User with technical ID does not have correct permission to view the account.
Request URI: localhost:8080/corporate/payment-refunds/v1/refunds/{id}
Headers:
Technical-user-id:44420010764772010
X-IBM-Client-Id:{client_id}
X-IBM-Client-Secret:{secret_id}
Response:
{
"group_header": {
"message_identification": "a9b50159c41b18a0f56f5255108ffb52",
"creation_date_time": "2024-04-11T11:27:17.804403205Z",
"http_code": 403
},
"error": {
"request": {
"url": "/corporate/payment-refunds/v1/refunds/a413ea0a29294c4dae258f39dabe73ea00"
},
"failures": [
{
"code": "error.resource.denied",
"description": "No permission to account"
}
]
}
}Create refund payment older than 24 months
Request URI: localhost:8080/corporate/payment-refunds/v1/refunds
Headers:
Technical-user-id:51014839302
X-IBM-Client-Id:{client_id}
X-IBM-Client-Secret:{secret_id}
Request body:
{
"payment_archive_id": "202103152588CEP10001",
"payment_account": "FI9820401800063766",
"amount": "50",
"original_payment_date": "2020-01-01",
"currency": "EUR",
"message": "Limit of 140 characters"
}Response:
{
"group_header": {
"message_identification": "85b474b24d203751d2b40efd3dfed769",
"creation_date_time": "2024-04-11T11:31:34.787002977Z",
"http_code": 400
},
"error": {
"request": {
"url": "/corporate/payment-refunds/v1/refunds"
},
"failures": [
{
"code": "error.validation",
"description": "Payments older than 24 months are not possible to refund."
}
]
}
}