A lightweight, dependency-free one-page checkout that replaces Magento's stock Knockout/RequireJS checkout with a single Alpine.js component and plain REST calls. No Knockout, no RequireJS, no jsLayout, no uiComponents — the entire checkout is one template, one JS file, and one CSS file.
Born on a production store serving high mobile / in-app-browser traffic, where the stock checkout's ~2 MB of JS was the main conversion killer. This open-source edition is stripped of every store-specific customization: it is intentionally plain, unstyled beyond default-Luma colors, and meant to be a starting point you can read top to bottom in one sitting.
- One-page checkout: address → shipping method → payment → place order, with a live order summary and coupon support.
- Guest + customer checkout: guests get an email field and the
/V1/guest-carts/{maskedId}/*REST flow; signed-in customers get saved addresses and/V1/carts/mine/*. - Stock REST only — no custom API endpoints. The order is placed by the same
payment-informationcall the native checkout uses, so payment methods, totals collectors, tax, and sales rules all behave exactly as Magento intends. - Theme-agnostic: works on Luma and Luma-based themes. The page keeps your theme's header/footer; only the checkout content area is replaced.
- Tiny: Alpine.js (~45 KB min) + ~15 KB of component JS + ~7 KB CSS, vs. megabytes for the stock checkout stack.
- Resilient by design (battle-tested against Facebook/Instagram in-app WebViews): Alpine dual-registration guard against boot-order races, a framework-free watchdog that shows a reload fallback if the app never boots, and network errors surfaced as translated messages instead of raw fetch text.
- CSP-safe: the inline config is emitted through Magento's
SecureHtmlRenderer(nonce/whitelist aware — Magento 2.4.7+ enforces CSP on checkout pages); all logic lives in external same-origin files. - Safe rollout: a config toggle per store view. Off = the stock checkout
renders untouched. On = this checkout takes over
/checkout.
- Magento Open Source / Adobe Commerce 2.4.4+ (tested on 2.4.9)
- PHP 8.1+
mkdir -p app/code/Bonlineco
cp -R <this repo> app/code/Bonlineco/Checkout
bin/magento module:enable Bonlineco_Checkout
bin/magento setup:upgrade
bin/magento setup:static-content:deploy # production mode only
bin/magento cache:flushAdmin → Stores → Configuration → Sales → Bonlineco Checkout:
| Setting | Default | Meaning |
|---|---|---|
| Enable Bonlineco Checkout | No | Master switch, per store view. |
| Allow Guest Checkout | Yes | When No, guests are sent to sign in first. |
| Hidden Payment Methods | — | Comma-separated method codes hidden from customers (staff/admin-only methods). |
checkout_index_index
└─ Observer\TakeOverCheckoutLayout adds the 'bonlineco_checkout' handle
└─ removes block 'checkout.root' (the whole Knockout app)
└─ adds Bonlineco_Checkout::checkout.phtml (cacheable="false")
├─ window.bonlinecoCheckoutConfig (SecureHtmlRenderer inline)
├─ js/checkout.js (Alpine component + watchdog, defer)
└─ js/alpine.min.js (Alpine 3.15, MIT, defer)
REST flow (cookie-authenticated, store-scoped; mine ⇄ guest-carts/{maskedId}):
POST estimate-shipping-methods → available rates (first auto-selected)
POST shipping-information → payment methods + totals
PUT selected-payment-method → totals refresh
POST payment-information → order placed → redirect to /checkout/onepage/success
- Redirect payment gateways (cards, wallets, BNPL): after
payment-informationsucceeds,checkout.js:placeOrder()redirects toconfig.urls.success. Gateways that need a hosted-page hop should branch on the selected method code there — that's the single extension point, kept deliberately small. - Extra address fields: add inputs to the form in
checkout.phtml, carry them incurrentAddress()(usecustom_attributes/extension_attributesfor EAV address attributes). - Styling: everything is namespaced under
.bonlineco-checkout__*in one CSS file using logical properties (RTL works out of the box).
- Terms & Conditions: fully supported — active checkout agreements are rendered in the payment step (checkbox for manual-mode ones) and their ids are sent with place-order, satisfying core's server-side agreement validation.
- Hidden payment methods are enforced on both the read path (method list)
and the write path (
selected-payment-method/payment-information), so the restriction can't be bypassed by sending a hidden code directly to REST. Admin- and integration-token API clients are exempt.
- Storefront reCAPTCHA for the "Place Order" and "Apply Coupon" forms is not
yet integrated (the REST calls don't send the
X-ReCaptchaheader). If you enable those two reCAPTCHA forms, orders will be rejected server-side — leave them off for this checkout, or contribute the integration.
- No multi-address shipping, no billing address different from shipping (billing = shipping, the dominant e-commerce pattern).
- No in-checkout registration ("create an account" belongs on the success page).
- No payment-method iframes/hosted fields on the page — redirect gateways only.
- No attempt to reimplement the stock checkout's jsLayout extension points. If your store depends on many checkout plugins, this module is not for you — its entire value is NOT being that architecture.
MIT — see LICENSE. Bundles Alpine.js v3.15.0 (MIT, © Caleb Porzio and contributors).
