Domestic Credit Transfer Drafts
Domestic credit transfer drafts use /payments/drafts/domestic-credit-transfer. They follow the same draft lifecycle and are approved through signing baskets.
In addition to the common fields, domestic credit transfer drafts support:
| Field | Type | Description |
|---|---|---|
receiverAccountBban | string | Receiver account number (BBAN). 11–14 characters. |
kidNumber | string | Optional Norwegian KID payment reference for NOK transfers between Norwegian sender and recipient accounts. Send as a string to preserve leading zeroes; included in draft responses when set. See KID payments in Norway for an explanation. |
receiverName | string | Name of the receiver. Required for instant transfers in Denmark (all Lunar DK transfers are instant). |
amount | string | Payment amount as decimal string (e.g. "100.00"). Must be positive. |
currency | string | Currency code: DKK, SEK, or NOK. |
senderAccountId | string | Sender’s account UUID. |
executionDate | string | Execution date (ISO-8601 date, YYYY-MM-DD). Defaults to earliest possible when omitted on approval. |
senderMessage | string | Transaction title for the sender (visible on the sender’s account). Max length: 140 characters (DK, SE, NO). |
shortReceiverMessage | string | Message to the recipient. Max length by currency: DK 140 characters (instant; all Lunar DK transfers are instant), SE 12 characters, NO 70 characters. Danish non–banking-services accounts may be limited to 12 characters at validation. Same limits as message on direct initiation. |
All payment fields except draftId and name are optional at creation time and can be added later via PATCH. See Sender Account Access when setting senderAccountId.
Migrating from POST /payments/domestic-credit-transfer? See Migration from
direct DCT to
drafts for the
field mapping table and before/after flow.
KID payments in Norway
A KID (kundeidentifikasjon) is a structured Norwegian payment reference, often printed on an invoice. The recipient uses it to match an incoming payment to the correct invoice or customer. It is separate from the recipient’s bank account number (BBAN).
KID payments are supported only when both the sender and recipient accounts are Norwegian. For a Norwegian (NOK) domestic credit transfer draft between Norwegian accounts, set kidNumber when the recipient provides a KID. Send it as a string so any leading zeroes are preserved. The direct-initiation endpoint does not expose a KID field; use a draft to make a payment with a KID.
Whether a KID is required depends on the recipient’s account. Check the draft’s validation result: KID_REQUIRED means you need to provide one, INVALID_KID means you need to correct it, and KID_NOT_SUPPORTED means you should clear it or choose a different recipient account. See Validation Requirements for details.
When available on the resulting transaction, the KID reference is exposed as additionalInformation.kidNumber in Transactions v2. The value remains a string, preserving leading zeroes. The key is omitted when no non-empty KID reference is available; use this structured field rather than title or message to read the payment reference.
Validation Requirements
Before a domestic credit transfer draft can be approved, it must pass validation. Every create, update, and get response includes isValid, which tells you whether the payment details are valid. Because availability for approval is eventually consistent, also wait for the draft to appear as valid in GET /payments/drafts before calling POST /payments/drafts/approve.
When isValid is false, read validationErrors[0].code for programmatic handling and validationErrors[0].message for display. Pass X-Language (en, sv, da, nb) to localize the message; defaults to en. See Draft Response for the full response shape.
Minimum fields — all four must be populated before Lunar runs full domestic credit transfer validation (same rules as direct initiation):
| Field | Requirement |
|---|---|
receiverAccountBban | Must be non-empty |
amount | Must be a positive decimal string |
currency | Must be DKK, SEK, or NOK |
senderAccountId | Must be a valid account UUID |
If any minimum field is missing, isValid is false and validationErrors describes that required fields are still missing.
Full DCT validation runs once all minimum fields are present. The same rules as direct initiation apply, including:
| Field | Requirement |
|---|---|
receiverName | Required for instant transfers in Denmark (all Lunar DK transfers are instant) |
senderMessage, shortReceiverMessage, executionDate | Optional at creation, but validated when supplied |
Example — minimum fields not yet populated:
{
"draftId": "1f4a9c3e-2b7d-4e8a-9f10-6c8b3d5e7f01",
"status": "CREATED",
"isValid": false,
"name": "Rent May",
"validationErrors": [
{
"field": "draft",
"code": "MISSING_REQUIRED_FIELDS",
"message": "Several required fields are missing"
}
]
}Example — full validation ran but a value is invalid:
{
"draftId": "1f4a9c3e-2b7d-4e8a-9f10-6c8b3d5e7f01",
"status": "CREATED",
"isValid": false,
"name": "Rent May",
"receiverAccountBban": "11112222333344",
"amount": "100.00",
"currency": "DKK",
"senderAccountId": "acc-123",
"validationErrors": [
{
"field": "draft",
"code": "INVALID_RECEIVER_ACCOUNT",
"message": "The receiver account is invalid"
}
]
}Validation error codes — domestic credit transfer drafts return a single aggregated entry with field: "draft". The code identifies the reason. Only codes the TPP can resolve by updating draft fields are listed:
| Code | When returned |
|---|---|
MISSING_REQUIRED_FIELDS | One or more of receiverAccountBban, amount, currency, senderAccountId is missing |
INVALID_AMOUNT | Amount is not a valid positive number |
INVALID_CURRENCY | Currency is not DKK, SEK, or NOK |
INVALID_KID | The supplied KID reference is invalid |
INVALID_RECEIVER_ACCOUNT | Receiver BBAN is invalid or not found |
INVALID_SENDER_ACCOUNT | Sender account is invalid, closed, or inaccessible |
SAME_SENDER_AND_RECEIVER | Sender and receiver accounts are the same |
INVALID_SENDER_MESSAGE | Sender message contains invalid characters |
INVALID_RECEIVER_MESSAGE | Receiver message contains invalid characters |
INVALID_CREDITOR_NAME | Receiver name is invalid |
INVALID_PAYMENT_DATE | Execution date is invalid |
KID_NOT_SUPPORTED | Receiver account does not support the supplied KID; clear it or use a different receiver |
KID_REQUIRED | Receiver account requires a KID reference; supply kidNumber |
AMOUNT_EXCEEDS_MAXIMUM | Amount exceeds allowed maximum |
AMOUNT_BELOW_MINIMUM | Amount is below allowed minimum |
SENDER_MESSAGE_TOO_LONG | Sender message exceeds max length |
RECEIVER_MESSAGE_TOO_LONG | Receiver message exceeds max length |
GENERIC_ERROR | Validation service error |
UNKNOWN_VALIDATION_ERROR | Unmapped validation failure |
For KID-related results, set or correct kidNumber in response to KID_REQUIRED or INVALID_KID. For KID_NOT_SUPPORTED, clear kidNumber or select a receiver account that accepts KID payments.
Use code for programmatic handling; use message for localized display.
Payment failure and cancellation
When a previous approval or payment attempt fails, the draft returns to CREATED and GET /payments/drafts/domestic-credit-transfer/{id} includes previousFailureReason — a localized string describing the failure (pass X-Language; supported values: en, sv, da, nb). The same failure is surfaced as localized paymentError on GET /payments/drafts.
previousFailureReason and paymentError always reflect the draft’s
current state, regardless of which approval request caused the failure.
This is a different view from GET /payments/drafts/approve/{requestId} /status:
the request that experienced the failure keeps reporting FAILED with its
original errorMessage indefinitely, and does not update when you retry.
Track the retry under the new requestId you supply to POST /payments/drafts/approve rather than polling the failed request again.
Pass X-Language on GET (and on create/patch responses) to localize validationErrors[].message and previousFailureReason on domestic credit transfer drafts. Use validationErrors[].code for programmatic handling — it is language-independent. Defaults to en if omitted or unrecognized.
To cancel an in-flight payment linked to a draft:
DELETE /payments/drafts/domestic-credit-transfer/{id}/paymentReturns 204 No Content when the in-flight payment is cancelled. The operation is idempotent when the payment is already cancelled. Returns 409 Conflict when the draft has no in-flight payment to cancel (for example, the draft is still in CREATED with no prior approval).