Checkout+ on BigCommerce
Loop Checkout+ is opt-in order protection offered at checkout. When a customer accepts it, that acceptance has to reach Loop's Orders API so the resulting return is recognized as a protected order. On BigCommerce the frontend builds the offer with Loop's Analyze Cart API and captures four resulting fields. From there, either Loop's pre-built BigCommerce connector syncs them up for you, or you push the order to Loop's Orders API yourself with the same payload shape.
Checkout+ on docs.loopreturns.comBefore you start
- BigCommerce stencil or headless storefront where you control checkout completion.
- A Loop instance with an active Checkout+ plan, and API keys generated from the Loop admin.
- Checkout+ configured in the Loop admin (coverage rules, pricing tiers, eligible products).
- A server-side endpoint that holds your Loop API keys —
/v1/analyzeis called server-side, never directly from the browser.
The pieces you need
What you're wiring together, regardless of which path you take below.
Analyze Cart caller
Server/v1/analyze on cart changes. Holds your Loop credentials. Returns coverage eligibility, price, session, and accepted offer mode.Coverage offer UI
BrowserAcceptance state
BrowsersessionId, mode[], chargeInstructions.amount, and chargeInstructions.currency between offer acceptance and order completion.Metafield writer
Serverloop_checkout_plus metafields onto it via the BigCommerce Order Metafields API.Orders API pusher
Serverfees[] and metadata[] already populated from the four fields.The flow
What happens, in order, from cart change to Loop seeing the protected order.
Cart changes → call Analyze
Server-side, hit Loop's/v1/analyzewith the cart contents whenever items, quantities, or shipping address change.Loop responds with the offer
Eligibility, price (chargeInstructions.amount+currency),sessionId, andmode[]. Render the offer in the checkout UI when eligible.Customer accepts (or skips)
If they accept, capture all four values —sessionId,mode[], amount, currency — and carry them through to order completion.Checkout completes
BigCommerce creates the order; you now have theorder_id. Time to persist the four values somewhere Loop can read them.Persist the values
Either write them onto the order as metafields (the connector reads + forwards) or push the enriched order to Loop's Orders API yourself.Loop sees the protected order
Whether via the connector or your own sync, Loop's Orders API receivesfees[]+metadata[]and the order is recognized as Checkout+.
Where to start
Build the Analyze Cart caller first. Get /v1/analyze returning a clean response server-side against a test cart before you touch any checkout UI. That endpoint is the foundation — everything below assumes you have those four fields (sessionId, mode[], chargeInstructions.amount, chargeInstructions.currency) in hand by the time the order completes.
Once it's working, the rest goes in this order:
- Render the offer in your checkout / cart UI using the price from Analyze.
- Capture acceptance into the four-field state — carry it through to order completion.
- Persist on one of two paths, depending on your setup:
- Connector path — you're using Loop's pre-built BigCommerce connector. Write the four values as order metafields after the order is created. See below.
- DIY path — you're rolling your own commerce data sync. Push the enriched order to Loop's Orders API yourself. Same payload shape; you're just the one calling the API.
The connector path — four metafields
If you're on Loop's pre-built BigCommerce connector, the work ends with four metafields. The connector watches BigCommerce orders, reads these, and forwards Checkout+ data to Loop's Orders API on every sync.
Write each value onto the order as a metafield under namespace loop_checkout_plus, with permission_set: read_and_sf_access. One POST per metafield (four POSTs total per order, or five if you set the optional fee_name).
/v1/analyze response.| Key | Type | Source | Example |
|---|---|---|---|
session_id | string | sessionId | lop_a1b2c3d4e5f6g7h8i9j0 |
accepted_offer_mode | JSON-encoded array of strings | mode[] — verbatim, do not sort, dedupe, or transform | ["returnCoverage","shippingProtection"] |
fee_amount | integer cents (minor units) | chargeInstructions.amount | 798 (= $7.98) |
fee_currency | ISO 4217 currency code | chargeInstructions.currency | USD |
fee_nameoptional | string | — (defaults to Order protection if omitted) | Order protection |
Example metafield write
Repeat the call below for each of the four required keys (and optionally fee_name).
POST /v3/orders/{order_id}/metafields
Content-Type: application/json
X-Auth-Token: <bc store token>
{
"namespace": "loop_checkout_plus",
"key": "session_id",
"value": "lop_a1b2c3d4e5f6g7h8i9j0",
"permission_set": "read_and_sf_access"
}All or nothing
If any of session_id, accepted_offer_mode, fee_amount, or fee_currency is missing or malformed, the connector drops the entire Checkout+ block for that order and logs a warning. The order itself still syncs to Loop — just without coverage.
Why: Loop's Orders API returns 422 fees.0 field is unsupported when accepted_offer_mode is sent without a matching fee. Skipping is safer than breaking the sync.
Write all four, or write none.
The DIY path — push to Loop's Orders API yourself
If you're not using the connector — or you're rolling your own commerce data sync — the same four values still need to reach Loop. The shape the connector would have built is what you build. POST the enriched order to Loop's Orders API with fees[] and metadata[] populated:
{
"...": "standard order fields",
"fees": [
{
"name": "Order protection",
"amount": { "amount": 798, "currency_code": "USD" },
"accepted_offer_mode": ["returnCoverage", "shippingProtection"]
}
],
"metadata": [
{ "key": "session_id", "value": "lop_a1b2c3d4e5f6g7h8i9j0" }
]
}Idempotency
Loop's Orders API replaces fees[] and metadata[] on every upsert — it does not append. Re-send the same Checkout+ payload on every order update (fulfillment, refund, etc.). No need to guard against duplicate writes.
The connector does this automatically; on the DIY path, build your update payloads to always include the Checkout+ block when it applied at checkout.
Pitfalls
- Never call
/v1/analyzefrom the browser — your Loop credentials must stay server-side. mode[]is verbatim — don't sort, dedupe, or transform it. Loop's portal matches against the exact value the customer accepted.fee_amountis cents, not dollars.798, not7.98.- All-or-nothing on the four required fields — the connector drops the whole block if any is missing or malformed.
- Loop's Orders API replaces
fees[]andmetadata[]on every upsert. Always include the Checkout+ block on subsequent order updates. - HTTPS everywhere — applies to every Loop integration.