implementation 2026-04-18 16 min read the implementation desk

Implementation guide: migrating WooCommerce stores to a parent merchant account

3-minute scan
  • WooCommerce migration is a gateway-plugin swap, not a database rewrite. The customer vault, product catalog, order history, and subscription schedule all stay put; only the payment processor changes.
  • The two load-bearing artifacts are the gateway plugin configuration and the webhook endpoint URL. Everything else — descriptors, payouts, reporting — is driven from the parent account dashboard and does not require store-level changes.
  • Allocate 4–6 hours of engineering per store for the cutover itself, plus a 14-day pilot window on the first store before batching the rest.
On this page

    WooCommerce portfolios end up migrated more often than Shopify portfolios because Woo operators own their database, their gateway plugin, and their checkout template. That ownership makes migration tractable: there is no platform middleman charging per-transaction fees you cannot avoid and no forced checkout flow you cannot modify. This guide walks through the exact sequence we use to move a WooCommerce portfolio — anywhere from 3 to 30 stores — onto a single parent merchant account.

    1. Pre-migration inventory

    Before touching any store, build a spreadsheet with one row per WooCommerce site and these columns: domain, WP version, WooCommerce version, current gateway plugin and version, current processor (Stripe / Authorize.net / Square), monthly volume, active subscription count, saved-card count, webhook endpoints currently configured, and the last known Apple Pay domain verification state. This inventory becomes the migration tracker for the next 30 days.

    The two columns that most often surprise operators: subscription count (people forget they have active WooCommerce Subscriptions billing cycles that need vault migration) and webhook endpoints (people forget they wired a Zapier webhook to Stripe three years ago that feeds a Klaviyo list).

    2. Staging environment setup

    For each store, clone the production environment to a staging subdomain: staging.brandname.com. Use WP Staging Pro or a manual wp-cli db export + search-replace + import cycle. The staging clone becomes the integration lab. Every plugin swap and webhook change is tested there first.

    wp db export backup-pre-migration.sql
    wp search-replace 'brandname.com' 'staging.brandname.com' --all-tables
    wp cache flush

    Point staging at test keys for the new parent account. Run 10 test checkouts through staging before touching production.

    3. Install the parent-account gateway plugin

    The parent-account gateway plugin registers as a native WooCommerce payment method (WC_Payment_Gateway), appears in WooCommerce → Settings → Payments, and carries a brand descriptor field. On install, the plugin exposes a single shortcode [parent_gateway_checkout] that you can place on the Checkout page if the theme strips the default block, plus a REST endpoint the parent server calls to confirm the charge.

    // wp-config.php or plugin settings
    define('PARENT_GATEWAY_PUBLISHABLE_KEY', 'pk_live_...');
    define('PARENT_GATEWAY_SECRET_KEY', 'sk_live_...');
    define('PARENT_GATEWAY_BRAND_DESCRIPTOR', 'BRANDNAME* PEPTIDES');
    define('PARENT_GATEWAY_WEBHOOK_SECRET', 'whsec_...');

    One gotcha: if the existing Stripe plugin (woocommerce-gateway-stripe or payment-plugins-stripe-woocommerce) is still active during testing, checkout can render both payment methods. Deactivate the old plugin in staging to confirm the new gateway takes over cleanly. On production you deactivate it at cutover, not before.

    4. Vault migration: moving saved cards

    If the store has saved cards from returning customers, you need a PAN migration from the old processor to the new parent account. Stripe supports this via a migration request through support — they export an encrypted file, the new acquirer ingests it. Lead time is 10–14 business days. File this request at day 1 of the 30-day plan, not day 20.

    For stores where PAN migration is not available (Authorize.net, some legacy processors), run a re-authorization flow instead: on the first post-cutover login, customers are prompted to re-save their card. Expect a 15–25% drop in saved-card usage during the transition month; the curve recovers by month two.

    5. Subscription handoff

    WooCommerce Subscriptions stores the gateway name per subscription in postmeta under _payment_method. Write a migration SQL that bulk-updates this field for every active subscription from the old gateway ID to the new one, but only after the vault migration completes:

    UPDATE wp_postmeta SET meta_value = 'parent_gateway'
    WHERE meta_key = '_payment_method'
      AND meta_value = 'stripe'
      AND post_id IN (
        SELECT ID FROM wp_posts WHERE post_type = 'shop_subscription' AND post_status = 'wc-active'
      );

    Run this in a maintenance window with the site in maintenance mode. Confirm by opening three random subscriptions in the admin and verifying the payment method shows the new gateway.

    6. Webhook endpoint rewiring

    Every downstream system that listens to Stripe webhooks needs to be rewired — but not to the new acquirer directly. The pattern that works is a normalization layer: the new acquirer posts to https://yourbus.brandname.com/webhooks/acquirer, your layer transforms the event to Stripe-shape, and forwards to the downstream systems (Klaviyo, Zapier, NetSuite, the 3PL).

    The normalization layer is usually a 200-line Node or PHP service. See webhook reliability across sub-brands for the retry and dead-letter patterns that keep it reliable under load.

    7. Apple Pay domain re-verification

    Each WooCommerce domain needs a fresh Apple Pay domain association file from the new parent account, placed at /.well-known/apple-developer-merchantid-domain-association. Upload via SFTP or a small must-use plugin:

    // wp-content/mu-plugins/apple-pay-domain.php
    add_action('init', function() {
      if (strpos($_SERVER['REQUEST_URI'], '/.well-known/apple-developer-merchantid-domain-association') === 0) {
        header('Content-Type: text/plain');
        readfile(WP_CONTENT_DIR . '/uploads/apple-pay-domain-association.txt');
        exit;
      }
    });

    Trigger the verification from the parent account dashboard, confirm the checkmark, and smoke-test Apple Pay in staging on a real iPhone before going live.

    8. Production cutover sequence

    The cutover itself takes 45–60 minutes per store. The sequence:

    1. Enable maintenance mode (wp maintenance-mode activate).
    2. Deactivate the old gateway plugin.
    3. Activate the parent-account gateway plugin.
    4. Run the subscription SQL migration.
    5. Upload the Apple Pay domain file.
    6. Disable maintenance mode.
    7. Run five test checkouts from real devices — one Apple Pay, one saved card, one new card, one 3DS-challenged card, one refund.
    8. Watch the error log and webhook dashboard for 30 minutes.

    9. The 14-day pilot window

    Do not batch migrate. The first store goes live alone and runs for 14 days before the next store moves. During those 14 days, auth rate, webhook delivery, Apple Pay conversion, and refund success are monitored daily. If all four metrics hold within 0.5% of baseline for 14 consecutive days, the pilot is signed off and the rest of the portfolio can batch in groups of three per week.

    10. Gotchas

    • Cache layer: LiteSpeed and WP Rocket cache checkout by default. Add /checkout/, /my-account/, and the webhook URL to the cache exclusion list before cutover.
    • JS defer: LiteSpeed JS defer breaks WooCommerce block checkout. Turn JS defer off or add the gateway JS to the defer exclusion list.
    • Wordfence: Wordfence blocks the acquirer webhook IP by default. Whitelist the acquirer IP range in Wordfence → Firewall → Allowlisted IPs.
    • Dual-gateway render: If both the old Stripe plugin and the new parent gateway plugin are active, checkout renders two payment sections. Deactivate the old plugin at cutover, not before.
    • Subscription renewal timing: Subscriptions that renew in the first 48 hours post-cutover may fail if the vault migration has not propagated. Schedule cutover for a low-renewal window — check wp_wc_subscriptions_schedule_next_payment for the next 72 hours before picking the date.

    11. Rollback plan

    Keep the old gateway plugin installed but deactivated for 30 days post-cutover. If auth rate drops >2% for 6 consecutive hours, reverse the sequence: deactivate the new plugin, reactivate the old, run the subscription SQL backwards, purge cache. Rollback takes 15 minutes per store. Invoke it only once per store — if you rollback twice on the same store the underlying issue is not the migration, it is the store.

    Ready to plan your WooCommerce portfolio cutover? Start with our 12-question intake and we will return a store-by-store migration calendar within 48 hours. Or see pricing for the setup fee and volume-tiered per-transaction rates.

    Found this useful? Share it X LinkedIn Reddit HN Email

    FAQ

    Does this work with WooCommerce Blocks checkout or only classic checkout?
    Both. The parent-account gateway plugin registers as a WC_Payment_Gateway which both checkout experiences consume. If you run Blocks, also confirm the gateway registers its Blocks integration class — most parent plugins ship both.
    Can we migrate without downtime?
    Yes. The 45-minute maintenance window is conservative. Experienced teams run the plugin swap and SQL migration in under 5 minutes with maintenance mode off, using a feature flag to route traffic to the new gateway gradually. Start conservative on the pilot, tighten the window on subsequent stores.
    What about stores running WooCommerce Payments (WCPay)?
    Same sequence. WCPay is a Stripe wrapper under the hood; deactivate it and activate the parent gateway. The vault migration is slightly harder because WCPay PANs live in Stripe's WooCommerce-managed account — file the migration request explicitly against the WCPay account, not the standalone Stripe account.
    How do we handle WooCommerce Memberships or other post-payment logic?
    Memberships listens to the woocommerce_payment_complete hook, which fires regardless of gateway. As long as the parent-account gateway fires that hook on success (all properly written WC gateways do), Memberships continues to work with zero changes.
    Is there a multisite version of this guide?
    Yes — the sequence is identical per site. The only shared component is the Apple Pay domain file, which each subsite hosts individually even on multisite.

    Running multiple brands?
    multiflow was built for this.

    The Operator Briefing

    Twice-monthly. No fluff.

    Processor shutdowns, reserve-hold playbooks, reconciliation lessons, and the merchant-account decisions that save operators six-figure years. Delivered to your inbox — never spam.

    No spam. Unsubscribe in one click.

    We use essential cookies · Privacy