Overview
Checkout+ is Loop’s order protection product for non-Shopify platforms. It lets you offer order protection to your customers at checkout — covering returns, shipping issues, or both — via a single API call. Your integration calls the Checkout+ API during checkout, receives eligibility and pricing information, and applies the protection charge using your platform’s native mechanism. When a customer accepts protection and completes their order, Loop detects the charge on the order and activates coverage automatically.How It Works
-
Analyze the cart — Your integration sends the customer’s cart to
POST /v1/analyze. The API evaluates eligibility rules, calculates the protection price, and returns charge instructions. - Present the offer — If eligible, display the protection offer to the customer using the pricing from the response.
- Apply the charge — If the customer accepts, apply the fee to the cart using your platform’s native mechanism (see Platform Integration Guides).
-
Store the session ID — Save the
sessionIdfrom the API response as metadata on the completed order. Loop uses this to link the order back to the analysis. - Order completes — After the order is synced to Loop, we detect the protection fee on the order and activate coverage.
Authentication
Integration Steps
1
Call the Analyze endpoint
Send the customer’s cart data to
POST /v1/analyze whenever the cart changes or the customer reaches checkout.At minimum, include:shopDomain— your shop’s primary domainplatform—woocommerce,bigcommerce, orcustomcart— withlines,currencyCode,subtotalAmount,totalDiscountAmount,discountedSubtotalAmount,totalTaxAmount,totalAmount,itemCount, andregion
id, productId, quantity, unitPrice, totalPrice, originalTotalPrice, and title.2
Handle the response
The response tells you whether the cart is eligible and, if so, how to apply the charge.
If
| Field | What it tells you |
|---|---|
eligible | Whether to show the protection offer |
reason | Why the cart is or isn’t eligible (useful for debugging) |
chargeInstructions.amount | The fee to charge, in minor currency units |
chargeInstructions.label | The exact label to use when applying the fee |
id | Reference ID to store on the order (see next step) |
eligible is false, chargeInstructions will be null — do not show the offer.3
Apply the charge
If the customer accepts protection, apply the fee using your platform’s native mechanism. Always use the
label from chargeInstructions exactly as returned — Loop identifies protection charges on orders by matching this label.See Platform Integration Guides below for platform-specific instructions.4
Store the Loop reference ID on the order
Save the
id from the API response as metadata on the completed order. Loop uses this to link the order back to the original cart analysis.| Platform | Where to store | Key |
|---|---|---|
| WooCommerce | Order meta | _loop_session_id |
| BigCommerce | Order metafield | loop_session_id |
| Headless / Custom | Order metadata | loop_session_id |
Checkout+ UI Guidelines
Your checkout UI controls how the protection offer is presented to customers. Loop does not inject any UI — your integration is responsible for rendering the offer, handling customer interaction, and reflecting the charge in the cart total.Placement
Display the protection offer after the cart summary and before payment. The offer should feel like a natural part of the checkout flow, not a popup or interstitial. Recommended placements:- Below the order summary / line items
- Above the payment method section
- Near shipping options (especially for shipping protection)
Offer Display
At minimum, the offer UI should include:| Element | Source | Example |
|---|---|---|
| Toggle or checkbox | Your UI | A switch or checkbox the customer can interact with |
| Short description | Your copy (see Coverage Descriptions below) | “Protect your order against returns and shipping issues” |
| Price | chargeInstructions.amount + chargeInstructions.currencyCode | ”$2.98” |
298 → $2.98). Use the currencyCode to apply the correct currency symbol and formatting for the customer’s locale.
Default State
Whether the offer is pre-selected (opt-out) or unselected (opt-in) is a business decision. Consider your audience and regional requirements:| Approach | Behavior | When to use |
|---|---|---|
| Opt-in (default off) | Customer actively selects protection | Conservative approach; clearer consent signal |
| Opt-out (default on) | Customer must deselect to decline | Higher attach rates; check regional consumer protection regulations |
Coverage Descriptions
Themode field in the API response tells you what type of protection is being offered. Use it to tailor the description shown to the customer.
mode | What it covers | Suggested description |
|---|---|---|
returnCoverage | Returns | ”Get hassle-free returns on this order” |
shippingProtection | Lost, stolen, or damaged packages | ”Protect your package against loss or damage during shipping” |
returnCoverageAndShippingProtection | Returns + shipping issues | ”Cover your order for easy returns and shipping protection” |
Loading and Error States
Your UI should handle the time between calling the API and receiving a response, as well as failures:| State | Recommendation |
|---|---|
| Loading | Hide the offer or show a skeleton/placeholder until the API responds. Do not show stale pricing from a previous cart state. |
| Error / timeout | Hide the offer entirely. Do not block checkout if the Checkout+ API is unavailable. |
Ineligible (eligible: false) | Hide the offer. Do not show a disabled or grayed-out toggle. |
Updating on Cart Changes
Re-call the API whenever the cart contents change (items added, removed, or quantities updated). The protection price is based on the cart value, so stale pricing can lead to mismatches between what the customer sees and what Loop expects on the order. When the cart changes:- Call
POST /v1/analyzewith the updated cart data - Update the displayed price with the new
chargeInstructions.amount - Preserve the customer’s opt-in/opt-out selection across updates
Accessibility
Follow standard accessibility practices for the offer UI:- Use a native
<input type="checkbox">or an ARIA-equivalent toggle - Associate the description and price with the control using
<label>oraria-labelledby - Ensure the offer is keyboard-navigable and screen-reader friendly
- Maintain sufficient color contrast for the price and description text
Platform Integration Guides
Each platform has its own mechanism for applying fees and storing metadata. Follow the guide for your platform.WooCommerce
WooCommerce integrations apply the protection charge as a cart fee using the
WC_Cart::add_fee() method.amount and label from chargeInstructions to add a fee to the cart. Convert the amount from minor units to major units (divide by 100 for most currencies).
id from the API response as hidden order meta using the _loop_session_id key. The underscore prefix keeps it hidden from the customer-facing order details.
chargeInstructions.label returned by the API.
| Data | Location | Written by |
|---|---|---|
| Protection charge | Fee line item via WC_Cart::add_fee() | Your integration |
| Loop reference ID | Order meta: _loop_session_id | Your integration |
BigCommerce
BigCommerce integrations apply the protection charge as an order-level fee using the Checkout Fees API or Orders API.
id from the API response as an order metafield with the key loop_session_id.
Acceptance verification:
Loop detects protection acceptance by checking whether the completed order contains a fee whose label matches the chargeInstructions.label. BigCommerce also provides the cart_id on the Order object automatically, which Loop can use as a fallback for linking.
| Data | Location | Written by |
|---|---|---|
| Protection charge | Order-level fee via Checkout Fees API or Orders API | Your integration |
| Loop reference ID | Order metafield: loop_session_id | Your integration |
| Cart ID | cart_id on the Order object | BigCommerce (automatic) |
Headless / Custom
Headless and custom integrations have full flexibility over how the charge is applied and where metadata is stored. The requirements below are the minimum for Loop to detect and link protection purchases.
chargeInstructions.
Storing the reference ID:
Include the id from the API response in your order creation payload, stored as order metadata under the key loop_session_id.
Acceptance verification:
Loop detects protection acceptance by checking the order for a charge matching the label and amount from chargeInstructions. The reference ID stored on the order links it back to the analysis.
| Data | Location | Written by |
|---|---|---|
| Protection charge | Platform-specific mechanism | Your integration |
| Loop reference ID | Order metadata: loop_session_id | Your integration |
Your order data must flow to Loop for order linking and billing. The Loop team will work with you during onboarding to set up order data ingestion for your platform.
Charge Instructions
When the cart is eligible, the response includes achargeInstructions object that tells your integration exactly how to apply the protection charge.
| Field | Description |
|---|---|
amount | The fee amount in minor currency units (e.g., 298 = $2.98 USD) |
currencyCode | ISO 4217 currency code for the charge |
method | The charge mechanism — fee for all non-Shopify platforms |
label | The display label to use. You must use this exact label so Loop can identify the charge on the completed order. |
chargeInstructions is null.
Acceptance Determination
There is no explicit acceptance or rejection API call. Loop infers whether the customer accepted protection by examining the completed order:| Outcome | How Loop determines it |
|---|---|
| Accepted | The order contains a fee matching the chargeInstructions.label. Coverage is activated and the order is billed. |
| Declined | The order completes without the protection fee. No coverage, no billing. |
| Not shown | The API returned eligible: false. No offer was presented. |
| Abandoned | The cart was analyzed but no order was placed. No action needed. |
Error Handling
All error responses use a consistent envelope:| HTTP Status | Error Code | Condition |
|---|---|---|
| 400 | invalid_request | Malformed JSON or missing required fields |
| 400 | validation_error | Schema validation failure — check error.details for per-field errors |
| 401 | unauthorized | Missing or invalid API key |
| 404 | shop_domain_not_found | shopDomain not recognized |
| 429 | rate_limited | Per-merchant rate limit exceeded |
| 500 | internal_error | Unexpected server error |
X-Request-Id header for log correlation. Include this value when contacting support about a specific request.
Idempotency
If you provide acart.id in the request, the API uses it for idempotent analysis. Repeated calls with the same shopDomain + cart.id combination update the existing analysis rather than creating a new one.
This is useful when the customer modifies their cart during checkout — call the API again with the updated cart data and the same cart.id, and the response will reflect the new pricing.
Debugging
Technical Considerations
| Consideration | Requirement |
|---|---|
| Monetary values | All amounts are in minor currency units (cents). $10.00 = 1000. |
| Currency codes | ISO 4217 format (e.g., USD, EUR, GBP). |
| Cart updates | Re-call the API when the cart changes to get updated pricing. |
| Additive changes | Loop may add new fields to API responses at any time. Build your integration to tolerate unknown fields. |
Related Resources
Analyze Cart — API Reference
Full request and response schema for the POST /v1/analyze endpoint.
Loop Anywhere
Push commerce data into Loop from any source — orders, products, customers, and more.