diff --git a/app/DataMapper/Billing/WebhookConfiguration.php b/app/DataMapper/Billing/WebhookConfiguration.php new file mode 100644 index 000000000000..fe562650b938 --- /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 000000000000..a6036cd83566 --- /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 000000000000..8cd0a3bc9221 --- /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 000000000000..0bb3cba62bb5 --- /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 000000000000..8a7afa8ce4e5 --- /dev/null +++ b/resources/views/portal/ninja2020/components/livewire/billing-portal-purchase.blade.php @@ -0,0 +1,127 @@ +
{{ $billing_subscription->product->notes }}
+ + {{ ctrans('texts.total') }}: + +