Skip to content

Subscriptions

The subscriptions module adds products with recurring payments. Customers buy subscriptions with manual renewal, and the administrator manages them in WooCommerce.

  1. The administrator marks an ordinary product as a subscription, with a cycle and a price, on the Polski Pro tab of the product editor
  2. The customer purchases a subscription and pays the first order
  3. The plugin creates a subscription with “Active” status
  4. Before the renewal date, the customer receives a reminder email
  5. On the renewal date, the plugin creates a renewal order
  6. The customer pays the renewal order (manual renewal)
  7. The cycle repeats until the subscription is cancelled

Since Polski PRO 1.22.0 subscriptions have their own row on Polski > Modules (module key subscriptions). Switch the module on there, and set the store-wide values on the same row; saving writes them into the polski_subscriptions option. The module ships off.

The row does not expose every key the module reads. Anything missing from it can still be set on the option directly, for example with WP-CLI:

Terminal window
wp option patch update polski_subscriptions reminder_first_days 10

Per-product values (whether a product is a subscription at all, and its cycle) are on the Polski Pro tab of the product editor, see Per-product settings.

Key Default Description
show_on_single true Show the subscription options on the product page
reminder_first_days 14 Days before renewal for the first reminder email
reminder_second_days 7 Days before renewal for the second reminder email
allow_cancellation true Let the customer cancel from My Account
allow_pause true Let the customer pause and resume from My Account
show_in_account / account_label true / Subscriptions My Account section listing subscriptions
date_format d.m.Y Date format in customer-facing output

Reminder and renewal emails, the status names and the cycle wording each have their own key (reminder_subject, renewal_intro_text, status_paused and so on). The defaults live in Polski\Pro\Service\SubscriptionService. Renewal reminders and renewal orders run on the polski_daily_maintenance cron event.

There is no “Subscription” product type. A subscription is an ordinary product with the subscription meta set on it, and since Polski PRO 1.26.0 the Polski Pro tab in the product data box writes that meta:

  1. Go to Products > Add New and build an ordinary product. Its price is the amount charged per billing period.
  2. Open the Polski Pro tab in the Product data box and tick Sell as a subscription.
  3. Configure the cycle:
Field Meta key Description
Bill every _polski_subscription_interval Number of periods between charges, at least 1
Billing period _polski_subscription_period Day, week, month or year; month when unset
Number of payments _polski_subscription_length 0 renews until the customer cancels
Sign-up fee _polski_subscription_signup_fee Charged once, with the first payment
Trial days _polski_subscription_trial_days Days before the first charge, 0 for no trial
  1. Publish the product

See Per-product settings for the whole tab.

Two fields make the first payment differ from the ones after it:

  • Sign-up fee is added once, to the first order only.
  • Trial days pushes the first charge out by that many days, and the subscription starts in the trial status instead of active.

There is no separate “initial price” field. Everything else is the product price, charged again each billing period.

Pending -> Active -> On Hold -> Active -> ...
-> Expired
-> Cancelled
Status Description
Pending Awaiting payment of the first order
Active Active - customer has access to the product
On Hold Suspended - renewal order awaiting payment
Expired Expired - renewal count reached the limit or grace period passed
Cancelled Cancelled by the customer or administrator

In the current version, the plugin supports manual renewals. This means that:

  1. The plugin creates a renewal order with “Pending payment” status
  2. The customer receives an email with a link to pay the order
  3. The customer pays the order using their chosen payment method
  4. After payment, the subscription is renewed for the next period

The plugin checks subscriptions due for renewal daily using WP cron:

polski_daily_maintenance

The cron task runs once daily and performs:

  • checking subscriptions whose renewal date falls on today or earlier
  • creating renewal orders for subscriptions requiring renewal
  • suspending subscriptions that have exceeded the grace period
  • expiring subscriptions that have reached the renewal limit

The plugin sends email reminders before the renewal date:

Email When Content
Renewal reminder X days before renewal Information about the upcoming renewal, amount, link to the panel
Renewal order On the renewal date Order to pay with a payment link
Subscription suspended After payment due date passes Information about suspension, link to pay
Subscription expired After grace period passes Information about expiration, link to repurchase

Email templates can be customized in WooCommerce > Settings > Emails.

The module adds a /polski-subscriptions endpoint to the customer’s My Account panel. The endpoint is available at:

/moje-konto/polski-subscriptions/

The customer sees a table with subscriptions:

Column Description
Product Subscription product name
Status Current subscription status
Price Amount per period
Next renewal Next renewal date
Actions Cancel / Pay renewal

After clicking on a subscription, the customer sees:

  • full subscription data (product, price, cycle, dates)
  • renewal history (list of associated orders)
  • subscription cancellation button
  • button to pay a pending renewal (if applicable)

The customer can cancel an active subscription from the My Account panel. Cancellation:

  • changes the subscription status to “Cancelled”
  • the subscription remains active until the end of the current paid period
  • the customer is informed about the access end date

Action fired after a subscription status change.

/**
* @param int $subscription_id ID subskrypcji
* @param string $new_status Nowy status
* @param string $old_status Poprzedni status
*/
do_action('polski_pro/subscription/status_changed', int $subscription_id, string $new_status, string $old_status);

Example:

add_action('polski_pro/subscription/status_changed', function (int $subscription_id, string $new_status, string $old_status): void {
if ($new_status === 'cancelled') {
$subscription = polski_pro_get_subscription($subscription_id);
// Wysłanie ankiety o powód rezygnacji
wp_mail(
$subscription->get_customer_email(),
'Szkoda, że odchodzisz',
'Powiedz nam, dlaczego anulujesz subskrypcję: https://example.com/ankieta'
);
}
}, 10, 3);

Action fired after a renewal order is created.

/**
* @param int $order_id ID zamówienia odnowienia
* @param int $subscription_id ID subskrypcji
*/
do_action('polski_pro/subscription/renewal_created', int $order_id, int $subscription_id);

Example:

add_action('polski_pro/subscription/renewal_created', function (int $order_id, int $subscription_id): void {
$order = wc_get_order($order_id);
$order->add_order_note(
sprintf('Zamówienie odnowienia dla subskrypcji #%d', $subscription_id)
);
}, 10, 2);

Action fired after a renewal order is paid.

/**
* @param int $order_id ID zamówienia odnowienia
* @param int $subscription_id ID subskrypcji
*/
do_action('polski_pro/subscription/renewal_paid', int $order_id, int $subscription_id);

The reminder engine (14 + 7 days before renewal by default) exposes filters and actions:

// Customise windows (days before renewal)
add_filter('polski_subscription_reminder_windows', fn ($w) => ['first' => 21, 'second' => 7, 'last' => 1]);
// Subject / body / headers filters
add_filter('polski_subscription_reminder_subject', fn ($s, $sub, $type) => "[$type] $s", 10, 3);
add_filter('polski_subscription_reminder_body', fn ($b, $sub, $type) => $b . "\n\nThanks!", 10, 3);
add_filter('polski_subscription_reminder_headers', fn () => ['Content-Type: text/html; charset=UTF-8']);
// Skip a specific subscription
add_filter('polski_subscription_skip_reminder', fn ($skip, $sub) => $sub->productId === 42, 10, 2);
// Observe dispatch
add_action('polski_subscription_reminder_sent', fn ($sub, $type, $days) => null, 10, 3);
add_action('polski_subscription_reminder_failed', fn ($sub, $type) => null, 10, 2);

SubscriptionRepository::updateRecurringAmount() detects an amount change and emails the customer with old/new price, effective next billing date and a one-click cancel link (EU consumer-protection requirement).

add_action('polski_subscription_amount_changed', function (int $id, float $prev, float $next) {
error_log("Subscription $id: $prev -> $next");
}, 10, 3);
add_filter('polski_subscription_amount_change_body', fn ($body, $sub, $prev, $next) => $body, 10, 4);
add_action('polski_subscription_amount_change_notified', fn ($sub, $prev, $next, $sent) => null, 10, 4);

Go to WooCommerce > Subscriptions. The table contains:

  • subscription ID
  • customer (first name, last name, email)
  • product
  • status
  • price and cycle
  • next renewal date
  • creation date

Available filters: status, product, creation date.

The administrator can:

  • change the subscription status
  • change the next renewal date
  • change the price (affects subsequent renewals)
  • add a note
  • browse status history and associated orders
  1. Check if WP-Cron is working properly (wp_cron is being called)
  2. Go to Tools > Scheduled Actions and check if the polski_daily_maintenance task is scheduled
  3. Verify that the subscription has “Active” status and a correct renewal date
  1. Check the WooCommerce email configuration
  2. Verify that the reminder email template is enabled
  3. Check the “Reminder days” setting - whether it is greater than 0

Subscription does not change status after payment

Section titled “Subscription does not change status after payment”
  1. Check if the renewal order has a correct association with the subscription
  2. Verify WooCommerce logs for errors
  3. Check if the payment gateway correctly changes the order status
This page is for informational purposes only and does not constitute legal advice. Consult a lawyer before implementation. Polski for WooCommerce is open source software (GPLv2) provided without warranty.