Discounts & Cart Data

Croissant Pay is not a Shopify payment method. It reduces the amount due with discounts equal to the value it has authorized, then settles with you directly. Read this before touching cart code, and before adding automatic discounts of your own.

The Five Discounts

The app registers five automatic discounts on install. They stay inert until a shopper authorizes a Croissant Pay session.

DiscountClassRepresents
Croissant IncentiveOrderA first-order offer, when the shopper qualifies
Croissant Credit DropOrderA targeted credit award Croissant sent the shopper
Croissant CreditOrderThe shopper's existing Croissant credit balance
Croissant PayOrderThe amount authorized on the shopper's card
Croissant ShippingShippingFree shipping on every delivery option
Warning
Renaming or deleting these breaks the integration. Croissant matches by title and recreates anything missing, so a rename yields a duplicate rather than a relabelled discount. To change what a shopper sees on their order summary, talk to Croissant.

What Reaches the Order

The authorized value arrives as separate discount lines — one for each component that applies, using the titles above. A shopper with no offer and no credit drop sees three lines rather than five. Two properties are worth knowing when you verify an order:

  • The Croissant discount lines always sum to the amount Croissant authorized for that cart. This is the check to make when testing.
  • Each is capped against the order total, so the combined Croissant discounts can never exceed what is owed, whatever happens to the cart afterwards.

Free shipping applies whenever a session is authorized, and is not configurable per store.

Stacking With Your Own Discounts

Croissant's discounts are registered as combinable, so they are set up to coexist with your promotions:

Croissant discountCombines with productCombines with orderCombines with shipping
Incentive, Credit Drop, Credit, PayYesYesYes
ShippingYesYesNo
Warning
Shopify only stacks two discounts when both opt in. Croissant's side is already set, so if your own automatic order discount does not have “combines with order discounts” enabled, Shopify picks one and the shopper loses the other. Check every automatic discount you run alongside Croissant.

The one deliberate exception is shipping: Croissant Shipping does not combine with other shipping discounts. If you run your own free-shipping promotion, expect one of the two to win rather than both to apply — which is the correct outcome, since shipping can only be free once.

Info
Croissant Pay is unavailable alongside a Shopify gift card. Since gift cards are applied in checkout, it is the checkout block that detects one and explains it rather than offering the button. The cart blocks cannot see applied gift cards and are unaffected.

Cart Data You Must Not Modify

When a shopper authorizes, Croissant records the authorization on the cart so the discounts apply at checkout. What that looks like depends on your plan.

Shopify Plus

Handled by the checkout block, and nothing in your theme needs to change. The authorized amounts live in a cart metafield, croissant/croissant_pay_session, which the discount functions read — not in cart attributes. The block does write one attribute, croissant_checkout_tokens, so Croissant can follow a shopper across checkout reloads, and it clears croissant_pay_checkout_id if a cart block left one behind. Treat both as owned by Croissant.

Basic, Grow, and Advanced

The cart block adds the Croissant cart attributes below. Treat every one as an opaque value owned by Croissant: your theme, your apps, and anything else touching the cart must leave them exactly as they are.

Cart attributeVisible in admin
croissant_pay_tokenYes
croissant_pay_checkout_idYes
_croissant_pay_session_idNo
_croissant_pay_subtotalNo

Attributes prefixed with an underscore are private to Shopify: they travel with the cart and order and are readable through the API, but are not displayed in the admin. croissant_pay_token is deliberately public — private attributes read as empty on the storefront, and the discount functions have to be able to read the token while the shopper is still on the cart. It is an opaque signed value, so exposing it costs nothing.

To confirm the handoff worked, from any browser on the storefront:

js
// After returning from the Croissant session
fetch("/cart.js")
  .then((r) => r.json())
  .then(({ attributes }) => console.log(attributes));

// Expect the four croissant_* attributes to be present
Warning
Do not clear, rewrite, or copy these attributes, and audit anything that calls the AJAX cart with a full attributes object — replacing the object drops keys you did not include. Clearing them cancels the shopper's authorization for that cart, and they will reach checkout with no discount. Croissant clears them itself when they are no longer valid; you never need to.

When the Cart Changes After Authorization

Croissant authorizes a specific amount against the cart as it stood. If the shopper edits the cart afterwards, the discounts still cap to the live order total, so the store is never over-discounted — but the shopper may now be leaving credit unused. The Croissant block detects this and offers to re-authorize: the reauthorize action in the checkout block on Plus, or the Your cart changed state on the cart for other plans. On Plus that prompt also appears whenever a balance remains after the Croissant discounts, since reauthorizing is how the shopper covers more of it.

You do not need to handle any of this. Just do not hide the Croissant block once a session is authorized, or the shopper will have no way to update or remove it.


Next: Orders & Reconciliation → what lands on the order and what Croissant receives