Payments API
The Payments API allows Third Party Providers (TPPs) to initiate payments on behalf of authorized users. All payment endpoints require the PSP_PI (Payment Initiation) scope.
Payment Authorization Flow
All payment initiations follow a redirect-based authorization flow. When you initiate a payment, the user must authorize it through the Lunar app before it can be executed.
Payment Types
Domestic Credit Transfer
National bank transfers within Denmark, Norway, or Sweden.
Initiate Transfer
POST /payments/domestic-credit-transfer| Field | Type | Required | Description |
|---|---|---|---|
redirectUrl | string | Yes | URL to redirect user after authorization |
accountId | string | Yes | Source account ID |
recipientBBAN | string | Yes | Recipient’s BBAN (11-14 characters) |
recipientName | string | DK only | Required for instant transfers in Denmark |
amount | string | Yes | Payment amount |
currency | string | Yes | Currency code (ISO 4217) |
message | string | No | Message to recipient (see limits below) |
title | string | No | Transaction title for sender (max 140 chars) |
date | date | No | Execution date (ISO-8601 date, YYYY-MM-DD, defaults to earliest possible) |
Message length limits by country: - Denmark (instant): 140 characters
- Denmark (intraday): 20 characters - Sweden: 12 characters - Norway: 70 characters All Lunar transfers in Denmark are executed as instant transfers.
Get Transfer Status
GET /payments/domestic-credit-transfer/{id}Returns the payment details including current status. The response includes an instant boolean field (defaults to true, indicates the transfer is executed as an instant transfer in Denmark) and a status object containing state, failureCode, and message fields. See Generic Status object for details.
Standing Orders
Recurring national bank transfers for regular bills or payments.
List Standing Orders
GET /payments/standing-orderReturns all standing orders for the authenticated user.
Create Standing Order
POST /payments/standing-order| Field | Type | Required | Description |
|---|---|---|---|
senderAccountId | string | Yes | Source account ID |
senderMessage | string | Yes | Message/reference for sender |
receiverAccount | string | Yes | Recipient’s BBAN |
receiverMessage | string | Yes | Message to recipient |
amount | number | Yes | Payment amount |
currency | string | Yes | Currency code |
activeFrom | date | Yes | Start date (ISO-8601 date, YYYY-MM-DD) |
frequency | object | Yes | Payment schedule (see below) |
terminationPolicy | object | Yes | When to stop payments |
redirectUrl | string | No | Redirect URL after authorization |
The response is a PaymentInitiationResponse containing authUrl and paymentId (not the created standing order itself). The user must follow the authUrl to authorize the standing order.
Frequency Options
Standing orders support flexible scheduling:
Daily:
{ "daily": true }Weekly:
{ "weekly": { "dayOfWeek": "MONDAY" } }Monthly:
{ "monthly": { "interval": 1, "paymentDay": "15" } }Payment day options: FIRST_BANK_DAY, LAST_BANK_DAY, or a specific day (1-31).
Standing Order Status
Each standing order has a status field indicating its lifecycle state:
| Status | Description |
|---|---|
ACTIVE | The standing order is active and will execute |
DISABLED | The standing order is temporarily disabled |
DELETED | The standing order has been deleted |
Get Standing Order
GET /payments/standing-order/{id}Returns a wrapper object containing standingOrder (the standing order details) and redirectUrl.
Delete Standing Order
DELETE /payments/standing-order/{id}Returns { "success": true } on successful deletion.
Danish Payment Slip (GIRO/FI)
Traditional Danish payment slips for utility bills and invoices.
Initiate Payment Slip
POST /payments/dk-payment-slip| Field | Type | Required | Description |
|---|---|---|---|
redirectUrl | string | Yes | URL to redirect user after authorization |
accountId | string | Yes | Source account ID |
amount | number | Yes | Payment amount |
currency | string | Yes | Currency code (ISO 4217) |
type | string | Yes | GIRO/FI type: 01, 04, 15, 71, 73, or 75 |
debtorId | string | Yes | Your identifier (payer reference) |
creditorId | string | Yes | Creditor number (max 8 characters) |
message | string | No | Payment message (max 140 characters) |
title | string | No | Transaction title for sender |
date | date | No | Execution date (ISO-8601 date, YYYY-MM-DD) |
When retrieving a DK Payment Slip via GET, the type field in the response
may also include the value Unspecified in addition to the initiation types
listed above.
Get Payment Slip Status
GET /payments/dk-payment-slip/{id}SE Bank Giro
Swedish Bank Giro payments for paying invoices to Swedish businesses.
Initiate Bank Giro Payment
POST /payments/se-bank-giro| Field | Type | Required | Description |
|---|---|---|---|
giroNumber | string | Yes | The Bank Giro number of the recipient (with or without dash, e.g. 5894-2590 or 58942590) |
ocrReference | string | Yes | OCR payment reference |
amount | string | Yes | Payment amount as decimal string (e.g. “100.00”) |
currency | string | Yes | Currency code (SEK) |
senderAccountId | string | Yes | Sender’s account UUID |
redirectUrl | string | Yes | TPP callback URL for redirect after completion |
messageToSender | string | No | Message to sender |
date | date | No | Future execution date (ISO-8601 date, YYYY-MM-DD) |
Errors:
| Status | Description |
|---|---|
400 | Invalid request. The response contains a top-level code and message, plus an errors array of validation errors each with field, code, and message fields |
500 | Internal server error |
Get Bank Giro Payment
GET /payments/se-bank-giro/{id}Returns the payment details with the following fields:
| Field | Type | Description |
|---|---|---|
paymentId | string | Unique payment identifier |
status | string | Payment status string (see SE Giro status) |
authUrl | string | Authorization URL (present when AWAITING_APPROVAL) |
giroNumber | string | The Bank Giro number |
ocrReference | string | OCR payment reference |
amount | string | Payment amount |
currency | string | Currency code |
senderAccountId | string | Sender’s account UUID |
messageToSender | string | Message to sender |
redirectUrl | string | TPP redirect URL |
date | date | Execution date (ISO-8601 date, YYYY-MM-DD) |
Cancel Bank Giro Payment
DELETE /payments/se-bank-giro/{id}Cancels a Bank Giro payment. The operation is idempotent — cancelling an already-cancelled payment returns 204.
A payment can only be cancelled when its status is APPROVED or POSTPONED (i.e. the user has authorized the payment but it has not yet been executed).
| Status | Code | Description |
|---|---|---|
204 | Payment cancelled (or was already cancelled) | |
404 | NOT_FOUND | Payment not found |
409 | PAYMENT_AWAITING_CHALLENGE | Payment is still in the challenge flow — complete or decline the challenge before cancelling |
409 | PAYMENT_ALREADY_FULFILLED_FAILED | Payment has already been fulfilled or failed and cannot be cancelled |
500 | INTERNAL_ERROR | Internal server error |
SE Plus Giro
Swedish Plus Giro payments for paying invoices to Swedish businesses.
Initiate Plus Giro Payment
POST /payments/se-plus-giro| Field | Type | Required | Description |
|---|---|---|---|
giroNumber | string | Yes | The Plus Giro number of the recipient |
ocrReference | string | Yes | OCR payment reference |
amount | string | Yes | Payment amount as decimal string (e.g. “100.00”) |
currency | string | Yes | Currency code (SEK) |
senderAccountId | string | Yes | Sender’s account UUID |
redirectUrl | string | Yes | TPP callback URL for redirect after completion |
messageToSender | string | No | Message to sender |
date | date | No | Future execution date (ISO-8601 date, YYYY-MM-DD) |
Errors:
| Status | Description |
|---|---|
400 | Invalid request. The response contains a top-level code and message, plus an errors array of validation errors each with field, code, and message fields |
500 | Internal server error |
Get Plus Giro Payment
GET /payments/se-plus-giro/{id}Returns the payment details with the following fields:
| Field | Type | Description |
|---|---|---|
paymentId | string | Unique payment identifier |
status | string | Payment status string (see SE Giro status) |
authUrl | string | Authorization URL (present when AWAITING_APPROVAL) |
giroNumber | string | The Plus Giro number |
ocrReference | string | OCR payment reference |
amount | string | Payment amount |
currency | string | Currency code |
senderAccountId | string | Sender’s account UUID |
messageToSender | string | Message to sender |
redirectUrl | string | TPP redirect URL |
date | date | Execution date (ISO-8601 date, YYYY-MM-DD) |
Cancel Plus Giro Payment
DELETE /payments/se-plus-giro/{id}Cancels a Plus Giro payment. The operation is idempotent — cancelling an already-cancelled payment returns 204.
A payment can be cancelled as long as it has not yet reached its execution date. Once the payment has been processed (past its execution date), cancellation is no longer possible and returns 409.
| Status | Code | Description |
|---|---|---|
204 | Payment cancelled (or was already cancelled) | |
404 | NOT_FOUND | Payment not found |
409 | PAYMENT_AWAITING_CHALLENGE | Payment is still in the challenge flow — complete or decline the challenge before cancelling |
409 | PAYMENT_ALREADY_FULFILLED_FAILED | Payment has already been fulfilled or failed and cannot be cancelled |
500 | INTERNAL_ERROR | Internal server error |
Payment Statuses
Payment status models differ between payment types.
Generic Status Object
Used by Domestic Credit Transfer, DK Payment Slip, and Standing Orders. The status is returned as an object with the following fields:
| Field | Description |
|---|---|
state | One of the state values listed below |
failureCode | Error code when the payment has failed (optional) |
message | Additional status details (optional) |
| State | Description |
|---|---|
AWAITING_APPROVAL | Payment created, waiting for user authorization |
PENDING | Payment authorized, pending execution |
COMPLETED | Payment successfully executed |
FAILED | Payment execution failed (see failureCode) |
CANCELLED | Payment was cancelled |
UNKNOWN | Status could not be determined |
SE Giro Status
Used by SE Bank Giro and SE Plus Giro. The status is returned as a plain string enum (not an object):
| Status | Description |
|---|---|
AWAITING_APPROVAL | Payment created, waiting for user authorization |
APPROVED | Payment has been approved |
FAILED | Payment execution failed |
DECLINED | Payment was declined |
CANCELLED | Payment was cancelled |
Always check the payment status after the user returns from the authorization
flow. A redirect back to your redirectUrl does not guarantee the payment was
approved.
Error Handling
Error responses contain a list of all validation errors found in the request.
Each error in the list includes an errorCode and message field, making it
easy to understand what went wrong and fix all issues in a single pass.
| Status | Description |
|---|---|
400 | Invalid request (e.g., invalid BBAN, insufficient data) |
404 | Payment not found |
500 | Internal server error |
Error responses include an errorCode and message with details about the failure.