本文へ移動
cccskills
無料GitHub で公開

wcs-data-model-switching-gifting

WooCommerce Subscriptions data model, switcher, and gifting reference for exact order type names, product type slugs, subscription meta keys, schedule/date keys, related-order relation meta, switch cart data, switch order data, switched item types/meta, proration hooks, and WCS Gifting recipient storage. Use when code reads or writes shop_subscription, subscription, variable-subscription, subscription_variation, _billing_period, _schedule_next_payment, _subscription_switch_data, _subscription_switch, subscription_switch, _switched_subscription_item_id, wcsg_gift_recipients_email, _recipient_user, _recipient_user_email_address, wcsg_recipient, or when an agent needs the full WooCommerce Subscriptions switcher/gifting flow.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md16.8 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

WooCommerce Subscriptions: data model, switching, gifting

Use this when exact storage names or switch/gift internals matter. Prefer WCS CRUD functions and WC_Subscription methods for writes; use raw keys only for audits, migrations, debugging, or compatibility glue.

Core names

EntityName/keyNotes
Subscription order typeshop_subscriptionRegistered with wc_register_order_type(), class WC_Subscription. In CPT storage it is a post type; in HPOS it is an order type.
Simple subscription product typesubscriptionWC_Product_Subscription::get_type().
Variable subscription product typevariable-subscriptionWC_Product_Variable_Subscription::get_type().
Subscription variation product typesubscription_variationWC_Product_Subscription_Variation::get_type().
Action Scheduler groupwc_subscription_scheduled_eventUsed for subscription scheduled events.

Subscription statuses are WooCommerce order statuses with wc- prefix in storage: wc-pending, wc-active, wc-on-hold, wc-cancelled, wc-switched, wc-expired, and wc-pending-cancel. Object APIs usually use unprefixed values.

Subscription meta keys

These keys map to WC_Subscription props in both CPT and HPOS subscription data stores.

Meta keyProp/date keyPurpose
_billing_periodbilling_periodday, week, month, or year.
_billing_intervalbilling_intervalBilling interval integer.
_suspension_countsuspension_countCustomer/admin suspension count.
_cancelled_email_sentcancelled_email_sentCancellation email guard.
_requires_manual_renewalrequires_manual_renewalManual renewal flag.
_trial_periodtrial_periodTrial period unit.
_last_order_date_createdlast_order_date_createdLast related parent/renewal order created date used by WCS.
_schedule_startstart / schedule_startSubscription start datetime.
_schedule_trial_endtrial_end / schedule_trial_endTrial end datetime.
_schedule_next_paymentnext_payment / schedule_next_paymentNext renewal datetime.
_schedule_cancelledcancelled / schedule_cancelledCancellation datetime.
_schedule_endend / schedule_endEnd/expiration datetime.
_schedule_payment_retrypayment_retry / schedule_payment_retryRetry datetime.
_subscription_switch_dataswitch_dataSwitch order execution payload.

Use WC_Subscription::update_dates(), delete_date(), setters like set_billing_period(), and save(). Directly updating these meta keys can desync validation and scheduled actions.

Product subscription meta

Subscription product data lives on product or product_variation posts.

Meta keyPurpose
_subscription_priceRecurring price.
_subscription_sign_up_feeSign-up fee.
_subscription_periodBilling period.
_subscription_period_intervalBilling interval.
_subscription_lengthSubscription length.
_subscription_trial_periodTrial period unit.
_subscription_trial_lengthTrial length.
_subscription_giftingProduct-level gifting override: enabled, disabled, or empty for global setting.
_subscription_one_time_shippingOne-time shipping flag.
_subscription_payment_sync_dateRenewal synchronization setting.

Use WC_Subscriptions_Product helpers such as get_price(), get_period(), get_interval(), get_length(), get_trial_length(), get_sign_up_fee(), and get_gifting().

Related order relation meta

WCS relates ordinary orders to subscriptions with order meta and relation stores. Do not infer relation from parent ID alone.

Meta keyRelation
_subscription_renewalRenewal order to subscription.
_subscription_switchSwitch order to subscription.
_subscription_resubscribeResubscribe order to subscription.

Use wcs_get_subscription_ids_for_order(), wcs_get_subscriptions_for_order(), wcs_get_subscriptions_for_renewal_order(), wcs_get_subscriptions_for_switch_order(), and $subscription->get_related_orders().

Switcher flow

Switching replaces or adds subscription line items through checkout. It is not a simple product ID update.

  1. A user clicks the switch link printed in My Account by WC_Subscriptions_Switcher::print_switch_link().
  2. The link points to the product/grouped product URL with switch-subscription, item, and _wcsnonce query args.
  3. subscription_switch_handler() validates ownership, nonce, and item switchability.
  4. validate_switch_request() blocks non-subscription products and identical product/variation/quantity switches.
  5. set_switch_details_in_cart() adds cart item data under subscription_switch.
  6. WCS_Switch_Totals_Calculator calculates proration, switch direction, first payment timestamp, and possible prepaid-term changes.
  7. Checkout line item meta records prorated amounts on the switch order and switched item links on subscription items.
  8. process_checkout() creates _subscription_switch_data on the switch order and may create pending switch items on the existing subscription.
  9. When the switch order is paid/completed, complete_subscription_switches() applies the payload to the subscription.
  10. WCS fires woocommerce_subscriptions_switch_completed and item-level switch actions after completion.

Custom switch flows

WCS does not expose a simple customer REST endpoint for "switch this subscription item to that product". The built-in switcher is a cart/checkout/order-completion flow. Custom account UI, AJAX, or REST layers must wrap that flow or deliberately reproduce its order payload.

Safe pattern:

  1. Verify the current user can switch the exact subscription item with WC_Subscriptions_Switcher::can_item_be_switched_by_user().
  2. Build a temporary cart/session context for the current user and add the replacement product with subscription_switch cart item data.
  3. Let WCS_Switch_Totals_Calculator calculate prorations, first_payment_timestamp, end_timestamp, force_payment, and switch direction.
  4. Return preview totals from the calculated cart/order data, not from hand-written price math.
  5. On confirmation, create the switch order with the same _subscription_switch_data shape WCS checkout writes.
  6. If an immediate payment is due, process it through the gateway/order payment flow; if no payment is due, complete/apply the switch through WCS completion logic.
  7. Let complete_subscription_switches() apply the change and let WCS fire its normal hooks.

Do not implement switching by directly calling $subscription->remove_item() and $subscription->add_product() from a customer action. That bypasses switch orders, prorations, tax/fee/coupon handling, old item archival, pending switch item types, cancellation of older unpaid switch orders, and completion hooks.

For read-only previews or eligibility checks, it is fine to expose custom endpoints that return allowed products, switchable item IDs, and WCS-calculated preview totals. For writes, prefer a service that uses WCS cart/checkout objects internally.

Switch cart data

The cart item key is subscription_switch. Typical shape:

$cart_item['subscription_switch'] = array(
    'subscription_id'        => 123,
    'item_id'                => 456,
    'next_payment_timestamp' => 1770000000,
    'upgraded_or_downgraded' => 'upgraded', // or downgraded/crossgraded, after calculation
    'first_payment_timestamp' => 1771000000, // after proration calculation
    'end_timestamp'          => 1780000000, // when length changes
    'recurring_payment_prorated' => true,
    'force_payment'          => true,
);

item_id is the subscription line item being replaced. When adding an item to a subscription without replacing one, item_id can be empty and wcs_cart_contains_switches( 'add' ) is relevant.

Switch order data

Switch orders store subscription_switch_data, persisted as _subscription_switch_data on the order. Shape by subscription ID:

$switch_data[ $subscription_id ] = array(
    'switches' => array(
        $switch_order_item_id => array(
            'remove_line_item'  => 456,
            'add_line_item'     => 789,
            'switch_direction'  => 'upgrade',
        ),
    ),
    'billing_schedule' => array(
        '_billing_period'   => 'month',
        '_billing_interval' => 1,
    ),
    'dates' => array(
        'update' => array(
            'next_payment' => '2026-06-01 00:00:00',
            'trial_end'    => 0,
            'end'          => '2027-06-01 00:00:00',
        ),
        'delete' => array( 'trial_end' ),
    ),
    'coupons'             => array( 111 ),
    'fee_items'           => array( 222 ),
    'shipping_line_items' => array( 333 ),
);

WCS can cancel older unpaid switch orders for the same subscription when a new switch order is created.

Switched item types and meta

WCS uses custom order item types during and after switch execution.

Item typeMeaning
line_item_pending_switchNew line item staged on a subscription before switch completion.
line_item_switchedOld subscription line item archived after replacement.
line_item_removedRemoved subscription line item.
coupon_pending_switch, fee_pending_switch, shipping_pending_switchStaged recurring coupon/fee/shipping items.
coupon_switched, fee_switched, shipping_switchedArchived old recurring coupon/fee/shipping items.

Important item meta:

Item metaStored onPurpose
_switched_subscription_item_idNew subscription line itemOld subscription item ID.
_switched_subscription_new_item_idOld subscription line itemNew subscription/order line item ID.
_switched_subscription_sign_up_fee_proratedSwitch order line itemPortion of order line total from prorated sign-up fee.
_switched_subscription_price_proratedSwitch order line itemPortion of order line total from prorated recurring price.
_has_trialPending switch itemMarks new item with trial.

Switch extension points

NeedHook/filterArgs
Check product switchabilitywcs_is_product_switchable$is_switchable, $product, $variation
Check item switchabilitywoocommerce_subscriptions_can_item_be_switched$can, $item, $subscription
Check user can switch itemwoocommerce_subscriptions_can_item_be_switched_by_user$can, $item, $subscription
Switch URLwoocommerce_subscriptions_switch_url$url, $item_id, $item, $subscription
Switch link markup/text/classeswoocommerce_subscriptions_switch_link, woocommerce_subscriptions_switch_link_text, woocommerce_subscriptions_switch_link_classesLink context.
Retain couponswoocommerce_subscriptions_retain_coupon_on_switch$retain, $coupon_code, $coupon, $subscription
Switch added to cartwoocommerce_subscriptions_switch_added_to_cart$subscription, $existing_item, $cart_item_key, $cart_item
Proration price/daywcs_switch_proration_old_price_per_day, wcs_switch_proration_new_price_per_dayCalculator context.
Switch typewcs_switch_proration_switch_type$type, $subscription, $cart_item, $old_price_per_day, $new_price_per_day
Prorate recurring/sign-up feewcs_switch_should_prorate_recurring_price, wcs_switch_should_prorate_sign_up_fee$bool, $switch_item
Extra amountwcs_switch_proration_extra_to_pay$extra, $subscription, $cart_item, $days_in_old_cycle
Completionwoocommerce_subscriptions_switch_completed$order
Item switchedwoocommerce_subscriptions_switched_item$subscription, $new_order_item, $old_subscription_item
Subscription item switchedwoocommerce_subscription_item_switched$order, $subscription, $new_item_id, $old_item_id

Gifting storage

Gifting is included in Subscriptions. It lets purchaser and recipient differ.

StorageKeyPurpose
Cart item datawcsg_gift_recipients_emailRecipient email before checkout/subscription creation.
Subscription meta_recipient_user_email_addressRecipient email captured at subscription creation before a user is resolved.
Subscription meta_recipient_userRecipient user ID after account lookup/creation. Primary gifted-subscription marker.
Parent order item meta_wcsg_cart_keyLinks checkout order item to the recurring cart/subscription item.
Parent order item metawcsg_recipientValue format wcsg_recipient_id_{user_id}.
Parent order item metawcsg_deleted_recipient_dataJSON snapshot used after recipient deletion.
User metawcsg_update_accountRecipient account setup/update flag.
User metawcsg_recipient_just_reset_passwordRecipient onboarding flag.

Gifted subscriptions are detected by WCS_Gifting::is_gifted_subscription(): true when _recipient_user exists or _recipient_user_email_address is present.

Gifting flow

  1. Product page/cart/checkout collects recipient email when WCSG_Product::is_giftable() is true.
  2. Cart item stores wcsg_gift_recipients_email; gifting is blocked for renewal and switch cart items.
  3. Checkout uses recipient email in recurring cart keys so different recipients produce separate subscriptions.
  4. woocommerce_checkout_subscription_created writes _recipient_user_email_address to the subscription.
  5. On parent order processing/completion, recipient management finds or creates the recipient user, writes _recipient_user, adds wcsg_recipient to the matching parent order item, and updates shipping fields from recipient user meta.
  6. Recipients are granted view/pay/suspend/cancel capabilities for gifted subscriptions, but cannot change payment method.
  7. _recipient_user is not copied to renewal orders.

Product giftability:

  • Global enablement comes from WCSG admin settings.
  • Product-level override is _subscription_gifting: enabled, disabled, or empty for global.
  • Variable subscription parent returns giftable to render UI; each variation decides final gifting variation data.
  • Product page gifting UI is suppressed during switching (switch-subscription query arg).

Memberships integration for gifts

If WooCommerce Memberships is active and a giftable subscription product grants a plan:

  • Membership access is granted to the recipient when order item meta has wcsg_recipient.
  • Purchaser access is skipped unless the same product was also purchased for the purchaser.
  • The created wc_user_membership still stores _subscription_id.
  • Because one order can contain the same product for multiple recipients, link the membership to the recipient's subscription, not just the first subscription in the order.

Common mistakes

// WRONG: direct date meta write can desync Action Scheduler.
update_post_meta( $subscription_id, '_schedule_next_payment', '2026-06-01 00:00:00' );

// RIGHT:
$subscription = wcs_get_subscription( $subscription_id );
$subscription->update_dates( array( 'next_payment' => '2026-06-01 00:00:00' ), 'gmt' );

// WRONG: treating a switch as a product meta update.
$subscription->remove_item( $old_item_id );
$subscription->add_product( wc_get_product( $new_product_id ) );

// RIGHT: use WCS switch flow or reproduce its order payload deliberately.
$is_switch = wcs_order_contains_switch( $order );

// WRONG: gifted subscription recipient is not the subscription customer.
$recipient_id = $subscription->get_user_id();

// RIGHT:
$recipient_id = WCS_Gifting::get_recipient_user( $subscription );

Cross-references

  • Use wcs-subscription-hooks for general lifecycle hook selection.
  • Use wcs-renewal-scheduler for renewal dates, Action Scheduler, and payment retry timing.
  • Use wcm-data-model-subscriptions-link for Memberships CPT/meta and the Memberships-to-Subscriptions relation.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月13日 更新

Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月13日 更新

Control a headless browser to navigate URLs, click elements, fill forms, extract content from JavaScript-rendered pages, take screenshots, and automate end-to-end web workflows.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月13日 更新

Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月13日 更新

Review code for quality, simplicity, and maintainability. Identifies unnecessary abstractions, duplicated logic, oversized functions, missing error handling, and naming issues — then fixes them automatically before presenting the result.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月13日 更新

WooCommerce store operations through NV oOS Pro — product research, catalog cross-referencing, inventory lookups, and Shopify or Flowhub comparisons where integrations are configured.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月13日 更新

nvdigitalsolutions のスキルをすべて見る

このスキルの問題を報告する