SubscriptionRepository — Billing Methods
Benecaster\Membership\SubscriptionRepository
Two methods added to SubscriptionRepository in feature/built-in-membership-portal-emails to support the billing email subsystem.
mark_cancelled()
SubscriptionRepository::mark_cancelled( int $id ): bool
Sets status = 'cancelled' and cancelled_at to the current UTC timestamp on the benecaster_subscriptions row identified by $id. Returns true on success, false on DB error.
Called by SubscriptionDeletedListener when customer.subscription.deleted arrives from Stripe. The row is not deleted — it is kept in place for historical reference and to distinguish subscribers who have a cancellation history from subscribers who never had a subscription.
find_renewal_candidates()
SubscriptionRepository::find_renewal_candidates(
int $show_id,
string $window_start,
string $window_end
): array
Returns benecaster_subscriptions rows for a show where current_period_end falls in the UTC half-open window [$window_start, $window_end). Used by RenewalReminderCron to find subscribers who should receive a renewal reminder on the current day.
Parameters:
| Name | Type | Description |
|---|---|---|
$show_id |
int | Show post ID |
$window_start |
string | UTC datetime string (inclusive). Typically midnight + N days. |
$window_end |
string | UTC datetime string (exclusive). Typically midnight + (N+1) days. |
Returns: Array of subscription row objects (same shape as find_active_by_user_show()).
Explicit exclusions — rows that are NOT returned:
| Condition | Reason |
|---|---|
cancel_at_period_end = 1 |
Subscriber already cancelled — a renewal reminder is misleading |
Status past_due |
Active payment failure — renewal reminder would conflict with the payment_failed flow |
Status not in active, trialing |
Only active and trialing rows receive reminders |
The past_due exclusion is load-bearing: RenewalReminderCron must not overlap with InvoicePaymentFailedListener’s messaging. A subscriber whose payment just failed should receive the payment_failed email, not a renewal reminder.