feat(payment): implement comprehensive Polar subscription sync with proper date and cancellation handling
- Add Polar-specific date field mapping in PaymentOrchestrator (current_period_start, current_period_end, cancelled_at, trial_end) - Handle both cancellation scenarios: cancel_at_period_end=true and existing cancelled_at timestamp - Map customer_cancellation_reason and customer_cancellation_comment from Polar to database - Update billing page to show correct renewal vs expiry dates based on cancellation status - Restrict cancel button to activation_key provider only (Polar uses customer portal) - Fix button spacing between "Manage in Polar" and "Sync" buttons - Ensure both "Sync" and "Recheck Status" buttons use identical sync functionality
This commit is contained in:
@@ -197,7 +197,7 @@ class Subscription extends Model
|
||||
{
|
||||
try {
|
||||
// For Polar provider, check if we need to fetch subscription ID first
|
||||
if ($this->provider === 'polar' && empty($this->provider_subscription_id) && !empty($this->user->polar_cust_id)) {
|
||||
if ($this->provider === 'polar' && empty($this->provider_subscription_id) && ! empty($this->user->polar_cust_id)) {
|
||||
$this->fetchPolarSubscriptionId();
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ class Subscription extends Model
|
||||
$data = $response->json();
|
||||
$subscriptions = $data['items'] ?? [];
|
||||
|
||||
if (!empty($subscriptions)) {
|
||||
if (! empty($subscriptions)) {
|
||||
// Find the subscription that matches our plan or take the most recent active one
|
||||
$matchingSubscription = null;
|
||||
|
||||
@@ -265,23 +265,55 @@ class Subscription extends Model
|
||||
}
|
||||
|
||||
// If no exact match, take the most recent active subscription
|
||||
if (!$matchingSubscription && !empty($subscriptions)) {
|
||||
if (! $matchingSubscription && ! empty($subscriptions)) {
|
||||
$matchingSubscription = $subscriptions[0];
|
||||
}
|
||||
|
||||
if ($matchingSubscription) {
|
||||
// Parse dates from Polar response
|
||||
$startsAt = null;
|
||||
$endsAt = null;
|
||||
$cancelledAt = null;
|
||||
|
||||
// Handle current_period_start
|
||||
if (isset($matchingSubscription['current_period_start'])) {
|
||||
$startsAt = \Carbon\Carbon::parse($matchingSubscription['current_period_start']);
|
||||
}
|
||||
|
||||
// Handle current_period_end (renewal date)
|
||||
if (isset($matchingSubscription['current_period_end'])) {
|
||||
$endsAt = \Carbon\Carbon::parse($matchingSubscription['current_period_end']);
|
||||
}
|
||||
// Handle ends_at (cancellation/expiry date)
|
||||
elseif (isset($matchingSubscription['ends_at'])) {
|
||||
$endsAt = \Carbon\Carbon::parse($matchingSubscription['ends_at']);
|
||||
}
|
||||
// Handle expires_at (expiry date)
|
||||
elseif (isset($matchingSubscription['expires_at'])) {
|
||||
$endsAt = \Carbon\Carbon::parse($matchingSubscription['expires_at']);
|
||||
}
|
||||
|
||||
// Handle cancelled_at
|
||||
if (isset($matchingSubscription['cancelled_at'])) {
|
||||
$cancelledAt = \Carbon\Carbon::parse($matchingSubscription['cancelled_at']);
|
||||
}
|
||||
|
||||
$this->update([
|
||||
'provider_subscription_id' => $matchingSubscription['id'],
|
||||
'status' => $matchingSubscription['status'],
|
||||
'starts_at' => isset($matchingSubscription['current_period_start'])
|
||||
? \Carbon\Carbon::parse($matchingSubscription['current_period_start'])
|
||||
: null,
|
||||
'ends_at' => isset($matchingSubscription['current_period_end'])
|
||||
? \Carbon\Carbon::parse($matchingSubscription['current_period_end'])
|
||||
: null,
|
||||
'starts_at' => $startsAt,
|
||||
'ends_at' => $endsAt,
|
||||
'cancelled_at' => $cancelledAt,
|
||||
'provider_data' => array_merge($this->provider_data ?? [], [
|
||||
'polar_subscription' => $matchingSubscription,
|
||||
'subscription_id_fetched_at' => now()->toISOString(),
|
||||
'polar_dates' => [
|
||||
'current_period_start' => $matchingSubscription['current_period_start'] ?? null,
|
||||
'current_period_end' => $matchingSubscription['current_period_end'] ?? null,
|
||||
'ends_at' => $matchingSubscription['ends_at'] ?? null,
|
||||
'expires_at' => $matchingSubscription['expires_at'] ?? null,
|
||||
'cancelled_at' => $matchingSubscription['cancelled_at'] ?? null,
|
||||
],
|
||||
]),
|
||||
]);
|
||||
|
||||
@@ -289,6 +321,9 @@ class Subscription extends Model
|
||||
'subscription_id' => $this->id,
|
||||
'polar_subscription_id' => $matchingSubscription['id'],
|
||||
'customer_id' => $this->user->polar_cust_id,
|
||||
'starts_at' => $startsAt?->toISOString(),
|
||||
'ends_at' => $endsAt?->toISOString(),
|
||||
'cancelled_at' => $cancelledAt?->toISOString(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user