diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6b8448a..ebb0dd0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ stages: - setup - test + - deploy - package cache: @@ -64,6 +65,7 @@ sw-phpstan: - cd ${CI_PROJECT_DIR}/sw_dir/custom/plugins/${CI_PROJECT_NAME} && vendor/bin/phpstan analyse -c phpstan_sw.neon -a vendor/autoload.php -a ../../../vendor/autoload.php . shopware-validate: + allow_failure: true image: name: friendsofshopware/plugin-uploader:0.3.5 entrypoint: [ "/bin/sh", "-c" ] @@ -81,9 +83,34 @@ shopware-validate: - php /app/bin/pluginupload ext:zip . $CI_COMMIT_SHA - php /app/bin/pluginupload ext:validate *$CI_COMMIT_SHA.zip +staging: + image: "edbizarro/gitlab-ci-pipeline-php:7.2" + stage: deploy + environment: + name: staging + url: https://unzer-sw5.kellerkinder.io + only: + - master + before_script: + # Run ssh-agent (inside the build environment) + - eval $(ssh-agent -s) + + # Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store + - ssh-add <(echo "$SSH_PRIVATE_KEY") + + # For Docker builds disable host key checking. Be aware that by adding that + # you are suspectible to man-in-the-middle attacks. + # WARNING: Use this only with the Docker executor, if you use it with shell + # you will overwrite your user's SSH config. + - mkdir -p ~/.ssh + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' + script: + - ssh -A web-user@c-140.maxcluster.net 'cd /var/www/share/unzer-sw5.kellerkinder.io/htdocs/custom/plugins/HeidelPayment && git pull && /var/www/share/unzer-sw5.kellerkinder.io/htdocs/bin/console sw:cache:clear && /var/www/share/unzer-sw5.kellerkinder.io/htdocs/bin/console sw:plugin:refresh && /var/www/share/unzer-sw5.kellerkinder.io/htdocs/bin/console sw:plugin:uninstall HeidelPayment && /var/www/share/unzer-sw5.kellerkinder.io/htdocs/bin/console sw:plugin:install --activate HeidelPayment && /var/www/share/unzer-sw5.kellerkinder.io/htdocs/bin/console sw:theme:cache:generate' + package: image: kellerkinder/shopware-package-plugin:latest stage: package + needs: [] only: - tags - master diff --git a/Components/HeidelpayDebugHandler.php b/Components/HeidelpayDebugHandler.php new file mode 100644 index 0000000..76fcf1d --- /dev/null +++ b/Components/HeidelpayDebugHandler.php @@ -0,0 +1,24 @@ +logger = $logger; + } + + public function log(string $message): void + { + $this->logger->info($message); + } +} diff --git a/Components/Hydrator/ResourceHydrator/BasketHydrator.php b/Components/Hydrator/ResourceHydrator/BasketHydrator.php index 38bb8b2..0157c4c 100644 --- a/Components/Hydrator/ResourceHydrator/BasketHydrator.php +++ b/Components/Hydrator/ResourceHydrator/BasketHydrator.php @@ -13,6 +13,8 @@ class BasketHydrator implements ResourceHydratorInterface { + public const UNZER_DEFAULT_PRECISION = 4; + private const SW_VOUCHER_MODE = '2'; private const SW_DISCOUNT = '3'; private const SW_ABO_DISCOUNT_MODE = '10'; @@ -31,91 +33,99 @@ public function hydrateOrFetch( return $heidelpayObj->fetchBasket($resourceId); } - $isAmountInNet = isset($data['sAmountWithTax']); - $isTaxFree = $data['taxFree']; - $amountTotalGrossTransaction = $isAmountInNet && !$isTaxFree ? $data['sAmountWithTax'] : $data['sAmount']; + $isAmountInNet = isset($data['sAmountWithTax']); + $isTaxFree = $data['taxFree']; + $amountTotalGross = $isAmountInNet && !$isTaxFree ? $data['sAmountWithTax'] : $data['sAmount']; - $basketAmountTotalGross = 0; - $basketAmountTotalVat = 0; - $basketAmountTotalDiscount = 0; + $basket = new Basket( + $this->generateOrderId(), + round($amountTotalGross, self::UNZER_DEFAULT_PRECISION), + $data['sCurrencyName'] + ); - $result = new Basket(); - $result->setCurrencyCode($data['sCurrencyName']); - $result->setOrderId($this->generateOrderId()); + $basket->setAmountTotalVat(round($data['sAmountTax'], self::UNZER_DEFAULT_PRECISION)); - //Actual line items - foreach ($data['content'] as $lineItem) { - $amountNet = abs($lineItem['amountnetNumeric']); - $amountGross = $isAmountInNet ? abs($lineItem['amountWithTax']) : abs($lineItem['amountNumeric']); - $amountPerUnit = $isAmountInNet - ? $amountGross / $lineItem['quantity'] - : abs($lineItem['additional_details']['price_numeric']); + $this->hydrateBasketItems($basket, $data['content'], $isAmountInNet); + $this->hydrateDispatch($basket, $data); + $this->hydrateDiscount($basket); - if (!$amountPerUnit) { - $amountPerUnit = abs($lineItem['priceNumeric']); - } + return $basket; + } + protected function hydrateBasketItems(Basket $basket, array $lineItems, bool $isAmountInNet): void + { + foreach ($lineItems as $lineItem) { $basketItem = new BasketItem(); + $basketItem->setType($this->getBasketItemType($lineItem)); + $basketItem->setTitle($lineItem['articlename']); + $basketItem->setQuantity((int) $lineItem['quantity']); - if ($this->isBasketItemVoucher($lineItem)) { - $basketItem->setType($this->getBasketItemType($lineItem)); - $basketItem->setTitle($lineItem['articlename']); - $basketItem->setAmountDiscount(round($amountGross, 4)); - $basketItem->setQuantity((int) $lineItem['quantity']); + $amountGross = round(abs( + $isAmountInNet ? $lineItem['amountWithTax'] : $lineItem['amountNumeric'] + ), self::UNZER_DEFAULT_PRECISION); - $basketAmountTotalDiscount += $basketItem->getAmountDiscount(); + if ($this->isBasketItemVoucher($lineItem)) { + $basketItem->setAmountDiscount($amountGross); } else { - $basketItem->setType($this->getBasketItemType($lineItem)); - $basketItem->setTitle($lineItem['articlename']); - $basketItem->setAmountPerUnit(round($amountPerUnit, 4)); - $basketItem->setAmountGross(round($amountGross, 4)); - $basketItem->setAmountNet(round($amountNet, 4)); - $basketItem->setAmountVat(round(abs(str_replace(',', '.', $lineItem['tax'])), 4)); - $basketItem->setQuantity((int) $lineItem['quantity']); + $amountPerUnit = $isAmountInNet + ? $amountGross / $lineItem['quantity'] + : abs($lineItem['additional_details']['price_numeric']); + + if (!$amountPerUnit) { + $amountPerUnit = abs($lineItem['priceNumeric']); + } + + $basketItem->setAmountPerUnit(round($amountPerUnit, self::UNZER_DEFAULT_PRECISION)); + $basketItem->setAmountGross($amountGross); + $basketItem->setAmountNet(round(abs($lineItem['amountnetNumeric']), self::UNZER_DEFAULT_PRECISION)); + $basketItem->setAmountVat(round(abs(str_replace(',', '.', $lineItem['tax'])), self::UNZER_DEFAULT_PRECISION)); $basketItem->setVat((float) $lineItem['tax_rate']); - - $basketAmountTotalGross += $basketItem->getAmountGross(); - $basketAmountTotalVat += $basketItem->getAmountVat(); } - if ($lineItem['abo_attributes']['isAboArticle']) { - $result->setSpecialParams(array_merge($result->getSpecialParams(), ['isAbo' => true])); + if (array_key_exists('abo_attributes', $lineItem) && !empty($lineItem['abo_attributes']) + && array_key_exists('isAboArticle', $lineItem['abo_attributes']) && !empty($lineItem['abo_attributes']['isAboArticle'])) { + $basket->setSpecialParams(array_merge($basket->getSpecialParams(), ['isAbo' => true])); $basketItem->setSpecialParams([ 'aboCommerce' => $lineItem['aboCommerce'], ]); } - $result->addBasketItem($basketItem); + $basket->addBasketItem($basketItem); } + } - //No dispatch selected! - if (empty($data['sDispatch'])) { - return $result; + protected function hydrateDispatch(Basket $basket, array $data): void + { + if (!array_key_exists('sDispatch', $data) || empty($data['sDispatch'])) { + return; } //Shipping cost line item $dispatchBasketItem = new BasketItem(); $dispatchBasketItem->setType(BasketItemTypes::SHIPMENT); $dispatchBasketItem->setTitle($data['sDispatch']['name']); - $dispatchBasketItem->setAmountGross(round($data['sShippingcostsWithTax'], 4)); - $dispatchBasketItem->setAmountPerUnit(round($data['sShippingcostsWithTax'], 4)); - $dispatchBasketItem->setAmountNet(round($data['sShippingcostsNet'], 4)); - $dispatchBasketItem->setAmountVat(round($data['sShippingcostsWithTax'] - $data['sShippingcostsNet'], 4)); - $dispatchBasketItem->setQuantity(1); + $dispatchBasketItem->setAmountGross(round($data['sShippingcostsWithTax'], self::UNZER_DEFAULT_PRECISION)); + $dispatchBasketItem->setAmountPerUnit(round($data['sShippingcostsWithTax'], self::UNZER_DEFAULT_PRECISION)); + $dispatchBasketItem->setAmountNet(round($data['sShippingcostsNet'], self::UNZER_DEFAULT_PRECISION)); + $dispatchBasketItem->setAmountVat(round($data['sShippingcostsWithTax'] - $data['sShippingcostsNet'], self::UNZER_DEFAULT_PRECISION)); $dispatchBasketItem->setVat((float) $data['sShippingcostsTax']); + $dispatchBasketItem->setQuantity(1); - $result->addBasketItem($dispatchBasketItem); + $basket->addBasketItem($dispatchBasketItem); + } - $basketAmountTotalGross += $dispatchBasketItem->getAmountGross(); - $basketAmountTotalVat += $dispatchBasketItem->getAmountVat(); - $basketAmountTotalDiscount += $dispatchBasketItem->getAmountDiscount(); + protected function hydrateDiscount(Basket $basket): void + { + $calculatedDiscount = 0; - // setting of all totalAmounts - $result->setAmountTotalGross(round((float) $basketAmountTotalGross, 4)); - $result->setAmountTotalVat(round((float) $basketAmountTotalVat, 4)); - $result->setAmountTotalDiscount(round((float) $basketAmountTotalDiscount, 4)); + /** @var BasketItem $basketItem */ + foreach ($basket->getBasketItems() as $basketItem) { + if ((int) round($basketItem->getAmountDiscount(), self::UNZER_DEFAULT_PRECISION) !== 0) { + $calculatedDiscount += round($basketItem->getAmountDiscount(), self::UNZER_DEFAULT_PRECISION); + } + } - return $result; + $basket->setAmountTotalDiscount($calculatedDiscount); } private function generateOrderId(): string diff --git a/Components/Hydrator/ResourceHydrator/CustomerHydrator/AbstractCustomerHydrator.php b/Components/Hydrator/ResourceHydrator/CustomerHydrator/AbstractCustomerHydrator.php index bad0b4b..a2e65e3 100644 --- a/Components/Hydrator/ResourceHydrator/CustomerHydrator/AbstractCustomerHydrator.php +++ b/Components/Hydrator/ResourceHydrator/CustomerHydrator/AbstractCustomerHydrator.php @@ -10,6 +10,12 @@ abstract class AbstractCustomerHydrator { + /* + * This regex is used to remove any non whitespace, plus or number parts, + * while also removing occurrences of more than one whitespace at a time. + */ + public const PHONE_NUMBER_REGEX = '/([^0-9 +]|\s{2,})/'; + /** @var Connection */ protected $connection; diff --git a/Components/Hydrator/ResourceHydrator/CustomerHydrator/PrivateCustomerHydrator.php b/Components/Hydrator/ResourceHydrator/CustomerHydrator/PrivateCustomerHydrator.php index a074da6..89fc836 100644 --- a/Components/Hydrator/ResourceHydrator/CustomerHydrator/PrivateCustomerHydrator.php +++ b/Components/Hydrator/ResourceHydrator/CustomerHydrator/PrivateCustomerHydrator.php @@ -27,6 +27,8 @@ public function hydrateOrFetch( $shippingAddress = $data['shippingaddress']; $billingAddress = $data['billingaddress']; + $phoneNumber = \preg_replace(self::PHONE_NUMBER_REGEX, '', $billingAddress['phone']); + try { if ($heidelpayObj) { $result = $heidelpayObj->fetchCustomerByExtCustomerId($resourceId); @@ -43,7 +45,7 @@ public function hydrateOrFetch( $result->setEmail($user['email']); $result->setSalutation($this->getSalutation($billingAddress['salutation'])); $result->setCustomerId($user['customernumber']); - $result->setPhone($billingAddress['phone']); + $result->setPhone($phoneNumber); $result->setBillingAddress($this->getHeidelpayAddress($billingAddress)); $result->setShippingAddress($this->getHeidelpayAddress($shippingAddress)); diff --git a/Controllers/AbstractHeidelpayPaymentController.php b/Controllers/AbstractHeidelpayPaymentController.php index 4ba9c20..674bc96 100644 --- a/Controllers/AbstractHeidelpayPaymentController.php +++ b/Controllers/AbstractHeidelpayPaymentController.php @@ -183,7 +183,7 @@ public function recurring(): void } $heidelBasket = $this->getRecurringBasket($recurringData['order']); - $this->paymentDataStruct = new PaymentDataStruct($heidelBasket->getAmountTotalGross(), $recurringData['order']['currency'], $this->getChargeRecurringUrl()); + $this->paymentDataStruct = new PaymentDataStruct($this->getAmount(), $recurringData['order']['currency'], $this->getChargeRecurringUrl()); $this->paymentDataStruct->fromArray([ 'basket' => $heidelBasket, diff --git a/Controllers/Widgets/HeidelpayCreditCard.php b/Controllers/Widgets/HeidelpayCreditCard.php index 80fa1fb..069cc66 100644 --- a/Controllers/Widgets/HeidelpayCreditCard.php +++ b/Controllers/Widgets/HeidelpayCreditCard.php @@ -23,7 +23,7 @@ public function createPaymentAction(): void { parent::pay(); - if ($this->paymentDataStruct->isRecurring()) { + if (!$this->paymentType && $this->paymentDataStruct->isRecurring()) { $activateRecurring = false; try { @@ -41,9 +41,19 @@ public function createPaymentAction(): void return; } + + if ($this->recurring->getRedirectUrl() !== null) { + $this->view->assign('redirectUrl', $this->recurring->getRedirectUrl()); + + return; + } } - $this->handleNormalPayment(); + if ($this->paymentType && $this->paymentType->isRecurring()) { + $this->recurringFinishedAction(); + } else { + $this->handleNormalPayment(); + } } public function chargeRecurringPaymentAction(): void @@ -57,9 +67,8 @@ public function chargeRecurringPaymentAction(): void return; } - $this->handleNormalPayment(); - try { + $this->charge($this->paymentDataStruct->getReturnUrl()); $orderNumber = $this->createRecurringOrder(); } catch (HeidelpayApiException $ex) { $this->getApiLogger()->logException($ex->getMessage(), $ex); @@ -73,6 +82,47 @@ public function chargeRecurringPaymentAction(): void } } + protected function recurringFinishedAction(): void + { + try { + parent::pay(); + + if (!$this->paymentType) { + $session = $this->container->get('session'); + $paymentTypeId = $session->offsetGet('PaymentTypeId'); + $this->paymentType = $this->heidelpayClient->fetchPaymentType($paymentTypeId); + } + + if (!$this->paymentType->isRecurring()) { + $this->getApiLogger()->getPluginLogger()->warning('Recurring could not be activated for basket', [$this->paymentDataStruct->getBasket()->jsonSerialize()]); + $redirectUrl = $this->getHeidelpayErrorUrlFromSnippet('recurringError'); + } + + $bookingMode = $this->container->get('heidel_payment.services.config_reader')->get('credit_card_bookingmode'); + + if (in_array($bookingMode, [BookingMode::CHARGE, BookingMode::CHARGE_REGISTER])) { + $redirectUrl = $this->charge($this->paymentDataStruct->getReturnUrl()); + } elseif (in_array($bookingMode, [BookingMode::AUTHORIZE, BookingMode::AUTHORIZE_REGISTER])) { + $redirectUrl = $this->authorize($this->paymentDataStruct->getReturnUrl()); + } + + $this->saveToDeviceVault($bookingMode); + } catch (HeidelpayApiException $ex) { + $this->getApiLogger()->logException('Error while creating CreditCard recurring payment', $ex); + $redirectUrl = $this->getHeidelpayErrorUrl($ex->getClientMessage()); + } catch (RuntimeException $ex) { + $redirectUrl = $this->getHeidelpayErrorUrlFromSnippet('communicationError'); + } finally { + if (!$redirectUrl) { + $this->getApiLogger()->getPluginLogger()->warning('CreditCard is not chargeable for basket', [$this->paymentDataStruct->getBasket()->jsonSerialize()]); + + $redirectUrl = $this->getHeidelpayErrorUrlFromSnippet('communicationError'); + } + + $this->view->assign('redirectUrl', $redirectUrl); + } + } + private function handleNormalPayment(): void { $bookingMode = $this->container->get('heidel_payment.services.config_reader')->get('credit_card_bookingmode'); diff --git a/Controllers/Widgets/HeidelpayPaypal.php b/Controllers/Widgets/HeidelpayPaypal.php index 93b7300..1a08640 100644 --- a/Controllers/Widgets/HeidelpayPaypal.php +++ b/Controllers/Widgets/HeidelpayPaypal.php @@ -52,7 +52,35 @@ public function createPaymentAction(): void } } - public function recurringFinishedAction(): void + public function chargeRecurringPaymentAction(): void + { + parent::recurring(); + + if (!$this->paymentDataStruct) { + $this->getApiLogger()->getPluginLogger()->error('The payment data struct could not be created'); + $this->view->assign('success', false); + + return; + } + + try { + $this->charge($this->paymentDataStruct->getReturnUrl()); + $orderNumber = $this->createRecurringOrder(); + } catch (HeidelpayApiException $ex) { + $this->getApiLogger()->logException($ex->getMessage(), $ex); + } catch (RuntimeException $ex) { + $this->getApiLogger()->getPluginLogger()->error($ex->getMessage(), $ex); + } finally { + $this->view->assign([ + 'success' => !empty($orderNumber), + 'data' => [ + 'orderNumber' => $orderNumber ?: '', + ], + ]); + } + } + + protected function recurringFinishedAction(): void { try { parent::pay(); @@ -91,34 +119,6 @@ public function recurringFinishedAction(): void } } - public function chargeRecurringPaymentAction(): void - { - parent::recurring(); - - if (!$this->paymentDataStruct) { - $this->getApiLogger()->getPluginLogger()->error('The payment data struct could not be created'); - $this->view->assign('success', false); - - return; - } - - try { - $this->charge($this->paymentDataStruct->getReturnUrl()); - $orderNumber = $this->createRecurringOrder(); - } catch (HeidelpayApiException $ex) { - $this->getApiLogger()->logException($ex->getMessage(), $ex); - } catch (RuntimeException $ex) { - $this->getApiLogger()->getPluginLogger()->error($ex->getMessage(), $ex); - } finally { - $this->view->assign([ - 'success' => !empty($orderNumber), - 'data' => [ - 'orderNumber' => $orderNumber ?: '', - ], - ]); - } - } - private function handleRecurringPayment(): void { $redirectUrl = $this->paymentDataStruct->getReturnUrl(); diff --git a/Resources/frontend/js/jquery.heidelpay-base.js b/Resources/frontend/js/jquery.heidelpay-base.js index f408a4f..0b16eed 100644 --- a/Resources/frontend/js/jquery.heidelpay-base.js +++ b/Resources/frontend/js/jquery.heidelpay-base.js @@ -51,7 +51,7 @@ redirectToErrorPage: function (message) { var encodedMessage = encodeURIComponent(message); - window.location = `${this.opts.heidelpayErrorUrl}${encodedMessage}`; + window.location = this.opts.heidelpayErrorUrl + encodedMessage; }, setSubmitButtonActive: function (active) { @@ -117,11 +117,11 @@ return message; }, - getFormattedBirthday(htmlTarget) { + getFormattedBirthday: function (htmlTarget) { var datePickerPlugin = $(htmlTarget).data('plugin_swDatePicker'), flatpickr = null, currentValue = null, - formattedDate = null, + splitted = [], dateValue = null; if (!datePickerPlugin) { @@ -140,37 +140,27 @@ currentValue = $(datePickerPlugin.flatpickr._input).val(); } - dateValue = new Date(currentValue); + if (!currentValue.includes('.')) { + return null; + } - if (dateValue.toString() === 'Invalid Date') { - if (currentValue.includes('.')) { - var splitted = currentValue.split('.'); - - if (splitted.length === 3) { - dateValue = new Date(`${splitted[2]}-${splitted[1]}-${splitted[0]}`); - - if (dateValue.toString() !== 'Invalid Date') { - try { - formattedDate = flatpickr.formatDate(dateValue, datePickerPlugin.opts.dateFormat); - } catch (e) { - return null; - } - } - } - } - } else { - try { - formattedDate = flatpickr.formatDate(dateValue, datePickerPlugin.opts.dateFormat); - } catch (e) { - return null; - } + splitted = currentValue.split('.'); + + if (splitted.length !== 3) { + return null; } - if (new Date(formattedDate).toString() === 'Invalid Date') { + dateValue = new Date(splitted[2] + '-' + splitted[1] + '-' + splitted[0]); + + if (dateValue.toString() === 'Invalid Date') { return null; } - return formattedDate; + try { + return flatpickr.formatDate(dateValue, datePickerPlugin.opts.dateFormat); + } catch (e) { + return null; + } } }); diff --git a/Resources/frontend/js/jquery.heidelpay-credit-card.js b/Resources/frontend/js/jquery.heidelpay-credit-card.js index ef45fc4..e070a7a 100644 --- a/Resources/frontend/js/jquery.heidelpay-credit-card.js +++ b/Resources/frontend/js/jquery.heidelpay-credit-card.js @@ -103,7 +103,7 @@ setValidationError: function (type, message) { var $element = this.getEventElement(type), - $elementLabel = $(`#card-element-error-${type}-label`); + $elementLabel = $('#card-element-error-' + type + '-label'); if (message) { $elementLabel.removeClass(this.opts.elementHiddenClass); @@ -136,7 +136,7 @@ }, getEventElement: function (type) { - return $(`*[data-type="${type}"]`); + return $('*[data-type="' + type + '"]'); }, onFormChange: function (event) { diff --git a/Resources/frontend/js/jquery.heidelpay-hire-purchase.js b/Resources/frontend/js/jquery.heidelpay-hire-purchase.js index bfc61a6..4f2c843 100644 --- a/Resources/frontend/js/jquery.heidelpay-hire-purchase.js +++ b/Resources/frontend/js/jquery.heidelpay-hire-purchase.js @@ -51,7 +51,7 @@ amount: this.opts.basketAmount, currency: this.opts.currencyIso, effectiveInterest: this.opts.effectiveInterest - }).then(() => { + }).then(function() { $(me.opts.generatedBirthdayElementSelector).attr('required', 'required'); $(me.opts.generatedBirthdayElementSelector).attr('form', 'confirm--form'); }).catch(function() { diff --git a/Resources/frontend/js/jquery.heidelpay-invoice-factoring.js b/Resources/frontend/js/jquery.heidelpay-invoice-factoring.js index e30338b..0d4b509 100644 --- a/Resources/frontend/js/jquery.heidelpay-invoice-factoring.js +++ b/Resources/frontend/js/jquery.heidelpay-invoice-factoring.js @@ -104,7 +104,7 @@ var me = this, birthDate = this.heidelpayPlugin.getFormattedBirthday(this.opts.birthdayElementSelector); - if (!birthDate) { + if (!birthDate && !this.opts.isB2bCustomer) { me.onError({ message: me.heidelpayPlugin.opts.heidelpayBirthdayError }); return; diff --git a/Resources/frontend/js/jquery.heidelpay-invoice-guaranteed.js b/Resources/frontend/js/jquery.heidelpay-invoice-guaranteed.js index d4fb2cb..65c46ce 100644 --- a/Resources/frontend/js/jquery.heidelpay-invoice-guaranteed.js +++ b/Resources/frontend/js/jquery.heidelpay-invoice-guaranteed.js @@ -61,7 +61,7 @@ containerId: 'heidelpay--invoice-guaranteed-container' }); - $.publish('plugin/heidel_invoice_guaranteed/createB2bForm', [this, this.customerProvider]); + $.publish('plugin/heidelpay/invoice_guaranteed/createB2bForm', [this, this.customerProvider]); } }); }, @@ -71,7 +71,7 @@ $(this.opts.generatedBirthdayElementSelector).attr('form', 'confirm--form'); this.heidelpayPlugin.setSubmitButtonActive(true); - $.publish('plugin/heidel_invoice_guaranteed/createB2cForm', [this, this.customerProvider]); + $.publish('plugin/heidelpay/invoice_guaranteed/createB2cForm', [this, this.customerProvider]); }, registerEvents: function () { @@ -103,7 +103,7 @@ var me = this, birthDate = this.heidelpayPlugin.getFormattedBirthday(this.opts.birthdayElementSelector); - if (!birthDate) { + if (!birthDate && !this.opts.isB2bCustomer) { me.onError({ message: me.heidelpayPlugin.opts.heidelpayBirthdayError }); return; diff --git a/Resources/frontend/js/jquery.heidelpay-sepa-direct-debit-guaranteed.js b/Resources/frontend/js/jquery.heidelpay-sepa-direct-debit-guaranteed.js index db985ad..f6bc2cd 100644 --- a/Resources/frontend/js/jquery.heidelpay-sepa-direct-debit-guaranteed.js +++ b/Resources/frontend/js/jquery.heidelpay-sepa-direct-debit-guaranteed.js @@ -77,17 +77,13 @@ createPaymentFromVault: function (typeId) { var me = this, - birthDateTarget = `#${typeId}_birthDate`, + birthDateTarget = '#' + typeId + '_birthDate', birthDate = $(birthDateTarget).val(); - if ($(birthDateTarget).data('datepicker')) { - birthDate = this.heidelpayPlugin.getFormattedBirthday(birthDateTarget); - - if (!birthDate) { - me.onError({ message: me.heidelpayPlugin.opts.heidelpayBirthdayError }); + if (!birthDate) { + me.onError({ message: me.heidelpayPlugin.opts.heidelpayBirthdayError }); - return; - } + return; } $.ajax({ diff --git a/Resources/services.xml b/Resources/services.xml index 719ee3e..6c1c90e 100644 --- a/Resources/services.xml +++ b/Resources/services.xml @@ -2,11 +2,14 @@ - + + + Psr\Log\LogLevel::INFO + diff --git a/Resources/snippets/frontend/heidelpay/frames.ini b/Resources/snippets/frontend/heidelpay/frames.ini index 8f4ea3e..d8dda82 100644 --- a/Resources/snippets/frontend/heidelpay/frames.ini +++ b/Resources/snippets/frontend/heidelpay/frames.ini @@ -1,5 +1,5 @@ [en_GB] -label/birthday="Please enter your date of birth (in the following format: [YEAR-MONTH-DAY]):" +label/birthday="Please enter your date of birth (in the following format: [DAY.MONTH.YEAR]):" placeholder/birthday="Your Birthday" invalid/birthday="The specified birthday has an invalid format" diff --git a/Resources/views/frontend/heidelpay/frames/hire_purchase.tpl b/Resources/views/frontend/heidelpay/frames/hire_purchase.tpl index baebd0d..d058500 100644 --- a/Resources/views/frontend/heidelpay/frames/hire_purchase.tpl +++ b/Resources/views/frontend/heidelpay/frames/hire_purchase.tpl @@ -31,7 +31,9 @@ placeholder="{s name="placeholder/birthday" namespace="frontend/heidelpay/frames"}{/s}" {if $sUserData.additional.user.birthday !== ''}value="{$sUserData.additional.user.birthday}"{/if} data-datepicker="true" - data-allowInput="true"/> + data-allowInput="true" + data-dateFormat="d.m.Y" + data-altInput="false"/> {/block} {/block} diff --git a/Resources/views/frontend/heidelpay/frames/invoice_factoring.tpl b/Resources/views/frontend/heidelpay/frames/invoice_factoring.tpl index 0c4d2cc..da70b17 100644 --- a/Resources/views/frontend/heidelpay/frames/invoice_factoring.tpl +++ b/Resources/views/frontend/heidelpay/frames/invoice_factoring.tpl @@ -22,6 +22,7 @@ {if $sUserData.additional.user.birthday !== ''}value="{$sUserData.additional.user.birthday}"{/if} data-datepicker="true" data-allowInput="true" + data-dateFormat="d.m.Y" data-altInput="false"/> {/block} diff --git a/Resources/views/frontend/heidelpay/frames/invoice_guaranteed.tpl b/Resources/views/frontend/heidelpay/frames/invoice_guaranteed.tpl index 7b5b6e3..d430db9 100644 --- a/Resources/views/frontend/heidelpay/frames/invoice_guaranteed.tpl +++ b/Resources/views/frontend/heidelpay/frames/invoice_guaranteed.tpl @@ -22,6 +22,7 @@ {if $sUserData.additional.user.birthday !== ''}value="{$sUserData.additional.user.birthday}"{/if} data-datepicker="true" data-allowInput="true" + data-dateFormat="d.m.Y" data-altInput="false"/> {/block} diff --git a/Resources/views/frontend/heidelpay/frames/sepa_direct_debit_guaranteed.tpl b/Resources/views/frontend/heidelpay/frames/sepa_direct_debit_guaranteed.tpl index 4aa1b99..dce57fd 100644 --- a/Resources/views/frontend/heidelpay/frames/sepa_direct_debit_guaranteed.tpl +++ b/Resources/views/frontend/heidelpay/frames/sepa_direct_debit_guaranteed.tpl @@ -44,6 +44,7 @@ {if $sUserData.additional.user.birthday !== ''}value="{$sUserData.additional.user.birthday}"{/if} data-datepicker="true" data-allowInput="true" + data-dateFormat="d.m.Y" data-altInput="false"/> {/block} diff --git a/Resources/views/frontend/heidelpay/frames/vault/sepa_direct_debit.tpl b/Resources/views/frontend/heidelpay/frames/vault/sepa_direct_debit.tpl index b98af66..53c7927 100644 --- a/Resources/views/frontend/heidelpay/frames/vault/sepa_direct_debit.tpl +++ b/Resources/views/frontend/heidelpay/frames/vault/sepa_direct_debit.tpl @@ -33,6 +33,7 @@ {if $sUserData.additional.user.birthday !== ''}value="{$sUserData.additional.user.birthday}"{/if} data-datepicker="true" data-allowInput="true" + data-dateFormat="d.m.Y" data-altInput="false"/> {/if} {/block} diff --git a/Services/HeidelpayClient/HeidelpayClientService.php b/Services/HeidelpayClient/HeidelpayClientService.php index b09d3ff..9691242 100644 --- a/Services/HeidelpayClient/HeidelpayClientService.php +++ b/Services/HeidelpayClient/HeidelpayClientService.php @@ -4,6 +4,7 @@ namespace HeidelPayment\Services\HeidelpayClient; +use HeidelPayment\Components\HeidelpayDebugHandler; use HeidelPayment\Services\ConfigReader\ConfigReaderServiceInterface; use HeidelPayment\Services\HeidelpayApiLogger\HeidelpayApiLoggerServiceInterface; use heidelpayPHP\Heidelpay; @@ -44,7 +45,12 @@ public function getHeidelpayClient(): ?Heidelpay } try { - return new Heidelpay($this->getPrivateKey(), $locale); + $heidelpay = new Heidelpay($this->getPrivateKey(), $locale); + + $heidelpay->setDebugMode((bool) $this->configReaderService->get('extended_logging')); + $heidelpay->setDebugHandler((new HeidelpayDebugHandler($this->apiLoggerService->getPluginLogger()))); + + return $heidelpay; } catch (RuntimeException $ex) { $this->apiLoggerService->getPluginLogger()->error(sprintf('Could not initialize Heidelpay client due to the following error: %s', $ex->getMessage())); } diff --git a/composer.json b/composer.json index ae06f3e..a50749f 100644 --- a/composer.json +++ b/composer.json @@ -10,9 +10,9 @@ "homepage": "https://www.heidelpay.com/de/support/" }, { - "name": "Kellerkinder / Pluginwerk GmbH", - "email": "hallo@pluginwerk.de", - "homepage": "https://www.pluginwerk.de", + "name": "Kellerkinder GmbH", + "email": "hallo@kellerkinder.de", + "homepage": "https://www.kellerkinder.de", "role": "Contributor" } ], diff --git a/package-lock.json b/package-lock.json index 1510fad..778480c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -910,9 +910,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "mimic-fn": { diff --git a/phpstan.neon b/phpstan.neon index 89a6ade..9e1749d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -7,3 +7,4 @@ parameters: excludes_analyse: - Controllers - vendor + - node_modules diff --git a/plugin.xml b/plugin.xml index 4687faa..e3efbba 100644 --- a/plugin.xml +++ b/plugin.xml @@ -4,23 +4,148 @@ - 1.2.1 + 1.2.2 heidelpay GmbH MIT - heidelpay GmbH, Kellerkinder Pluginwerk GmbH + heidelpay GmbH, Kellerkinder GmbH https://www.heidelpay.com Produktinformationen "heidelpay - Payment Plugin für ab 5.6 Zahlungen per Kreditkarte, Rechnungskauf, SOFORT, ..."

Die Omnichannel Payment Solution: Vollständige Zahlungsabwicklung und –management mit heidelpay.

Die Installationsanleitung  finden Sie im Online-Handbuch


Verfügbare Zahlarten: 


Speicherung für Bezahldaten bei Zahlungsarten:


Weitere Features

+

Produktinformationen "heidelpay - Payment Plugin für ab 5.6 Zahlungen per Kreditkarte, Rechnungskauf, SOFORT, ..."

+

Die Omnichannel Payment Solution: Vollständige Zahlungsabwicklung und –management mit heidelpay.

+

Die Installationsanleitung  finden Sie im Online-Handbuch

+
+

Verfügbare Zahlarten: 

+
+ +

+

Speicherung für Bezahldaten bei Zahlungsarten:

+
+ +

+

Weitere Features

+
+ ]]>
Productinformation "heidelpay - payment plugin for 5.6 for  credit cards, direct debit, prepayment, PayPal, SOFORT and more…"

You can find the manual at https://dev.heidelpay.de/handbuch-shopware-ab-5-6/


Available payment methods


Feature List:


Registration of payment data for following payment methods:


Additional features:

+

Productinformation "heidelpay - payment plugin for 5.6 for  credit cards, direct debit, prepayment, PayPal, SOFORT and more…"

You can find the manual at https://dev.heidelpay.de/handbuch-shopware-ab-5-6/


Available payment methods


+

+

Feature List:

+
+

Registration of payment data for following payment methods:

+
+ +

+

Additional features:

+
+ ]]>
+ + + +
  • Format der Geburtstagsangabe im Checkout wurde vereinheitlicht
  • +
  • Das erweiterte Logging wurde verbessert und erweitert.
  • +
  • Korrektur eines Fehlers für wiederkehrende Kreditkarten Zahlung in Verbindung mit SwagAboCommerce
  • +
  • Korrektur der Validierung des Geburtsdatums für FlexiPay Rechnung für B2B
  • +
  • Korrektur der Warenkorb Verarbeitung
  • +
  • Korrektur eines Fehlers für FlexiPay Lastschrift (gesichert) für gespeicherte Lastschriftkonten
  • + + ]]> +
    + + +
  • Birthday input format in the checkout got standardized
  • +
  • The extended logging was improved
  • +
  • Fixed an error of credit card payments in combination with AboCommerce orders
  • +
  • Fixed the validation of the birthdate for FlexiPay invoice for B2B
  • +
  • Fixed the shopping cart hydration
  • +
  • Fixed an error with FlexiPay Direct Debit (secured) for saved bank accounts
  • + + ]]> +
    +