Skip to main content
Shop Now: On-Store must be enabled for your account, and the API key you use needs the Carts scope. To get started, reach out to support@loopreturns.com.

Overview

Shop Now: On-Store redirects a shopper from the Loop returns portal to your storefront to pick replacement products with their return credit. When they’re done, your storefront hands the selected items back to Loop as a cart token, and Loop completes the exchange server-side. Most merchants implement this with Loop’s On-Store SDK, which assumes it runs inside a Shopify Online Store theme. This guide is for headless / custom storefronts that need to implement the same flow themselves, without the SDK. It documents the contract the Loop portal and Loop API expect, and the theme dependencies a headless storefront must replace.
Shopify Checkout is never used in this flow. Loop creates the exchange order itself, and computes all exchange pricing, credit, bonus, and tax — not Shopify. Store discount codes and Shopify Functions do not apply to the exchange.
The three pieces a headless storefront must implement:
  1. Inbound — read the loop_* query params on your landing page and enter “on-store mode”.
  2. Handoff — when the shopper checks out, collect the selected variant IDs, POST them to the Loop Cart API, and store the returned token.
  3. Outbound — redirect back to the Loop portal with that token, and clear your own cart.

How It Works


Base URL

The Cart API is served from:

Authentication

The Cart API uses the same authentication as the rest of Loop’s APIs. Send your merchant API key in the X-Authorization header — see Authentication for how to create and manage keys, the full header contract, and the 401 response shape. The key must have the Carts scope. Generate one from Returns Management → Tools & integrations → Developer tools in the Loop Admin and select the Carts scope.
Keep the API key server-side. Prefer proxying the Cart API calls through your own backend so the key is never exposed to the browser. A key scoped to Carts only keeps the blast radius minimal if it ever leaks.

Step 1 — Inbound: portal → storefront

Loop redirects the shopper to your storefront (your apex domain, or a market-localized URL) with loop_* query params. On-store mode is keyed on the presence of loop_total.

Query parameters

Amounts are minor units in the shop base currency (e.g. 12099 = 120.99). For multi-currency display, convert using your own storefront FX rate. The portal omits any param with a falsy value, so treat loop_total as the reliable credit total and don’t assume loop_base / loop_credit are always present.

What to do on landing

1

Detect on-store mode

Check for loop_total in the query string. Its presence means the shopper arrived from the Loop portal in Shop Now: On-Store mode.
2

Persist the loop_* values

Store the loop_* values (for example in sessionStorage or localStorage) so they survive navigation across your store.
3

Discard stale carts

If loop_return_id differs from a previously saved session, discard any saved cart or token — it belonged to a different return.
4

Render a credit UI (optional)

Show available credit and bonus % from loop_total and loop_discount_percentage.
5

Suppress non-applicable UI (recommended)

Hide storefront elements that don’t apply during an exchange: discount-code popups, alternative payment buttons (PayPal, Afterpay, Google Pay), home try-on, sticky mobile add-to-cart, and chat widgets. Store discounts and Functions will not apply to the exchange.

Step 2 — Handoff: storefront → Loop Cart API

When the shopper is done and clicks your “checkout” equivalent, collect the selected Shopify variant IDs from your cart and POST them to the Cart API.
Quantities are not supported. To add a variant N times, repeat its ID N times in the cart array.
Each variant ID must resolve to a real Shopify variant for the shop — Loop validates against Shopify and returns Variant ID X not found. otherwise. The cart array is required and must be non-empty.

Create a cart

The response returns the cart token — persist it:
To amend the selection later, POST /api/v1/cart/{token} with a new full cart array — it replaces the cart contents. See the Cart API reference for the full request and response schema, including update and delete.

Step 3 — Outbound: storefront → portal

Once you have a token:
1

Clear your storefront cart

Empty your own cart so the shopper doesn’t accidentally buy the items through normal checkout. Skip only if you intentionally preserve it.
2

Redirect back to the Loop portal

Send the browser back to the portal with the token. Only the token travels in the URL — the variant selections were persisted server-side in Step 2.

Redirect URL rules

URL-encode token, to, and return_key. {loop_domain} and {loop_redirect_url} come from the inbound params.
Loop then loads the selected products and shows the shopper the review screen to submit their return.

Carrying storefront discounts into the exchange

To keep a discount the shopper had on your storefront in the exchange, send it to the Cart API in the optional shopify field — a Base64-encoded copy of the Shopify Ajax cart object (GET /cart.js). Loop reads the discount fields already present in that object; it does not evaluate discount codes or Shopify Functions itself.
Loop only consumes this snapshot when your shop is configured to use Shopify Scripts. Without it, the snapshot is ignored and exchange items price at catalog price. Most headless stores don’t need it — omit shopify entirely unless you carry cart discounts.
Automatic cart discounts work the same way — any discount already applied to the Shopify cart (automatic discounts or discount codes) is carried into the exchange as long as it appears in the /cart.js snapshot you send. Loop mirrors whatever the snapshot contains; it never applies or re-evaluates discounts itself.

Where the discount data comes from

The snapshot is Shopify’s own cart object, so you don’t build the schema yourself — you take what Shopify already gives you:
1

Apply the discount on the Shopify cart

Add or manage discount codes with POST /cart/update.js ({ "discount": "CODE" }; comma-separate for multiple, empty string to clear).
2

Read the resulting cart

Fetch the cart with GET /cart.js. The response now carries the discount fields (total_discount, cart_level_discount_applications, per-item discount_allocations).
3

Base64-encode it as `shopify`

Send that cart object as the shopify field on POST /api/v1/cart (see below).

What Loop reads

Loop consumes a subset of the /cart.js object. All money values are minor units (cents), exactly as Shopify returns them:
  • Cart levelcurrency, total_price, total_discount, and each cart_level_discount_applications[] entry (title, value, value_type, total_allocated_amount).
  • Per line item (items[]) — variant_id, quantity, original_price, discounted_price, final_line_price, and each discount_allocations[] / line_level_discount_allocations[] entry (amount, discount_application).
Here is a trimmed /cart.js object with a 10% cart-level discount and a line-level discount — see the Shopify reference for the full shape:

Sending the snapshot

Base64-encode the cart object and include it as shopify alongside cart. Do this on your backend so the API key stays server-side:
Node (server-side)
In the browser the equivalent encoding is btoa(unescape(encodeURIComponent(json))), but prefer encoding and sending from your backend. Regardless of the snapshot, exchange pricing, credit, bonus, and tax are always computed by Loop, not by Shopify checkout.

Replacing the theme dependencies

The stock On-Store SDK assumes it runs inside a Shopify Online Store theme. A headless storefront must provide substitutes for each dependency:
You don’t need the Ajax Cart API at all if you drive the flow yourself. The only hard external dependencies are (1) the inbound loop_* param contract, (2) the Loop Cart API, and (3) the redirect-back URL format.

Eligibility and access

Access to the Cart API is granted through the Carts scope on your API key, which Loop provisions when Shop Now: On-Store is enabled for your account. Contact support@loopreturns.com to get set up. If the API key isn’t authorized — On-Store isn’t enabled for the shop, or the key lacks the Carts scope — the Cart API responds with 401 Unauthorized:
Confirm On-Store is enabled and your key carries the Carts scope before offering the flow to shoppers.

Minimal reference implementation

The browser never sees the API key. It calls your own backend, which holds the Carts-scoped key and forwards the request to Loop.
Storefront (browser)
Your backend proxy (Node)

Technical considerations


On-Store Exchanges

Conceptual overview of Shop Now and Shop Now: On-Store.

Create Cart — API Reference

Full request and response schema for the Cart API (create, get, update, delete).