
When the checkout needs one more step
Checkouts hold up fine until one has to branch. Take a deposit now and the balance in thirty days. Hold the card while a human approves a wholesale order. On Shopify those two requests live in different places: Shopify Functions run on every plan except Starter, but putting your own UI inside the checkout requires Plus, and Plus starts at $2,300 a month. The work is an afternoon. The bill is a plan tier.
What the extra step costs on a hosted checkout
Shopify's pricing page today lists Basic at $29 a month, Grow at $79, Advanced at $299, and Plus from $2,300. Card rates improve as you climb, from 2.9% plus 30 cents on Basic down to 2.25% plus 30 cents on Plus. Plus is also the only tier whose feature list says "fully customizable checkout", and that phrase is doing more work than it looks like it is.
The developer docs are blunter than the pricing page. Checkout UI extensions: Shopify Plus. Checkout branding through the GraphQL Admin API: Shopify Plus. Thank you and order status extensions: every plan except Starter. Market overrides: Advanced and above. A store paying $79 a month on Grow can change plenty about what happens after the order and almost nothing about what happens during it.
Webflow draws the line somewhere else. Its ecommerce tiers all advertise a custom shopping cart and checkout, with Standard capped at 500 products and carrying a 2% transaction fee that Plus and Advanced drop to zero. The cap and the fee are the part you can plan around. The customization is styling and layout, which is a different thing from logic that branches on who the buyer is.
The branch in code
Stripe's Payment Intents API is the version of this you write yourself. You create a PaymentIntent as soon as you know the amount, update it if the cart changes, and send only the client secret to the browser. Stripe's own guidance is to key the idempotency key on the cart or session, which is what stops an impatient double click from becoming two charges. Order IDs go in metadata, so reconciliation later is a join instead of an afternoon in a spreadsheet.
Manual capture is where the deposit flow actually lives, and the windows are specific enough to design around. For card-not-present transactions that the customer initiated, Stripe documents a seven day authorization window on Visa, Mastercard, American Express and Discover. Merchant-initiated Visa drops to five days, which Stripe notes is really four days and eighteen hours. In person it gets tighter: Mastercard and Amex hold for two days. Japanese accounts get thirty days on JPY transactions for most brands. ACH and iDEAL do not support separate authorization and capture at all, so a flow that assumes a hold works everywhere has a bug waiting in it.
None of this makes processing cheaper. Stripe's standard rate is 2.9% plus 30 cents on domestic cards, the same headline number as Shopify Basic. A custom domain on Stripe's hosted checkout is $10 a month. Letting Stripe act as merchant of record through Managed Payments adds 3.5% on top of the payments fee. What changes is that the processing fee stops arriving bundled with a platform fee you cannot separate from it.
Shopify Functions are real, and they are small
Functions deserve more credit than they usually get in posts like this one. They run on every plan except Starter, they execute inside Shopify's checkout rather than beside it, and they can replace backend logic for discounts, delivery options, payment method ordering and cart validation. You compile to WebAssembly, and Shopify strongly prefers Rust.
Then you read the resource table. A compiled binary cannot exceed 256 kB. A single execution gets 11 million WebAssembly instructions for carts up to 200 line items, 128 kB of input and 20 kB of output. The input query itself is capped at 3000 bytes with a calculated cost ceiling of 30. You cannot debug by printing to STDOUT or STDERR. The fetch target, the one that calls an external service, is limited to custom apps on Enterprise stores.
That last limit is the one that decides things. A discount rule you can express in Rust against data Shopify already holds is a good fit for a Function. A discount rule that has to ask your pricing service what this customer's negotiated rate is cannot run there unless you are on Enterprise. The ceiling is not the instruction count. It is that your own systems are on the other side of a wall.
When staying is the right call
If your checkout is a cart, a card and a confirmation email, the hosted one beats anything you would build. Shopify is certified Level 1 PCI DSS compliant and says stores on it are PCI compliant by default, which is a compliance burden you are not carrying and not paying an auditor for. At $29 a month, Basic costs less than two hours of an engineer's time. Stay if the branch you want already exists as a setting somewhere in the admin. Stay if nobody on your team wants to be the person who owns a payment integration at 2am on Black Friday.
Move when the step you need sits behind a tier that costs more per year than building it. Shopify Plus at $2,300 a month is $27,600 a year, and that is the number to argue with, not a feeling about ownership. Move also when the step sits behind no tier at all, which is what the Enterprise-only fetch target means in practice for anyone whose pricing lives in their own database. Those are two different decisions and they deserve two different conversations.
