Documentation Index
Fetch the complete documentation index at: https://docs.dintero.com/llms.txt
Use this file to discover all available pages before exploring further.
You can create and pay invoices programmatically without the customer going through checkout. There are two approaches depending on your use case:
- One-step: use the Merchant Initiate Transaction (MIT) endpoint
POST /v1/sessions/pay. Best for automated invoicing or recurring billing.
- Two-step: create a session via
POST /v1/sessions or POST /v1/sessions-profile, then call POST /v1/sessions/{session_id}/pay to complete it. Useful when you want to set up the session first and pay it later, or when integrating with existing session creation flows.
Billing Address Requirements
Both flows require a billing address with the same fields as customer checkout. The location differs: in one-step it’s in session.order.billing_address, in two-step it’s in the pay request body.
One-Step: Create and Pay
A single call creates the session and registers the invoice:
Identity verification is automatically skipped. The billing address is provided in session.order.billing_address (see required fields). The transaction is AUTHORIZED on creation and moves to CAPTURED once Kravia confirms the shopper has paid.
B2B Example
POST /v1/sessions/pay
Authorization: Bearer <token>
Content-Type: application/json
{
"payment": {
"payment_product_type": "kravia.invoice_b2b",
"operation": "invoice_payment",
"days_until_due": 30
},
"session": {
"url": {
"callback_url": "https://example.com/callback"
},
"order": {
"amount": 29900,
"currency": "NOK",
"vat_amount": 5980,
"merchant_reference": "<your-unique-id-here>",
"items": [
{
"description": "Monthly subscription - Premium",
"quantity": 1,
"amount": 29900,
"vat": 25,
"line_id": "sub-001"
}
],
"billing_address": {
"first_name": "Ola",
"last_name": "Nordmann",
"business_name": "Nordmann AS",
"organization_number": "123456789",
"email": "ola@nordmann.no",
"phone_number": "+4799999999",
"address_line": "Storgata 1",
"postal_code": "0151",
"postal_place": "Oslo",
"country": "NO"
}
}
}
}
B2C Example
For B2C invoices, omit business_name and organization_number:
POST /v1/sessions/pay
Authorization: Bearer <token>
Content-Type: application/json
{
"payment": {
"payment_product_type": "kravia.invoice_b2c",
"operation": "invoice_payment",
"days_until_due": 14
},
"session": {
"url": {
"callback_url": "https://example.com/callback"
},
"order": {
"amount": 29900,
"currency": "NOK",
"vat_amount": 5980,
"merchant_reference": "<your-unique-id-here>",
"items": [
{
"description": "Online subscription",
"quantity": 1,
"amount": 29900,
"vat": 25,
"line_id": "item-1"
}
],
"billing_address": {
"first_name": "Kari",
"last_name": "Nordmann",
"email": "kari@example.no",
"phone_number": "+4798765432",
"address_line": "Lillegata 5",
"postal_code": "5003",
"postal_place": "Bergen",
"country": "NO"
}
}
}
}
One-Step Payment Fields
| Field | Type | Required | Description |
|---|
payment_product_type | String | Yes | "kravia.invoice_b2b", "kravia.invoice_b2b_grouped", or "kravia.invoice_b2c" |
operation | String | Yes | Must be "invoice_payment" |
days_until_due | Integer | Yes | Days until invoice is due (0-365) |
invoice_channel | String | No | "kravia" (default) or "merchant". See Invoice Delivery. |
Two-Step: Create Session, Then Pay
Create a session first, then programmatically call the pay endpoint. We recommend setting require_identity_verification: false on the payment type configuration to skip identity verification.
Step 1: Create the Session
For B2B
POST /v1/sessions
Authorization: Bearer <token>
Content-Type: application/json
{
"url": {
"callback_url": "https://example.com/callback"
},
"order": {
"amount": 29900,
"currency": "NOK",
"vat_amount": 5980,
"merchant_reference": "<your-unique-id-here>",
"items": [
{
"description": "Consulting services",
"quantity": 1,
"amount": 29900,
"vat": 25,
"line_id": "item-1"
}
]
},
"configuration": {
"kravia": {
"type": "payment_type",
"invoice_b2b": {
"type": "payment_product_type",
"enabled": true,
"days_until_due": 30,
"require_identity_verification": false,
"invoice_channel": "kravia"
}
}
}
}
For B2C, set the same flags:
{
"configuration": {
"kravia": {
"type": "payment_type",
"invoice_b2c": {
"type": "payment_product_type",
"enabled": true,
"days_until_due": 14,
"require_identity_verification": false,
"invoice_channel": "kravia"
}
}
}
}
Step 2: Pay the Session
Call the pay endpoint with the payment_product_type and billing_address. Note that the billing address is provided in the pay request body, not in the session order:
B2B:
POST /v1/sessions/{session_id}/pay
Authorization: Bearer <token>
Content-Type: application/json
{
"payment_product_type": "kravia.invoice_b2b",
"billing_address": {
"first_name": "Ola",
"last_name": "Nordmann",
"business_name": "Nordmann AS",
"organization_number": "123456789",
"email": "ola@nordmann.no",
"phone_number": "+4799999999",
"address_line": "Storgata 1",
"postal_code": "0151",
"postal_place": "Oslo",
"country": "NO"
}
}
B2C:
POST /v1/sessions/{session_id}/pay
Authorization: Bearer <token>
Content-Type: application/json
{
"payment_product_type": "kravia.invoice_b2c",
"billing_address": {
"first_name": "Kari",
"last_name": "Nordmann",
"email": "kari@example.no",
"phone_number": "+4798765432",
"address_line": "Lillegata 5",
"postal_code": "5003",
"postal_place": "Bergen",
"country": "NO"
}
}
Two-Step Pay Fields
| Field | Type | Required | Description |
|---|
payment_product_type | String | Yes | "kravia.invoice_b2b", "kravia.invoice_b2b_grouped", or "kravia.invoice_b2c" |
billing_address | Object | Yes | Customer billing details, see billing address requirements |
Response
Both approaches return a transaction with status AUTHORIZED. An INITIATE_CAPTURE event is added automatically as Kravia begins delivery. The transaction moves to CAPTURED (or PARTIALLY_CAPTURED) once Kravia confirms the shopper has paid.
{
"id": "T12345",
"status": "AUTHORIZED",
"payment_product_type": "kravia.invoice_b2b",
"amount": 29900,
"merchant_reference": "inv-2026-001",
"metadata": {
"kravia:invoice_number": "INV-2026-0001",
"kravia:invoice_url": "https://api.dintero.com/v1/files/f-abc123"
},
"events": [
{
"event": "AUTHORIZE",
"created_at": "2026-01-15T10:30:00Z",
"metadata": {
"kravia:invoice_date": "2026-01-15",
"kravia:invoice_due_date": "2026-02-14",
"kravia:invoice_number": "INV-2026-0001"
}
},
{
"event": "INITIATE_CAPTURE",
"created_at": "2026-01-15T10:30:00Z"
}
]
}
Cancellations
Refund is not supported for Kravia. To cancel an invoice, call POST /v1/transactions/{id}/void. Void is allowed on AUTHORIZED (cancels the invoice) and on PARTIALLY_CAPTURED (cancels the remaining amount). See Cancellations in Customer checkout for the full rules per state.
Duplicate Prevention
Use the Dintero-Feature-Toggles header to prevent duplicate invoices:
| Toggle | Behavior |
|---|
strict-merchant-reference | Returns 400 if merchant_reference already exists in any session |
strict-success-merchant-reference | Returns 400 if merchant_reference exists in a successfully authorized session. Allows retries after failures. |
POST /v1/sessions/pay
Authorization: Bearer <token>
Dintero-Feature-Toggles: strict-success-merchant-reference
Content-Type: application/json
{ ... }
See Also