diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 0f9c4fc32ab6..497f96d0c487 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -120,7 +120,7 @@ class PaymentController extends Controller return $gateway ->driver(auth()->user()->client) - ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\ACH') + ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\Alipay') ->processPaymentView($data); } @@ -130,7 +130,7 @@ class PaymentController extends Controller return $gateway ->driver(auth()->user()->client) - ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\ACH') + ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\Alipay') ->processPaymentResponse($request); } } diff --git a/app/PaymentDrivers/Stripe/Alipay.php b/app/PaymentDrivers/Stripe/Alipay.php new file mode 100644 index 000000000000..452221ed483a --- /dev/null +++ b/app/PaymentDrivers/Stripe/Alipay.php @@ -0,0 +1,113 @@ +stripe = $stripe; + } + + public function paymentView(array $data) + { + $data['gateway'] = $this->stripe; + $data['return_url'] = $this->buildReturnUrl($data); + $data['currency'] = $this->stripe->client->getCurrencyCode(); + $data['stripe_amount'] = $this->stripe->convertToStripeAmount($data['amount_with_fee'], $this->stripe->client->currency()->precision); + + return render('gateways.stripe.alipay.pay', $data); + } + + private function buildReturnUrl($data): string + { + return route('client.payments.response', [ + 'company_gateway_id' => $this->stripe->company_gateway->id, + 'gateway_type_id' => GatewayType::SOFORT, + 'hashed_ids' => implode(",", $data['hashed_ids']), + 'amount' => $data['amount'], + 'fee' => $data['fee'], + ]); + } + + public function paymentResponse($request) + { + $state = array_merge($request->all(), []); + $amount = $state['amount'] + $state['fee']; + $state['amount'] = $this->stripe->convertToStripeAmount($amount, $this->stripe->client->currency()->precision); + + if ($request->redirect_status == 'succeeded') { + return $this->processSuccesfulRedirect($state); + } + + return $this->processUnsuccesfulRedirect($state); + } + + public function processSuccesfulRedirect($state) + { + $state['charge_id'] = $state['source']; + + $this->stripe->init(); + + $state['payment_type'] = PaymentType::ALIPAY; + + $data = [ + 'payment_method' => $state['charge_id'], + 'payment_type' => $state['payment_type'], + 'amount' => $state['amount'], + ]; + + $payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING); + + if (isset($state['hashed_ids'])) { + $this->stripe->attachInvoices($payment, $state['hashed_ids']); + } + + event(new PaymentWasCreated($payment, $payment->company)); + + $logger_message = [ + 'server_response' => $state, + 'data' => $data + ]; + + SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->stripe->client); + + return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]); + } + + public function processUnsuccesfulRedirect($state) + { + PaymentFailureMailer::dispatch($this->stripe->client, $state['charge']->failure_message, $this->stripe->client->company, $state['amount']); + + $message = [ + 'server_response' => $state['charge'], + 'data' => $state, + ]; + + SystemLogger::dispatch($message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_STRIPE, $this->stripe->client); + + throw new \Exception('Failed to process the payment.', 1); + } +} diff --git a/resources/js/clients/payments/alipay.js b/resources/js/clients/payments/alipay.js new file mode 100644 index 000000000000..8449a4924254 --- /dev/null +++ b/resources/js/clients/payments/alipay.js @@ -0,0 +1,54 @@ +/** + * Invoice Ninja (https://invoiceninja.com) + * + * @link https://github.com/invoiceninja/invoiceninja source repository + * + * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * + * @license https://opensource.org/licenses/AAL + */ + +class ProcessAlipay { + constructor(key) { + this.key = key; + this.errors = document.getElementById('errors'); + } + + setupStripe = () => { + this.stripe = Stripe(this.key); + + return this; + }; + + handle = () => { + let data = { + type: 'alipay', + amount: document.querySelector('meta[name="amount"]').content, + currency: document.querySelector('meta[name="currency"]').content, + redirect: { + return_url: document.querySelector('meta[name="return-url"]') + .content, + }, + }; + + document.getElementById('pay-now').addEventListener('submit', (e) => { + e.preventDefault(); + + this.stripe.createSource(data).then(function(result) { + if (result.hasOwnProperty('source')) { + return (window.location = result.source.redirect.url); + } + + this.errors.textContent = ''; + this.errors.textContent = result.error.message; + this.errors.hidden = false; + }); + }); + }; +} + +const publishableKey = document.querySelector( + 'meta[name="stripe-publishable-key"]' +).content; + +new ProcessAlipay(publishableKey).setupStripe().handle(); diff --git a/resources/views/portal/ninja2020/gateways/stripe/alipay/pay.blade.php b/resources/views/portal/ninja2020/gateways/stripe/alipay/pay.blade.php new file mode 100644 index 000000000000..fa4a81fae099 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/stripe/alipay/pay.blade.php @@ -0,0 +1,57 @@ +@extends('portal.ninja2020.layout.app') +@section('meta_title', ctrans('texts.alipay')) + +@push('head') + + + + +@endpush + +@section('body') +
+ {{ ctrans('texts.complete_your_payment') }} +
+