diff --git a/README.md b/README.md index 46798a4..10c4f06 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,22 @@ services: - registerRedirectResolver(Crm\FooModule\Model\FooPaymentCompleteRedirectResolver(), 400) ``` +#### Bank Transfer landing page + +When `bank_transfer` is used, user isn't redirected to external payment gateway provider, but CRM displays payment information that user should use to complete the payment manually. + +By default, this is handled by [`BankTransferPresenter`](src/presenters/BankTransferPresenter.php), but you can use your own custom screen with transfer information by using your own redirect resolver instead of bank transfers' [default resolver](src/model/SuccessPageResolver/BankTransferPaymentCompleteRedirectResolver.php). + +Create the resolver and register it with priority >10 in your `config.neon`. + +```neon +services: + # ... + paymentCompleteRedirect: + setup: + - registerRedirectResolver(Crm\FooModule\BankTransferPaymentCompleteRedirectResolver(), 50) +``` + ## Bank email processing Sometimes user doesn't finish the whole payment process and quits after the payment was made but before returning to the CRM diff --git a/src/config/config.neon b/src/config/config.neon index 28f1212..e2c22e4 100644 --- a/src/config/config.neon +++ b/src/config/config.neon @@ -81,7 +81,9 @@ services: class: Crm\PaymentsModule\Components\SubscribersWithPaymentWidgetFactory paymentCompleteRedirect: - class: Crm\PaymentsModule\Model\PaymentCompleteRedirectManager + class: Crm\PaymentsModule\Model\PaymentCompleteRedirectManager + setup: + - registerRedirectResolver(Crm\PaymentsModule\BankTransferPaymentCompleteRedirectResolver(), 10) paymentInvoiceProvider: class: Crm\PaymentsModule\DataProvider\PaymentInvoiceProviderManager diff --git a/src/model/Gateway/BankTransfer.php b/src/model/Gateway/BankTransfer.php index 70b4ccb..dbfc5c4 100644 --- a/src/model/Gateway/BankTransfer.php +++ b/src/model/Gateway/BankTransfer.php @@ -19,18 +19,15 @@ protected function initialize() public function begin($payment) { - $url = $this->linkGenerator->link( - 'Payments:Return:bankTransfer', - [ - 'VS' => $payment->variable_symbol, - ] - ); + $url = $this->generateReturnUrl($payment, [ + 'VS' => $payment->variable_symbol, + ]); $this->httpResponse->redirect($url); exit(); } public function complete($payment): ?bool { - return true; + return null; } } diff --git a/src/model/SuccessPageResolver/BankTransferPaymentCompleteRedirectResolver.php b/src/model/SuccessPageResolver/BankTransferPaymentCompleteRedirectResolver.php new file mode 100644 index 0000000..c4da740 --- /dev/null +++ b/src/model/SuccessPageResolver/BankTransferPaymentCompleteRedirectResolver.php @@ -0,0 +1,31 @@ +payment_gateway->code === 'bank_transfer') { + return true; + } + return false; + } + + public function redirectArgs(?ActiveRow $payment, string $status): array + { + if (!$payment || $payment->payment_gateway->code !== 'bank_transfer') { + throw new \Exception('unhandled status when requesting redirectArgs (did you check wantsToRedirect first?): ' . $status); + } + + return [ + ':Payments:BankTransfer:info', + [ + 'id' => $payment->variable_symbol, + ], + ]; + } +} diff --git a/src/model/SuccessPageResolver/PaymentCompleteRedirectResolver.php b/src/model/SuccessPageResolver/PaymentCompleteRedirectResolver.php index 4da8c27..2c5f7d8 100644 --- a/src/model/SuccessPageResolver/PaymentCompleteRedirectResolver.php +++ b/src/model/SuccessPageResolver/PaymentCompleteRedirectResolver.php @@ -6,14 +6,33 @@ interface PaymentCompleteRedirectResolver { + /** + * PAID represents valid paid payment, that ended up successfully. + */ const PAID = 'paid'; + /** + * NOT_SETTLED represents state where payment will most likely be confirmed in the near future, + * but the gateway provider didn't make the final confirmation yet. + */ const NOT_SETTLED = 'not_settled'; + /** + * CANCELLED is used when user intentionally cancels the payment process on the payment gateway provider site. + */ const CANCELLED = 'cancelled'; + /** + * ERROR is used if there's any kind of unexpected error during payment processing. + */ const ERROR = 'error'; + /** + * FORM is used for payments, that didn't really go through external gateway and will be confirmed offline later + * (e.g. manually, by importing bank statements or by reading notification emails from gateway provider) + */ + const FORM = 'form'; + /** * shouldRedirect decides whether the implementation should be used to redirect user after successful payment to * custom location based on arbitrary condition using $payment instance. diff --git a/src/presenters/BankTransferPresenter.php b/src/presenters/BankTransferPresenter.php new file mode 100644 index 0000000..2788cfc --- /dev/null +++ b/src/presenters/BankTransferPresenter.php @@ -0,0 +1,28 @@ +paymentsRepository->findLastByVS($id); + if (!$payment) { + throw new BadRequestException('Payment with variable symbol not found: ' . $id); + } + + $this->template->bankNumber = $this->applicationConfig->get('supplier_bank_account_number'); + $this->template->bankIban = $this->applicationConfig->get('supplier_iban'); + $this->template->bankSwift = $this->applicationConfig->get('supplier_swift'); + + $this->template->payment = $payment; + $this->template->note = 'VS' . $payment->variable_symbol; + } +} diff --git a/src/presenters/ReturnPresenter.php b/src/presenters/ReturnPresenter.php index 050c46e..7dabc29 100644 --- a/src/presenters/ReturnPresenter.php +++ b/src/presenters/ReturnPresenter.php @@ -61,17 +61,6 @@ public function renderGateway($gatewayCode) return $this->returnPayment($gatewayCode); } - public function renderBankTransfer() - { - $this->template->bankNumber = $this->applicationConfig->get('supplier_bank_account_number'); - $this->template->bankIban = $this->applicationConfig->get('supplier_iban'); - $this->template->bankSwift = $this->applicationConfig->get('supplier_swift'); - - $payment = $this->getPayment(); - $this->template->payment = $payment; - $this->template->note = 'VS' . $payment->variable_symbol; - } - public function renderGoPay($id) { if ($id === null) { @@ -224,6 +213,8 @@ private function processPayment($payment) $this->resolveRedirect($payment, PaymentCompleteRedirectResolver::ERROR); } }); + + $this->resolveRedirect($payment, PaymentCompleteRedirectResolver::FORM); } public function getPayment() diff --git a/src/templates/Return/bankTransfer.latte b/src/templates/BankTransfer/info.latte similarity index 100% rename from src/templates/Return/bankTransfer.latte rename to src/templates/BankTransfer/info.latte