From bde8d4801ef00270df1ddcbb277efa03d9183289 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Mon, 22 Jun 2026 12:32:03 -0300 Subject: [PATCH] feat(billing): attach persona to conversion tracking and polish annual banner Send the user's persona on both the server-side subscription.created event and the client-side checkout.completed/dataLayer purchase event, for ICP analysis. Hold the processing screen ~5s before redirecting so PostHog and the ad pixels (Google/Meta via GTM) reliably flush. Sharpen the annual-upgrade banner copy (lead with '2 months free') and give its check icon a white tile. --- .../Controllers/App/BillingController.php | 1 + app/Jobs/PostHog/TrackBilling.php | 3 +- lang/en/billing.php | 4 +- lang/es/billing.php | 4 +- lang/pt-BR/billing.php | 4 +- resources/js/composables/useTracking.ts | 3 ++ resources/js/pages/billing/Processing.vue | 46 ++++++++++++------- .../js/pages/settings/account/Billing.vue | 4 +- .../Feature/Jobs/PostHog/TrackBillingTest.php | 14 ++++++ 9 files changed, 58 insertions(+), 25 deletions(-) diff --git a/app/Http/Controllers/App/BillingController.php b/app/Http/Controllers/App/BillingController.php index d085906f..e85d36c5 100644 --- a/app/Http/Controllers/App/BillingController.php +++ b/app/Http/Controllers/App/BillingController.php @@ -40,6 +40,7 @@ public function processing(Request $request): Response|RedirectResponse return Inertia::render('billing/Processing', [ 'subscriptionActive' => $account && $account->subscribed(Account::SUBSCRIPTION_NAME), 'fromCheckout' => $fromCheckout, + 'persona' => $request->user()->persona?->value, 'conversion' => $fromCheckout && $account?->stripe_id ? fn () => $this->buildConversionData($account, $sessionId) : null, diff --git a/app/Jobs/PostHog/TrackBilling.php b/app/Jobs/PostHog/TrackBilling.php index 59f2a1a9..5994b0ed 100644 --- a/app/Jobs/PostHog/TrackBilling.php +++ b/app/Jobs/PostHog/TrackBilling.php @@ -39,7 +39,7 @@ public function handle(PostHogService $postHog): void return; } - $account = Account::with('plan')->find($this->accountId); + $account = Account::with(['plan', 'owner'])->find($this->accountId); if (! $account || ! $account->owner_id) { return; @@ -53,6 +53,7 @@ public function handle(PostHogService $postHog): void 'plan' => $account->plan?->name, 'plan_slug' => $account->plan?->slug->value, 'previous_plan' => $this->previousPlan, + 'persona' => $account->owner?->persona?->value, ], $account, ); diff --git a/lang/en/billing.php b/lang/en/billing.php index 196e8e45..ed4ffa1f 100644 --- a/lang/en/billing.php +++ b/lang/en/billing.php @@ -10,8 +10,8 @@ ], 'annual_banner' => [ - 'title' => 'Save 2 months with annual billing', - 'description' => 'Switch to annual and get 2 months free — pay less every month.', + 'title' => 'Get 2 months free', + 'description' => 'Switch to annual billing and pay less every month — same plan, nothing else changes.', 'cta' => 'Upgrade to annual', ], diff --git a/lang/es/billing.php b/lang/es/billing.php index 9a51050d..deb54eb1 100644 --- a/lang/es/billing.php +++ b/lang/es/billing.php @@ -10,8 +10,8 @@ ], 'annual_banner' => [ - 'title' => 'Ahorra 2 meses con la facturación anual', - 'description' => 'Cambia al anual y obtén 2 meses gratis — paga menos cada mes.', + 'title' => 'Consigue 2 meses gratis', + 'description' => 'Cambia a la facturación anual y paga menos al mes — el mismo plan, sin cambios.', 'cta' => 'Cambiar a anual', ], diff --git a/lang/pt-BR/billing.php b/lang/pt-BR/billing.php index f78d5879..52e5e9f7 100644 --- a/lang/pt-BR/billing.php +++ b/lang/pt-BR/billing.php @@ -10,8 +10,8 @@ ], 'annual_banner' => [ - 'title' => 'Economize 2 meses com a cobrança anual', - 'description' => 'Mude para o anual e ganhe 2 meses grátis — pague menos por mês.', + 'title' => 'Ganhe 2 meses grátis', + 'description' => 'Mude para a cobrança anual e pague menos por mês — sem mudar nada do seu plano.', 'cta' => 'Mudar para anual', ], diff --git a/resources/js/composables/useTracking.ts b/resources/js/composables/useTracking.ts index c12b472a..8384a3ef 100644 --- a/resources/js/composables/useTracking.ts +++ b/resources/js/composables/useTracking.ts @@ -33,10 +33,12 @@ export const useTracking = () => ({ trackPurchase: ( plan: { name: string; interval: string }, conversion?: { value: number; currency: string; transaction_id: string } | null, + persona?: string | null, ) => { captureEvent('checkout.completed', { plan_name: plan.name, interval: plan.interval, + ...(persona ? { persona } : {}), ...(conversion ? { conversion_value: conversion.value, conversion_currency: conversion.currency, @@ -48,6 +50,7 @@ export const useTracking = () => ({ event: 'purchase', plan_name: plan.name, plan_interval: plan.interval, + ...(persona ? { persona } : {}), ...(conversion ? { conversion_value: conversion.value, conversion_currency: conversion.currency, diff --git a/resources/js/pages/billing/Processing.vue b/resources/js/pages/billing/Processing.vue index 96673402..295acb42 100644 --- a/resources/js/pages/billing/Processing.vue +++ b/resources/js/pages/billing/Processing.vue @@ -1,7 +1,7 @@