A Rebuy Alternative: Native Shopify Checkout Blocks
We replaced Rebuy for a subscription-heavy DTC brand on Shopify Plus with native checkout blocks we built ourselves. Same surfaces Rebuy sells: cross-sells in the checkout page and the cart drawer. The difference is the store now owns them, the $360 a month in Rebuy billing is gone, and the reporting we get out of it is deeper than anything the app's dashboard ever showed us, including the one number that actually matters for a subscription business.
The whole pattern is open source: shopify-checkout-cross-sell on GitHub (MIT) has the extension, the cart-drawer reference, and the reporting script, with one config file to adapt to your catalog.
Why We Ripped It Out
This store has an architecture that breaks most apps' assumptions. There are no Shopify selling plans and no subscription app. "Subscription" is just a variant flag on the SKU, and the actual recurring billing runs in an external backend the brand has used for years. Shopify handles catalog, cart, and checkout. That's it.
Upsell apps are built around selling plans. This isn't us reading tea leaves: Rebuy's own dev team told us they couldn't support what we needed, because their subscription features only work with selling plans. That answer is what kicked off the build.
The reporting had the same blind spot. What we got was attributed revenue at the order level, in the app's own dashboard, with no way to see what happened to a customer after the add. For a business where the entire economics live in whether a customer ends up on the recurring program, that's reporting on the wrong thing.
The client is on Shopify Plus, which means Checkout Extensibility: you can render your own blocks inside the actual checkout page (info, shipping, payment steps) with Shopify's component library. That's the same surface the apps build on, which makes the checkout itself the most flexible Rebuy alternative there is: an agency can build the exact blocks the store needs, with the exact data model the store has.
What We Built
A checkout UI extension with a cross-sell block, plus the same offers ported into the theme's cart drawer. Both surfaces run the same brain:
- A curated offer table. Each core product maps to up to three cross-sell products, ordered by what actually sells. No algorithm pretending to know the catalog better than the merchant does.
- Family exclusion. If any product from a family is already in the cart, nothing from that family gets offered. Nobody sees an upsell for the thing they just added.
- Size preselection. If the cart says the customer wears a Large, the offer defaults to Large, mapped across products that size differently (one product's L is another's XL/XXL).
- One-tap add for single-variant products, a two-step picker for sized ones.
A generic rendering of the offer card. Curated product, size preselected from what's in the cart, one tap to add.
Offers add the one-time variant on purpose. A separate per-line card then offers to switch that line to the subscription variant with the real savings computed from live prices. That card deserved its own write-up, because in-checkout variant switching is the thing we could never get out of Rebuy, even paired with another app.
Claude Code built both surfaces inside the repos, the same workflow we use to build Shopify landing pages: the checkout extension in its own app repo, the cart version as a port of the same logic into the theme's jQuery drawer. The checkout block is merchant-placeable, so the client drags it wherever they want in the checkout editor without a redeploy.
The Attribution Layer Is the Whole Trick
Every add writes hidden line-item properties onto the order at the moment it happens:
_cross_sell: "checkout" # which surface sold it: checkout or cart _cross_sell_anchor: "..." # which product in the cart earned the offer _cross_sell_slot: "2" # position 1-3 in the offer list _cross_sell_size: "preselected" # did our size guess hold, or did they change it _sub_switch: "cart" # the line was switched to subscription, and where
Underscore-prefixed properties are invisible to the customer but land on the order and stay queryable forever. That's the entire analytics stack. No pixel, no app database, no vendor dashboard. The order itself carries its own attribution.
The whole system. Two surfaces, one brain, and attribution that lives on the order itself.
One practical wrinkle worth stealing: we don't even need Shopify admin access to report on it. Klaviyo's Shopify integration mirrors the full order payload, properties included, so a script pulls Placed Order events through our Klaviyo CLI and computes everything from there. Useful when your agency seat doesn't have the Orders permission, and it's the same mirror we lean on for the metrics Klaviyo doesn't give you.
What the Report Shows
The weekly report answers questions the app dashboard never could. From the first three days of tracked data:
- Take rate: 9 of 296 web orders carried a cross-sell line, 3.04%. Web orders only in the denominator, because a quarter of this brand's volume is Amazon and never sees a checkout.
- Direct cross-sell line revenue: $335 in those three days.
- Slot performance: position 1 took 5 of the 9 adds. The curation order is doing its job.
- Size behavior: we can see whether customers kept the preselected size or changed it, which tells us whether the size mapping is right per product.
- Per-anchor performance: which product in the cart actually earns the adds, separate from which product got added.
- Surface split: cart adds and checkout adds report as separate rows, so we'll know where the offers actually convert instead of guessing.
The Number the App Could Never Show Us
Of the 9 cross-sold orders, 4 switched the added product to a subscription before paying. That's the compounding story: the cross-sell adds a one-time product, the switch card converts it to recurring, and the stamps record the whole chain on the order.
A $30 one-time add is a $30 win. The same add switched to a subscription feeds the external billing program, and the value is a multiple of the first order. Because this brand's subscriptions don't exist inside Shopify at all, no app dashboard was ever going to connect an upsell to recurring revenue. Two line properties connect it for free.
We report the caveats too: take rate is per-order rather than per-impression (some carts legitimately render no offers), and the AOV comparison between cross-sold and other orders has selection bias baked in, since bigger carts get more offers. Deeper reporting includes being honest about what the numbers can't say.
What It Took
The checkout extension, the cart drawer port, the attribution stamps, and the reporting script were built with Claude Code over a handful of working sessions, deployed behind a draft checkout profile first and QA'd on the live store. The offer table is a hand-curated map the client can change with a one-line edit. Ongoing cost went from $360 a month to zero, and the client owns the codebase.
If your store is on Plus and your upsell app is a black box with a monthly bill, the best Rebuy alternative may be no app at all. We open-sourced the whole pattern, MIT licensed: github.com/BeauchampAndrew/shopify-checkout-cross-sell has the extension (config-driven offers, the switch card, the attribution stamps), the cart-drawer reference implementation, and the reporting script. And if you want help building it, talk to us.