fix: stripe invoice paid webhook

fix: prepare customer initiated tier change
fix: separate view for subscriptions
This commit is contained in:
Andras Bacsai 2024-02-23 11:21:14 +01:00
parent ce09ef8848
commit b59e47dcf9
11 changed files with 108 additions and 59 deletions

View File

@ -7,6 +7,13 @@
class Actions extends Component
{
public $server_limits = 0;
public function mount()
{
$limits = currentTeam()->limits;
$this->server_limits = data_get($limits, 'serverLimit', 0);
}
public function cancel()
{
try {
@ -69,7 +76,8 @@ public function resume()
return handleError($e, $this);
}
}
public function stripeCustomerPortal() {
public function stripeCustomerPortal()
{
$session = getStripeCustomerPortalSession(currentTeam());
redirect($session->url);
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Livewire\Subscription;
use Livewire\Component;
class Show extends Component
{
public function mount()
{
if (!isCloud()) {
return redirect()->route('dashboard');
}
}
public function render()
{
return view('livewire.subscription.show');
}
}

View File

@ -109,7 +109,7 @@ function isPaddle()
function getStripeCustomerPortalSession(Team $team)
{
Stripe::setApiKey(config('subscription.stripe_api_key'));
$return_url = route('team.index');
$return_url = route('subscription.show');
$stripe_customer_id = data_get($team,'subscription.stripe_customer_id');
if (!$stripe_customer_id) {
return null;
@ -123,7 +123,7 @@ function getStripeCustomerPortalSession(Team $team)
function allowedPathsForUnsubscribedAccounts()
{
return [
'subscription',
'subscription/new',
'login',
'logout',
'waitlist',

View File

@ -130,11 +130,20 @@ class="{{ request()->is('team*') ? 'text-warning icon' : 'icon' }}"
<path d="M5 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path d="M3 13v-1a2 2 0 0 1 2 -2h2" />
</svg>
Teams @if (isCloud())
/ Subscription
@endif
Teams
</a>
</li>
@if (isCloud())
<li title="Subscription" class="hover:bg-coolgray-200">
<a class="hover:bg-transparent hover:no-underline"
href="{{ route('subscription.show') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="{{ request()->is('subscription*') ? 'text-warning icon' : 'icon' }}" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3zm0 2h18M7 15h.01M11 15h2"/>
</svg>
Subscription
</a>
</li>
@endif
@if (isInstanceAdmin())
<li title="Settings" class="hover:bg-coolgray-200">

View File

@ -34,7 +34,7 @@ class="font-bold text-warning">{{ config('constants.limits.trial_period') }}
<div>
</div>
</div>
<div class="p-4 rounded bg-coolgray-400">
{{-- <div class="p-4 rounded bg-coolgray-400">
<h2 id="tier-hobby" class="flex items-start gap-4 text-4xl font-bold tracking-tight">Unlimited Trial
<x-forms.button><a class="font-bold text-white hover:no-underline"
href="https://github.com/coollabsio/coolify">Get Started</a></x-forms.button>
@ -42,8 +42,11 @@ class="font-bold text-warning">{{ config('constants.limits.trial_period') }}
<p class="mt-4 text-sm leading-6">Start self-hosting <span class="text-warning">without limits</span> with
our
OSS version. Same features as the paid version, but you have to manage by yourself.</p>
</div>
</div> --}}
<div class="flow-root mt-12">
<div class="pb-10 text-xl text-center">For the detailed list of features, please visit our landing page: <a
class="font-bold text-white underline" href="https://coolify.io">coolify.io</a></div>
<div
class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap-y-16 sm:mx-auto lg:-mx-8 lg:mt-0 lg:max-w-none lg:grid-cols-3 lg:divide-x lg:divide-y-0 xl:-mx-4">
@ -70,21 +73,18 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap
{{ $basic }}
@endisset
@endif
<p class="mt-10 text-sm leading-6 text-white h-[6.5rem]">Start self-hosting in
the cloud
with a
single
server.
<p class="mt-10 text-sm leading-6 text-white h-[6.5rem]">Begin hosting your own services in the
cloud.
</p>
<ul role="list" class="space-y-3 text-sm leading-6 ">
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
<li class="flex">
<svg class="flex-none w-5 h-6 mr-3 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
2 servers <x-helper helper="Bring Your Own Server." />
Connect <span class="px-1 font-bold text-white">2</span> servers
</li>
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
@ -141,17 +141,18 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap
{{ $pro }}
@endisset
@endif
<p class="h-20 mt-10 text-sm leading-6 text-white">Scale your business or self-hosting environment.
<p class="h-20 mt-10 text-sm leading-6 text-white">Expand your business or set up your own hosting
environment.
</p>
<ul role="list" class="mt-6 space-y-3 text-sm leading-6 ">
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
<li class="flex ">
<svg class="flex-none w-5 h-6 mr-3 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
10 servers <x-helper helper="Bring Your Own Server." />
Connect <span class="px-1 font-bold text-white">10</span> servers
</li>
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
@ -208,17 +209,17 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap
{{ $ultimate }}
@endisset
@endif
<p class="h-20 mt-10 text-sm leading-6 text-white">Deploy complex infrastructures and
manage them easily in one place.</p>
<p class="h-20 mt-10 text-sm leading-6 text-white">Easily manage complex infrastructures in a
single location.</p>
<ul role="list" class="mt-6 space-y-3 text-sm leading-6 ">
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
<li class="flex ">
<svg class="flex-none w-5 h-6 mr-3 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
? servers <x-helper helper="Bring Your Own Server." />
Connect <span class="px-1 font-bold text-white">unlimited</span> servers
</li>
<li class="flex gap-x-3">
@ -254,7 +255,7 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap
</ul>
</div>
</div>
<div class="p-4 mt-10 rounded">
{{-- <div class="p-4 mt-10 rounded">
<div class="flex items-start gap-4 text-xl tracking-tight">Need official support for
your self-hosted instance?
<x-forms.button>
@ -263,9 +264,10 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap
Us</a>
</x-forms.button>
</div>
</div>
</div> --}}
</div>
<div class="pt-8 pb-12 text-4xl font-bold text-center text-white">Included in all plans</div>
{{-- <div class="pt-8 pb-12 text-4xl font-bold text-center text-white">Included in all plans</div>
<div class="grid grid-cols-1 gap-10 md:grid-cols-2 gap-y-28">
<div>
<div class="flex items-center gap-4 mb-4">
@ -433,7 +435,7 @@ class="text-warning">*</span>
</div>
<div class="pt-20 text-xs">
<span class="text-warning">*</span> Some features are work in progress and will be available soon.
</div>
</div> --}}
</div>
@isset($other)
{{ $other }}

View File

@ -3,5 +3,5 @@
You can try out Coolify, without payment information for free. If you like it, you can upgrade to a paid plan at any time.
[Click here](https://app.coolify.io/subscription) to start your trial.
[Click here](https://app.coolify.io/subscription/new) to start your trial.
</x-emails.layout>

View File

@ -1,25 +1,34 @@
<div>
@if (subscriptionProvider() === 'stripe')
<x-forms.button wire:click='stripeCustomerPortal'>Manage My Subscription</x-forms.button>
<div class="pt-4">
<div>Current Plan: <span class="text-warning">{{ data_get(currentTeam(), 'subscription')->type() }}<span>
</div>
<div class="pb-4">Your current Plan is: <strong
class="text-warning">{{ data_get(currentTeam(), 'subscription')->type() }}</strong></div>
@if (currentTeam()->subscription->stripe_cancel_at_period_end)
<div>Subscription is active but on cancel period.</div>
@else
<div>Subscription is active. Last invoice is
{{ currentTeam()->subscription->stripe_invoice_paid ? 'paid' : 'not paid' }}.</div>
@endif
<h3 class="pt-4">Limits</h3>
<div>Server: {{ $server_limits }}</div>
<h3 class="pt-4">Actions</h3>
<div class="pb-4">Cancel, upgrade or downgrade your subscription.</div>
<div class="flex gap-2">
<x-forms.button wire:click='stripeCustomerPortal'>Manage your subscription on <svg
xmlns="http://www.w3.org/2000/svg" class="w-12" viewBox="0 0 512 214">
<path fill="#635BFF"
d="M512 110.08c0-36.409-17.636-65.138-51.342-65.138c-33.85 0-54.33 28.73-54.33 64.854c0 42.808 24.179 64.426 58.88 64.426c16.925 0 29.725-3.84 39.396-9.244v-28.445c-9.67 4.836-20.764 7.823-34.844 7.823c-13.796 0-26.027-4.836-27.591-21.618h69.547c0-1.85.284-9.245.284-12.658Zm-70.258-13.511c0-16.071 9.814-22.756 18.774-22.756c8.675 0 17.92 6.685 17.92 22.756h-36.694Zm-90.31-51.627c-13.939 0-22.899 6.542-27.876 11.094l-1.85-8.818h-31.288v165.83l35.555-7.537l.143-40.249c5.12 3.698 12.657 8.96 25.173 8.96c25.458 0 48.64-20.48 48.64-65.564c-.142-41.245-23.609-63.716-48.498-63.716Zm-8.534 97.991c-8.391 0-13.37-2.986-16.782-6.684l-.143-52.765c3.698-4.124 8.818-6.968 16.925-6.968c12.942 0 21.902 14.506 21.902 33.137c0 19.058-8.818 33.28-21.902 33.28ZM241.493 36.551l35.698-7.68V0l-35.698 7.538V36.55Zm0 10.809h35.698v124.444h-35.698V47.36Zm-38.257 10.524L200.96 47.36h-30.72v124.444h35.556V87.467c8.39-10.951 22.613-8.96 27.022-7.396V47.36c-4.551-1.707-21.191-4.836-29.582 10.524Zm-71.112-41.386l-34.702 7.395l-.142 113.92c0 21.05 15.787 36.551 36.836 36.551c11.662 0 20.195-2.133 24.888-4.693V140.8c-4.55 1.849-27.022 8.391-27.022-12.658V77.653h27.022V47.36h-27.022l.142-30.862ZM35.982 83.484c0-5.546 4.551-7.68 12.09-7.68c10.808 0 24.461 3.272 35.27 9.103V51.484c-11.804-4.693-23.466-6.542-35.27-6.542C19.2 44.942 0 60.018 0 85.192c0 39.252 54.044 32.995 54.044 49.92c0 6.541-5.688 8.675-13.653 8.675c-11.804 0-26.88-4.836-38.827-11.378v33.849c13.227 5.689 26.596 8.106 38.827 8.106c29.582 0 49.92-14.648 49.92-40.106c-.142-42.382-54.329-34.845-54.329-50.774Z" />
</svg></x-forms.button>
@if (currentTeam()->subscription->stripe_cancel_at_period_end)
<a class="hover:no-underline" href="{{ route('subscription.index') }}"><x-forms.button>Subscribe
again</x-forms.button></a>
@endif
<div>To update your subscription (upgrade / downgrade), please <a class="text-white underline"
href="{{ config('coolify.contact') }}" target="_blank">contact us.</a></div>
</div>
</div>
<div class="pt-4">
If you have any problem, please <a class="text-white underline" href="{{ config('coolify.contact') }}"
target="_blank">contact us.</a>
</div>
@endif
@if (subscriptionProvider() === 'lemon')
{{-- @if (subscriptionProvider() === 'lemon')
<div>Status: {{ currentTeam()->subscription->lemon_status }}</div>
<div>Type: {{ currentTeam()->subscription->lemon_variant_name }}</div>
@if (currentTeam()->subscription->lemon_status === 'cancelled')
@ -49,6 +58,5 @@ class="text-white underline" href="{{ config('coolify.contact') }}" target="_bla
Subscription</x-forms.button></a>
</div>
</div>
@endif
@endif --}}
</div>

View File

@ -0,0 +1,16 @@
<div>
<div >
<h1>Subscription</h1>
<div>Here you can see and manage your subscription.</div>
</div>
<div class="pb-8">
@if (data_get(currentTeam(), 'subscription'))
<livewire:subscription.actions />
@else
<div>You are not subscribed to any plan. Please subscribe to a plan to continue.</div>
<x-forms.button class="mt-4"><a class="text-white hover:no-underline"
href="{{ route('subscription.index') }}">Subscribe Now</a>
</x-forms.button>
@endif
</div>
</div>

View File

@ -14,19 +14,6 @@
</div>
</form>
@if (isCloud())
<div class="pb-8">
<h2>Subscription</h2>
@if (data_get(currentTeam(), 'subscription'))
<livewire:subscription.actions />
@else
<x-forms.button class="mt-4"><a class="text-white hover:no-underline"
href="{{ route('subscription.index') }}">Subscribe Now</a>
</x-forms.button>
@endif
</div>
@endif
<div>
<h2>Danger Zone</h2>
<div class="pb-4">Woah. I hope you know what are you doing.</div>
@ -36,7 +23,7 @@
@elseif(auth()->user()->teams()->get()->count() === 1)
<div>You can't delete your last team.</div>
@elseif(currentTeam()->subscription && currentTeam()->subscription?->lemon_status !== 'cancelled')
<div>Please cancel your subscription before delete this team (Manage My Subscription).</div>
<div>Please cancel your subscription <a class="text-white underline" href="{{route('subscription.show')}}">here</a> before delete this team.</div>
@else
@if (currentTeam()->isEmpty())
<div class="pb-4">This will delete your team. Beware! There is no coming back!</div>

View File

@ -72,6 +72,7 @@
use App\Livewire\Server\Proxy\Logs as ProxyLogs;
use App\Livewire\Source\Github\Change as GitHubChange;
use App\Livewire\Subscription\Index as SubscriptionIndex;
use App\Livewire\Subscription\Show as SubscriptionShow;
use App\Livewire\Tags\Index as TagsIndex;
use App\Livewire\Tags\Show as TagsShow;
@ -110,7 +111,8 @@
Route::get('/', Dashboard::class)->name('dashboard');
Route::get('/boarding', BoardingIndex::class)->name('boarding');
Route::get('/subscription', SubscriptionIndex::class)->name('subscription.index');
Route::get('/subscription/new', SubscriptionIndex::class)->name('subscription.index');
Route::get('/subscription', SubscriptionShow::class)->name('subscription.show');
Route::get('/settings', SettingsIndex::class)->name('settings.index');
Route::get('/settings/license', SettingsLicense::class)->name('settings.license');

View File

@ -816,9 +816,7 @@
Sleep::for(5)->seconds();
$subscription = Subscription::where('stripe_customer_id', $customerId)->firstOrFail();
}
$subscription->update([
'stripe_plan_id' => $planId,
'stripe_invoice_paid' => true,
]);
break;