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:
- Go to:
WooCommerce > Settings > Subscriptions
. - 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