Last updated

Start Building

The Manual Checkout Flow

Norce Checkout Path

This tutorial covers the Norce Checkout path, where the Order API and adapter APIs handle the flow.

The legacy checkout path (Shopping Service) is documented separately in Working with the Legacy Purchase Process.

This guide takes you through a complete manual integration flow, starting from an existing basket in Norce Commerce and ending with a completed order.

Instead of relying on an external payment provider, we use the Norce Adapter together with a Non-PSP Adapter to simulate the entire checkout process.

This setup is ideal for understanding:

  • How the Order API manages state
  • How adapters synchronize data using hooks
  • How an order transitions from Checkout to Completed

Prerequisites

To follow this guide, you need:

  1. Access to Norce Commerce Playground This guide assumes that you are using the Playground environment.

  2. An existing basket in Norce Commerce The basket must be configured with Payment Method 239 (Norce Checkout) and optionally Delivery Method 128 (External Delivery) if you use external shipping logic.


We recommend using an HTTP client such as Bruno or Postman.

You can download our ready-to-use collection here: Norce Checkout Collection (GitHub)


Quick Reference: The Minimal Flow

For experienced developers, here is the API sequence we will build:

  1. Configure Create a channel by configuring a Norce Adapter (one-time setup)
  2. Configure the Non-PSP Adapter for the channel (one-time setup)
  3. Create checkout order: POST /api/v1/orders (Norce Adapter)
  4. Add payment: POST /api/v1/checkout/orders/{id}/payments (Non-PSP Adapter)
  5. Add customer: PUT /api/v0/checkout/orders/{id}/customer/billing (Order API)
  6. Complete order: POST /api/v1/checkout/orders/{id}/payments/{pid}/complete (Non-PSP Adapter)

Detailed Flow (Step by Step)

This section walks through the full integration flow in detail, including example requests and explanations.

The examples use a fictional merchant called Things & Stuff and the Playground environment to illustrate the flow. Replace the example values (merchant, channel, and IDs) with the ones from your own Playground tenant.

ConceptExample / Description
EnvironmentThe examples in this guide use the playground environment
Merchantthingsandstuff (Replace with your organization slug)
Slugthingsandstuff (Replace with your organization slug)
Channelthingsandstuff-se-nonpsp (Or your specific channel key)
tokenYour OAuth2 Bearer token
BasketIdThe basket ID from Norce Commerce (used as cartReference on the NCO order)

Note: In most setups, the Merchant and Slug values are identical (as in this example). However, they are two different identifiers and may differ depending on how your tenant is configured. Always use the Slug in the base URL and the Merchant value in the X-Merchant header.


Step 1: Configure the Norce Adapter

The Norce Adapter needs credentials to communicate with your Norce Commerce instance. This is a one-time configuration.

PUT /api/v1/configuration/merchants/thingsandstuff/channels/thingsandstuff-se-nonpsp/configurations/norce_adapter
Host: thingsandstuff.api-se.playground.norce.tech/checkout/configuration
x-merchant: thingsandstuff
x-channel: thingsandstuff-se-nonpsp
Authorization: Bearer {token}
Content-Type: application/json

{
  "$schema": "https://thingsandstuff.api-se.playground.norce.tech/checkout/norce-adapter/openapi/v1/schemas/norce_adapter.json",
  "id": "norce_adapter",
  "active": true,
  "adapter": {
    "internalUrl": "https://norce-adapter.checkout.playground.internal.norce.tech",
    "publicUrl": "https://thingsandstuff.api-se.playground.norce.tech/checkout/norce-adapter"
  },
  "settings": {
    "clientId": 1234,
    "applicationId": 5678
  },
  "api": {
    "identityAddress": "https://thingsandstuff.api-se.playground.norce.tech/identity/1.0/connect/token",
    "identityClientId": "YOUR_CLIENT_ID",
    "identityClientSecret": "YOUR_CLIENT_SECRET",
    "identityScope": "playground"
  },
  "application": {
    "productUrlPattern": "https://your-site.com/product/{productId}",
    "imageBaseUrl": "https://thingsandstuff.test.cdn-norce.tech/{{commerceClientId}}"
  },
  "country": {
    "defaultCountry": "SE"
  },
  "features": {
    "shippingChangedHookEnabled": true
  }
}

Note: Set shippingChangedHookEnabled to false if you handle shipping purely inside Norce Commerce.


Step 2: Configure the Non-PSP Adapter

This is also a one-time configuration.

PUT /api/v1/configuration/merchants/thingsandstuff/channels/thingsandstuff-se-nonpsp/configurations/nonpsp_adapter
Host: thingsandstuff.api-se.playground.norce.tech/checkout/configuration
x-merchant: thingsandstuff
x-channel: thingsandstuff-se-nonpsp
Authorization: Bearer {token}
Content-Type: application/json

{
  "$schema": "https://nonpsp-adapter.checkout.playground.internal.norce.tech/openapi/v1/schemas/nonpsp_adapter.json",
  "id": "nonpsp_adapter",
  "active": true,
  "adapter": {
    "internalUrl": "https://nonpsp-adapter.checkout.playground.internal.norce.tech",
    "publicUrl": "{{nonpspAdapterUrl}}"
  },
  "redirectUrls": {
    "checkoutUrl": "https://app.checkout.test.internal.norce.tech/newcheckout?orderId={orderId}&merchant=thingsandstuff&channel=thingsandstuff-se-nonpsp",
    "confirmationUrl": "https://app.checkout.test.internal.norce.tech/neworderconfirmation?orderId={orderId}&merchant=thingsandstuff&channel=thingsandstuff-se-nonpsp"
  },
  "methods": [
    { "identifier": "invoice", "preSelected": true },
    { "identifier": "account-credit", "preSelected": false }
  ]
}

Step 3: Create the Order

Once you have a basket in Norce Commerce, initiate the checkout session by calling the Norce Adapter and use the basket id (876543 in this example) from Norce Commerce as the cartReference.

POST /api/v1/orders
Host: thingsandstuff.api-se.playground.norce.tech/checkout/norce-adapter
x-merchant: thingsandstuff
x-channel: thingsandstuff-se-nonpsp
Authorization: Bearer {token}
Content-Type: application/json

{
  "cartReference": 876543,
  "culture": "sv-SE"
}
201 Created
Content-Type: application/json

{
  "id": "oaAaAaAA..."
}

What just happened?

  1. The adapter fetched the basket from Norce Commerce
  2. It mapped items, prices, and VAT into a Norce Checkout order
  3. It registered hooks and notifications on the order

Step 4: Add a Payment

POST /api/v1/checkout/orders/{orderId}/payments
Host: thingsandstuff.api-se.playground.norce.tech/checkout/nonpsp-adapter
x-merchant: thingsandstuff
x-channel: thingsandstuff-se-nonpsp
Authorization: Bearer {token}
Content-Type: application/json

{}
201 Created
Content-Type: application/json

{
  "paymentId": "paBbBbBB...",
  "selectedPaymentMethod": "thing-payment"
}

The order now has a reserved payment intent covering the full amount.


Step 5: Add Customer Information

You cannot complete an order without a customer.

You can either:

  1. Update the basket in Norce Commerce and call PUT /api/v1/orders/{id} on the Norce Adapter
  2. Update the order directly in the Order API (recommended for checkout UIs)

Here we update the Order API:

PUT /api/v0/checkout/orders/{orderId}/customer/billing
Host: thingsandstuff.api-se.playground.norce.tech/checkout/order
x-merchant: thingsandstuff
x-channel: thingsandstuff-se-nonpsp
Authorization: Bearer {token}
Content-Type: application/json

The adapter immediately syncs this data back to Norce Commerce using hooks.


Step 6: Complete the Order

POST /api/v1/checkout/orders/{orderId}/payments/{paymentId}/complete
Host: thingsandstuff.api-se.playground.norce.tech/checkout/nonpsp-adapter
x-merchant: thingsandstuff
x-channel: thingsandstuff-se-nonpsp
Authorization: Bearer {token}
Content-Type: application/json

{}
200 OK

State transition chain

  1. Checkout → Processing – payment verified, order locked
  2. Processing → Accepted – basket converted to purchase in Norce Commerce
  3. Accepted → Completed – payment captured, confirmation sent

Next Steps

You have now manually built a complete checkout flow.