Create a session from your backend

In order to use a component of Pay.Parts in your frontend you need to initialize a session. A session is initialized by sending a POST request from your backend.

Create a session from your backend

In order to use a component of Pay.Parts in your frontend you need to initialize a session. A session is initialized by sending a POST request from your backend.

Base URL

The following URLs are available:

Production

https://parts.pay.nl

Zero (Pre-Production)

https://zero-parts.pay.nl

Authentication

Session Create (Basic Auth)

The POST /v1/session/start endpoint uses HTTP Basic Authentication with your Sales Location credentials:

Authorization: Basic <base64(sl-code:secret)>

Session Get (Basic Auth)

The GET /v1/session/{sessionId} endpoint uses Basic Authentication with your Sales Location credentials (same as create session):

Authorization: Basic <base64(sl-code:secret)>

Endpoints

Create Session

Create a new payment session.

Endpoint: POST /v1/session/start

Authentication: Basic Auth (SL-CODE:SECRET)

Minimum Required Request

curl -X POST 'https://parts.pay.nl/v1/session/start' \
  -H 'Authorization: Basic <base64(sl-code:secret)>' \
  -H 'Content-Type: application/json' \
  -d '{
    "returnUrl": "https://example.com/return",
    "exchangeUrl": "https://example.com/exchange",
    "amount": {
      "value": 100,
      "currency": "EUR"
    }
  }'
💡

Required fields for order-based / redirect methods (e.g. iDEAL)

The minimal request only requires amount, returnUrl and exchangeUrl. However, when the payer selects an order-based/redirect payment method — such as iDEAL, a redirect method where the payer finalizes payment on Pay's page — the session must also contain the full order (line items with vatPercentage, plus delivery and invoice addresses) and the customer.

Without these, the POST /v1/session/{id}/pay call fails with 422 PAY-2880 requiredDataMissing. Use the full request below as your starting point (the order and customer fields are not optional in practice for these methods).

📘

reference format

reference is a free-text merchant reference (e.g. your order number) that Pay stores with the transaction. Pay's own examples use plain values such as REF.210709461 or 210709461. It is forwarded to the underlying Pay order API, which validates it server-side — the exact allowed charset is not exposed in the API spec.

In practice keep it short and plain. Identifiers containing characters such as _ (underscore) — e.g. a Medusa cart id cart_01M3... or order_123 — are rejected with 422 PAY-1422 reference: Deze waarde is niet geldig. ("reference: this value is not valid"). Strip non-alphanumerics from internal IDs (or send a clean order number) before creating the session.

Full Request (recommended — includes the order and customer)
curl -X POST 'https://parts.pay.nl/v1/session/start' \
  -H 'Authorization: Basic <base64(sl-code:secret)>' \
  -H 'Content-Type: application/json' \
  -d '{
    "returnUrl": "https://example.com/return",
    "exchangeUrl": "https://example.com/exchange",
    "amount": { "value": 100, "currency": "EUR" },
    "description": "Order 12345",
    "reference": "REF-12345",
    "expire": "2026-09-01T12:00:00Z",
    "customer": {
      "email": "[email protected]",
      "firstName": "John",
      "lastName": "Doe",
      "phone": "+31000000000",
      "birthDate": "1990-01-01",
      "gender": "M",
      "locale": "nl_NL"
    },
    "order": {
      "countryCode": "NL",
      "deliveryDate": "2026-09-02",
      "invoiceDate": "2026-09-01",
      "deliveryAddress": {
        "firstName": "John",
        "lastName": "Doe",
        "street": "Main Street",
        "streetNumber": "1",
        "streetNumberExtension": "A",
        "zipCode": "1234AB",
        "city": "Amsterdam",
        "country": "NL",
        "region": "Noord-Holland"
      },
      "invoiceAddress": {
        "firstName": "John",
        "lastName": "Doe",
        "street": "Main Street",
        "streetNumber": "1",
        "streetNumberExtension": "A",
        "zipCode": "1234AB",
        "city": "Amsterdam",
        "country": "NL"
      },
      "products": [
        {
          "id": "SKU-001",
          "description": "Product one",
          "type": "ARTICLE",
          "price": { "value": 800, "currency": "EUR" },
          "quantity": 1,
          "vatPercentage": 21
        },
        {
          "id": "SKU-002",
          "description": "Product two",
          "type": "SHIPPING",
          "price": { "value": 200, "currency": "EUR" },
          "quantity": 1,
          "vatPercentage": 21
        }
      ]
    },
    "integration": {
      "checkoutUrl": "https://example.com/checkout/<order_id>"
    }
  }'
💱

Units — all monetary values are in the smallest currency unit

All monetary values (amount.value, and every order products[].price.value) are in the smallest currency unit (e.g. cents). €10.00 = 1000 — never send decimal euros. Convert at the boundary.

⚠️

Zero-priced order lines are rejected

Order/product lines with price.value: 0 are rejected (422 amount.value must be greater than 0). Omit zero-priced lines (e.g. free shipping) instead of sending them with a 0 value.

📘

Session expiry and expire

Sessions expire. Set the optional expire field (ISO-8601, e.g. "2026-09-01T12:00:00Z") to establish or extend the session's lifetime.

Once a session has expired, POST /v1/session/{id}/pay (and the SDK's onError) return 410 Gone — create a fresh session or set a longer expire. See the pay call.

Successful Response

{
  "sessionId": "a3fc44c532784ce1b8ac2f2a003e1239",
  "sessionToken": "st_eyJTZXNzaW9uSWQiOiJhM2ZjNDRjNTMyNzg0Y2UxYjhhYzJmMmEwMDNlMTIzOSIsIkNvbmZpZyI6eyJtZXJjaGFudE5hbWUiOiJDYW55b24gQmlrZXMiLCJhbW91bnQiOnsidmFsdWUiOjI5OTksImN1cnJlbmN5IjoiRVVSIiwiZm9ybWF0dGVkIjoiMjk5Ljk5In19fQ=="
}

Get a session

Retrieve session details. Returns the same session token, amount, customer, and order that were used when creating the session.

Endpoint: GET /v1/session/{sessionId}

Authentication: Basic Auth (SL-CODE:SECRET)

curl -X GET "https://parts.pay.nl/v1/session/a3fc44c532784ce1b8ac2f2a003e1239" \
  -H 'Authorization: Basic <base64(sl-code:secret)>'
Successful Response
{
  "sessionId": "a3fc44c532784ce1b8ac2f2a003e1239",
  "sessionToken": "st_eyJhbGciOiJIUzI1NiJ9...",
  "amount": {
    "value": 1000,
    "currency": "EUR"
  },
  "customer": {
    "email": "[email protected]",
    "firstName": "John",
    "lastName": "Doe",
    "phone": "+31000000000",
    "birthDate": "1990-01-01",
    "gender": "M",
    "locale": "nl_NL"
  },
  "order": {
    "countryCode": "NL",
    "deliveryDate": "2026-09-02",
    "invoiceDate": "2026-09-01",
    "deliveryAddress": {
      "firstName": "John",
      "lastName": "Doe",
      "street": "Main Street",
      "streetNumber": "1",
      "streetNumberExtension": "A",
      "zipCode": "1234AB",
      "city": "Amsterdam",
      "country": "NL",
      "region": "Noord-Holland"
    },
    "invoiceAddress": {
      "firstName": "John",
      "lastName": "Doe",
      "street": "Main Street",
      "streetNumber": "1",
      "streetNumberExtension": "A",
      "zipCode": "1234AB",
      "city": "Amsterdam",
      "country": "NL",
      "region": "Noord-Holland"
    },
    "products": [
      {
        "id": "SKU-001",
        "description": "Product one",
        "type": "ARTICLE",
        "price": { "value": 800, "currency": "EUR" },
        "quantity": 1,
        "vatPercentage": 21
      }
    ]
  },
  "orderStatus": {
    "orderId": "50xxxxxxxxxx7f",
    "status": "PENDING",
    "amount": { "value": 1000, "currency": "EUR" },
    "capturedAmount": { "value": 0, "currency": "EUR" },
    "authorizedAmount": { "value": 1000, "currency": "EUR" },
    "outstandingAmount": { "value": 1000, "currency": "EUR" },
    "isFullyPaid": false,
    "payments": [
      {
        "id": "11111111-1111-2222-3333-123412341234",
        "paymentMethod": {
          "id": 1
        },
        "amount": { "value": 1000, "currency": "EUR" },
        "capturedAmount": { "value": 0, "currency": "EUR" },
        "authorizedAmount": { "value": 1000, "currency": "EUR" },
        "status": {
          "code": 25,
          "action": "AUTHORIZE"
        }
      }
    ]
  }
}

orderStatus is only present once the session has an order (after the first authenticate step); before that it's null.

Update a session

Update the session amount and/or order (products) before a payment order has been created.

Endpoint: PATCH /v1/session/{sessionId}

Authentication: Authenticated against the session (typically invoked via the SDK's checkout.updateSession() after initialization).

This endpoint isn't yet available in Production.


Did this page help you?