Wcs data model switching gifting
Skill Lonsdale201/wp-agent-skills/woocommerce/wcs-data-model-switching-gifting
A community-maintained collection of agent skills for WordPress plugin and theme development.
npx -y skills add Lonsdale201/wp-agent-skills --skill wcs-data-model-switching-giftingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
WooCommerce Subscriptions data model, switching, and gifting reference for order/product types, schedule and relation storage, switch cart/order payloads, proration hooks, recipient data, and WCS 9.0 APFS plan markers. Use for shop_subscription, _schedule_next_payment, _subscription_switch_data, subscription_switch, _switched_subscription_item_id, wcsg_gift_recipients_email, _recipient_user, _wcsatt_schemes, or _wcsatt_scheme.
SKILL.md
16.5 KB, ~3.6k tokens by cl100k_base, as published. Nobody here has run it
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
| Entity | Name/key | Notes |
|---|---|---|
| Subscription order type | shop_subscription | Registered 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 type | subscription | WC_Product_Subscription::get_type(). |
| Variable subscription product type | variable-subscription | WC_Product_Variable_Subscription::get_type(). |
| Subscription variation product type | subscription_variation | WC_Product_Subscription_Variation::get_type(). |
| Action Scheduler group | wc_subscription_scheduled_event | Used 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 key | Prop/date key | Purpose |
|---|---|---|
_billing_period | billing_period | day, week, month, or year. |
_billing_interval | billing_interval | Billing interval integer. |
_suspension_count | suspension_count | Customer/admin suspension count. |
_cancelled_email_sent | cancelled_email_sent | Cancellation email guard. |
_requires_manual_renewal | requires_manual_renewal | Manual renewal flag. |
_trial_period | trial_period | Trial period unit. |
_last_order_date_created | last_order_date_created | Last related parent/renewal order created date used by WCS. |
_schedule_start | start / schedule_start | Subscription start datetime. |
_schedule_trial_end | trial_end / schedule_trial_end | Trial end datetime. |
_schedule_next_payment | next_payment / schedule_next_payment | Next renewal datetime. |
_schedule_cancelled | cancelled / schedule_cancelled | Cancellation datetime. |
_schedule_end | end / schedule_end | End/expiration datetime. |
_schedule_payment_retry | payment_retry / schedule_payment_retry | Retry datetime. |
_subscription_switch_data | switch_data | Switch 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 key | Purpose |
|---|---|
_subscription_price | Recurring price. |
_subscription_sign_up_fee | Sign-up fee. |
_subscription_period | Billing period. |
_subscription_period_interval | Billing interval. |
_subscription_length | Subscription length. |
_subscription_trial_period | Trial period unit. |
_subscription_trial_length | Trial length. |
_subscription_gifting | Product-level gifting override: enabled, disabled, or empty for global setting. |
_subscription_one_time_shipping | One-time shipping flag. |
_subscription_payment_sync_date | Renewal 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().
APFS / Subscription Plans storage in WCS 9.0+
All Products for Subscriptions is bundled into WooCommerce Subscriptions 9.0 as Subscription Plans. It can make ordinary product types behave as subscriptions through runtime meta and woocommerce_is_subscription.
| Storage | Key | Purpose |
|---|---|---|
| Option | wcsatt_subscribe_to_cart_schemes | Storewide plan definitions. |
| Product meta | _wcsatt_schemes_status | Product purchase mode: disable, override, or inherit. |
| Product meta | _wcsatt_schemes | Product-specific custom plans in override mode. |
| Product meta | _wcsatt_storewide_selection_mode | all or specific storewide plan selection. |
| Product meta | _wcsatt_selected_storewide_plans | Storewide plan IDs allowed for a specific product. |
| Product meta | _wcsatt_force_subscription | yes means disable one-time purchase when plans are active. |
| Product meta | _wcsatt_disabled | Legacy one-time-only flag maintained for compatibility. |
| Cart item data | wcsatt_data.active_subscription_scheme | Selected plan key, false for one-time, null for undefined/default. |
| Order item meta | _wcsatt_scheme | Selected plan key persisted on order/subscription line items. |
| Order item meta | _wcsatt_scheme_id | Legacy APFS plan key. |
Use WCS_ATT_Product::get_subscription_scheme_mode(), WCS_ATT_Product::set_subscription_scheme_mode(), WCS_ATT_Product_Schemes::get_subscription_schemes(), WCS_ATT_Cart::get_subscription_scheme(), and WCS_ATT_Order::get_subscription_scheme(). Do not infer APFS plans from the native _subscription_* product meta table above; APFS sets WCS-compatible values as runtime meta when a scheme is active.
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 key | Relation |
|---|---|
_subscription_renewal | Renewal order to subscription. |
_subscription_switch | Switch order to subscription. |
_subscription_resubscribe | Resubscribe 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.
- A user clicks the switch link printed in My Account by
WC_Subscriptions_Switcher::print_switch_link(). - The link points to the product/grouped product URL with
switch-subscription,item, and_wcsnoncequery args. subscription_switch_handler()validates ownership, nonce, and item switchability.validate_switch_request()blocks non-subscription products and identical product/variation/quantity switches.set_switch_details_in_cart()adds cart item data undersubscription_switch.WCS_Switch_Totals_Calculatorcalculates proration, switch direction, first payment timestamp, and possible prepaid-term changes.- Checkout line item meta records prorated amounts on the switch order and switched item links on subscription items.
process_checkout()creates_subscription_switch_dataon the switch order and may create pending switch items on the existing subscription.- When the switch order is paid/completed,
complete_subscription_switches()applies the payload to the subscription. - WCS fires
woocommerce_subscriptions_switch_completedand 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:
- Verify the current user can switch the exact subscription item with
WC_Subscriptions_Switcher::can_item_be_switched_by_user(). - Build a temporary cart/session context for the current user and add the replacement product with
subscription_switchcart item data. - Let
WCS_Switch_Totals_Calculatorcalculate prorations,first_payment_timestamp,end_timestamp,force_payment, and switch direction. - Return preview totals from the calculated cart/order data, not from hand-written price math.
- On confirmation, create the switch order with the same
_subscription_switch_datashape WCS checkout writes. - 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.
- 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 payload and extension reference
Cart items use subscription_switch; switch orders persist _subscription_switch_data; staged/archive items use custom *_pending_switch, *_switched, and line_item_removed types. These payloads include item IDs, proration results, schedule changes, coupons, fees, and shipping lines and are not a stable shortcut for direct mutation.
Use switching-reference.md for exact payload shapes, item meta, and hook signatures. In WCS 8.8+, wcs_switch_proration_extra_to_pay has a fifth $switch_item argument; register accepted args 5 when that context matters.
Gifting storage
Gifting is included in Subscriptions. It lets purchaser and recipient differ.
| Storage | Key | Purpose |
|---|---|---|
| Cart item data | wcsg_gift_recipients_email | Recipient email before checkout/subscription creation. |
| Subscription meta | _recipient_user_email_address | Recipient email captured at subscription creation before a user is resolved. |
| Subscription meta | _recipient_user | Recipient user ID after account lookup/creation. Primary gifted-subscription marker. |
| Parent order item meta | _wcsg_cart_key | Links checkout order item to the recurring cart/subscription item. |
| Parent order item meta | wcsg_recipient | Value format wcsg_recipient_id_{user_id}. |
| Parent order item meta | wcsg_deleted_recipient_data | JSON snapshot used after recipient deletion. |
| User meta | wcsg_update_account | Recipient account setup/update flag. |
| User meta | wcsg_recipient_just_reset_password | Recipient 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
- Product page/cart/checkout collects recipient email when
WCSG_Product::is_giftable()is true. - Cart item stores
wcsg_gift_recipients_email; gifting is blocked for renewal and switch cart items. - Checkout uses recipient email in recurring cart keys so different recipients produce separate subscriptions.
woocommerce_checkout_subscription_createdwrites_recipient_user_email_addressto the subscription.- On parent order processing/completion, recipient management finds or creates the recipient user, writes
_recipient_user, addswcsg_recipientto the matching parent order item, and updates shipping fields from recipient user meta. - Recipients are granted view/pay/suspend/cancel capabilities for gifted subscriptions, but cannot change payment method.
_recipient_useris 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. - In WCS 9.0 APFS, the Subscription Plans product panel can also write the product-level gifting override while saving ordinary products sold via plans.
- Variable subscription parent returns giftable to render UI; each variation decides final
giftingvariation data. - Product page gifting UI is suppressed during switching (
switch-subscriptionquery 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_membershipstill 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-hooksfor general lifecycle hook selection. - Use
wcs-subscription-plans-apfsfor the full WCS 9.0 Subscription Plans / APFS plan API, REST endpoints, and headless cart behavior. - Use
wcs-renewal-schedulerfor renewal dates, Action Scheduler, and payment retry timing. - Use
wcs-subscription-downloadsfor linked downloadable products, download permission grants/revokes, and the subscription downloads mapping table. - Use
wcm-data-model-subscriptions-linkfor Memberships CPT/meta and the Memberships-to-Subscriptions relation.
References
- Official documentation: https://woocommerce.com/document/subscriptions/develop/
- Verified source paths:
wp-content/plugins/woocommerce-subscriptions/includes/core/class-wc-subscriptions-core-plugin.phpwp-content/plugins/woocommerce-subscriptions/includes/core/class-wc-subscription.phpwp-content/plugins/woocommerce-subscriptions/includes/core/data-stores/class-wcs-subscription-data-store-cpt.phpwp-content/plugins/woocommerce-subscriptions/includes/core/data-stores/class-wcs-orders-table-subscription-data-store.phpwp-content/plugins/woocommerce-subscriptions/includes/core/class-wc-subscriptions-product.phpwp-content/plugins/woocommerce-subscriptions/includes/core/wcs-functions.phpwp-content/plugins/woocommerce-subscriptions/includes/core/wcs-switch-functions.phpwp-content/plugins/woocommerce-subscriptions/includes/switching/class-wc-subscriptions-switcher.phpwp-content/plugins/woocommerce-subscriptions/includes/switching/class-wcs-switch-totals-calculator.phpwp-content/plugins/woocommerce-subscriptions/includes/downloads/wp-content/plugins/woocommerce-subscriptions/includes/apfs/class-wcs-att-product.phpwp-content/plugins/woocommerce-subscriptions/includes/apfs/product/class-wcs-att-product-schemes.phpwp-content/plugins/woocommerce-subscriptions/includes/apfs/class-wcs-att-cart.phpwp-content/plugins/woocommerce-subscriptions/includes/apfs/class-wcs-att-order.phpwp-content/plugins/woocommerce-subscriptions/includes/gifting/class-wcs-gifting.phpwp-content/plugins/woocommerce-subscriptions/includes/gifting/class-wcsg-product.phpwp-content/plugins/woocommerce-subscriptions/includes/gifting/class-wcsg-cart.phpwp-content/plugins/woocommerce-subscriptions/includes/gifting/class-wcsg-checkout.phpwp-content/plugins/woocommerce-subscriptions/includes/gifting/class-wcsg-recipient-management.php
What ships with it: 1 file
4.1 KB alongside SKILL.md
- switching-reference.md4.1 KB