Policy Recipes
Practical step-by-step guides for common policy configurations. Each recipe describes a scenario, walks through the configuration, and explains the expected result.
For the full field reference, see Available Policies. For where to make changes, see Configuring Policies.
Recipe 1: Set a 30-day grace period for all Plugin entitlements
Scenario
You want plugin entitlements to wait 30 days in the "expired" state before being automatically cancelled, instead of the current 14 days. This gives customers more time to renew lapsed plugin licenses.
Configuration
Level: Entitlement Class (PLG)
Policy: Cancellation Policy
File: docs/commerce/policies/class-plg.yaml
Change:
cancellation:
expired_to_cancelled_days: 30 # was: 14What happens
- All PLG entitlements that expire will now remain in the "expired" state for 30 days.
- During those 30 days, the customer can still renew and reactivate.
- After 30 days without renewal, the entitlement moves to "cancelled" automatically.
- This only affects PLG entitlements. ENV, SVC, and other classes keep their own values.
Verification
After syncing, check any expired PLG entitlement. The scheduled cancellation date should be 30 days after the expiration date, not 14.
Recipe 2: Disable auto-renewal for a specific organization
Scenario
Organization "University ABC" wants to handle renewals manually through their procurement office. They do not want automatic charges.
Configuration
Level: Organization
Policy: Renewal Policy
Location: WP Admin > Organizations > University ABC > Edit > Policies tab (Planned UI)
Override:
| Field | Value |
|---|---|
auto_renew | false |
Until the admin UI is available, this can be set as organization metadata with key policy.renewal.auto_renew and value false.
What happens
- All entitlements owned by University ABC will NOT auto-renew.
- Renewal reminder emails will still be sent (per the Notification Policy) so their procurement office knows when to act.
- If they do not renew manually before expiration, the entitlement will expire and follow the Cancellation Policy timeline.
- All other organizations continue to auto-renew as configured globally.
Verification
Check an active entitlement for University ABC. The renewal behavior should show "Manual" instead of "Automatic." The entitlement should not trigger a renewal charge before expiration.
Recipe 3: Configure SLA response times for Service entitlements
Scenario
Your service contracts (SVC class) should default to the Priority SLA tier with extended support hours, and escalation should trigger earlier (at 70% of SLA time) because service clients have higher expectations.
Configuration
Level: Entitlement Class (SVC)
Policy: SLA Policy
File: docs/commerce/policies/class-svc.yaml
Values:
sla:
sla_level: priority
response_time:
priority:
P1: "4h"
P2: "8h"
P3: "1d"
P4: "2d"
P5: "3d"
resolution_time:
priority:
P1: "1d"
P2: "2d"
P3: "3d"
P4: "5d"
P5: "7d"
support_hours: extended
escalation_after_pct: 70What happens
- All service requests created against SVC entitlements will use Priority SLA targets.
- A P1 ticket gets a 4-hour first response target and a 1-day resolution target.
- Support hours are extended (8:00-22:00 BRT, Mon-Fri) instead of standard business hours.
- Escalation triggers at 70% of the SLA deadline instead of the global 80%.
- PLG and ENV entitlements are unaffected; they keep their own SLA configuration.
Verification
Create a test service request against a SVC entitlement. Confirm that the SLA targets shown match the Priority tier values, and that the support hours display as "Extended."
Recipe 4: Set up trial periods for the Campus EAD hosting product
Scenario
You want to offer a 14-day free trial for your Campus EAD hosting product (ENV class). To prevent abuse of cloud provisioning, a credit card is required to start the trial. Each organization can only trial once.
Configuration
Level: Entitlement Class (ENV)
Policy: Trial Policy
File: docs/commerce/policies/class-env.yaml
Values:
trial:
enabled: true
duration_days: 14
auto_convert: true
require_payment_method: true
max_trials_per_org: 1
extend_allowed: false
notification_days_before_end:
- 3
- 1What happens
- Customers can start a 14-day trial for any ENV product.
- A valid payment method is required before the trial begins.
- At the end of the trial, the entitlement automatically converts to a paid subscription (the card is charged).
- Each organization can only start one trial -- if they try again, the system rejects it.
- Notifications are sent 3 days and 1 day before the trial ends.
- Admin cannot extend trials (set
extend_allowed: trueif you want to allow this).
Verification
Attempt to start a trial for an ENV product. Confirm that:
- A payment method is required before the trial activates.
- The trial duration shows 14 days.
- A second trial attempt for the same organization is rejected.
- Notification emails are sent at 3 days and 1 day before trial end.
Recipe 5: Handle payment recovery with escalation
Scenario
You want a firm but fair payment recovery process:
- Do not suspend on the first failed payment -- wait until all Stripe retries are exhausted.
- Once suspended, give the customer 30 days to fix their payment.
- Auto-reactivate the moment payment succeeds.
- For one specific customer (Org "Gamma Corp") who has slow internal processes, extend the suspension window to 60 days.
Configuration
Step 1: Global defaults (already in global.yaml)
payment_recovery:
trigger: retry_exhausted
suspended_to_cancelled_days: 30
auto_reactivate_on_payment: trueStep 2: Organization override for Gamma Corp
Level: Organization
Location: WP Admin > Organizations > Gamma Corp > Edit > Policies tab (Planned UI)
| Field | Value |
|---|---|
suspended_to_cancelled_days | 60 |
What happens
- For most customers: Stripe retries payment (typically 3-4 attempts over ~7 days). If all retries fail, the entitlement is suspended. 30 days later, if still unpaid, the entitlement is automatically cancelled.
- For Gamma Corp: same process, but they get 60 days in suspended state instead of 30.
- In both cases, if the customer updates their payment method and the charge succeeds, the entitlement is immediately reactivated without admin intervention.
Verification
For a standard customer: trigger a payment failure in the test environment. After retries exhaust, confirm the entitlement moves to "suspended." Confirm the scheduled cancellation is 30 days later.
For Gamma Corp: same test, but confirm the scheduled cancellation is 60 days after suspension.
Recipe 6: Set up generous refund terms for Plugin products
Scenario
Your plugin products should offer a 30-day refund window with automatic refunds for purchases under R$500 BRL or $100 USD. Larger amounts require admin approval. A full refund cancels the entitlement.
Configuration
Level: Entitlement Class (PLG)
Policy: Refund Policy
File: docs/commerce/policies/class-plg.yaml
Values:
refund:
refund_window_days: 30
auto_refund: true
auto_refund_max:
brl: "500.00"
usd: "100.00"Other fields (partial_allowed, approval_required, cancel_entitlement, credits_on_refund) inherit from the global defaults.
What happens
- A customer who purchased a plugin within the last 30 days can request a refund.
- If the purchase amount is R$500 or less (BRL) or $100 or less (USD), the refund is processed automatically without admin involvement.
- If the amount exceeds the threshold, the refund request is queued for admin approval.
- After a full refund, the entitlement is automatically cancelled (inherited
cancel_entitlement: true). - Partial refunds are allowed (inherited
partial_allowed: true), calculated proportional to usage.
Verification
Test with a purchase under the auto-refund threshold. Request a refund within 30 days. Confirm it is approved automatically and the entitlement moves to "cancelled." Test again with an amount above the threshold and confirm it requires admin approval.
Recipe 7: Prevent tier-change abuse on service contracts
Scenario
You want to prevent customers from rapidly switching between service tiers on annual contracts. Downgrades should require admin approval, there should be a 90-day cooldown between changes, and tier changes should take effect at the next billing cycle (not immediately).
Configuration
Level: Entitlement Class (SVC)
Policy: Tier Change Policy
File: docs/commerce/policies/class-svc.yaml
Values:
tier_change:
effect: next_cycle
downgrade_requires_approval: admin
cooldown_days: 90
credit_behavior: next_cycleWhat happens
- When a SVC customer requests an upgrade, it is accepted but takes effect on the next billing cycle, not immediately.
- When a SVC customer requests a downgrade, it must be approved by an admin before proceeding.
- After any tier change (up or down), the customer must wait 90 days before making another change.
- Credit allocations are adjusted on the next billing cycle, not at the moment of the change.
- PLG and ENV entitlements are unaffected -- their tier changes remain immediate with no cooldown (global defaults).
Verification
Attempt a downgrade on a SVC entitlement. Confirm it is held for admin approval. After approval, confirm the change is scheduled for the next billing cycle. Attempt another tier change within 90 days and confirm it is rejected with a cooldown message.
Recipe 8: Configure earlier expiry warnings for hosting environments
Scenario
Hosting environments (ENV class) going offline is a critical issue for customers. You want to send expiry warnings earlier and more frequently than the global default.
Configuration
Level: Entitlement Class (ENV)
Policy: Notification Policy
File: docs/commerce/policies/class-env.yaml
Values:
notification:
expiry_warning_days:
- 60
- 30
- 7
- 1What happens
- ENV entitlements will send expiry warnings at 60, 30, 7, and 1 day before expiration.
- The global default (
[30, 7, 1]) is fully replaced -- not merged with -- the class override. - PLG and SVC entitlements keep their own notification schedules.
- All other notification settings (channels, events, opt-out) are inherited from the global defaults unless also overridden.
Verification
Check an active ENV entitlement with an expiration date 65 days in the future. Over the next days, confirm warning emails are sent at the 60, 30, 7, and 1 day marks.
Summary
| Recipe | Level | Policy | Key change |
|---|---|---|---|
| 1 | Class (PLG) | Cancellation | 30-day expired-to-cancelled |
| 2 | Organization | Renewal | Disable auto-renewal |
| 3 | Class (SVC) | SLA | Priority tier, extended hours |
| 4 | Class (ENV) | Trial | 14-day trial, card required |
| 5 | Global + Org | Payment Recovery | 30d default, 60d for one customer |
| 6 | Class (PLG) | Refund | Auto-refund under R$500/$100 |
| 7 | Class (SVC) | Tier Change | 90d cooldown, admin approval |
| 8 | Class (ENV) | Notification | Earlier expiry warnings |
Next steps
- Policy Engine Overview -- the big picture
- Available Policies -- full field reference
- Policy Hierarchy -- how override resolution works
- Configuring Policies -- where to find the settings