From ee15ea9434185931962e8b807622421c080bf29b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 18 Mar 2021 11:58:10 +1100 Subject: [PATCH] v5.1.27 --- .../Billing/WebhookConfiguration.php | 47 ++++++ .../BillingSubscriptionPurchaseController.php | 30 ++++ app/Http/Livewire/BillingPortalPurchase.php | 158 ++++++++++++++++++ .../views/billing-portal/purchase.blade.php | 17 ++ .../billing-portal-purchase.blade.php | 127 ++++++++++++++ 5 files changed, 379 insertions(+) create mode 100644 app/DataMapper/Billing/WebhookConfiguration.php create mode 100644 app/Http/Controllers/ClientPortal/BillingSubscriptionPurchaseController.php create mode 100644 app/Http/Livewire/BillingPortalPurchase.php create mode 100644 resources/views/billing-portal/purchase.blade.php create mode 100644 resources/views/portal/ninja2020/components/livewire/billing-portal-purchase.blade.php diff --git a/app/DataMapper/Billing/WebhookConfiguration.php b/app/DataMapper/Billing/WebhookConfiguration.php new file mode 100644 index 0000000000..fe562650b9 --- /dev/null +++ b/app/DataMapper/Billing/WebhookConfiguration.php @@ -0,0 +1,47 @@ + 'string', + 'post_purchase_url' => 'string', + 'post_purchase_headers' => 'array', + 'post_purchase_body' => 'object', + ]; +} diff --git a/app/Http/Controllers/ClientPortal/BillingSubscriptionPurchaseController.php b/app/Http/Controllers/ClientPortal/BillingSubscriptionPurchaseController.php new file mode 100644 index 0000000000..a6036cd835 --- /dev/null +++ b/app/Http/Controllers/ClientPortal/BillingSubscriptionPurchaseController.php @@ -0,0 +1,30 @@ + $billing_subscription, + 'hash' => Str::uuid()->toString(), + ]); + } +} diff --git a/app/Http/Livewire/BillingPortalPurchase.php b/app/Http/Livewire/BillingPortalPurchase.php new file mode 100644 index 0000000000..8cd0a3bc92 --- /dev/null +++ b/app/Http/Livewire/BillingPortalPurchase.php @@ -0,0 +1,158 @@ + ['required', 'email'], + ]; + + public $company_gateway_id; + + public $payment_method_id; + + public $steps = [ + 'passed_email' => false, + 'existing_user' => false, + 'fetched_payment_methods' => false, + 'fetched_client' => false, + ]; + + public $methods = []; + + public $invoice; + + public $coupon; + + public function authenticate() + { + $this->validate(); + + $contact = ClientContact::where('email', $this->email)->first(); + + if ($contact && $this->steps['existing_user'] === false) { + return $this->steps['existing_user'] = true; + } + + if ($contact && $this->steps['existing_user']) { + $attempt = Auth::guard('contact')->attempt(['email' => $this->email, 'password' => $this->password]); + + return $attempt + ? $this->getPaymentMethods($contact) + : session()->flash('message', 'These credentials do not match our records.'); + } + + $this->steps['existing_user'] = false; + + $contact = $this->createBlankClient(); + + if ($contact && $contact instanceof ClientContact) { + $this->getPaymentMethods($contact); + } + } + + protected function createBlankClient() + { + $company = $this->billing_subscription->company; + $user = $this->billing_subscription->user; + + $client_repo = new ClientRepository(new ClientContactRepository()); + + $client = $client_repo->save([ + 'name' => 'Client Name', + 'contacts' => [ + ['email' => $this->email], + ] + ], ClientFactory::create($company->id, $user->id)); + + return $client->contacts->first(); + } + + protected function getPaymentMethods(ClientContact $contact): self + { + $this->steps['fetched_payment_methods'] = true; + + $this->methods = $contact->client->service()->getPaymentMethods(1000); + + $this->heading_text = 'Pick a payment method'; + + Auth::guard('contact')->login($contact); + + $this->contact = $contact; + + return $this; + } + + public function handleMethodSelectingEvent($company_gateway_id, $gateway_type_id) + { + $this->company_gateway_id = $company_gateway_id; + $this->payment_method_id = $gateway_type_id; + + $this->handleBeforePaymentEvents(); + } + + public function handleBeforePaymentEvents() + { + $data = [ + 'client_id' => $this->contact->client->id, + 'date' => now()->format('Y-m-d'), + 'invitations' => [[ + 'key' => '', + 'client_contact_id' => $this->contact->hashed_id, + ]], + 'user_input_promo_code' => $this->coupon, + 'quantity' => 1, // Option to increase quantity + ]; + + $this->invoice = $this->billing_subscription + ->service() + ->createInvoice($data) + ->service() + ->markSent() + ->save(); + + Cache::put($this->hash, [ + 'email' => $this->email ?? $this->contact->email, + 'client_id' => $this->contact->client->id, + 'invoice_id' => $this->invoice->id], + now()->addMinutes(60) + ); + + $this->emit('beforePaymentEventsCompleted'); + } + + public function applyCouponCode() + { + dd('Applying coupon code: ' . $this->coupon); + } + + public function render() + { + if ($this->contact instanceof ClientContact) { + $this->getPaymentMethods($this->contact); + } + + return render('components.livewire.billing-portal-purchase'); + } +} diff --git a/resources/views/billing-portal/purchase.blade.php b/resources/views/billing-portal/purchase.blade.php new file mode 100644 index 0000000000..0bb3cba62b --- /dev/null +++ b/resources/views/billing-portal/purchase.blade.php @@ -0,0 +1,17 @@ +@extends('portal.ninja2020.layout.clean') +@section('meta_title', $billing_subscription->product->product_key) + +@section('body') + @livewire('billing-portal-purchase', ['billing_subscription' => $billing_subscription, 'contact' => auth('contact')->user(), 'hash' => $hash]) +@stop + +@push('footer') + +@endpush diff --git a/resources/views/portal/ninja2020/components/livewire/billing-portal-purchase.blade.php b/resources/views/portal/ninja2020/components/livewire/billing-portal-purchase.blade.php new file mode 100644 index 0000000000..8a7afa8ce4 --- /dev/null +++ b/resources/views/portal/ninja2020/components/livewire/billing-portal-purchase.blade.php @@ -0,0 +1,127 @@ +
+
+
+ {{ $billing_subscription->company->present()->name }} + +

+ {{ $billing_subscription->product->product_key }} +

+ +

{{ $billing_subscription->product->notes }}

+ + {{ ctrans('texts.total') }}: + +

{{ App\Utils\Number::formatMoney($billing_subscription->product->price, $billing_subscription->company) }}

+ + @if(auth('contact')->user()) + + + + + + + {{ ctrans('texts.client_portal') }} + + @endif +
+
+ +
+
+
+

{{ $heading_text }}

+ @if (session()->has('message')) + @component('portal.ninja2020.components.message') + {{ session('message') }} + @endcomponent + @endif + + @if($this->steps['fetched_payment_methods']) +
+
+ @csrf + + @if($invoice instanceof \App\Models\Invoice) + + + + @endif + + + + +
+ + @foreach($this->methods as $method) + + @endforeach +
+ @else +
+ @csrf + + + + @if($steps['existing_user']) + + @endif + + +
+ @endif + +
+
+
+
+ +
+ Have a coupon code? +
+
+ +
+ @csrf + +
+ + + +
+
+
+
+
+