diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index b8a52f6a284f..dd79784878eb 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\\CreditCard') + ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\SOFORT') ->processPaymentView($data); } @@ -130,7 +130,7 @@ class PaymentController extends Controller return $gateway ->driver(auth()->user()->client) - ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\CreditCard') + ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\SOFORT') ->processPaymentResponse($request); } } diff --git a/app/PaymentDrivers/Stripe/CreditCard.php b/app/PaymentDrivers/Stripe/CreditCard.php index 09d63795a3c9..249287cd0cb8 100644 --- a/app/PaymentDrivers/Stripe/CreditCard.php +++ b/app/PaymentDrivers/Stripe/CreditCard.php @@ -172,7 +172,7 @@ class CreditCard } $data = [ - 'payment_method' => $state['charge_id'], // ???? + 'payment_method' => $state['charge_id'], 'payment_type' => $state['payment_type'], 'amount' => $state['server_response']->amount, ]; diff --git a/app/PaymentDrivers/Stripe/SOFORT.php b/app/PaymentDrivers/Stripe/SOFORT.php new file mode 100644 index 000000000000..ebec8a35144b --- /dev/null +++ b/app/PaymentDrivers/Stripe/SOFORT.php @@ -0,0 +1,106 @@ +stripe = $stripe; + } + + public function paymentView(array $data) + { + $data['gateway'] = $this->stripe; + $data['return_url'] = $this->buildReturnUrl($data); + $data['stripe_amount'] = $this->stripe->convertToStripeAmount($data['amount_with_fee'], $this->stripe->client->currency()->precision); + $data['client'] = $this->stripe->client; + // $data['country'] = $this->stripe->client->country->iso_3166_2; + $data['country'] = 'DE'; + + return render('gateways.stripe.sofort.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->processSuccessfulPayment($state); + } + + return $this->processUnsuccessfulPayment($state); + } + + public function processSuccessfulPayment($state) + { + $state['charge_id'] = $state['source']; + + $this->stripe->init(); + + $state['payment_type'] = PaymentType::SOFORT; + + $data = [ + 'payment_method' => $state['charge_id'], + 'payment_type' => $state['payment_type'], + 'amount' => $state['amount'], + ]; + + $payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING); + + /** @todo: https://github.com/invoiceninja/invoiceninja/pull/3789/files#r436175798 */ + 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 processUnsuccessfulPayment($state) + { + return redirect()->route('client.invoices.index')->with('warning', ctrans('texts.status_voided')); + } +} diff --git a/public/js/clients/payments/sofort.js.LICENSE.txt b/public/js/clients/payments/sofort.js.LICENSE.txt new file mode 100644 index 000000000000..e3350dd9a69d --- /dev/null +++ b/public/js/clients/payments/sofort.js.LICENSE.txt @@ -0,0 +1,9 @@ +/** + * 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 + */ diff --git a/resources/js/clients/payments/sofort.js b/resources/js/clients/payments/sofort.js new file mode 100644 index 000000000000..66a5b12e5cee --- /dev/null +++ b/resources/js/clients/payments/sofort.js @@ -0,0 +1,57 @@ +/** + * 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 ProcessSOFORT { + constructor(key) { + this.key = key; + this.errors = document.getElementById('errors'); + } + + setupStripe = () => { + this.stripe = Stripe(this.key); + + return this; + }; + + handle = () => { + let data = { + type: 'sofort', + amount: document.querySelector('meta[name="amount"]').content, + currency: 'eur', + redirect: { + return_url: document.querySelector('meta[name="return-url"]') + .content, + }, + sofort: { + country: document.querySelector('meta[name="country"').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 ProcessSOFORT(publishableKey).setupStripe().handle(); diff --git a/resources/views/portal/ninja2020/gateways/stripe/sofort/pay.blade.php b/resources/views/portal/ninja2020/gateways/stripe/sofort/pay.blade.php new file mode 100644 index 000000000000..0bb9511f53b0 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/stripe/sofort/pay.blade.php @@ -0,0 +1,57 @@ +@extends('portal.ninja2020.layout.app') +@section('meta_title', ctrans('texts.sofort')) + +@push('head') + + + + +@endpush + +@section('body') +
+ {{ ctrans('texts.complete_your_payment') }} +
+