# Guide: Sales-assisted checkout links

> **Availability:** This feature is available from **Limio Commerce Release 114** onwards.

### Overview

The Checkout Link feature allows you to create shareable URLs that direct customers to a pre-configured checkout. This is useful for sales-assisted flows where an agent configures an order in your CRM (e.g., Salesforce) and sends the customer a link to complete payment.

Common use cases include:

* **Sales quotes** - Agent builds an order, customer completes payment
* **Renewal campaigns** - Pre-fill renewal offers for existing customers
* **Win-back flows** - Send targeted offers to lapsed subscribers
* **B2B sales** - Multiple users from the same organisation can complete orders linked to the same account

### Prerequisites

* **Access to the Limio Commerce API** with a valid [Bearer token](https://docs.limio.com/developers/api-documentation/authentication-overview/oauth-bearer-token). All requests use `Authorization: Bearer <YOUR_TOKEN>`.
* A **published Offer** configured in Limio.
* A **Modular Checkout page** using the [Form component](https://docs.limio.com/components/component-library/modular-checkout-components) to consume the basket.

### What you'll build

1. **Create a basket** with your chosen offer(s) and customer context via the Checkout Initiate API.
2. **Receive a checkout link** in the response that can be shared with the customer.
3. **Customer completes checkout** using the link - no authentication required.

***

### Create a Checkout Link

Use `POST /api/admin/checkout/initiate` to create a basket and receive a checkout link.

#### Example - Create checkout link with Salesforce account (curl)

```bash
curl -s -X POST \
  'https://your-environment.prod.limio.com/api/admin/checkout/initiate' \
  -H 'Authorization: Bearer <YOUR_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "order": {
      "orderItems": [
        {
          "offer": {
            "id": "fab052ce94fbfd0d3663ec0cb9d977367a593684",
            "version": "101d166f7386bb9f1c7635412424b51bbe393ccc"
          },
          "quantity": 1
        }
      ],
      "tracking": {
        "accountId": "001bb00000sIZ0JAAW",
        "contactId": "003bb00000uQQtqAAG"
      },
      "order_type": "new"
    },
    "journey": {
      "checkout": "/anonymous-checkout"
    }
  }'
```

**Response:**

```json
{
  "id": "basket-8cf72b2a-eb57-462d-8e55-981c3b5e5364",
  "recoveryLink": "/api/checkout/recover?basketId=basket-8cf72b2a...&recover=<JWT>",
  "assistedCheckoutLink": "/api/checkout/assisted?basketId=basket-8cf72b2a...&cl=<JWT>",
  "order": { ... }
}
```

**Notes:**

* `assistedCheckoutLink` is the shareable checkout link - use this for sales-assisted flows
* `recoveryLink` is for abandoned cart recovery (different flow)
* The `tracking.accountId` triggers account ownership linking (see caveat below)

***

### Send the Customer to Checkout

Build the full checkout URL by combining your shop domain with the `assistedCheckoutLink`:

```
https://your-environment-shop.prod.limio.com/api/checkout/assisted?basketId=basket-8cf72b2a...&cl=<JWT>
```

When the customer clicks this link:

1. They receive a secure token to complete the checkout
2. The checkout page loads with the pre-configured basket
3. They provide payment details and complete the order

***

### Authentication Caveat: Salesforce Account Linking

> **Important:** When providing a Salesforce `accountId` in the tracking data, the checkout page **must use anonymous authentication** to correctly link the customer's order to the Salesforce account.

When `tracking.accountId` is provided:

1. Limio resolves (or creates) an owner identity linked to that Salesforce Account
2. The checkout link issues a short-lived "on-behalf-of" (OBO) token for that owner
3. The customer completes checkout acting on behalf of the account owner

**Why this matters:**

* Ensures all orders for a Salesforce Account are linked to the same canonical owner
* Allows multiple users from the same organisation to complete orders correctly
* Maintains proper ownership of Salesforce Account/Contact records in Limio

**Configuration requirement:**

* Your checkout page must be configured for **anonymous authentication** (not requiring login)
* If authenticated checkout is enforced, the OBO token flow will not work correctly and the account linking will fail

***

### Request Parameters

| Parameter                          | Required | Description                              |
| ---------------------------------- | -------- | ---------------------------------------- |
| `order.orderItems`                 | Yes      | Array of offers to include in the basket |
| `order.orderItems[].offer.id`      | Yes      | The Offer ID                             |
| `order.orderItems[].offer.version` | Yes      | The Offer version                        |
| `order.orderItems[].quantity`      | No       | Quantity (default: 1)                    |
| `order.source`                     | Yes      | Source identifier (typically "shop")     |
| `order.order_type`                 | Yes      | Order type: "new"                        |
| `order.tracking`                   | Yes      | Additional metadata (see below)          |

#### Tracking Parameters

| Parameter            | Description                                                |
| -------------------- | ---------------------------------------------------------- |
| `tracking.accountId` | Salesforce Account ID - triggers account ownership linking |
| `tracking.contactId` | Salesforce Contact ID - stored for reference               |
| `tracking.offers`    | Array of offer paths for analytics                         |
| Custom fields        | Any additional fields you need for analytics/CRM           |

***

### End-to-end Example (Node.js)

```js
import express from "express";
import fetch from "node-fetch";

const app = express();
app.use(express.json());

const LIMIO_BASE = "https://your-environment.prod.limio.com";
const SHOP_BASE = "https://your-environment-shop.prod.limio.com";
const TOKEN = process.env.LIMIO_TOKEN;

// Generate a checkout link for a Salesforce quote
app.post("/generate-checkout-link", async (req, res) => {
  const {
    offerId,
    offerVersion,
    accountId,
    contactId,
  } = req.body;

  const initiateResp = await fetch(`${LIMIO_BASE}/api/admin/checkout/initiate`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      order: {
        orderItems: [
          {
            offer: { id: offerId, version: offerVersion },
            quantity: 1,
          },
        ],
        tracking: {
          accountId,
          contactId
        },
        source: "shop",
        order_type: "new",
      },
    }),
  });

  if (!initiateResp.ok) {
    const err = await initiateResp.text();
    return res.status(initiateResp.status).send(err);
  }

  const { id: basketId, assistedCheckoutLink } = await initiateResp.json();

  // Build the full checkout URL
  const checkoutUrl = `${SHOP_BASE}${assistedCheckoutLink}`;

  res.json({ basketId, checkoutUrl });
});

app.listen(3000);
```

***

### Tips & Troubleshooting

* **Link not working?** Check that the basket hasn't expired (30-day default)
* **Account not linked?** Ensure `tracking.accountId` is a valid Salesforce Account ID and checkout uses anonymous authentication
* **Multiple offers?** Add multiple items to the `orderItems` array
* **Need offer details?** Use the [Get Offers V2 API](https://docs.limio.com/api) to fetch offer IDs and versions

***

### Related Documentation

* [Initiate a Basket with a Limio Offer](/guides/developer-guides/guide-initiate-a-basket-with-a-limio-offer.md) - General basket initiation guide
* [Limio for Salesforce: Generate Checkout Link](https://docs.limio.com/integrations/using-limio-for-salesforce/generate-checkout-link) - Salesforce-specific UI guide
* [Modular Checkout Form Component](https://docs.limio.com/components/component-library/modular-checkout-components/component-checkout-form) - Checkout page setup


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.limio.com/guides/developer-guides/guide-checkout-link.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
