From 779791ac862536cafd9594c037292ef6aa07029b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:27:56 +0200 Subject: [PATCH 01/16] Scaffold `DirectDebit` --- app/PaymentDrivers/GoCardless/DirectDebit.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 app/PaymentDrivers/GoCardless/DirectDebit.php diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php new file mode 100644 index 000000000000..3d1987798f74 --- /dev/null +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -0,0 +1,28 @@ + Date: Sat, 16 Oct 2021 15:29:06 +0200 Subject: [PATCH 02/16] Define DIRECT_DEBIT constant --- app/Models/GatewayType.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/GatewayType.php b/app/Models/GatewayType.php index 31b7083326b6..7fa88df5e14a 100644 --- a/app/Models/GatewayType.php +++ b/app/Models/GatewayType.php @@ -32,6 +32,7 @@ class GatewayType extends StaticModel const GIROPAY = 15; const PRZELEWY24 = 16; const EPS = 17; + const DIRECT_DEBIT = 18; public function gateway() { From e06aefdd223c3d44e7c514869f650f6111d1c549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:31:00 +0200 Subject: [PATCH 03/16] Add `DIRECT_DEBIT` to `Gateway` --- app/Models/Gateway.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index f1c55fbae701..3aaaf4a33f3a 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -155,7 +155,8 @@ class Gateway extends StaticModel break; case 52: return [ - GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']] // GoCardless + GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']], + GatewayType::DIRECT_DEBIT => ['refund' => false, 'token_billing' => true, 'webhooks' => [' ']] // GoCardless ]; break; case 58: From 32f81ab25356c6918eced8c7f5be80cb8ebb1a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:35:07 +0200 Subject: [PATCH 04/16] Add DirectDebit to GoCardlessPaymentDriver --- app/PaymentDrivers/GoCardlessPaymentDriver.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/PaymentDrivers/GoCardlessPaymentDriver.php b/app/PaymentDrivers/GoCardlessPaymentDriver.php index 770a272c7d37..646c69619e21 100644 --- a/app/PaymentDrivers/GoCardlessPaymentDriver.php +++ b/app/PaymentDrivers/GoCardlessPaymentDriver.php @@ -38,6 +38,7 @@ class GoCardlessPaymentDriver extends BaseDriver public static $methods = [ GatewayType::BANK_TRANSFER => \App\PaymentDrivers\GoCardless\ACH::class, + GatewayType::DIRECT_DEBIT => \App\PaymentDrivers\GoCardless\DirectDebit::class, ]; const SYSTEM_LOG_TYPE = SystemLog::TYPE_GOCARDLESS; @@ -63,6 +64,14 @@ class GoCardlessPaymentDriver extends BaseDriver $types[] = GatewayType::BANK_TRANSFER; } + if ( + $this->client + && isset($this->client->country) + && in_array($this->client->country->iso_3166_3, ['GBR']) + ) { + $types[] = GatewayType::DIRECT_DEBIT; + } + return $types; } From b368ff23df21d07a0f8a4a1dd4011a0b45ce54f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:36:16 +0200 Subject: [PATCH 05/16] Initialize GoCardlessPro\Client --- app/PaymentDrivers/GoCardless/DirectDebit.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php index 3d1987798f74..2ccca69315d0 100644 --- a/app/PaymentDrivers/GoCardless/DirectDebit.php +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -15,9 +15,19 @@ namespace App\PaymentDrivers\GoCardless; use App\Http\Requests\Request; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\PaymentDrivers\Common\MethodInterface; +use App\PaymentDrivers\GoCardlessPaymentDriver; class DirectDebit implements MethodInterface { + protected GoCardlessPaymentDriver $go_cardless; + + public function __construct(GoCardlessPaymentDriver $go_cardless) + { + $this->go_cardless = $go_cardless; + + $this->go_cardless->init(); + } + public function authorizeView(array $data) { } public function authorizeResponse(Request $request) { } From 05f4a33459bbd3ded7405c6e327ae0af51842efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:48:26 +0200 Subject: [PATCH 06/16] Authorization --- app/PaymentDrivers/GoCardless/DirectDebit.php | 99 ++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php index 2ccca69315d0..4f2c490224ca 100644 --- a/app/PaymentDrivers/GoCardless/DirectDebit.php +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -12,10 +12,16 @@ namespace App\PaymentDrivers\GoCardless; +use App\Exceptions\PaymentFailed; use App\Http\Requests\Request; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; +use App\Jobs\Util\SystemLogger; +use App\Models\GatewayType; +use App\Models\SystemLog; use App\PaymentDrivers\Common\MethodInterface; use App\PaymentDrivers\GoCardlessPaymentDriver; +use Illuminate\Http\RedirectResponse; +use Illuminate\Routing\Redirector; class DirectDebit implements MethodInterface { @@ -28,9 +34,98 @@ class DirectDebit implements MethodInterface $this->go_cardless->init(); } - public function authorizeView(array $data) { } + /** + * Handle authorization for Direct Debit. + * + * @param array $data + * @return Redirector|RedirectResponse|void + */ + public function authorizeView(array $data) + { + $session_token = \Illuminate\Support\Str::uuid()->toString(); - public function authorizeResponse(Request $request) { } + try { + $redirect = $this->go_cardless->gateway->redirectFlows()->create([ + 'params' => [ + 'session_token' => $session_token, + 'success_redirect_url' => route('client.payment_methods.confirm', [ + 'method' => GatewayType::DIRECT_DEBIT, + 'session_token' => $session_token, + ]), + 'prefilled_customer' => [ + 'given_name' => auth('contact')->user()->first_name, + 'family_name' => auth('contact')->user()->last_name, + 'email' => auth('contact')->user()->email, + 'address_line1' => auth('contact')->user()->client->address1, + 'city' => auth('contact')->user()->client->city, + 'postal_code' => auth('contact')->user()->client->postal_code, + ], + ], + ]); + + return redirect( + $redirect->redirect_url + ); + } catch (\Exception $exception) { + return $this->processUnsuccessfulAuthorization($exception); + } + } + + /** + * Handle unsuccessful authorization. + * + * @param Exception $exception + * @throws PaymentFailed + * @return void + */ + public function processUnsuccessfulAuthorization(\Exception $exception): void + { + SystemLogger::dispatch( + $exception->getMessage(), + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + SystemLog::TYPE_GOCARDLESS, + $this->go_cardless->client, + $this->go_cardless->client->company, + ); + + throw new PaymentFailed($exception->getMessage(), $exception->getCode()); + } + + /** + * Handle authorization response for Direct Debit. + * + * @param Request $request + * @return RedirectResponse|void + */ + public function authorizeResponse(Request $request) + { + try { + $redirect_flow = $this->go_cardless->gateway->redirectFlows()->complete( + $request->redirect_flow_id, + ['params' => [ + 'session_token' => $request->session_token + ]], + ); + + $payment_meta = new \stdClass; + $payment_meta->brand = ctrans('texts.payment_type_direct_debit'); + $payment_meta->type = GatewayType::DIRECT_DEBIT; + $payment_meta->state = 'authorized'; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $redirect_flow->links->mandate, + 'payment_method_id' => GatewayType::DIRECT_DEBIT, + ]; + + $payment_method = $this->go_cardless->storeGatewayToken($data, ['gateway_customer_reference' => $redirect_flow->links->customer]); + + return redirect()->route('client.payment_methods.show', $payment_method->hashed_id); + } catch (\Exception $exception) { + return $this->processUnsuccessfulAuthorization($exception); + } + } public function paymentView(array $data) { } From 9480215f47471614d4f6db42a01417816385d09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:53:05 +0200 Subject: [PATCH 07/16] Add DIRECT_DEBIT for PaymentType --- app/Models/PaymentType.php | 1 + ...5200_add_direct_debit_to_payment_types.php | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 database/migrations/2021_10_16_135200_add_direct_debit_to_payment_types.php diff --git a/app/Models/PaymentType.php b/app/Models/PaymentType.php index f0f6d8c91b3c..af84feeb9796 100644 --- a/app/Models/PaymentType.php +++ b/app/Models/PaymentType.php @@ -50,6 +50,7 @@ class PaymentType extends StaticModel const GIROPAY = 39; const PRZELEWY24 = 40; const EPS = 41; + const DIRECT_DEBIT = 42; public static function parseCardType($cardName) { diff --git a/database/migrations/2021_10_16_135200_add_direct_debit_to_payment_types.php b/database/migrations/2021_10_16_135200_add_direct_debit_to_payment_types.php new file mode 100644 index 000000000000..8783488476cf --- /dev/null +++ b/database/migrations/2021_10_16_135200_add_direct_debit_to_payment_types.php @@ -0,0 +1,28 @@ +id = 42; + $type->name = 'Direct Debit'; + $type->gateway_type_id = GatewayType::DIRECT_DEBIT; + + $type->save(); + }); + } +} From 6bd39916bc7dabed36d2a4db17cc1ae9b04e9d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:55:33 +0200 Subject: [PATCH 08/16] Payments --- app/PaymentDrivers/GoCardless/DirectDebit.php | 120 +++++++++++++++++- .../gocardless/direct_debit/pay.blade.php | 56 ++++++++ 2 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 resources/views/portal/ninja2020/gateways/gocardless/direct_debit/pay.blade.php diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php index 4f2c490224ca..78a75586f6a1 100644 --- a/app/PaymentDrivers/GoCardless/DirectDebit.php +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -15,16 +15,25 @@ namespace App\PaymentDrivers\GoCardless; use App\Exceptions\PaymentFailed; use App\Http\Requests\Request; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; +use App\Jobs\Mail\PaymentFailureMailer; use App\Jobs\Util\SystemLogger; +use App\Models\ClientGatewayToken; use App\Models\GatewayType; +use App\Models\Payment; +use App\Models\PaymentType; use App\Models\SystemLog; use App\PaymentDrivers\Common\MethodInterface; use App\PaymentDrivers\GoCardlessPaymentDriver; +use App\Utils\Traits\MakesHash; +use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Http\RedirectResponse; use Illuminate\Routing\Redirector; +use Illuminate\View\View; class DirectDebit implements MethodInterface { + use MakesHash; + protected GoCardlessPaymentDriver $go_cardless; public function __construct(GoCardlessPaymentDriver $go_cardless) @@ -127,7 +136,114 @@ class DirectDebit implements MethodInterface } } - public function paymentView(array $data) { } + /** + * Payment view for Direct Debit. + * + * @param array $data + * @return View + */ + public function paymentView(array $data): View + { + $data['gateway'] = $this->go_cardless; + $data['amount'] = $this->go_cardless->convertToGoCardlessAmount($data['total']['amount_with_fee'], $this->go_cardless->client->currency()->precision); + $data['currency'] = $this->go_cardless->client->getCurrencyCode(); - public function paymentResponse(PaymentResponseRequest $request) { } + return render('gateways.gocardless.ach.pay', $data); + } + + public function paymentResponse(PaymentResponseRequest $request) + { + $token = ClientGatewayToken::find( + $this->decodePrimaryKey($request->source) + )->firstOrFail(); + + try { + $payment = $this->go_cardless->gateway->payments()->create([ + 'params' => [ + 'amount' => $request->amount, + 'currency' => $request->currency, + 'metadata' => [ + 'payment_hash' => $this->go_cardless->payment_hash->hash, + ], + 'links' => [ + 'mandate' => $token->token, + ], + ], + ]); + + + if ($payment->status === 'pending_submission') { + return $this->processPendingPayment($payment, ['token' => $token->hashed_id]); + } + + return $this->processUnsuccessfulPayment($payment); + } catch (\Exception $exception) { + throw new PaymentFailed($exception->getMessage(), $exception->getCode()); + } + } + + /** + * Handle pending payments for Direct Debit. + * + * @param ResourcesPayment $payment + * @param array $data + * @return RedirectResponse + */ + public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = []) + { + $data = [ + 'payment_method' => $data['token'], + 'payment_type' => PaymentType::DIRECT_DEBIT, + 'amount' => $this->go_cardless->payment_hash->data->amount_with_fee, + 'transaction_reference' => $payment->id, + 'gateway_type_id' => GatewayType::DIRECT_DEBIT, + ]; + + $payment = $this->go_cardless->createPayment($data, Payment::STATUS_PENDING); + + SystemLogger::dispatch( + ['response' => $payment, 'data' => $data], + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_SUCCESS, + SystemLog::TYPE_GOCARDLESS, + $this->go_cardless->client, + $this->go_cardless->client->company, + ); + + return redirect()->route('client.payments.show', ['payment' => $this->go_cardless->encodePrimaryKey($payment->id)]); + } + + /** + * Process unsuccessful payments for Direct Debit. + * + * @param ResourcesPayment $payment + * @return never + */ + public function processUnsuccessfulPayment(\GoCardlessPro\Resources\Payment $payment) + { + PaymentFailureMailer::dispatch($this->go_cardless->client, $payment->status, $this->go_cardless->client->company, $this->go_cardless->payment_hash->data->amount_with_fee); + + PaymentFailureMailer::dispatch( + $this->go_cardless->client, + $payment, + $this->go_cardless->client->company, + $payment->amount + ); + + $message = [ + 'server_response' => $payment, + 'data' => $this->go_cardless->payment_hash->data, + ]; + + SystemLogger::dispatch( + $message, + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + SystemLog::TYPE_GOCARDLESS, + $this->go_cardless->client, + $this->go_cardless->client->company, + ); + + throw new PaymentFailed('Failed to process the payment.', 500); + } } \ No newline at end of file diff --git a/resources/views/portal/ninja2020/gateways/gocardless/direct_debit/pay.blade.php b/resources/views/portal/ninja2020/gateways/gocardless/direct_debit/pay.blade.php new file mode 100644 index 000000000000..cb0620ad1cd3 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/gocardless/direct_debit/pay.blade.php @@ -0,0 +1,56 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Direct Debit', 'card_title' => 'Direct Debit']) + +@section('gateway_content') + @if (count($tokens) > 0) + + + @include('portal.ninja2020.gateways.includes.payment_details') + +
+ @csrf + + + + + + +
+ + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) + @if (count($tokens) > 0) + @foreach ($tokens as $token) + + @endforeach + @endisset + @endcomponent + + @else + @component('portal.ninja2020.components.general.card-element-single', ['title' => 'Direct Debit', 'show_title' => false]) + {{ ctrans('texts.bank_account_not_linked') }} + + {{ ctrans('texts.add_payment_method') }} + @endcomponent + @endif + + @include('portal.ninja2020.gateways.includes.pay_now') +@endsection + +@push('footer') + +@endpush From a562f7e711ae6ad301a5c43a2e83e79bb1f7ce10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Sat, 16 Oct 2021 15:58:29 +0200 Subject: [PATCH 09/16] Add DirectDebit to GatewayType --- app/Models/GatewayType.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Models/GatewayType.php b/app/Models/GatewayType.php index 7fa88df5e14a..61e15855a739 100644 --- a/app/Models/GatewayType.php +++ b/app/Models/GatewayType.php @@ -79,6 +79,8 @@ class GatewayType extends StaticModel return ctrans('texts.giropay'); case self::EPS: return ctrans('texts.eps'); + case self::DIRECT_DEBIT: + return ctrans('texts.payment_type_direct_debit'); default: return 'Undefined.'; break; From 98d2a4a4074bdc5d9cf1759c4d9127af644c9cd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 19 Oct 2021 15:37:23 +0200 Subject: [PATCH 10/16] Support for DIRECT_DEBIT on authorization pages --- .../ClientPortal/PaymentMethodController.php | 6 +++--- app/Models/Client.php | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/ClientPortal/PaymentMethodController.php b/app/Http/Controllers/ClientPortal/PaymentMethodController.php index 2ab293af2397..809dedac63a1 100644 --- a/app/Http/Controllers/ClientPortal/PaymentMethodController.php +++ b/app/Http/Controllers/ClientPortal/PaymentMethodController.php @@ -149,11 +149,11 @@ class PaymentMethodController extends Controller private function getClientGateway() { if (request()->query('method') == GatewayType::CREDIT_CARD) { - return $gateway = auth()->user()->client->getCreditCardGateway(); + return auth()->user()->client->getCreditCardGateway(); } - if (request()->query('method') == GatewayType::BANK_TRANSFER) { - return $gateway = auth()->user()->client->getBankTransferGateway(); + if (in_array(request()->query('method'), [GatewayType::BANK_TRANSFER, GatewayType::DIRECT_DEBIT])) { + return auth()->user()->client->getBankTransferGateway(); } abort(404, 'Gateway not found.'); diff --git a/app/Models/Client.php b/app/Models/Client.php index aaf56737c465..8aade69c1943 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -518,6 +518,18 @@ class Client extends BaseModel implements HasLocalePreference } + if ($this->country->iso_3166_3 == 'GBR' && in_array(GatewayType::DIRECT_DEBIT, array_column($pms, 'gateway_type_id'))) { + foreach ($pms as $pm) { + if ($pm['gateway_type_id'] == GatewayType::DIRECT_DEBIT) { + $cg = CompanyGateway::find($pm['company_gateway_id']); + + if ($cg && $cg->fees_and_limits->{GatewayType::DIRECT_DEBIT}->is_enabled) { + return $cg; + } + } + } + } + return null; // $company_gateways = $this->getSetting('company_gateway_ids'); @@ -556,6 +568,10 @@ class Client extends BaseModel implements HasLocalePreference if ($this->currency()->code == 'EUR') { return GatewayType::SEPA; } + + if ($this->currency()->code == 'GBP') { + return GatewayType::DIRECT_DEBIT; + } } public function getCurrencyCode() From ed414fdb34e3ea2cfa8a8cc80806c962f001137d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 19 Oct 2021 16:15:16 +0200 Subject: [PATCH 11/16] Specify scheme type for ACH --- app/PaymentDrivers/GoCardless/ACH.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/PaymentDrivers/GoCardless/ACH.php b/app/PaymentDrivers/GoCardless/ACH.php index 2dd94a453b25..28e75f12ae3b 100644 --- a/app/PaymentDrivers/GoCardless/ACH.php +++ b/app/PaymentDrivers/GoCardless/ACH.php @@ -57,6 +57,7 @@ class ACH implements MethodInterface try { $redirect = $this->go_cardless->gateway->redirectFlows()->create([ "params" => [ + "scheme" => "ach", "session_token" => $session_token, "success_redirect_url" => route('client.payment_methods.confirm', [ 'method' => GatewayType::BANK_TRANSFER, From 9b4e6c6c25533edccec71e074ede1f193effaeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 19 Oct 2021 16:16:57 +0200 Subject: [PATCH 12/16] Apply style fixes --- app/PaymentDrivers/GoCardless/DirectDebit.php | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php index 78a75586f6a1..4df220fa26d3 100644 --- a/app/PaymentDrivers/GoCardless/DirectDebit.php +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -13,8 +13,8 @@ namespace App\PaymentDrivers\GoCardless; use App\Exceptions\PaymentFailed; -use App\Http\Requests\Request; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; +use App\Http\Requests\Request; use App\Jobs\Mail\PaymentFailureMailer; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; @@ -25,14 +25,13 @@ use App\Models\SystemLog; use App\PaymentDrivers\Common\MethodInterface; use App\PaymentDrivers\GoCardlessPaymentDriver; use App\Utils\Traits\MakesHash; -use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Http\RedirectResponse; use Illuminate\Routing\Redirector; use Illuminate\View\View; class DirectDebit implements MethodInterface { - use MakesHash; + use MakesHash; protected GoCardlessPaymentDriver $go_cardless; @@ -45,9 +44,9 @@ class DirectDebit implements MethodInterface /** * Handle authorization for Direct Debit. - * - * @param array $data - * @return Redirector|RedirectResponse|void + * + * @param array $data + * @return Redirector|RedirectResponse|void */ public function authorizeView(array $data) { @@ -103,9 +102,9 @@ class DirectDebit implements MethodInterface /** * Handle authorization response for Direct Debit. - * - * @param Request $request - * @return RedirectResponse|void + * + * @param Request $request + * @return RedirectResponse|void */ public function authorizeResponse(Request $request) { @@ -138,9 +137,9 @@ class DirectDebit implements MethodInterface /** * Payment view for Direct Debit. - * - * @param array $data - * @return View + * + * @param array $data + * @return View */ public function paymentView(array $data): View { @@ -182,7 +181,7 @@ class DirectDebit implements MethodInterface } } - /** + /** * Handle pending payments for Direct Debit. * * @param ResourcesPayment $payment @@ -246,4 +245,4 @@ class DirectDebit implements MethodInterface throw new PaymentFailed('Failed to process the payment.', 500); } -} \ No newline at end of file +} From a8f16deaf7357a58fb5eb230f62701b1f1bf498b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 19 Oct 2021 16:18:14 +0200 Subject: [PATCH 13/16] Tests --- .../Gateways/GoCardless/DirectDebitTest.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/Browser/ClientPortal/Gateways/GoCardless/DirectDebitTest.php diff --git a/tests/Browser/ClientPortal/Gateways/GoCardless/DirectDebitTest.php b/tests/Browser/ClientPortal/Gateways/GoCardless/DirectDebitTest.php new file mode 100644 index 000000000000..5989196c3f3d --- /dev/null +++ b/tests/Browser/ClientPortal/Gateways/GoCardless/DirectDebitTest.php @@ -0,0 +1,42 @@ +driver->manage()->deleteAllCookies(); + } + + $this->disableCompanyGateways(); + + CompanyGateway::where('gateway_key', 'b9886f9257f0c6ee7c302f1c74475f6c')->restore(); + + $this->browse(function (Browser $browser) { + $browser + ->visit(new Login()) + ->auth(); + }); + } + + public function testPayingWithNoPreauthorizedIsntPossible() + { + $this->browse(function (Browser $browser) { + $browser + ->visitRoute('client.invoices.index') + ->click('@pay-now') + ->press('Pay Now') + ->clickLink('Direct Debit') + ->assertSee('To pay with a bank account, first you have to add it as payment method.'); + }); + } +} From 11f27761285d875f3e8401781d4c3ad74780f65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 19 Oct 2021 16:24:48 +0200 Subject: [PATCH 14/16] Add new gateway type --- ...2200_add_gateway_type_for_direct_debit.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 database/migrations/2021_10_19_142200_add_gateway_type_for_direct_debit.php diff --git a/database/migrations/2021_10_19_142200_add_gateway_type_for_direct_debit.php b/database/migrations/2021_10_19_142200_add_gateway_type_for_direct_debit.php new file mode 100644 index 000000000000..b85ada2a59cd --- /dev/null +++ b/database/migrations/2021_10_19_142200_add_gateway_type_for_direct_debit.php @@ -0,0 +1,23 @@ +id = 18; + $type->alias = 'direct_debit'; + $type->name = 'Direct Debit'; + + $type->save(); + } +} From 0825e096c455b1277037931c1a5de4b4bb723818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 19 Oct 2021 16:24:55 +0200 Subject: [PATCH 15/16] `Direct Debit` translation --- resources/lang/en/texts.php | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 00030eba5201..2a744a833578 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4328,6 +4328,7 @@ $LANG = array( 'giropay_law' => 'By entering your Customer information (such as name, sort code and account number) you (the Customer) agree that this information is given voluntarily.', 'eps' => 'EPS', 'you_need_to_accept_the_terms_before_proceeding' => 'You need to accept the terms before proceeding.', + 'direct_debit' => 'Direct Debit', ); return $LANG; From 569613da5c5a4e2be68dfa15ed4e31ae26bbe161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 19 Oct 2021 18:57:19 +0200 Subject: [PATCH 16/16] Update correct view --- app/PaymentDrivers/GoCardless/DirectDebit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php index 4df220fa26d3..0507c38f6324 100644 --- a/app/PaymentDrivers/GoCardless/DirectDebit.php +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -147,7 +147,7 @@ class DirectDebit implements MethodInterface $data['amount'] = $this->go_cardless->convertToGoCardlessAmount($data['total']['amount_with_fee'], $this->go_cardless->client->currency()->precision); $data['currency'] = $this->go_cardless->client->getCurrencyCode(); - return render('gateways.gocardless.ach.pay', $data); + return render('gateways.gocardless.direct_debit.pay', $data); } public function paymentResponse(PaymentResponseRequest $request)