File: /home/xedaptot/ai.naniguide.com/app/Http/Controllers/CheckoutController.php
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Library\Facades\Billing;
use App\Model\Invoice;
use App\Model\PaymentGateway;
use App\Model\PaymentMethod;
class CheckoutController extends Controller
{
protected function findOwnedInvoice(Request $request, string $invoiceUid): ?Invoice
{
$customer = $request->user()->customer;
return $customer->invoices()->where('invoices.uid', $invoiceUid)->first();
}
protected function findOwnedPaymentMethod(Request $request, string $paymentMethodUid): ?PaymentMethod
{
$customer = $request->user()->customer;
return $customer->paymentMethods()->where('payment_methods.uid', $paymentMethodUid)->first();
}
public function cart(Request $request, $invoice_uid)
{
// init
$customer = $request->user()->customer;
$invoice = $this->findOwnedInvoice($request, $invoice_uid);
if (!$invoice) {
return view('somethingWentWrong', ['message' => 'Can not find the invoice #'.$invoice_uid]);
}
return view('checkout.cart', [
'invoice' => $invoice,
]);
}
public function billingAddress(Request $request, $invoice_uid)
{
// init
$customer = $request->user()->customer;
$invoice = $this->findOwnedInvoice($request, $invoice_uid);
if (!$invoice) {
return view('somethingWentWrong', ['message' => 'Can not find the invoice #'.$invoice_uid]);
}
// get default billing address from customer
$billingAddress = $customer->getDefaultBillingAddress();
if ($billingAddress) {
$invoice->fillBillingAddressNotReplace($billingAddress);
}
// Save posted data
if ($request->isMethod('post')) {
$validator = $invoice->updateBillingInformation($request->all());
// redirect if fails
if ($validator->fails()) {
return response()->view('checkout.billingAddress', [
'invoice' => $invoice,
'errors' => $validator->errors(),
], 400);
}
// Khúc này customer cập nhật thông tin billing information cho lần tiếp theo
$customer->updateBillingInformationFromInvoice($invoice);
$request->session()->flash('alert-success', trans('messages.billing_address.updated'));
// return to subscription
return redirect()->action('CheckoutController@payment', [
'invoice_uid' => $invoice->uid,
]);
}
return view('checkout.billingAddress', [
'invoice' => $invoice,
]);
}
public function payment(Request $request, $invoice_uid)
{
// init
$customer = $request->user()->customer;
$invoice = $this->findOwnedInvoice($request, $invoice_uid);
if (!$invoice) {
return view('somethingWentWrong', ['message' => 'Can not find the invoice #'.$invoice_uid]);
}
// not have billing address
if (!$invoice->hasBillingInformation()) {
return view('somethingWentWrong', ['message' => 'Can not find the invoice #'.$invoice_uid]);
}
return view('checkout.payment', [
'invoice' => $invoice,
]);
}
public function orderBox(Request $request, $invoice_uid)
{
// init
$customer = $request->user()->customer;
$invoice = $this->findOwnedInvoice($request, $invoice_uid);
if (!$invoice) {
return view('somethingWentWrong', ['message' => 'There are no new sender ID invoice!']);
}
// gateway fee
if ($request->payment_gateway_id) {
$paymentGateway = \App\Model\PaymentGateway::global()->where('uid', $request->payment_gateway_id)->first();
}
return view('checkout.orderBox', [
'invoice' => $invoice,
]);
}
public function checkout(Request $request, $invoice_uid)
{
// init
$invoice = $this->findOwnedInvoice($request, $invoice_uid);
if (!$invoice) {
return view('somethingWentWrong', ['message' => 'There are no new invoice!']);
}
// not have billing address
if (!$invoice->hasBillingInformation()) {
return view('somethingWentWrong', ['message' => 'Invoice do not has billing address!']);
}
// always update invoice price from plan
app(\App\Library\OrderFulfillment\FulfillmentService::class)->refreshPrice($invoice->order);
// set return url
switch ($invoice->order->orderItems->first()->type) {
case \App\Library\OrderFulfillment\OrderItemTypes::SUBSCRIPTION_NEW:
case \App\Library\OrderFulfillment\OrderItemTypes::SUBSCRIPTION_RENEW:
case \App\Library\OrderFulfillment\OrderItemTypes::SUBSCRIPTION_CHANGE_PLAN:
Billing::setReturnUrl(route('refactor.account.subscription'));
break;
case \App\Library\OrderFulfillment\OrderItemTypes::CREDIT_VERIFICATION_TOPUP:
Billing::setReturnUrl(action('EmailVerificationPlanController@index'));
break;
case \App\Library\OrderFulfillment\OrderItemTypes::CREDIT_SENDING_TOPUP:
Billing::setReturnUrl(action('SendingCreditPlanController@index'));
break;
default:
throw new \Exception("Invoice type #{$invoice->type} not found!");
}
// free plan. No charge
if ($invoice->total() == 0) {
app(\App\Library\OrderFulfillment\FulfillmentService::class)->completeInvoice($invoice);
return redirect()->away(Billing::getReturnUrl());
}
// if auto charge
if ($request->payment_method_id) {
// payment method
$paymentMethod = $this->findOwnedPaymentMethod($request, $request->payment_method_id);
if (!$paymentMethod) {
return view('somethingWentWrong', ['message' => 'Can not find the payment method #'.$request->payment_method_id]);
}
// auto charge
app(\App\Services\Subscription\SubscriptionManagementService::class)
->autoChargeInvoice($invoice, $paymentMethod);
// redirect to invoice page
return redirect()->away(Billing::getReturnUrl());
} else {
// get payment gateway
$paymentGateway = PaymentGateway::global()->where('uid', $request->payment_gateway_id)->first();
// redirect to service checkout
return redirect()->away(Billing::buildCheckoutUrl($paymentGateway, $invoice));
}
}
public function cancel(Request $request, $invoice_uid)
{
// init
$customer = $request->user()->customer;
$invoice = $this->findOwnedInvoice($request, $invoice_uid);
if (!$invoice) {
return view('somethingWentWrong', ['message' => "Can not find the invoice #{$invoice_uid}"]);
}
// cancel invoice
app(\App\Library\OrderFulfillment\FulfillmentService::class)->cancelInvoice($invoice);
return redirect()->back();
}
}