Dorokhov.codes

Subscriptions

WooCommerce Subscriptions is a premium extension that offers two methods for accepting recurring payments:

  • Automatic payments.
  • Manual payments.

Here’s a list of extensions that support automatic payments.

Also, there’s an extension called WooCommerce Payments with subscriptions functionality.

From documentation:

To enable subscriptions for gateways other than WooCommerce Payments, please ensure that WooCommerce Subscriptions is installed and active.

After installation of WooCommerce Subscriptions we will get two new product types:

  • Simple subscription.
  • Variable subscription.

Manual payments

It’s possible to accept payments via payment gateways that do not support automatic recurring payments.

To accept manual payments:

  1. Go to: WooCommerce > Settings > Subscriptions.
  2. Select the Accept Manual Renewals option.

If you enable this setting, it offers all active payment gateways as a payment option when purchasing a subscription, not just gateways that support Subscriptions. If the customer chooses to pay via a payment gateway that does not support automatic payments, then the subscription will use the manual renewal process.

After enabling this option, we will see a list of all the gateways on the checkout page. Some of them will be using manual payments, other will be using automatic payments. But if we want to use manual payments even for those gateways which support automatic payments, we should enable the Turn off Automatic Payments option.

Mixed Checkout

Enable Mixed Checkout on the Subscriptions settings to allow a subscription product to be purchased with other products in the same transaction, including simple, variable and other non-subscription products as well as multiple different subscription products.

Managing subscriptions

The Manage Subscriptions page can be found at: WooCommerce > Subscriptions.

On the subscription management page, you can change the status of a subscription. Hover over a subscription to see actions that can be performed on the subscription.

  • To temporarily pause a subscription, click Suspend.
  • To resume a suspended subscription, click Reactivate.
  • To permanently stop a subscription, click Cancel.

Suspend and Cancel only display if the subscription was purchased using the manual renewal method or a payment gateway that supports subscription suspension and cancellation.

Subscription statuses

Subscription status is bound to order status changes, so using the WooCommerce Payment Gateway API to set an order’s status will automatically set the status of a subscription.

When an order status changes to processing or complete, a subscription purchased in the order is activated automatically. When an order is cancelled, refunded or marked as failed, the status of a subscription in that order will also be updated to cancelled or failed.

Technical introduction

When we sign up for a subscription, a new record is added to the wp_posts table where post_type=shop_subscription.

Also, a new record with post_type=shop_order is added to the same table.

The post_parent of the subscription record refers to the order’s record ID.

It will always be crated one subscription record, even if there were several subscription products in the cart.

Implementation

1. Registering support for subscriptions

Option Description
subscriptions Tells that the gateway supports subscriptions.
subscription_cancellation Subscription Suspension, Cancellation or Reactivation: A store manager or customer can change the status of a subscription directly from your store, i.e., without visiting the payment gateway.
subscription_suspension
subscription_reactivation
multiple_subscriptions Multiple Subscriptions: A customer can add different subscription products to their cart and complete checkout.
subscription_amount_changes Recurring Total Changes: You as store manager can manually change the recurring amount charged for renewal payments.
subscription_date_changes Payment Date Changes: You as store manager can manually change the payment schedule for a subscription, including the expiration date, trial length or next payment date.
subscription_payment_method_change
subscription_payment_method_change_customer Customer Payment Method Changes: Payment gateway is presented as an option when a customer changes the recurring payment method used for a subscription. It also means Subscriptions can update the payment method used for future recurring payments when a customer pays for a failed renewal.
subscription_payment_method_change_admin Store Manager Payment Method Changes: Payment gateway is presented to the store manager as an option when changing the recurring payment method used for a subscription on the Edit Subscription screen.
gateway_scheduled_payments Tells that the payment gateway manages the billing schedule.

2. Process subscription sign-ups

Like processing payment for a product, your payment gateway extension will need to process a subscription sign-up in its process_payment() function.

Depending on how you gateway processes subscriptions, you may need to know any of the initial payment amount, the subscription’s sign-up fee, price per period, billing period and duration at outset of the subscription.

To obtain these details for an order containing a subscription, use the WC_Subscriptions_Order class methods.

// Checks the cart to see if it contains a subscription product:
WC_Subscriptions_Cart::cart_contains_subscription();

// Get initial amount:
WC_Subscriptions_Order::get_total_initial_payment( $order );

// How much to charge for each individual billing period:
WC_Subscriptions_Order::get_price_per_period( $order );

// Sign-up fee amount for an order
WC_Subscriptions_Order::get_sign_up_fee( $order );

// Get the subscription period for an order:
WC_Subscriptions_Order::get_subscription_period( $order );

/**
 *  Payment gateways typically require one of two methods for setting up a free trial:
 * 1. Passing the free trial period and length, like PayPal; or
 * 2. Setting the start date for the subscription, like WorldPay.
 * To use the first method, get a subscriptions trial details with the following two functions:
 */
WC_Subscriptions_Order::get_subscription_trial_period( $order );
WC_Subscriptions_Order::get_subscription_trial_length( $order );

// To use the second method and set the start date, use the following function:
WC_Subscriptions_Product::get_trial_expiration_date( $product_id, $order_start_date );

// To get the subscription duration for an order:
WC_Subscriptions_Order::get_subscription_length( $order );

3. Process renewals

If your payment gateway can automatically charge recurring payments, you use the

WC_Subscriptions_Manager::process_subscription_payments_on_order()

function to keep a record of each payment once the gateway has processed the payment.

If your payment gateway also manages the billing schedule, then you should also add the gateway_scheduled_payments flag when registering support for Subscriptions.

Recurring Payments Processed by the plugin

Some payment gateways may have little or no support for recurring payments, but may allow you to charge a stored credit card. These gateways can still be integrated with WC Subscriptions to offer automatic recurring billing.

For each subscription, a woocommerce_scheduled_subscription_payment_{payment_gateway_id} hook is fired whenever a payment is due for a specific gateway. This hook includes the amount due on the subscription (including outstanding payments, if any) as well as the order and product ID of the subscription. You can use this hook to process a subscription payment.

Activating a Subscription

WC_Subscriptions_Manager::activate_subscriptions_for_order( $order ) can be used to mark all subscriptions in an order as active.

This function is fired automatically when an order’s status changes to completed or processing, so if you are correctly updating an order’s status, you do not need to call this function.

The function calls the WC_Subscriptions_Manager::activate_subscription() function for each subscription item in an order.

Cancelling a Subscription

If your gateway provides an API for cancelling a subscription (or you are manually charging recurring payments), you can add support for subscriptions to be cancelled in the store.

Just like registering support for subscriptions, you notify Subscriptions of your cancellation capability by including a flag in your extensions supports() property.

Including this flag will expose the Cancel action link on a subscription purchased with your gateway to store managers and subscribers. When this action link is clicked, Subscriptions will cancel the subscription in the store and you need to cancel the subscription with your gateway.

Subscriptions fires a cancelled_subscription hook whenever a subscription is cancelled, but a better action to hook to use is woocommerce_subscription_cancelled_{payment_gateway_id}. This hook passes the WC_Order object and WC_Product ID of the subscription product being cancelled. You can use these details to cancel the subscription with your gateway.

If a user can cancel a subscription with the payment gateway directly, you must reflect this change in the WooCommerce store by calling:

WC_Subscriptions_Manager::cancel_subscriptions_for_order( $order )

This function is automatically called when an order’s status is changed to cancelled, failed or refunded order.

Internally, the function acts as a convenience wrapper function for the WC_Subscriptions_Manager::cancel_subscription() function. If you need to cancel just one subscription and no its associated order, you can call the cancel subscription function directly:

WC_Subscriptions_Order::cancel_subscription( $user_id, $subscription_key )

Where $subscription_key is the key derived from the concatenation of the order ID, an underscore and the subscription product’s ID e.g. 153_12 for product ID 12 purchased on order 153.

Expiring a Subscription

The Subscriptions extension schedules a action to set a subscription’s status to expired when its expiration date arrives, so you do not need to manually expire a subscription.

However, if your payment gateway provides an expiration notification and you like the security of redundancy, you can call the WC_Subscriptions_Manager function directly.

To expire any subscriptions on an order call:

WC_Subscriptions_Manager::expire_subscriptions_for_order( $order )

To expire an individual subscription call:

WC_Subscriptions_Manager::expire_subscription( $user_id, $subscription_key )

If you’re charging recurring payments manually, you do not need to expire a subscription because the scheduled payment hooks will no longer fire once a subscriptions is cancelled.

Recording Payments

If your gateway provides a notification system, it’s a good idea to call the process_subscription_payments_on_order() function to keep a record of the payment on the order.

WC_Subscriptions_Manager::process_subscription_payments_on_order( $order )

Recording Failed Payments

A subscription’s status does not change when a payment fails (unless the total number of failed payments exceeds the number the administrator has set for the store). However, you should still record failed payments. If your gateway provides a notification system, it’s a good idea to call the process_subscription_payment_failure_on_order() function to keep a record of the payment on the order.

WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $order )

Useful functions

WooCommerce subscriptions order functions:

woocommerce-subscriptions/includes/wcs-order-functions.php.:

wcs_get_subscriptions_for_order();
wcs_order_contains_subscription();
wcs_get_subscription_orders();
wcs_order_contains_manual_subscription();
wcs_order_contains_product();

woocommerce-subscriptions/includes/wcs-renewal-functions.php:

wcs_order_contains_renewal();
wcs_cart_contains_renewal();
wcs_get_subscriptions_for_renewal_order();

Other files containing functions related to subscriptions:

wcs-cart-functions.php
class-wc-subscriptions-order.php
class-wc-subscriptions-cart.php