Skip to content

Renewal Discount Flow

How a discount is applied on renewal

The Subscriptions module hooks into wcs_renewal_order_created (priority 1000) and applies any pending discount to the new renewal order.

sequenceDiagram
    participant WCS as WooCommerce Subscriptions
    participant Sub as Subscriptions module
    participant DB as DataDiscount
    participant Scheme as DiscountScheme

    WCS->>Sub: wcs_renewal_order_created(renewal_order, subscription)
    Sub->>DB: get({ subscription_id, order_id: null })
    alt No pending discounts
        Sub-->>WCS: return renewal_order unchanged
    else Pending discount found
        Sub->>DB: discount.set_order_id(renewal_order.id)
        Sub->>Scheme: apply(discount, renewal_order)
        Scheme->>Scheme: can_apply(discount, order)?
        alt Cannot apply (e.g. winback renewal)
            Scheme-->>Sub: return (no-op)
        else Apply discount
            Scheme->>WCS: add coupon line item to order
            Scheme->>WCS: recalculate_coupons()
            Scheme->>DB: discount.save() (persist order_id)
            Scheme->>WCS: add order note
        end
    end

Offboarding discount lifecycle

stateDiagram-v2
    [*] --> Pending : Created via REST / AJAX
    Pending --> Applied : Renewal order created
    Pending --> Deleted : Subscription cancelled
    Applied --> [*]
    Deleted --> [*]

Creating a discount (admin / API flow)

  1. Admin selects a discount type and amount in the subscription meta box (Vue component) or calls the REST API.
  2. BaseDiscountScheme::create() validates via can_create(), persists the DataDiscount record with order_id = NULL, and saves any meta_data (e.g. amount).
  3. On the next WooCommerce Subscriptions renewal, the Subscriptions module picks up the pending discount and calls apply().