Discount Schemes¶
Discount schemes use a strategy pattern. Each scheme implements the DiscountScheme interface and extends BaseDiscountScheme.
Built-in schemes¶
| Scheme class | Enum constant | Description |
|---|---|---|
FixedAmountDiscountScheme | FIXED_AMOUNT_DISCOUNT | Deducts a fixed currency amount; requires amount meta |
PercentageOrderDiscountScheme | PERCENTAGE_ORDER_DISCOUNT | Deducts a percentage of the order total; requires amount meta |
OffboardingDiscountScheme | OFFBOARDING_ORDER_DISCOUNT | Extends PercentageOrderDiscountScheme; can only be granted once per subscription; auto-deleted on cancellation |
Scheme interface¶
interface DiscountScheme {
public static function enum(): string;
public static function get_name(): string;
public static function get_description(): string;
public static function get_helper_text(): string;
public function create(WC_Subscription $subscription, string $created_via, array $meta_data = []): DataDiscount;
public function apply(DataDiscount $discount, WC_Order $order): void;
}
Adding a custom scheme¶
- Create a class extending
BaseDiscountScheme:
namespace MyPlugin\DiscountSchemes;
use RenewalDiscounts\DiscountScheme\BaseDiscountScheme;
use RenewalDiscounts\Data\Models\DataDiscount;
use WC_Order;
use WC_Subscription;
class FreeShippingDiscountScheme extends BaseDiscountScheme {
public const enum = 'FREE_SHIPPING_DISCOUNT';
public static function enum(): string { return self::enum; }
public static function get_name(): string { return 'Free Shipping'; }
public static function get_description(): string { return 'Waives shipping on the next renewal.'; }
public static function get_helper_text(): string { return ''; }
protected function can_create(WC_Subscription $subscription, array $meta_data = []): bool {
return true; // add your guard conditions
}
public function apply(DataDiscount $discount, WC_Order $order): void {
if (!$this->can_apply($discount, $order)) {
return;
}
// apply discount logic here
$discount->set_order_id($order->get_id());
$discount->save();
$this->log_discount_usage($discount, $order);
}
}
- Register the scheme via the filter:
add_filter('renewal-discounts/schemes', function (array $schemes): array {
$schemes[FreeShippingDiscountScheme::enum()] = FreeShippingDiscountScheme::class;
return $schemes;
});
- Seed the new type in the database (e.g. in a migration):
can_apply guard¶
BaseDiscountScheme::can_apply() blocks the discount if the renewal order has the _winback_renewal meta set to a non-zero value. Override this method in your scheme to add additional guards.