feat(messaging): suite-channel email/SMS and entitlement sync
Deploy Ladill Events / deploy (push) Successful in 48s

Prefer platform suite messaging (channel=suite) for attendee email, fall back
to Bird integrations; sync suite plan entitlements on subscribe/renew.
This commit is contained in:
isaacclad
2026-07-16 11:24:21 +00:00
parent b73b071cb1
commit 3d5ffa593d
8 changed files with 365 additions and 86 deletions
+39 -3
View File
@@ -154,6 +154,9 @@ class SubscriptionService
? $this->enterprisePriceMinor()
: $this->priceMinor();
$periodEnd = Carbon::now()->addMonths($months);
$reference = 'events-prepaid-'.$plan.'-'.$user->id.'-'.now()->format('YmdHis');
ProSubscription::updateOrCreate(
['user_id' => $user->id],
[
@@ -163,13 +166,16 @@ class SubscriptionService
'currency' => (string) config('events.pro.currency', 'GHS'),
'auto_renew' => false,
'started_at' => $existing?->started_at ?? now(),
'current_period_end' => Carbon::now()->addMonths($months),
'current_period_end' => $periodEnd,
'last_charged_at' => now(),
'canceled_at' => null,
'last_reference' => null,
'last_reference' => $reference,
'last_error' => null,
],
);
// Prepaid checkout already writes entitlements on the platform; this is a repair/sync.
$this->syncMessagingEntitlement($user, $plan, ProSubscription::STATUS_ACTIVE, $reference, $periodEnd, 'checkout');
}
/** @return array{0:bool,1:string} */
@@ -210,19 +216,23 @@ class SubscriptionService
$result = $this->billing->charge($user, $sub->price_minor, $reference, "Ladill Events {$planLabel} — renewal");
if ($result['ok']) {
$periodEnd = Carbon::now()->addDays((int) config('events.pro.period_days', 30));
$sub->forceFill([
'current_period_end' => Carbon::now()->addDays((int) config('events.pro.period_days', 30)),
'current_period_end' => $periodEnd,
'last_charged_at' => now(),
'last_reference' => $reference,
'last_error' => null,
])->save();
$this->syncMessagingEntitlement($user, $sub->plan, ProSubscription::STATUS_ACTIVE, $reference, $periodEnd);
return;
}
$graceEnd = optional($sub->current_period_end)->addDays((int) config('events.pro.grace_days', 3));
if ($graceEnd && $graceEnd->isPast()) {
$sub->forceFill(['status' => ProSubscription::STATUS_PAST_DUE, 'last_error' => $result['error']])->save();
$this->syncMessagingEntitlement($user, $sub->plan, 'past_due', $reference.'-pastdue', $sub->current_period_end);
} else {
$sub->forceFill(['last_error' => $result['error']])->save();
}
@@ -263,6 +273,32 @@ class SubscriptionService
],
);
$this->syncMessagingEntitlement($user, $plan, ProSubscription::STATUS_ACTIVE, $reference, $periodEnd);
return [true, $successMessage.' Your subscription is active.'];
}
/**
* Map Events plan platform suite entitlement plan (enterprise = Business tier).
*/
private function syncMessagingEntitlement(
User $user,
string $plan,
string $status,
string $reference,
?Carbon $periodEnd,
string $source = 'wallet_debit',
): void {
$platformPlan = $plan === ProSubscription::PLAN_ENTERPRISE ? 'enterprise' : ($plan === 'free' ? 'free' : 'pro');
$publicId = (string) ($user->public_id ?? '');
if ($publicId === '') {
return;
}
$this->billing->syncSuiteEntitlement($publicId, $platformPlan, $status, $reference, [
'period_starts_at' => now()->toIso8601String(),
'period_ends_at' => $periodEnd?->toIso8601String(),
'source' => $source,
]);
}
}