WooCommerce migration guide
Moving from shortcode checkout to WooCommerce Checkout Blocks is an application migration, not a visual switch. Payment methods, shipping logic, custom fields and analytics all need compatibility evidence.
Inventory everything that touches checkout
Start with payment gateways, shipping methods, tax services, address validation, subscriptions, fraud tools, marketing tags and custom snippets. Search the theme and custom plugins for checkout hooks, filters and direct DOM manipulation.
A feature may look unrelated while depending on the old checkout lifecycle. Document what each extension changes, where its data is stored and whether the vendor explicitly declares block compatibility.
Map hooks to supported extension points
Checkout Blocks use the Store API and a React-based interface. Some PHP hooks from the shortcode experience still work, while others need block slots, filters, additional checkout fields or Store API extensions.
Do not reproduce an old jQuery patch against generated markup. Use documented extension APIs, declare compatibility and keep business validation on the server. Client-side checks improve feedback but cannot protect an order by themselves.
Test payments beyond a successful card
Cover authorization failures, asynchronous payment confirmation, saved tokens, 3-D Secure, cancelled redirects, duplicate clicks, refunds and order status transitions. Subscription stores also need renewal and payment-method-change scenarios.
Verify that gateway scripts load once, errors remain visible and an interrupted browser session does not create an ambiguous paid order. Compare gateway dashboards with WooCommerce records during testing.
Shipping and totals need realistic carts
Test physical, virtual, taxable, non-taxable, discounted and mixed carts. Include remote postcodes, free-shipping thresholds, local pickup and address changes after a rate is selected.
Watch requests to the Store API and confirm totals are recalculated from trusted server data. A visually correct summary can still hide stale shipping or tax state.
Rebuild analytics around confirmed events
Do not fire purchase events because a button was clicked. Use the completed order and stable identifiers to deduplicate browser and server tracking. Validate item arrays, value, currency, coupons and consent state.
Checkout migrations often change selectors and event timing. Test analytics with real tag debugging and compare recorded transactions against WooCommerce.
Release with a rollback path
Use a staging copy with anonymised realistic orders, then run a controlled production rollout. Capture baseline conversion, payment errors and support issues before the change.
Keep the previous checkout configuration documented and reversible until the new path has processed enough real orders. Rollback is a planned control, not an admission that testing failed.
Checkout Blocks acceptance checklist
- Every gateway and shipping method declares or proves compatibility.
- Custom fields save, validate and appear in admin and emails.
- Coupons, taxes and totals recalculate correctly.
- Renewals and saved payment tokens are tested.
- Analytics deduplicates confirmed purchases.
- Accessibility and keyboard completion are verified.
- Rollback steps are written and rehearsed.
Questions clients usually ask
Can I switch to Checkout Blocks with one click?
The interface can be switched quickly, but a customised store still needs extension, payment, shipping and tracking tests.
Do old checkout hooks still work?
Some do and some require alternatives. Check current WooCommerce documentation and test each customisation.
Should the migration happen directly in production?
No. Use staging, realistic test cases, a controlled release and a documented rollback.
Migrate checkout without gambling with revenue
I can audit your extensions and custom checkout logic, build a compatibility matrix and test the commercial paths before release.
Hands-on migration: declare Checkout Blocks compatibility
Developer lab: start by declaring compatibility only after the extension has been tested against block checkout. This prevents a false signal in WooCommerce admin.
<?php
add_action(
'before_woocommerce_init',
static function (): void {
if ( class_exists( Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
'cart_checkout_blocks',
__FILE__,
true
);
}
}
);
Then replace DOM-dependent checkout scripts with supported extension points. Data needed by the browser should come from a registered Store API extension, while server-side validation remains authoritative.
import { registerCheckoutFilters } from '@woocommerce/blocks-checkout';
registerCheckoutFilters( 'muzammil/checkout-copy', {
placeOrderButtonLabel: ( value, extensions, args ) => {
return args?.cart?.needsShipping ? 'Place order securely' : value;
},
} );
Regression matrix I use
- Guest and signed-in checkout.
- Physical, virtual, subscription and mixed carts.
- Every enabled gateway, including failed and retried payments.
- Coupons, taxes, address changes and express wallets.
- Order creation, email delivery, analytics and fulfilment events.
A visually correct checkout is not enough. I verify the resulting order data and downstream events because migration defects often appear after the customer leaves the page.
Complete migration workflow: from shortcode checkout to blocks
Full implementation: migrating checkout is not a template swap. It changes the rendering model, extension surface and way browser state reaches the server. I treat it as a compatibility project with an inventory, a staging branch, a regression matrix and a rollback decision made before production traffic is involved.
1. Inventory everything that modifies checkout
Start with code, not screenshots. Search the active theme, child theme, must-use plugins and custom plugins for classic checkout hooks, template overrides, jQuery selectors and direct reads from posted checkout fields. Then list every gateway, shipping extension, tax provider, address service, subscription extension, analytics script and consent tool.
wp plugin list --status=active --format=table
wp theme list --status=active --format=table
rg "woocommerce_(before|after|checkout|review_order|place_order)" wp-content/
rg "form.checkout|#place_order|checkout_fields" wp-content/The search results become a migration register. For each item, record its owner, customer-visible purpose, data written to the order, replacement mechanism and test case. A hook that prints a trust message is low risk. A hook that changes fees, validates an account number or supplies a fulfilment field is not.
2. Move custom fields to supported registration
Checkout Blocks supports additional checkout fields through WooCommerce APIs. Register each field with a stable namespace, appropriate location and clear validation rule. Avoid storing a critical value only in browser state. The server must be able to reject an invalid value even if the front-end script is bypassed.
<?php
add_action( 'woocommerce_init', static function (): void {
woocommerce_register_additional_checkout_field(
[
'id' => 'muzammil/delivery-instructions',
'label' => __( 'Delivery instructions', 'muzammil' ),
'location' => 'order',
'type' => 'text',
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
]
);
} );Choose the location deliberately. Contact fields, address fields and order fields have different lifecycle and privacy implications. Confirm where WooCommerce stores the value, whether it appears in admin and emails, and whether fulfilment or exports need it. A field is not complete because it appears on screen.
3. Rebuild browser behaviour with extension points
Classic checkout customisations often watch DOM changes and mutate fragments after every Ajax refresh. That approach is brittle in a React-driven block. Prefer registered filters, slot and fill components and Store API extension data. Subscribe to documented state instead of searching for an element that happens to have a particular class today.
If a component needs server data, expose a narrow Store API extension with only the required fields. Do not print an entire configuration object into the page or trust a client-supplied price. The browser can request an option, but WooCommerce must calculate commercial values on the server.
4. Treat gateways and express wallets as separate products
A card gateway passing one desktop test proves very little. Test saved payment methods, strong customer authentication, declined cards, return URLs, asynchronous confirmation, refunds and duplicate submissions. Express wallets may bypass visible fields or populate addresses in a different order, so validate them independently.
- Guest and authenticated checkout.
- New card and saved token.
- Successful, declined and interrupted payment.
- Physical, virtual, subscription and mixed carts.
- Domestic and international addresses.
- Coupons, taxes, shipping changes and express wallets.
5. Verify analytics after the order, not at the click
Block checkout can expose different browser events from a classic template. Audit GA4, Meta and affiliate tags so purchase events use the confirmed order identifier and value. A click on Place order is not a purchase. Deduplicate browser and server events, exclude failed orders and confirm that a refresh does not send the purchase again.
I validate the tracking payload beside the WooCommerce order, including currency, tax, shipping, coupon and item identifiers. This is especially important when a headless layer, tag manager and server-side conversion API all participate. A visually successful checkout can still corrupt attribution.
6. Test accessibility and recovery states
Use keyboard-only navigation, visible focus, screen-reader labels and error summaries. Trigger validation errors high and low in the form and confirm focus moves to an understandable message. Test slow responses and expired sessions. The interface must explain what happened without encouraging the customer to submit payment repeatedly.
7. Roll out with a controlled decision point
- Create a production-like staging copy with current extensions and realistic products.
- Complete the regression matrix and record evidence for each gateway and fulfilment path.
- Deploy during a low-risk window with logs and order monitoring open.
- Run a live low-value transaction through every critical gateway.
- Compare order metadata, emails, analytics and downstream integrations.
- Keep the classic checkout rollback ready until real orders remain stable.
I do not declare compatibility simply to remove an admin warning. The declaration comes after tests show that the extension behaves correctly. If an essential gateway or field has no supported block path, keeping classic checkout temporarily is safer than forcing a migration that loses revenue or operational data.
Debugging checklist when the block looks correct but orders fail
- Inspect the Store API response for validation errors.
- Check browser console errors before the payment request starts.
- Review WooCommerce logs and gateway request identifiers.
- Compare created order metadata with the classic baseline.
- Disable unrelated third-party scripts to isolate race conditions.
- Repeat without cached assets and with a fresh customer session.
A good migration improves maintainability without asking customers or operations staff to absorb the risk. That requires code inventory, supported extension points, server validation, payment testing, analytics verification and an honest rollback plan.
Need a production review?
If this system carries revenue or customer data, I can review the current architecture, reproduce the risky paths and turn the findings into a prioritised implementation plan. Request a technical review.
What I document for the team after migration
A migration should leave the next developer with more than working code. I document every removed classic hook, its block replacement, the owner of each extension and the test that proves it works. I also record the gateway test accounts, webhook endpoints, analytics event source and the rollback procedure. This turns future plugin updates into controlled maintenance instead of another investigation.
For operations staff, I provide a short order-check guide: where the custom fields appear, how to recognise a pending payment, which logs contain the gateway request ID and when an order can be retried safely. Customer-service and fulfilment teams often detect checkout defects before developers do, so their workflow belongs in the technical acceptance plan.
Finally, I schedule a post-launch review after enough real orders have passed through the new checkout. We compare payment failures, missing metadata, support reports and analytics duplicates with the previous baseline. That review is where a successful deployment becomes a proven migration rather than a hopeful release.



Leave a Reply
You must be logged in to post a comment.