From dd74103003d5d1c3d4d8c2cec8539fdae7631370 Mon Sep 17 00:00:00 2001 From: Stefan Hagspiel Date: Tue, 9 Jun 2020 17:47:23 +0200 Subject: [PATCH 1/4] add additional configuration options, resolves #3 --- Api.php | 93 +++++++++++++++++++++++++++++++++++++++++++++++++------ README.md | 3 +- 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/Api.php b/Api.php index ae45ade..e0e50bd 100644 --- a/Api.php +++ b/Api.php @@ -42,6 +42,8 @@ class Api 'terminalId' => null, 'sandbox' => null, 'iframeCssUrl' => null, + 'interface' => null, + 'optionalParameters' => null, ); /** @@ -121,11 +123,7 @@ public function initTransaction(array $model): array 'ReturnUrls' => $model['ReturnUrls'], ]; - if (null !== $this->options['iframeCssUrl']) { - $payload['Styling'] = [ - 'CssUrl' => $this->options['iframeCssUrl'], - ]; - } + $payload = $this->addOptionalInterfaceParams(Constants::INTERFACE_TRANSACTION, $payload); $paymentMeans = $model['PaymentMeans'] ?? null; @@ -147,11 +145,7 @@ public function initPaymentPage(array $model): array 'ReturnUrls' => $model['ReturnUrls'], ]; - if (null !== $this->options['iframeCssUrl']) { - $payload['Styling'] = [ - 'CssUrl' => $this->options['iframeCssUrl'], - ]; - } + $payload = $this->addOptionalInterfaceParams(Constants::INTERFACE_PAYMENT_PAGE, $payload); $notification = $model['Notification'] ?? null; @@ -261,4 +255,83 @@ public function getCaptureStrategy() return Constants::INTERFACE_TRANSACTION; } + + protected function addOptionalInterfaceParams(string $interface, array $payload): array + { + $allowedOptions = [ + Constants::INTERFACE_PAYMENT_PAGE => [ + 'config_set', + 'payment_methods', + 'wallets', + 'notification_merchant_email', + 'notification_payer_email', + 'styling_css_url', + 'styling_content_security_enabled', + 'styling_theme', + ], + Constants::INTERFACE_TRANSACTION => [ + 'config_set', + 'payment_methods', + 'styling_css_url', // deprecated + 'styling_content_security_enabled', + 'styling_theme', + ] + ]; + + $optionalInterfaceOptions = $this->options['optionalParameters'] ?? []; + + // legacy + if (null !== $this->options['iframeCssUrl']) { + $optionalInterfaceOptions['styling_css_url'] = $this->options['iframeCssUrl']; + } + + foreach ($optionalInterfaceOptions as $optionName => $optionValue) { + + if (empty($optionValue)) { + continue; + } + + if (!in_array($optionName, $allowedOptions[$interface])) { + continue; + } + + switch($optionName) { + case 'config_set': + $payload['ConfigSet'] = (string) $optionValue; + break; + case 'payment_methods': + if (is_string($optionValue) && strpos($optionValue, ',') !== false) { + $optionValue = explode(',', $optionValue); + } + + $payload['PaymentMethods'] = (array) $optionValue; + break; + case 'wallets': + $payload['Wallets'] = explode(',', $optionValue); + break; + case 'notification_merchant_email': + $payload['Notification'] = $payload['Notification'] ?? []; + $payload['Notification']['MerchantEmails'] = explode(',', $optionValue); + break; + case 'notification_payer_email': + $payload['Notification'] = $payload['Notification'] ?? []; + $payload['Notification']['PayerEmail'] = (string) $optionValue; + break; + case 'styling_css_url': + $payload['Styling'] = $payload['Styling'] ?? []; + $payload['Styling']['CssUrl'] = $optionValue; + break; + case 'styling_content_security_enabled': + $payload['Styling'] = $payload['Styling'] ?? []; + $payload['Styling']['ContentSecurityEnabled'] = $optionValue; + break; + case 'styling_theme': + $payload['Styling'] = $payload['Styling'] ?? []; + $payload['Styling']['Theme'] = $optionValue; + break; + } + } + + return $payload; + } } diff --git a/README.md b/README.md index fa88a67..2df8c7a 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,9 @@ payum: customerId: '401860' terminalId: '17795278' interface: 'TRANSACTION' #optionally, can be defined via details too + optionalParameters: #optionally, add some additional interface options + styling_css_url: 'https://acme.com/hosted-page-styles.css' sandbox: true - iframeCssUrl: 'https://acme.com/hosted-page-styles.css' ``` ### With Payum From 36a8f3ca864dce42de786ba24ff86c3fab0ecbb3 Mon Sep 17 00:00:00 2001 From: Stefan Hagspiel Date: Wed, 10 Jun 2020 09:06:08 +0200 Subject: [PATCH 2/4] remove iframeCssUrl --- Api.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Api.php b/Api.php index e0e50bd..255781d 100644 --- a/Api.php +++ b/Api.php @@ -41,7 +41,6 @@ class Api 'customerId' => null, 'terminalId' => null, 'sandbox' => null, - 'iframeCssUrl' => null, 'interface' => null, 'optionalParameters' => null, ); @@ -280,11 +279,6 @@ protected function addOptionalInterfaceParams(string $interface, array $payload) $optionalInterfaceOptions = $this->options['optionalParameters'] ?? []; - // legacy - if (null !== $this->options['iframeCssUrl']) { - $optionalInterfaceOptions['styling_css_url'] = $this->options['iframeCssUrl']; - } - foreach ($optionalInterfaceOptions as $optionName => $optionValue) { if (empty($optionValue)) { From 8bbbcacec045d7ea50ac24d6de13604b4da0487a Mon Sep 17 00:00:00 2001 From: Stefan Hagspiel Date: Wed, 10 Jun 2020 09:07:24 +0200 Subject: [PATCH 3/4] simplify PaymentMethods --- Api.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Api.php b/Api.php index 255781d..1b02ce3 100644 --- a/Api.php +++ b/Api.php @@ -294,11 +294,7 @@ protected function addOptionalInterfaceParams(string $interface, array $payload) $payload['ConfigSet'] = (string) $optionValue; break; case 'payment_methods': - if (is_string($optionValue) && strpos($optionValue, ',') !== false) { - $optionValue = explode(',', $optionValue); - } - - $payload['PaymentMethods'] = (array) $optionValue; + $payload['PaymentMethods'] = explode(',', $optionValue); break; case 'wallets': $payload['Wallets'] = explode(',', $optionValue); From cac155cbd5a68df83f4782e9b0fd1abb2748f049 Mon Sep 17 00:00:00 2001 From: Stefan Hagspiel Date: Wed, 10 Jun 2020 09:27:32 +0200 Subject: [PATCH 4/4] udpate docs, add payer_note config --- Api.php | 5 +++++ README.md | 53 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/Api.php b/Api.php index 1b02ce3..063e9ea 100644 --- a/Api.php +++ b/Api.php @@ -267,6 +267,7 @@ protected function addOptionalInterfaceParams(string $interface, array $payload) 'styling_css_url', 'styling_content_security_enabled', 'styling_theme', + 'payer_note', ], Constants::INTERFACE_TRANSACTION => [ 'config_set', @@ -274,6 +275,7 @@ protected function addOptionalInterfaceParams(string $interface, array $payload) 'styling_css_url', // deprecated 'styling_content_security_enabled', 'styling_theme', + 'payer_note', ] ]; @@ -319,6 +321,9 @@ protected function addOptionalInterfaceParams(string $interface, array $payload) $payload['Styling'] = $payload['Styling'] ?? []; $payload['Styling']['Theme'] = $optionValue; break; + case 'payer_note': + $payload['PayerNote'] = $optionValue; + break; } } diff --git a/README.md b/README.md index 2df8c7a..46bf84d 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ All features are covered with tests. You can find useful examples in functional ## Installation ```bash -$ composer require trackmage/payum-saferpay +$ composer require karser/payum-saferpay ``` ## Configuration @@ -80,7 +80,7 @@ payum: customerId: '401860' terminalId: '17795278' interface: 'TRANSACTION' #optionally, can be defined via details too - optionalParameters: #optionally, add some additional interface options + optionalParameters: #optionally, add some additional interface options, read more below in section "Additional Configuration" styling_css_url: 'https://acme.com/hosted-page-styles.css' sandbox: true ``` @@ -88,7 +88,6 @@ payum: ### With Payum ```php -gateway->execute($captureRequest, true); ``` ```php -gateway->execute($status = new GetHumanStatus($payment)); ### Recurring Payments with the referenced transactions Method 1. Capture payment with Recurring or Installment option: - ```php use Karser\PayumSaferpay\Constants; - $payment = $storage->create(); $payment->setDetails(['Payment' => ['Recurring' => ['Initial' => true]]]); @@ -213,7 +207,6 @@ $captureRequest = new Capture($token); $captureRequest->setModel($payment); $reply = $this->gateway->execute($captureRequest, true); //then redirect user to $reply->getUrl(); - ``` 2. Capture a new transaction by providing a reference to the previous one: @@ -238,7 +231,6 @@ $this->gateway->execute($captureRequest); 1. Obtaining the Alias: The user will have to enter their card details in an iframe. - ```php use Karser\PayumSaferpay\Constants; use Karser\PayumSaferpay\Model\CardAlias; @@ -336,18 +328,53 @@ class ConvertPaymentExtension implements ExtensionInterface } ``` -## Testing +### Additional Configuration +Depending on given interface, there are several optional options available. + +Example: + +```yaml +payum: + gateways: + saferpay: + optionalParameters: + styling_css_url: 'https://acme.com/hosted-page-styles.css' +``` + +#### Payment Page interface +| Key | Description | +| --------------------------------------| ------------| +| `config_set` | This parameter let you define your payment page config (PPConfig) by name. If this parameters is not set, your default PPConfig will be applied if available. When the PPConfig can't be found (e.g. wrong name), the Saferpay basic style will be applied to the payment page. | +| `payment_methods` | Used to restrict the means of payment which are available to the payer for this transaction. If only one payment method id is set, the payment selection step will be skipped. | +| `wallets` | Used to control if wallets should be enabled on the payment selection page and to go directly to the given wallet (if exactly one wallet is filled and PaymentMethods is not set). | +| `notification_merchant_email` | Email addresses to which a confirmation email will be sent to the merchants after successful authorizations. | +| `notification_payer_email` | Email address to which a confirmation email will be sent to the payer after successful authorizations. | +| `styling_css_url` | Deprecated | +| `styling_content_security_enabled` | When enabled, then ContentSecurity/SAQ-A is requested, which leads to the CSS being loaded from the saferpay server. | +| `styling_theme` | This parameter let you customize the appearance of the displayed payment pages. Per default a lightweight responsive styling will be applied.If you don't want any styling use 'NONE'. | +| `payer_note` | Text which will be printed on payer's debit note. Supported by SIX Acquiring. No guarantee that it will show up on the payer's debit note, because his bank has to support it too. Please note that maximum allowed characters are rarely supported. It's usually around 10-12. | + +#### Transaction interface +| Key | Description | +| --------------------------------------| ------------| +| `config_set` | This parameter let you define your payment page config (PPConfig) by name. If this parameters is not set, your default PPConfig will be applied if available. When the PPConfig can't be found (e.g. wrong name), the Saferpay basic style will be applied to the payment page. | +| `payment_methods` | Used to restrict the means of payment which are available to the payer for this transaction. If only one payment method id is set, the payment selection step will be skipped. | +| `styling_css_url` | Deprecated | +| `styling_content_security_enabled` | When enabled, then ContentSecurity/SAQ-A is requested, which leads to the CSS being loaded from the saferpay server. | +| `styling_theme` | This parameter let you customize the appearance of the displayed payment pages. Per default a lightweight responsive styling will be applied. If you don't want any styling use 'NONE'. | +| `payer_note` | Text which will be printed on payer's debit note. Supported by SIX Acquiring. No guarantee that it will show up on the payer's debit note, because his bank has to support it too. Please note that maximum allowed characters are rarely supported. It's usually around 10-12. | + +## Testing ``` composer update vendor/bin/phpunit ``` - ## ToDo - Implement separate actions: Authorize, Cancel transaction - Improve and add more unit tests -- config parameters: LIABILITY_SHIFT condition, payer note +- config parameters: LIABILITY_SHIFT condition ## Credits - Dmitrii Poddubnyi