From 18045487282c49e5a2afb80ec148bce2407b6937 Mon Sep 17 00:00:00 2001 From: Hasan Hasanzade Date: Thu, 27 Jul 2023 16:33:38 +0400 Subject: [PATCH] rebase main --- CHANGELOG.md | 54 +++++++++++++++++++ README.md | 21 ++++++-- composer.json | 4 +- src/BetterPayment.php | 20 +++---- .../CheckoutConfirmEventSubscriber.php | 22 ++++++-- ...rInvoiceDocumentCreatedEventSubscriber.php | 8 +-- .../PluginConfigChangedEventSubscriber.php | 6 +-- src/Installer/CustomFieldInstaller.php | 6 +-- src/Installer/PaymentMethodInstaller.php | 8 +-- src/Installer/RuleInstaller.php | 6 +-- src/PaymentHandler/CreditCardHandler.php | 4 +- src/PaymentHandler/InvoiceB2BHandler.php | 4 +- src/PaymentHandler/InvoiceHandler.php | 4 +- src/PaymentHandler/PaydirektHandler.php | 4 +- src/PaymentHandler/PaypalHandler.php | 4 +- .../SEPADirectDebitB2BHandler.php | 4 +- src/PaymentHandler/SEPADirectDebitHandler.php | 4 +- src/PaymentHandler/SofortHandler.php | 4 +- .../src/capture/capture-card.html.twig | 2 +- .../app/administration/src/capture/index.js | 18 ++----- .../app/administration/src/refund/index.js | 18 ++----- .../src/refund/refund-card.html.twig | 2 +- .../administration/js/better-payment.js | 2 +- .../snippet/de-DE/messages.de-DE.json | 10 ++++ .../snippet/en-GB/messages.en-GB.json | 10 ++++ .../birthday-gender-fields.html.twig | 3 +- .../views/betterpayment/invoice-b2b.html.twig | 14 ++--- .../views/betterpayment/invoice.html.twig | 14 ++--- ...ing-risk-check-information-modal.html.twig | 49 +++++++++++++++++ .../betterpayment/sepa-direct-debit.html.twig | 4 +- src/Util/BetterPaymentClient.php | 24 +++++++-- src/Util/OrderParametersReader.php | 20 +++---- src/Util/PaymentStatusMapper.php | 6 +-- 33 files changed, 278 insertions(+), 105 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 src/Resources/views/betterpayment/missing-risk-check-information-modal.html.twig diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1feaeee --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,54 @@ +This changelog follows the specifications of https://keepachangelog.com. Please, follow the specs when adding a new entry + +## [2.0.0] - 2023-08-22 + +### Added + +- Support for Shopware 6.5.* + +### Changed + +- Refund and Capture cards on administration moved under Payment card in Details tab of the Order page + +### Removed + +- Removed support for Shopware 6.4.\*. Bug fixes for our plugin's 1.3.\* release will still be available for 6 months. + +## [1.3.0] - 2023-08-09 + +### Added + +- Feature to notify the existing customers when date of birth or gender fields are made required by the shop owner, while their account is missing this information. In such cases, customer will be redirected to the profile page to update their information and then proceed to checkout. This feature is not compatible with 3-step-checkout plugin in Shopware store, due to that plugin replacing the standard checkout page with a custom one. + +### Fixed + +- Fixed an issue in invoice payments where customer had no VAT IDs + +## [1.2.0] - 2023-07-31 + +### Fixed + +- Removal of trailing `/` character in APP_URL environment variable, in order to general webhook and return URLs correctly, when shop owner included a trailing `/` character in their domain in APP_URL. + +## [1.1.0] - 2023-06-19 + +### Added + +- Passing customer_id in payment requests to Better Payment API +- Captures +- Configuration option to automatically capture a transaction when an invoice document is created + +## [1.0.0] - 2023-04-17 + +### Added + +- Support Shopware 6.4.* +- Credit Card Payments +- SEPA Direct Debit B2C and B2B payments +- Invoice B2C and B2B Payments +- PayPal Payments +- Sofort Payments +- Paydirekt Payments +- Refunds for all payment methods +- Multi whitelabel(partner company) support +- Risk checks, including collection and configuration of DOB and Gender fields diff --git a/README.md b/README.md index 8eb80c0..5fe9adf 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,26 @@ This repository contains the codebase for the official Better Payment API2 plugin for Shopware 6 platform. +## Wiki + +Navigate to [our wiki page](https://github.com/better-payment/bp-plugin-shopware6-api2/wiki) for in depth explanation of available features and configurations that our plugin offers. + ## Installation -Currently, plugin installation can only be done manually using a ZIP file. To receive the ZIP file, please contact the payment gateway support, as it's not yet published nor planned to be published in Shopware marketplace. +Currently, plugin installation can only be done manually using a ZIP file. You can download the ZIP files by going to [Github Releases](https://github.com/better-payment/bp-plugin-shopware6-api2/releases). + +## Shopware and plugin versioning + +For each Shopware minor release, we are releasing a major version. + +We support Shopware 6.4 and onwards. + +**Latest Releases for:** + +- Shopware 6.5.* - [Plugin Version 2.0.0](https://github.com/better-payment/bp-plugin-shopware6-api2/releases/tag/2.0.0) + +- Shopware 6.4.* - [Plugin Version 1.3.0](https://github.com/better-payment/bp-plugin-shopware6-api2/releases/tag/1.3.0) -If you are accessing the repository through Github, please [click here](https://github.com/better-payment/bp-plugin-shopware6-api2/archive/refs/heads/main.zip) to get the latest version of the plugin. ## Configuration @@ -25,4 +40,4 @@ If you are accessing the repository through Github, please [click here](https:// ## Support -Regarding any feature requests or bug reports, please contact helpdesk@betterpayment.de. +Regarding any feature requests or bug reports, please contact helpdesk@betterpayment.de or open an issue in our [issue board](https://github.com/better-payment/bp-plugin-shopware6-api2/issues). diff --git a/composer.json b/composer.json index b36e1a7..fdcc9c0 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "better-payment/bp-plugin-shopware6-api2", "description": "Better Payment plugin to implement payment methods using API2", - "version": "1.1.0", + "version": "2.0.0", "type": "shopware-platform-plugin", "license": "proprietary", "authors": [ @@ -10,7 +10,7 @@ } ], "require": { - "shopware/core": "6.4.*" + "shopware/core": "6.5.*" }, "autoload": { "psr-4": { diff --git a/src/BetterPayment.php b/src/BetterPayment.php index a5e4aec..300ac49 100644 --- a/src/BetterPayment.php +++ b/src/BetterPayment.php @@ -5,7 +5,7 @@ use BetterPayment\Installer\PaymentMethodInstaller; use BetterPayment\Installer\CustomFieldInstaller; use BetterPayment\Installer\RuleInstaller; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Plugin; use Shopware\Core\Framework\Plugin\Context\ActivateContext; use Shopware\Core\Framework\Plugin\Context\DeactivateContext; @@ -44,11 +44,19 @@ public function deactivate(DeactivateContext $deactivateContext): void $this->getPaymentMethodInstaller()->deactivate($deactivateContext); } + private function getRuleInstaller(): RuleInstaller + { + /** @var EntityRepository $ruleRepository */ + $ruleRepository = $this->container->get('rule.repository'); + + return new RuleInstaller($ruleRepository); + } + public function getPaymentMethodInstaller(): PaymentMethodInstaller { /** @var PluginIdProvider $pluginIdProvider */ $pluginIdProvider = $this->container->get(PluginIdProvider::class); - /** @var EntityRepositoryInterface $paymentMethodRepository */ + /** @var EntityRepository $paymentMethodRepository */ $paymentMethodRepository = $this->container->get('payment_method.repository'); return new PaymentMethodInstaller($pluginIdProvider, $paymentMethodRepository); @@ -56,17 +64,11 @@ public function getPaymentMethodInstaller(): PaymentMethodInstaller private function getCustomFieldInstaller(): CustomFieldInstaller { - /** @var EntityRepositoryInterface $customFieldSetRepository */ + /** @var EntityRepository $customFieldSetRepository */ $customFieldSetRepository = $this->container->get('custom_field_set.repository'); return new CustomFieldInstaller($customFieldSetRepository); } - private function getRuleInstaller(): RuleInstaller - { - /** @var EntityRepositoryInterface $ruleRepository */ - $ruleRepository = $this->container->get('rule.repository'); - return new RuleInstaller($ruleRepository); - } } \ No newline at end of file diff --git a/src/EventSubscriber/CheckoutConfirmEventSubscriber.php b/src/EventSubscriber/CheckoutConfirmEventSubscriber.php index 226cc68..39b21c6 100644 --- a/src/EventSubscriber/CheckoutConfirmEventSubscriber.php +++ b/src/EventSubscriber/CheckoutConfirmEventSubscriber.php @@ -2,12 +2,14 @@ namespace BetterPayment\EventSubscriber; +use BetterPayment\Installer\CustomFieldInstaller; use BetterPayment\PaymentHandler\InvoiceB2BHandler; use BetterPayment\PaymentHandler\InvoiceHandler; use BetterPayment\PaymentHandler\SEPADirectDebitB2BHandler; use BetterPayment\PaymentHandler\SEPADirectDebitHandler; use BetterPayment\Storefront\Struct\CheckoutData; use BetterPayment\Util\ConfigReader; +use Shopware\Core\Checkout\Customer\CustomerEntity; use Shopware\Core\Framework\Uuid\Uuid; use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent; use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent; @@ -35,7 +37,7 @@ public function addPaymentMethodSpecificFormFields(PageLoadedEvent $event): void { $page = $event->getPage(); $paymentMethod = $event->getSalesChannelContext()->getPaymentMethod(); - + $customer = $event->getSalesChannelContext()->getCustomer(); if ($paymentMethod->getHandlerIdentifier() == SEPADirectDebitHandler::class) { $data = new CheckoutData(); @@ -45,6 +47,8 @@ public function addPaymentMethodSpecificFormFields(PageLoadedEvent $event): void 'creditorID' => $this->configReader->getString(ConfigReader::SEPA_DIRECT_DEBIT_CREDITOR_ID), 'companyName' => $this->configReader->getString(ConfigReader::SEPA_DIRECT_DEBIT_COMPANY_NAME), 'mandateReference' => Uuid::randomHex(), + 'birthdayIsMissing' => $this->birthdayIsMissing($customer) && $this->configReader->getBool(ConfigReader::SEPA_DIRECT_DEBIT_COLLECT_DATE_OF_BIRTH), + 'genderIsMissing' => $this->genderIsMissing($customer) && $this->configReader->getBool(ConfigReader::SEPA_DIRECT_DEBIT_COLLECT_GENDER), ]); $page->addExtension(CheckoutData::EXTENSION_NAME, $data); @@ -64,16 +68,18 @@ public function addPaymentMethodSpecificFormFields(PageLoadedEvent $event): void // in invoice payment methods (b2c|b2b) only risk check agreement checkbox is added as form field when corresponding config is enabled // that's why it also needs to check in if condition whether config is enabled before assigning related template view - elseif ($paymentMethod->getHandlerIdentifier() == InvoiceHandler::class && $this->configReader->getBool(ConfigReader::INVOICE_RISK_CHECK_AGREEMENT)) { + elseif ($paymentMethod->getHandlerIdentifier() == InvoiceHandler::class) { $data = new CheckoutData(); $data->assign([ 'template' => '@Storefront/betterpayment/invoice.html.twig', + 'birthdayIsMissing' => $this->birthdayIsMissing($customer) && $this->configReader->getBool(ConfigReader::INVOICE_COLLECT_DATE_OF_BIRTH), + 'genderIsMissing' => $this->genderIsMissing($customer) && $this->configReader->getBool(ConfigReader::INVOICE_COLLECT_GENDER), ]); $page->addExtension(CheckoutData::EXTENSION_NAME, $data); } - elseif ($paymentMethod->getHandlerIdentifier() == InvoiceB2BHandler::class && $this->configReader->getBool(ConfigReader::INVOICE_B2B_RISK_CHECK_AGREEMENT)) { + elseif ($paymentMethod->getHandlerIdentifier() == InvoiceB2BHandler::class) { $data = new CheckoutData(); $data->assign([ @@ -83,4 +89,14 @@ public function addPaymentMethodSpecificFormFields(PageLoadedEvent $event): void $page->addExtension(CheckoutData::EXTENSION_NAME, $data); } } + + private function birthdayIsMissing(CustomerEntity $customer): bool + { + return !$customer->getBirthday(); + } + + private function genderIsMissing(CustomerEntity $customer): bool + { + return !$customer->getCustomFields()[CustomFieldInstaller::CUSTOMER_GENDER]; + } } \ No newline at end of file diff --git a/src/EventSubscriber/OrderInvoiceDocumentCreatedEventSubscriber.php b/src/EventSubscriber/OrderInvoiceDocumentCreatedEventSubscriber.php index 04ab71d..6740843 100644 --- a/src/EventSubscriber/OrderInvoiceDocumentCreatedEventSubscriber.php +++ b/src/EventSubscriber/OrderInvoiceDocumentCreatedEventSubscriber.php @@ -10,7 +10,7 @@ use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -23,17 +23,17 @@ class OrderInvoiceDocumentCreatedEventSubscriber implements EventSubscriberInterface { private BetterPaymentClient $betterPaymentClient; - private EntityRepositoryInterface $orderRepository; + private EntityRepository $orderRepository; private ConfigReader $configReader; /** * OrderInvoiceDocumentCreatedEventSubscriber constructor. * * @param BetterPaymentClient $betterPaymentClient - * @param EntityRepositoryInterface $orderRepository + * @param EntityRepository $orderRepository * @param ConfigReader $configReader */ - public function __construct(BetterPaymentClient $betterPaymentClient, EntityRepositoryInterface $orderRepository, ConfigReader $configReader) + public function __construct(BetterPaymentClient $betterPaymentClient, EntityRepository $orderRepository, ConfigReader $configReader) { $this->betterPaymentClient = $betterPaymentClient; $this->orderRepository = $orderRepository; diff --git a/src/EventSubscriber/PluginConfigChangedEventSubscriber.php b/src/EventSubscriber/PluginConfigChangedEventSubscriber.php index b9f358d..7587f02 100644 --- a/src/EventSubscriber/PluginConfigChangedEventSubscriber.php +++ b/src/EventSubscriber/PluginConfigChangedEventSubscriber.php @@ -5,7 +5,7 @@ use BetterPayment\Installer\CustomFieldInstaller; use BetterPayment\Util\ConfigReader; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\System\CustomField\CustomFieldEntity; use Shopware\Core\System\SystemConfig\Event\SystemConfigChangedEvent; @@ -16,9 +16,9 @@ class PluginConfigChangedEventSubscriber implements EventSubscriberInterface { private ConfigReader $configReader; private SystemConfigService $systemConfigService; - private EntityRepositoryInterface $customFieldRepository; + private EntityRepository $customFieldRepository; - public function __construct(ConfigReader $configReader, SystemConfigService $systemConfigService, EntityRepositoryInterface $customFieldRepository) + public function __construct(ConfigReader $configReader, SystemConfigService $systemConfigService, EntityRepository $customFieldRepository) { $this->configReader = $configReader; $this->systemConfigService = $systemConfigService; diff --git a/src/Installer/CustomFieldInstaller.php b/src/Installer/CustomFieldInstaller.php index 7d98912..586d57a 100644 --- a/src/Installer/CustomFieldInstaller.php +++ b/src/Installer/CustomFieldInstaller.php @@ -2,7 +2,7 @@ namespace BetterPayment\Installer; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Plugin\Context\InstallContext; use Shopware\Core\System\CustomField\CustomFieldTypes; @@ -82,9 +82,9 @@ class CustomFieldInstaller // You can add more customer fields here ]; - private EntityRepositoryInterface $customFieldSetRepository; + private EntityRepository $customFieldSetRepository; - public function __construct(EntityRepositoryInterface $customFieldSetRepository) + public function __construct(EntityRepository $customFieldSetRepository) { $this->customFieldSetRepository = $customFieldSetRepository; } diff --git a/src/Installer/PaymentMethodInstaller.php b/src/Installer/PaymentMethodInstaller.php index 660480b..6324c2f 100644 --- a/src/Installer/PaymentMethodInstaller.php +++ b/src/Installer/PaymentMethodInstaller.php @@ -13,7 +13,7 @@ use BetterPayment\PaymentMethod\SEPADirectDebitB2B; use BetterPayment\PaymentMethod\Sofort; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Plugin\Context\ActivateContext; use Shopware\Core\Framework\Plugin\Context\DeactivateContext; use Shopware\Core\Framework\Plugin\Context\InstallContext; @@ -35,13 +35,13 @@ class PaymentMethodInstaller ]; private PluginIdProvider $pluginIdProvider; - private EntityRepositoryInterface $paymentMethodRepository; + private EntityRepository $paymentMethodRepository; /** * @param PluginIdProvider $pluginIdProvider - * @param EntityRepositoryInterface $paymentMethodRepository + * @param EntityRepository $paymentMethodRepository */ - public function __construct(PluginIdProvider $pluginIdProvider, EntityRepositoryInterface $paymentMethodRepository) + public function __construct(PluginIdProvider $pluginIdProvider, EntityRepository $paymentMethodRepository) { $this->pluginIdProvider = $pluginIdProvider; $this->paymentMethodRepository = $paymentMethodRepository; diff --git a/src/Installer/RuleInstaller.php b/src/Installer/RuleInstaller.php index a496ba0..9509203 100644 --- a/src/Installer/RuleInstaller.php +++ b/src/Installer/RuleInstaller.php @@ -7,7 +7,7 @@ use BetterPayment\PaymentMethod\SEPADirectDebit; use BetterPayment\PaymentMethod\SEPADirectDebitB2B; use Shopware\Core\Checkout\Customer\Rule\IsCompanyRule; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Plugin\Context\InstallContext; use Shopware\Core\Framework\Rule\Container\AndRule; @@ -18,9 +18,9 @@ class RuleInstaller private const CUSTOMER_IS_PRIVATE_RULE_ID = 'ea5c01b126ac4cd7861bc6daeff9bc3d'; private const CUSTOMER_IS_COMPANY_RULE_ID = 'fbac3618c6a2477ba079b31c07bb52fa'; - private EntityRepositoryInterface $ruleRepository; + private EntityRepository $ruleRepository; - public function __construct(EntityRepositoryInterface $ruleRepository) + public function __construct(EntityRepository $ruleRepository) { $this->ruleRepository = $ruleRepository; } diff --git a/src/PaymentHandler/CreditCardHandler.php b/src/PaymentHandler/CreditCardHandler.php index 586113b..7f2e248 100644 --- a/src/PaymentHandler/CreditCardHandler.php +++ b/src/PaymentHandler/CreditCardHandler.php @@ -36,7 +36,9 @@ public function pay(AsyncPaymentTransactionStruct $transaction, RequestDataBag $ } catch (\Exception $e) { throw new AsyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } diff --git a/src/PaymentHandler/InvoiceB2BHandler.php b/src/PaymentHandler/InvoiceB2BHandler.php index 7f05c94..250b284 100644 --- a/src/PaymentHandler/InvoiceB2BHandler.php +++ b/src/PaymentHandler/InvoiceB2BHandler.php @@ -33,7 +33,9 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d } catch (\Exception $e) { throw new SyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } } diff --git a/src/PaymentHandler/InvoiceHandler.php b/src/PaymentHandler/InvoiceHandler.php index 4e0ade0..a03136b 100644 --- a/src/PaymentHandler/InvoiceHandler.php +++ b/src/PaymentHandler/InvoiceHandler.php @@ -33,7 +33,9 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d } catch (\Exception $e) { throw new SyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } } diff --git a/src/PaymentHandler/PaydirektHandler.php b/src/PaymentHandler/PaydirektHandler.php index dff5808..b199a79 100644 --- a/src/PaymentHandler/PaydirektHandler.php +++ b/src/PaymentHandler/PaydirektHandler.php @@ -36,7 +36,9 @@ public function pay(AsyncPaymentTransactionStruct $transaction, RequestDataBag $ } catch (\Exception $e) { throw new AsyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } diff --git a/src/PaymentHandler/PaypalHandler.php b/src/PaymentHandler/PaypalHandler.php index 56038d2..470eb9e 100644 --- a/src/PaymentHandler/PaypalHandler.php +++ b/src/PaymentHandler/PaypalHandler.php @@ -36,7 +36,9 @@ public function pay(AsyncPaymentTransactionStruct $transaction, RequestDataBag $ } catch (\Exception $e) { throw new AsyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } diff --git a/src/PaymentHandler/SEPADirectDebitB2BHandler.php b/src/PaymentHandler/SEPADirectDebitB2BHandler.php index a4c48e7..61afb9a 100644 --- a/src/PaymentHandler/SEPADirectDebitB2BHandler.php +++ b/src/PaymentHandler/SEPADirectDebitB2BHandler.php @@ -33,7 +33,9 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d } catch (\Exception $e) { throw new SyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } } diff --git a/src/PaymentHandler/SEPADirectDebitHandler.php b/src/PaymentHandler/SEPADirectDebitHandler.php index 357e712..06908f3 100644 --- a/src/PaymentHandler/SEPADirectDebitHandler.php +++ b/src/PaymentHandler/SEPADirectDebitHandler.php @@ -33,7 +33,9 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d } catch (\Exception $e) { throw new SyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } } diff --git a/src/PaymentHandler/SofortHandler.php b/src/PaymentHandler/SofortHandler.php index 6fabfa1..b8d4fb7 100644 --- a/src/PaymentHandler/SofortHandler.php +++ b/src/PaymentHandler/SofortHandler.php @@ -36,7 +36,9 @@ public function pay(AsyncPaymentTransactionStruct $transaction, RequestDataBag $ } catch (\Exception $e) { throw new AsyncPaymentProcessException( $transaction->getOrderTransaction()->getId(), - 'An error occurred during the communication with external payment gateway' . PHP_EOL . $e->getMessage() + 'An error occurred during the communication with external payment gateway' . PHP_EOL + . $e->getMessage() . PHP_EOL + . 'TRACE: ' . $e->getTraceAsString() ); } diff --git a/src/Resources/app/administration/src/capture/capture-card.html.twig b/src/Resources/app/administration/src/capture/capture-card.html.twig index 70f47f4..2181f74 100644 --- a/src/Resources/app/administration/src/capture/capture-card.html.twig +++ b/src/Resources/app/administration/src/capture/capture-card.html.twig @@ -1,4 +1,4 @@ -{% block sw_order_detail_base_line_items_card %} +{% block sw_order_detail_details_payment %} {% parent %} this.getCaptures(), 1000); + } }, computed: { @@ -72,16 +76,6 @@ Component.override('sw-order-detail-base', { } }, - watch: { - // when order is set get its transaction captures - // order is not directly set in created() lifecycle hook - order() { - if (this.captureCardIsVisible) { - this.getCaptures(); - } - } - }, - methods: { setAPIProperties() { const pluginConfig = ApiService.getByName('systemConfigApiService'); @@ -99,8 +93,6 @@ Component.override('sw-order-detail-base', { this.apiUrl = whiteLabels[whiteLabel][environment].api_url; this.apiAuth = btoa(apiKey + ':' + outgoingKey); - - return Promise.resolve(); }); }, diff --git a/src/Resources/app/administration/src/refund/index.js b/src/Resources/app/administration/src/refund/index.js index 0df6f75..28341ea 100644 --- a/src/Resources/app/administration/src/refund/index.js +++ b/src/Resources/app/administration/src/refund/index.js @@ -3,7 +3,7 @@ import whiteLabels from '../../../../data/whitelabels.json'; const {Component, Mixin, ApiService} = Shopware; -Component.override('sw-order-detail-base', { +Component.override('sw-order-detail-details', { template, inject: [ @@ -33,6 +33,10 @@ Component.override('sw-order-detail-base', { created() { this.setAPIProperties(); + + if (this.refundCardIsVisible) { + setTimeout(() => this.getRefunds(), 1000); + } }, computed: { @@ -69,16 +73,6 @@ Component.override('sw-order-detail-base', { } }, - watch: { - // when order is set get its transaction refunds - // order is not directly set in created() lifecycle hook - order() { - if (this.refundCardIsVisible) { - this.getRefunds(); - } - } - }, - methods: { setAPIProperties() { const pluginConfig = ApiService.getByName('systemConfigApiService'); @@ -96,8 +90,6 @@ Component.override('sw-order-detail-base', { this.apiUrl = whiteLabels[whiteLabel][environment].api_url; this.apiAuth = btoa(apiKey + ':' + outgoingKey); - - return Promise.resolve(); }); }, diff --git a/src/Resources/app/administration/src/refund/refund-card.html.twig b/src/Resources/app/administration/src/refund/refund-card.html.twig index 596faf9..eb00453 100644 --- a/src/Resources/app/administration/src/refund/refund-card.html.twig +++ b/src/Resources/app/administration/src/refund/refund-card.html.twig @@ -1,4 +1,4 @@ -{% block sw_order_detail_base_line_items_card %} +{% block sw_order_detail_details_payment %} {% parent %} \n \n \n{% endblock %}',inject:["orderStateMachineService"],mixins:[i.getByName("notification")],data:function(){return{refund:{amount:null,comment:null,execution_date:null},refunds:[],processSuccess:!1,buttonDisabled:!1,apiUrl:null,apiAuth:null}},created:function(){this.setAPIProperties()},computed:{isBetterPaymentTransaction:function(){return null!==this.transaction.customFields&&this.transaction.customFields.hasOwnProperty("better_payment_transaction_id")},betterPaymentTransactionId:function(){return this.isBetterPaymentTransaction?this.transaction.customFields.better_payment_transaction_id:null},refundCardIsVisible:function(){return this.isBetterPaymentTransaction},isRefundable:function(){return["paid","paid_partially","refunded_partially"].includes(this.transaction.stateMachineState.technicalName)},isFullyRefunded:function(){return"refunded"===this.transaction.stateMachineState.technicalName},canCreateRefund:function(){return this.isRefundable},paymentMethod:function(){return this.transaction.paymentMethod.customFields.shortname}},watch:{order:function(){this.refundCardIsVisible&&this.getRefunds()}},methods:{setAPIProperties:function(){var e=this;o.getByName("systemConfigApiService").getValues("BetterPayment").then((function(t){var n=t["BetterPayment.config.environment"],r=t["BetterPayment.config.whiteLabel"],s=t["BetterPayment.config.testAPIKey"],i=t["BetterPayment.config.productionAPIKey"],o="test"===n?s:i,c=t["BetterPayment.config.testOutgoingKey"],d=t["BetterPayment.config.productionOutgoingKey"],p="test"===n?c:d;return e.apiUrl=a[r][n].api_url,e.apiAuth=btoa(o+":"+p),Promise.resolve()}))},getRefunds:function(){var e=this,t=this.apiUrl+"/rest/transactions/"+this.betterPaymentTransactionId+"/log",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),fetch(t,{method:"GET",headers:n}).then((function(e){return e.json()})).then((function(t){t.hasOwnProperty("error_code")?e.createNotificationError({message:t.error_message}):e.refunds=t.filter((function(e){return"refund"===e.type})).filter((function(e){return 7===e.status}))})).catch((function(t){e.createNotificationError({message:t})}))},createRefund:function(){var e=this;this.buttonDisabled=!0;var t=this.apiUrl+"/rest/refund",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),n.append("Content-Type","application/json");var a=JSON.stringify({transaction_id:this.betterPaymentTransactionId,amount:this.refund.amount,comment:this.refund.comment,execution_date:this.refund.execution_date});fetch(t,{method:"POST",headers:n,body:a}).then((function(e){return e.json()})).then((function(t){e.buttonDisabled=!1,0===t.error_code?"error"!==t.status?(e.getRefunds(),e.processSuccess=!0,e.createNotificationSuccess({message:e.$tc("betterpayment.refund.messages.successfulRefundRequest")}),e.updateTransactionState()):e.createNotificationError({message:e.$tc("betterpayment.refund.messages.invalidRefundRequest")}):e.createNotificationError({message:t.error_message})})).catch((function(t){e.createNotificationError({message:t})}))},createRefundFinished:function(){this.refund.amount=null,this.refund.comment=null,this.refund.execution_date=null,this.processSuccess=!1},updateTransactionState:function(){var e=this,t=this.apiUrl+"/rest/transactions/"+this.betterPaymentTransactionId,n=new Headers;n.append("Authorization","Basic "+this.apiAuth),fetch(t,{method:"GET",headers:n}).then((function(e){return e.json()})).then((function(t){if(t.hasOwnProperty("error_code"))e.createNotificationError({message:t.error_message});else if(t.refunded_amount>0){var n;n=t.refunded_amount>=t.amount?"refund":"refund_partially";e.orderStateMachineService.transitionOrderTransactionState(e.transaction.id,n,{documentIds:[],sendMail:!0}).then((function(){e.$emit("order-state-change")})).catch((function(t){e.createNotificationError(t)}))}})).catch((function(t){e.createNotificationError({message:t})}))}}});var c=Shopware,d=c.Component,p=c.Mixin,l=c.ApiService;d.override("sw-order-detail-base",{template:'{% block sw_order_detail_base_line_items_card %}\n {% parent %}\n \n \n \n{% endblock %}',inject:["orderStateMachineService"],mixins:[p.getByName("notification")],data:function(){return{capture:{amount:null,invoice_id:null,comment:this.$tc("betterpayment.capture.defaults.comment"),execution_date:null},captures:[],processSuccess:!1,buttonDisabled:!1,apiUrl:null,apiAuth:null}},created:function(){this.setAPIProperties()},computed:{isBetterPaymentTransaction:function(){return null!==this.transaction.customFields&&this.transaction.customFields.hasOwnProperty("better_payment_transaction_id")},betterPaymentTransactionId:function(){return this.isBetterPaymentTransaction?this.transaction.customFields.better_payment_transaction_id:null},isCapturablePaymentMethod:function(){return["kar","kar_b2b"].includes(this.paymentMethod)},captureCardIsVisible:function(){return this.isBetterPaymentTransaction&&this.isCapturablePaymentMethod},isCapturableState:function(){return["in_progress","paid_partially","paid"].includes(this.transaction.stateMachineState.technicalName)},canCreateCapture:function(){return this.isCapturableState},paymentMethod:function(){return this.transaction.paymentMethod.customFields.shortname}},watch:{order:function(){this.captureCardIsVisible&&this.getCaptures()}},methods:{setAPIProperties:function(){var e=this;l.getByName("systemConfigApiService").getValues("BetterPayment").then((function(t){var n=t["BetterPayment.config.environment"],r=t["BetterPayment.config.whiteLabel"],s=t["BetterPayment.config.testAPIKey"],i=t["BetterPayment.config.productionAPIKey"],o="test"===n?s:i,c=t["BetterPayment.config.testOutgoingKey"],d=t["BetterPayment.config.productionOutgoingKey"],p="test"===n?c:d;return e.apiUrl=a[r][n].api_url,e.apiAuth=btoa(o+":"+p),Promise.resolve()}))},getCaptures:function(){var e=this,t=this.apiUrl+"/rest/transactions/"+this.betterPaymentTransactionId+"/log",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),fetch(t,{method:"GET",headers:n}).then((function(e){return e.json()})).then((function(t){t.hasOwnProperty("error_code")?e.createNotificationError({message:t.error_message}):e.captures=t.filter((function(e){return"capture"===e.type})).filter((function(e){return[1,2,3].includes(e.status)}))})).catch((function(t){e.createNotificationError({message:t})}))},createCapture:function(){var e=this;this.buttonDisabled=!0;var t=this.apiUrl+"/rest/capture",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),n.append("Content-Type","application/json");var a=JSON.stringify({transaction_id:this.betterPaymentTransactionId,amount:this.capture.amount,invoice_id:this.capture.invoice_id,comment:this.capture.comment,execution_date:this.capture.execution_date});fetch(t,{method:"POST",headers:n,body:a}).then((function(e){return e.json()})).then((function(t){e.buttonDisabled=!1,0===t.error_code?"error"!==t.status?(e.getCaptures(),e.processSuccess=!0,e.createNotificationSuccess({message:e.$tc("betterpayment.capture.messages.successfulCaptureRequest")})):e.createNotificationError({message:e.$tc("betterpayment.capture.messages.invalidCaptureRequest")}):e.createNotificationError({message:t.error_message})})).catch((function(t){e.createNotificationError({message:t})}))},createCaptureFinished:function(){this.capture.amount=null,this.capture.invoice_id=null,this.capture.comment=this.$tc("betterpayment.capture.defaults.comment"),this.capture.execution_date=null,this.processSuccess=!1}}})}}); \ No newline at end of file +!function(t){var e={};function n(a){if(e[a])return e[a].exports;var r=e[a]={i:a,l:!1,exports:{}};return t[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=t,n.c=e,n.d=function(t,e,a){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:a})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(a,r,function(e){return t[e]}.bind(null,r));return a},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p=(window.__sw__.assetPath + '/bundles/betterpayment/'),n(n.s="UklF")}({"2xXY":function(t){t.exports=JSON.parse('{"betterpayment":{"test":{"api_url":"https://testapi.betterpayment.de","dash_url":"https://testdashboard.betterpayment.de"},"production":{"api_url":"https://api.betterpayment.de","dash_url":"https://dashboard.betterpayment.de"}},"solvendi":{"test":{"api_url":"https://testapi-solvendi.betterpayment.de","dash_url":"https://testdashboard-solvendi.betterpayment.de"},"production":{"api_url":"https://api-solvendi.betterpayment.de","dash_url":"https://dashboard-solvendi.betterpayment.de"}},"diagonal":{"test":{"api_url":"https://testapi.diagonal-payment.eu","dash_url":"https://testdashboard.diagonal-payment.eu"},"production":{"api_url":"https://api.diagonal-payment.eu","dash_url":"https://dashboard.diagonal-payment.eu"}},"collectai":{"test":{"api_url":"https://testapi-collectai.betterpayment.de","dash_url":"https://testdashboard-collectai.betterpayment.de"},"production":{"api_url":"https://api-collectai.betterpayment.de","dash_url":"https://dashboard-collectai.betterpayment.de"}},"betterbill":{"test":{"api_url":"https://testapi.betterbill.net","dash_url":"https://testdashboard.betterbill.net"},"production":{"api_url":"https://api.betterbill.net","dash_url":"https://dashboard.betterbill.net"}},"kleverpay":{"test":{"api_url":"https://testapi.kleverpay.de","dash_url":"https://testdashboard.kleverpay.de"},"production":{"api_url":"https://api.kleverpay.de","dash_url":"https://dashboard.kleverpay.de"}},"abilitapay":{"test":{"api_url":"https://testapi.abilitapay.de","dash_url":"https://testdashboard.abilitapay.de"},"production":{"api_url":"https://api.abilitapay.de","dash_url":"https://dashboard.abilitapay.de"}},"vr_dienste":{"test":{"api_url":"https://testapi.vr-jetztzahlen.de","dash_url":"https://testdashboard.vr-jetztzahlen.de"},"production":{"api_url":"https://api.vr-jetztzahlen.de","dash_url":"https://dashboard.vr-jetztzahlen.de"}},"vr_straubing":{"test":{"api_url":"https://testapi-raiffeisenbank-straubing.betterpayment.de","dash_url":"https://testdashboard-raiffeisenbank-straubing.betterpayment.de"},"production":{"api_url":"https://api-raiffeisenbank-straubing.betterpayment.de","dash_url":"https://dashboard-raiffeisenbank-straubing.betterpayment.de"}},"continentalpay":{"test":{"api_url":"https://testapi.continentalpay.com","dash_url":"https://testdashboard.continentalpay.com"},"production":{"api_url":"https://api.continentalpay.com","dash_url":"https://dashboard.continentalpay.com"}},"vrkg":{"test":{"api_url":"https://testapi-vrkg.betterpayment.de","dash_url":"https://testdashboard-vrkg.betterpayment.de"},"production":{"api_url":"https://api-vrkg.betterpayment.de","dash_url":"https://dashboard-vrkg.betterpayment.de"}},"demondo":{"test":{"api_url":"https://testapi.demondo-paygate.com","dash_url":"https://testdashboard.demondo-paygate.com"},"production":{"api_url":"https://api.demondo-paygate.com","dash_url":"https://dashboard.demondo-paygate.com"}},"vivapago":{"test":{"api_url":"https://testapi.vivapago.net","dash_url":"https://testdashboard.vivapago.net"},"production":{"api_url":"https://api.vivapago.net","dash_url":"https://dashboard.vivapago.net"}}}')},UklF:function(t,e,n){"use strict";n.r(e);var a=n("2xXY"),r=Shopware,s=r.Component,i=r.Mixin,o=r.ApiService;s.override("sw-order-detail-details",{template:'{% block sw_order_detail_details_payment %}\n {% parent %}\n \n \n \n{% endblock %}',inject:["orderStateMachineService"],mixins:[i.getByName("notification")],data:function(){return{refund:{amount:null,comment:null,execution_date:null},refunds:[],processSuccess:!1,buttonDisabled:!1,apiUrl:null,apiAuth:null}},created:function(){var t=this;this.setAPIProperties(),this.refundCardIsVisible&&setTimeout((function(){return t.getRefunds()}),1e3)},computed:{isBetterPaymentTransaction:function(){return null!==this.transaction.customFields&&this.transaction.customFields.hasOwnProperty("better_payment_transaction_id")},betterPaymentTransactionId:function(){return this.isBetterPaymentTransaction?this.transaction.customFields.better_payment_transaction_id:null},refundCardIsVisible:function(){return this.isBetterPaymentTransaction},isRefundable:function(){return["paid","paid_partially","refunded_partially"].includes(this.transaction.stateMachineState.technicalName)},isFullyRefunded:function(){return"refunded"===this.transaction.stateMachineState.technicalName},canCreateRefund:function(){return this.isRefundable},paymentMethod:function(){return this.transaction.paymentMethod.customFields.shortname}},methods:{setAPIProperties:function(){var t=this;o.getByName("systemConfigApiService").getValues("BetterPayment").then((function(e){var n=e["BetterPayment.config.environment"],r=e["BetterPayment.config.whiteLabel"],s=e["BetterPayment.config.testAPIKey"],i=e["BetterPayment.config.productionAPIKey"],o="test"===n?s:i,c=e["BetterPayment.config.testOutgoingKey"],d=e["BetterPayment.config.productionOutgoingKey"],p="test"===n?c:d;t.apiUrl=a[r][n].api_url,t.apiAuth=btoa(o+":"+p)}))},getRefunds:function(){var t=this,e=this.apiUrl+"/rest/transactions/"+this.betterPaymentTransactionId+"/log",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),fetch(e,{method:"GET",headers:n}).then((function(t){return t.json()})).then((function(e){e.hasOwnProperty("error_code")?t.createNotificationError({message:e.error_message}):t.refunds=e.filter((function(t){return"refund"===t.type})).filter((function(t){return 7===t.status}))})).catch((function(e){t.createNotificationError({message:e})}))},createRefund:function(){var t=this;this.buttonDisabled=!0;var e=this.apiUrl+"/rest/refund",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),n.append("Content-Type","application/json");var a=JSON.stringify({transaction_id:this.betterPaymentTransactionId,amount:this.refund.amount,comment:this.refund.comment,execution_date:this.refund.execution_date});fetch(e,{method:"POST",headers:n,body:a}).then((function(t){return t.json()})).then((function(e){t.buttonDisabled=!1,0===e.error_code?"error"!==e.status?(t.getRefunds(),t.processSuccess=!0,t.createNotificationSuccess({message:t.$tc("betterpayment.refund.messages.successfulRefundRequest")}),t.updateTransactionState()):t.createNotificationError({message:t.$tc("betterpayment.refund.messages.invalidRefundRequest")}):t.createNotificationError({message:e.error_message})})).catch((function(e){t.createNotificationError({message:e})}))},createRefundFinished:function(){this.refund.amount=null,this.refund.comment=null,this.refund.execution_date=null,this.processSuccess=!1},updateTransactionState:function(){var t=this,e=this.apiUrl+"/rest/transactions/"+this.betterPaymentTransactionId,n=new Headers;n.append("Authorization","Basic "+this.apiAuth),fetch(e,{method:"GET",headers:n}).then((function(t){return t.json()})).then((function(e){if(e.hasOwnProperty("error_code"))t.createNotificationError({message:e.error_message});else if(e.refunded_amount>0){var n;n=e.refunded_amount>=e.amount?"refund":"refund_partially";t.orderStateMachineService.transitionOrderTransactionState(t.transaction.id,n,{documentIds:[],sendMail:!0}).then((function(){t.$emit("order-state-change")})).catch((function(e){t.createNotificationError(e)}))}})).catch((function(e){t.createNotificationError({message:e})}))}}});var c=Shopware,d=c.Component,p=c.Mixin,l=c.ApiService;d.override("sw-order-detail-details",{template:'{% block sw_order_detail_details_payment %}\n {% parent %}\n \n \n \n{% endblock %}',inject:["orderStateMachineService"],mixins:[p.getByName("notification")],data:function(){return{capture:{amount:null,invoice_id:null,comment:this.$tc("betterpayment.capture.defaults.comment"),execution_date:null},captures:[],processSuccess:!1,buttonDisabled:!1,apiUrl:null,apiAuth:null}},created:function(){var t=this;this.setAPIProperties(),this.captureCardIsVisible&&setTimeout((function(){return t.getCaptures()}),1e3)},computed:{isBetterPaymentTransaction:function(){return null!==this.transaction.customFields&&this.transaction.customFields.hasOwnProperty("better_payment_transaction_id")},betterPaymentTransactionId:function(){return this.isBetterPaymentTransaction?this.transaction.customFields.better_payment_transaction_id:null},isCapturablePaymentMethod:function(){return["kar","kar_b2b"].includes(this.paymentMethod)},captureCardIsVisible:function(){return this.isBetterPaymentTransaction&&this.isCapturablePaymentMethod},isCapturableState:function(){return["in_progress","paid_partially","paid"].includes(this.transaction.stateMachineState.technicalName)},canCreateCapture:function(){return this.isCapturableState},paymentMethod:function(){return this.transaction.paymentMethod.customFields.shortname}},methods:{setAPIProperties:function(){var t=this;l.getByName("systemConfigApiService").getValues("BetterPayment").then((function(e){var n=e["BetterPayment.config.environment"],r=e["BetterPayment.config.whiteLabel"],s=e["BetterPayment.config.testAPIKey"],i=e["BetterPayment.config.productionAPIKey"],o="test"===n?s:i,c=e["BetterPayment.config.testOutgoingKey"],d=e["BetterPayment.config.productionOutgoingKey"],p="test"===n?c:d;t.apiUrl=a[r][n].api_url,t.apiAuth=btoa(o+":"+p)}))},getCaptures:function(){var t=this,e=this.apiUrl+"/rest/transactions/"+this.betterPaymentTransactionId+"/log",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),fetch(e,{method:"GET",headers:n}).then((function(t){return t.json()})).then((function(e){e.hasOwnProperty("error_code")?t.createNotificationError({message:e.error_message}):t.captures=e.filter((function(t){return"capture"===t.type})).filter((function(t){return[1,2,3].includes(t.status)}))})).catch((function(e){t.createNotificationError({message:e})}))},createCapture:function(){var t=this;this.buttonDisabled=!0;var e=this.apiUrl+"/rest/capture",n=new Headers;n.append("Authorization","Basic "+this.apiAuth),n.append("Content-Type","application/json");var a=JSON.stringify({transaction_id:this.betterPaymentTransactionId,amount:this.capture.amount,invoice_id:this.capture.invoice_id,comment:this.capture.comment,execution_date:this.capture.execution_date});fetch(e,{method:"POST",headers:n,body:a}).then((function(t){return t.json()})).then((function(e){t.buttonDisabled=!1,0===e.error_code?"error"!==e.status?(t.getCaptures(),t.processSuccess=!0,t.createNotificationSuccess({message:t.$tc("betterpayment.capture.messages.successfulCaptureRequest")})):t.createNotificationError({message:t.$tc("betterpayment.capture.messages.invalidCaptureRequest")}):t.createNotificationError({message:e.error_message})})).catch((function(e){t.createNotificationError({message:e})}))},createCaptureFinished:function(){this.capture.amount=null,this.capture.invoice_id=null,this.capture.comment=this.$tc("betterpayment.capture.defaults.comment"),this.capture.execution_date=null,this.processSuccess=!1}}})}}); \ No newline at end of file diff --git a/src/Resources/snippet/de-DE/messages.de-DE.json b/src/Resources/snippet/de-DE/messages.de-DE.json index d686a07..78c5e78 100644 --- a/src/Resources/snippet/de-DE/messages.de-DE.json +++ b/src/Resources/snippet/de-DE/messages.de-DE.json @@ -28,6 +28,16 @@ "agreementLabel": "Ich erkläre mich mit dem folgenden Sepa-Mandat einverstanden " }, + "missing-risk-check-information-modal": { + "title": "Fehlende Informationen für Risikoprüfungen", + "body1": "Für die von Ihnen gewählte Zahlungsmethode müssen Sie folgende Angaben machen:", + "body2": "Bitte gehen Sie zu Ihrem Profil, um die Informationen zu aktualisieren, oder wählen Sie einfach eine andere Zahlungsmethode.", + "birthdate": "Geburtsdatum", + "gender": "Geschlecht", + "close_button": "Schließen", + "action_button": "Zum Profil" + }, + "register": { "labelGender": "Geschlecht", "selectGender": "Geschlecht auswählen...", diff --git a/src/Resources/snippet/en-GB/messages.en-GB.json b/src/Resources/snippet/en-GB/messages.en-GB.json index dd0beef..26644da 100644 --- a/src/Resources/snippet/en-GB/messages.en-GB.json +++ b/src/Resources/snippet/en-GB/messages.en-GB.json @@ -28,6 +28,16 @@ "agreementLabel": "I agree to the following mandate " }, + "missing-risk-check-information-modal": { + "title": "Missing information for Risk Checks", + "body1": "Your selected payment method, requires you to provide following information:", + "body2": "Please, go to your profile to update the information, or simply select a different payment method.", + "birthdate": "Date of Birth", + "gender": "Gender", + "close_button": "Close", + "action_button": "Go to profile" + }, + "register": { "labelGender": "Gender", "selectGender": "Select gender...", diff --git a/src/Resources/views/betterpayment/birthday-gender-fields.html.twig b/src/Resources/views/betterpayment/birthday-gender-fields.html.twig index 810467d..b37c67b 100644 --- a/src/Resources/views/betterpayment/birthday-gender-fields.html.twig +++ b/src/Resources/views/betterpayment/birthday-gender-fields.html.twig @@ -2,8 +2,7 @@
-

-

{{ 'betterpayment.general.requiredLabel' | trans }}*

\ No newline at end of file +

{{ 'betterpayment.general.requiredLabel' | trans }}*

+ +{% sw_include '@Storefront/betterpayment/missing-risk-check-information-modal.html.twig' %} \ No newline at end of file diff --git a/src/Util/BetterPaymentClient.php b/src/Util/BetterPaymentClient.php index 4bf50e6..bafbead 100644 --- a/src/Util/BetterPaymentClient.php +++ b/src/Util/BetterPaymentClient.php @@ -15,8 +15,9 @@ use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity; use Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct; use Shopware\Core\Checkout\Payment\Cart\SyncPaymentTransactionStruct; +use Shopware\Core\DevOps\Environment\EnvironmentHelper; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Plugin\PluginService; use Shopware\Core\Framework\Validation\DataBag\RequestDataBag; @@ -24,14 +25,14 @@ class BetterPaymentClient { private ConfigReader $configReader; private OrderParametersReader $orderParametersReader; - private EntityRepositoryInterface $orderTransactionRepository; + private EntityRepository $orderTransactionRepository; private PluginService $pluginService; private string $shopwareVersion; public function __construct( ConfigReader $configReader, OrderParametersReader $orderParametersReader, - EntityRepositoryInterface $orderTransactionRepository, + EntityRepository $orderTransactionRepository, PluginService $pluginService, string $shopwareVersion ){ @@ -89,7 +90,7 @@ private function getRequestParameters(SyncPaymentTransactionStruct $transaction, $requestParameters += [ 'payment_type' => $transaction->getOrderTransaction()->getPaymentMethod()->getCustomFields()['shortname'], 'risk_check_approval' => '1', - 'postback_url' => getenv('APP_URL').'/api/betterpayment/webhook', + 'postback_url' => $this->getWebhookUrl(), 'app_name' => 'Shopware 6', 'app_version' => 'SW ' . $this->shopwareVersion . ', Plugin ' . $this->pluginService->getPluginByName(BetterPayment::PLUGIN_NAME, Context::createDefaultContext())->getVersion(), ]; @@ -97,7 +98,7 @@ private function getRequestParameters(SyncPaymentTransactionStruct $transaction, if (get_class($transaction) == AsyncPaymentTransactionStruct::class) { $requestParameters += [ 'success_url' => $transaction->getReturnUrl(), - 'error_url' => getenv('APP_URL').'/account/order/edit/' .$transaction->getOrder()->getId() + 'error_url' => $this->getAppUrl().'/account/order/edit/' .$transaction->getOrder()->getId() .'?error-code=CHECKOUT__ASYNC_PAYMENT_PROCESS_INTERRUPTED', ]; } @@ -215,4 +216,17 @@ public function capture(array $parameters) { throw new RuntimeException('Better Payment Client ERROR: ' . $exception->getMessage()); } } + + public function getAppUrl(): string + { + return rtrim(EnvironmentHelper::getVariable('APP_URL'), '/'); + } + + public function getWebhookUrl(): string + { + $baseUrl = $this->getAppUrl(); + $path = '/api/betterpayment/webhook'; + + return $baseUrl.$path; + } } \ No newline at end of file diff --git a/src/Util/OrderParametersReader.php b/src/Util/OrderParametersReader.php index 634a16a..142ceea 100644 --- a/src/Util/OrderParametersReader.php +++ b/src/Util/OrderParametersReader.php @@ -9,7 +9,7 @@ use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Checkout\Payment\Cart\SyncPaymentTransactionStruct; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\System\Currency\CurrencyEntity; use Shopware\Core\System\Language\LanguageEntity; @@ -18,17 +18,17 @@ class OrderParametersReader { private SystemConfigService $systemConfigService; - private EntityRepositoryInterface $orderAddressRepository; - private EntityRepositoryInterface $customerAddressRepository; - private EntityRepositoryInterface $languageRepository; - private EntityRepositoryInterface $currencyRepository; + private EntityRepository $orderAddressRepository; + private EntityRepository $customerAddressRepository; + private EntityRepository $languageRepository; + private EntityRepository $currencyRepository; public function __construct( SystemConfigService $systemConfigService, - EntityRepositoryInterface $orderAddressRepository, - EntityRepositoryInterface $customerAddressRepository, - EntityRepositoryInterface $languageRepository, - EntityRepositoryInterface $currencyRepository + EntityRepository $orderAddressRepository, + EntityRepository $customerAddressRepository, + EntityRepository $languageRepository, + EntityRepository $currencyRepository ){ $this->systemConfigService = $systemConfigService; $this->orderAddressRepository = $orderAddressRepository; @@ -182,7 +182,7 @@ public function getCompanyDetailParameters(OrderEntity $order): array // Get VAT ID from billing address, and fallback to customer's VAT ID $vatId = $billingAddress->getVatId(); if (!$vatId) { - $vatId = $order->getOrderCustomer()->getVatIds()[0]; + $vatId = $order->getOrderCustomer()->getVatIds() ? $order->getOrderCustomer()->getVatIds()[0] : null; } return [ diff --git a/src/Util/PaymentStatusMapper.php b/src/Util/PaymentStatusMapper.php index 0d44351..d7f582e 100644 --- a/src/Util/PaymentStatusMapper.php +++ b/src/Util/PaymentStatusMapper.php @@ -8,7 +8,7 @@ use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler; use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStates; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; use Symfony\Component\HttpFoundation\Request; @@ -18,12 +18,12 @@ class PaymentStatusMapper { private OrderTransactionStateHandler $orderTransactionStateHandler; private BetterPaymentClient $betterPaymentClient; - private EntityRepositoryInterface $orderTransactionRepository; + private EntityRepository $orderTransactionRepository; public function __construct( OrderTransactionStateHandler $orderTransactionStateHandler, BetterPaymentClient $betterPaymentClient, - EntityRepositoryInterface $orderTransactionRepository + EntityRepository $orderTransactionRepository ){ $this->orderTransactionStateHandler = $orderTransactionStateHandler; $this->betterPaymentClient = $betterPaymentClient;