diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7b9ce5d..8cbb64c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,8 +3,6 @@ name: Tests on: [push, pull_request] env: - DEFAULT_COMPOSER_FLAGS: "--prefer-dist --no-interaction" - PHPUNIT_EXCLUDE_GROUP: mssql,oci,wincache,xcache,zenddata,cubrid CC_TEST_REPORTER_ID: a9ab6de7fbc8f532a9f829091d3994223dfbef5542c42f5c6d5e3ec877eebc74 jobs: phpunit: @@ -14,34 +12,34 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - php: ['7.0', '7.1', '7.2', '7.3', '7.4'] + php: ['8.0', '8.1', '8.2', '8.3'] steps: ## checkout the repoistory - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 ## Install(?) php - name: Install PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - extensions: apc, curl, dom, imagick, intl, mbstring, mcrypt, memcached, mysql, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, pgsql, sqlite - ini-values: date.timezone='UTC' + extensions: curl, dom, intl, mbstring, mcrypt, mysql, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, sqlite + ini-values: date.timezone='UTC',error_reporting=E_ALL,display_errors=On ## install composer - name: Install dependencies - run: composer install $DEFAULT_COMPOSER_FLAGS + run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader ## run unit tests - name: PHP Unit tests for PHP run: vendor/bin/phpunit --verbose --configuration actions.phpunit.xml - if: matrix.php == '8.0' || matrix.php == '7.4' || matrix.php == '7.3' || matrix.php == '7.2' || matrix.php == '7.0' + if: matrix.php == '8.3' || matrix.php == '8.2' || matrix.php == '8.1' ## unit test with coverage - - name: PHP Unit tests for PHP 7.1 + - name: PHP Unit tests for PHP 8.0 run: vendor/bin/phpunit --verbose --coverage-clover=clover.xml --configuration actions.phpunit.xml - if: matrix.php == '7.1' + if: matrix.php == '8.0' ## coverage - name: Code coverage @@ -49,5 +47,5 @@ jobs: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter chmod +x ./cc-test-reporter ./cc-test-reporter after-build -t clover - if: matrix.php == '7.1' + if: matrix.php == '8.0' continue-on-error: true # if is fork \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9fe499f..ad232d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ /.buildpath /vendor/ /luya -composer.lock \ No newline at end of file +composer.lock +.tmp \ No newline at end of file diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache new file mode 100644 index 0000000..2f62b79 --- /dev/null +++ b/.php-cs-fixer.cache @@ -0,0 +1 @@ +{"php":"8.2.10","version":"3.26.1:v3.26.1#d023ba6684055f6ea1da1352d8a02baca0426983","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_typehint":true,"curly_braces_position":{"allow_single_line_empty_anonymous_classes":true},"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"sort_algorithm":"alpha"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"no_unused_imports":true},"hashes":{"src\/frontend\/messages\/it\/paymentfrontend.php":"8092a0a280e1e2e22b4dbd47ad907a51","src\/frontend\/messages\/en\/paymentfrontend.php":"d0b1777a2bbc98a0619f28a3d61915f1","src\/frontend\/messages\/de\/paymentfrontend.php":"d7a51433497f10f7f9edfc7336fd27c0","src\/frontend\/Module.php":"03530bc8303b9703e41cb6e2234c86fe","src\/frontend\/controllers\/DefaultController.php":"c3b878232e3b1b2aecc9f02a27652e61","src\/frontend\/controllers\/TestController.php":"52c4ebfdee18956dd4143b9b8fdf6307","src\/frontend\/stripe\/transaction.php":"efd3d97d7ddd78c133985331f23961d0","src\/frontend\/stripe\/layout.php":"acc021c792dd074265c91f5057a406a7","src\/Pay.php":"b5f2304c91cd8fa6cb1982d0c9d50c22","src\/models\/ProcessTrace.php":"b6805c9563e3309d12bc510474c076f4","src\/models\/ProcessItem.php":"46640258dba57f2e0b494889496a27df","src\/models\/Process.php":"f26462488556e1110b1cc5940537cd19","src\/PaymentException.php":"452ee7284cad4c39d89266fb4f95eb88","src\/providers\/SaferPayProvider.php":"0a7ed583b3f625b1b73d87aa09e8169f","src\/providers\/PayPalProvider.php":"1c166cae0fb56d91c5190044ea2e6480","src\/providers\/SaferPayLegacyProvider.php":"c430644229fb84fd0315420df488be15","src\/providers\/StripeProvider.php":"8febe1325997d67f53a42067ab9ad935","src\/helpers\/OrderHelper.php":"7607a0013357ecb2edee13695d41048a","src\/integrators\/DatabaseIntegrator.php":"cda377ffeeecc8941f3c9d2d5eb69947","src\/integrators\/HeadlessIntegrator.php":"1d527a17e2d372452d96d0a3b7da2cd3","src\/integrators\/headless\/ApiPaymentProcessTrace.php":"d50dd7f162b519aafeb3001dee3d26cb","src\/integrators\/headless\/ApiPaymentProcess.php":"d4540e885a61e3cf6b9dd9c727911439","src\/base\/ProviderInterface.php":"e81a8ab818df382b773923a1c0492080","src\/base\/PayItemModel.php":"7bc1840512d9538cc19cc9925b5529b7","src\/base\/IntegratorInterface.php":"d5ae361af2cc47ec1f5a55b9aa2fac6f","src\/base\/Transaction.php":"2c58c2ac43555a3475238621c4b5cfb6","src\/base\/Provider.php":"26bf694a9df53507078123c07b033864","src\/base\/PayModel.php":"0fd0ccdd88ec8435b558aa3f8f41e58d","src\/base\/OrderInterface.php":"a5672c1ca5796fd218e1a1e053636726","src\/widgets\/SubmitFormButtonWidget.php":"cf050a62be739bb44b8a77c0c70432a4","src\/transactions\/SaferPayTransaction.php":"ed6316686c033346cf6a6b563bc75785","src\/transactions\/PayPalTransaction.php":"f696c230f17b23a85bbc041f6d92eb88","src\/transactions\/SaferPayLegacyTransaction.php":"3b902f7acc67fcb50bff4047336b7fd6","src\/transactions\/StripeTransaction.php":"a5b9d7908aa8268acf9f152f36c7ad93","src\/admin\/Module.php":"973c4df3e4d59cb41c9427a69ee3f517","src\/admin\/apis\/ProcessItemController.php":"489069a50e2d18a3e92e73383c497183","src\/admin\/apis\/ProcessController.php":"f88ba4cbf35d2132bc19ce63506abcfc","src\/admin\/apis\/ProcessTraceController.php":"9b1ad622c0c9ed2df228c544c18bce37","src\/admin\/controllers\/ProcessItemController.php":"49adb30bfb300965582161a42894aaf1","src\/admin\/controllers\/ProcessController.php":"132c21c553c92deb0be9d7181bc95dae","src\/admin\/controllers\/ProcessTraceController.php":"defeed5d6671002a78ab94a51d743097","src\/admin\/migrations\/m181010_091426_order_fields_process_timestamp.php":"c8aaeda4704c0e2ed03303daae28996d","src\/admin\/migrations\/m181015_091426_order_state.php":"418b84a8aade7ff2bbb1bd45d294da82","src\/admin\/migrations\/m160303_090454_paymentprocess.php":"4026abbb550535b05e7f00aeb71a2526","src\/admin\/migrations\/m201405_101926_provider_infos.php":"8e2c172a2e254e197e44d4278de0108a","src\/admin\/migrations\/m180425_193943_drop_process_fields.php":"8e492968ba4c8b827252b1379a586a9f","tests\/src\/providers\/StripeProviderTest.php":"9e34dbecb8872a5782f661c1126d06bd","tests\/src\/providers\/SaferPayProviderTest.php":"00022b2033757a89f46953d552e238f4","tests\/src\/PayTest.php":"8ab1211743663fc566ad01e65b421954","tests\/src\/helpers\/OrderHelperTest.php":"513988bfe8290d6e53ddae238ae6f6ce","tests\/src\/integrators\/HeadlessIntegratorTest.php":"cce124780ba9dbe2d6f25c7168824276","tests\/src\/integrators\/DatabaseIntegratorTest.php":"e3276ef88bf5ece7d815633de48a585a","tests\/src\/PaymentProcessTest.php":"f7df5b2494a588f956bfebb0d65a5e81","tests\/src\/transaction\/GenericTransactionTest.php":"4ceb1e9eef1eb8998945621fc1a381b7","tests\/src\/transaction\/PayPalTransactionTest.php":"48801107cfffa954ad4017bdedb24b40","tests\/src\/transaction\/SaferPayTransactionTest.php":"38471ca10d73dcae368e23ccc7325ad8","tests\/src\/transaction\/SaferPayLegacyTransactionTest.php":"ffc9882a0f48825212a09266ede51141","tests\/src\/transaction\/StripeTransactionTest.php":"f84c27e95fed911012326b59c7332098","tests\/src\/controllers\/DefaultControllerTest.php":"3fd12440a4890140d4f5ca373b127c5f","tests\/src\/GenericTest.php":"8a02240924aecf2aeed7a968b878d8ed","tests\/src\/widgets\/SubmitFormButtonWidgetTest.php":"9bc69c33721773dd402e018145dc244f","tests\/data\/DummyIntegrator.php":"76dc65091dbffc176d075bae3aed7cd6","tests\/data\/DummyTransaction.php":"8b569a2bfe7ff3b51a8144b17c095096","tests\/data\/DummyProvider.php":"68ab873a578bcfafe625f7c1f6793f66","tests\/BasePaymentTestCase.php":"e5bcb33b708806e0ea6ee5d399c8308b"}} \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..17d118e --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,15 @@ +in(__DIR__) +; + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + '@PSR12' => true, + 'array_syntax' => ['syntax' => 'short'], + 'ordered_imports' => ['sort_algorithm' => 'alpha'], + 'no_unused_imports' => true, + ]) + ->setFinder($finder) +; \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dcb999..220d78d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). In order to read more about upgrading and BC breaks have a look at the [UPGRADE Document](UPGRADE.md). +## 4.0.0 (13. Septmeber 2023) + ++ [#28](https://github.com/luyadev/luya-module-payment/pull/28) Removed PayPal support from built in providers due to not upgraded composer SDK. ++ [#28](https://github.com/luyadev/luya-module-payment/pull/28) Removed SaferPayLegacy Provider ++ [#28](https://github.com/luyadev/luya-module-payment/pull/28) Dropped support for PHP 7.x versions + ## 3.0.4 (8. February 2022) + Upgrade stripe php sdk to allow php 8 compatibility diff --git a/README.md b/README.md index c2dfc3f..3d5f1a1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ Its even possible to define an `integrator` which allows you to add the module c Currently supported payment providers: -+ [paypal.com](https://paypal.com) + [saferpay.com](https://www.saferpay.com) + [stripe.com](https://stripe.com) diff --git a/UPGRADE.md b/UPGRADE.md index 79bff66..40a3752 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,11 @@ # Upgrade +## 3.x to 4.0 + ++ Removed the `SaferPayLegacy` provider, no replacment. ++ Removed `PayPal` provider, no replacment. ++ Dropped support for PHP 7.x versions + ## 2.x to 3.0 + [#22](https://github.com/luyadev/luya-module-payment/pull/22) The SaferPay Transaction has been replaced with the new JSON API and therefore the old HTTPS interface SaferPay Transaction class has been renamed to `SaferPayLegacyTransaction` while the new `SaferPayTransaction` contains the new code to work with the JSON API. Therefore the class parameters which are required has been changed. The new configuration looks as followed: diff --git a/composer.json b/composer.json index e8e6068..161c927 100644 --- a/composer.json +++ b/composer.json @@ -1,39 +1,56 @@ { - "name" : "luyadev/luya-module-payment", - "description" : "LUYA Payment allows you to integrate payments in a safe and fast way. The module take care of all the provider required steps (call, create, success, abort, etc.) and provides all the informations for your store.", - "type" : "luya-module", - "keywords" : ["php", "luya", "module", "yii2", "payment", "estore", "saferpay", "paypal", "luya-module", "stripe"], + "name": "luyadev/luya-module-payment", + "description": "LUYA Payment allows you to integrate payments in a safe and fast way. The module take care of all the provider required steps (call, create, success, abort, etc.) and provides all the informations for your store.", + "type": "luya-module", + "keywords": [ + "php", + "luya", + "module", + "yii2", + "payment", + "estore", + "saferpay", + "luya-module", + "stripe" + ], "license": "MIT", - "homepage" : "https://luya.io", - "authors" : [ + "homepage": "https://luya.io", + "authors": [ { - "name" : "Basil", - "email" : "git@nadar.io", - "homepage" : "https://github.com/nadar" + "name": "Basil", + "email": "git@nadar.io", + "homepage": "https://github.com/nadar" } ], - "support" : { - "issues" : "https://github.com/luyadev/luya-module-payment/issues" + "support": { + "issues": "https://github.com/luyadev/luya-module-payment/issues" }, - "require" : { - "luyadev/luya-module-admin" : ">=2.0", - "luyadev/luya-headless" : "*", - "stripe/stripe-php": "^7.1", - "paypal/rest-api-sdk-php" : "^1.0" + "require": { + "php": ">=8.0", + "luyadev/luya-module-admin": "^4.9.1", + "luyadev/luya-headless": "^2.10.1", + "stripe/stripe-php": "^7.1" }, - "require-dev" : { - "unglue/client" : "^1.0", - "luyadev/luya-testsuite" : "^2.0" + "require-dev": { + "unglue/client": "^1.0", + "luyadev/luya-testsuite": "^3.0", + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^1.7", + "rector/rector": "^0.14.2" }, - "autoload" : { - "psr-4" : { - "luya\\payment\\" : "src/", - "luya\\payment\\tests\\" : "tests/" + "autoload": { + "psr-4": { + "luya\\payment\\": "src/", + "luya\\payment\\tests\\": "tests/" } }, "config": { - "fxp-asset": { - "enabled": false + "platform": { + "php": "8.0" + }, + "allow-plugins": { + "yiisoft/yii2-composer": true, + "luyadev/luya-composer": true } }, "repositories": [ @@ -41,5 +58,10 @@ "type": "composer", "url": "https://asset-packagist.org" } - ] -} + ], + "scripts": { + "phpstan": "vendor/bin/phpstan -v", + "phpcsfixer": "vendor/bin/php-cs-fixer fix", + "rector": "vendor/bin/rector" + } +} \ No newline at end of file diff --git a/guide/providers.md b/guide/providers.md index b49a470..5e02739 100644 --- a/guide/providers.md +++ b/guide/providers.md @@ -26,25 +26,6 @@ The [Stripe](https://stripe.com) transaction integration config: [See all cards](https://stripe.com/docs/testing#regulatory-cards) -## PayPal Transaction - -The [PayPal](https://paypal.com) transaction integration config: - -```php -'payment' => [ - 'class' => 'luya\payment\frontend\Module', - 'transaction' => [ - 'class' => 'luya\payment\transactions\PayPalTransaction', - 'clientId' => '', - 'clientSecret' => '', - ] -] -``` - -+ `clientId`: The client id from the paypal website. -+ `clientSecret`: The client secret from the paypal website. -+ `mode`: The mode `live` or `sandbox` values are available. - ## SaferPay Transaction The [SaferPay](https://saferpay.com) transaction API integration config: diff --git a/guide/setup.md b/guide/setup.md index fc8f54b..9233ea0 100644 --- a/guide/setup.md +++ b/guide/setup.md @@ -18,12 +18,6 @@ Configure the payment module in your config with the transaction payment provide 'payment' => [ 'class' => 'luya\payment\frontend\Module', 'transaction' => [ - // Paypal Example - // 'class' => 'luya\payment\transactions\PayPalTransaction', - // 'clientId' => 'ClientIdFromPayPalApplication', - // 'clientSecret' => 'ClientSecretFromPayPalApplication', - // 'productDescription' => 'MyOnlineStore Order', - // SaferPay Example // 'terminalId' => '12345678', // 'customerId' => '123456', diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..ce8aee7 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + level: 0 + paths: + - src + bootstrapFiles: + - vendor/yiisoft/yii2/Yii.php + tmpDir: .tmp \ No newline at end of file diff --git a/src/Pay.php b/src/Pay.php index 6864285..8e40567 100644 --- a/src/Pay.php +++ b/src/Pay.php @@ -2,13 +2,11 @@ namespace luya\payment; -use Yii; use luya\helpers\Url; -use luya\web\Controller; -use luya\payment\frontend\Module; +use luya\payment\base\PayItemModel; use luya\payment\base\PayModel; -use luya\payment\models\ProcessItem; -use luya\payment\base\PayItemModel;// Rename to PayArticle? +use luya\payment\frontend\Module; +use luya\web\Controller;// Rename to PayArticle? use yii\base\InvalidConfigException; /** @@ -19,13 +17,13 @@ */ class Pay { - const STATE_PENDING = 0; + public const STATE_PENDING = 0; + + public const STATE_SUCCESS = 1; + + public const STATE_ERROR = 2; - const STATE_SUCCESS = 1; - - const STATE_ERROR = 2; - - const STATE_ABORT = 3; + public const STATE_ABORT = 3; private $_totalAmount; @@ -53,7 +51,7 @@ public function setCurrency($currency) if (strlen($currency) !== 3) { throw new InvalidConfigException("The currency must be a 3-letter ISO 4217 code."); } - + $this->_currency = $currency; } @@ -204,7 +202,7 @@ public function getAuthToken() { return $this->getCreateModel()->getAuthToken(); } - + /** * Dispatch the current controller to the getTransactionGatewayCreat link. * @@ -214,7 +212,7 @@ public function getAuthToken() public function dispatch(Controller $controller) { $url = $this->getCreateModel()->getTransactionGatewayCreateLink(); - + return $controller->redirect($url); } diff --git a/src/admin/Module.php b/src/admin/Module.php index bab5df9..ee16277 100644 --- a/src/admin/Module.php +++ b/src/admin/Module.php @@ -16,7 +16,7 @@ class Module extends \luya\admin\base\Module 'api-payment-processitem' => 'luya\payment\admin\apis\ProcessItemController', ]; - + public function getMenu() { return (new \luya\admin\components\AdminMenuBuilder($this)) diff --git a/src/admin/migrations/m160303_090454_paymentprocess.php b/src/admin/migrations/m160303_090454_paymentprocess.php index 31aae4e..f73630c 100644 --- a/src/admin/migrations/m160303_090454_paymentprocess.php +++ b/src/admin/migrations/m160303_090454_paymentprocess.php @@ -22,7 +22,7 @@ public function safeUp() 'close_state' => $this->integer(11)->defaultValue(0), 'is_closed' => $this->boolean()->defaultValue(false), ]); - + $this->createTable('payment_process_trace', [ 'id' => $this->primaryKey(), 'process_id' => $this->integer(11)->notNull(), diff --git a/src/base/IntegratorInterface.php b/src/base/IntegratorInterface.php index a5338bb..0a78f05 100644 --- a/src/base/IntegratorInterface.php +++ b/src/base/IntegratorInterface.php @@ -2,8 +2,6 @@ namespace luya\payment\base; -use luya\web\Controller; - /** * Integrator Interface. * @@ -86,5 +84,5 @@ public function saveProviderData(PayModel $model, array $data); * @return array * @since 3.0.0 */ - public function getProviderData(PayModel $model) : array; + public function getProviderData(PayModel $model): array; } diff --git a/src/base/PayItemModel.php b/src/base/PayItemModel.php index d7e07ab..f77f26d 100644 --- a/src/base/PayItemModel.php +++ b/src/base/PayItemModel.php @@ -1,6 +1,5 @@ isClosed; } - + /** * Is closed and successfull. * @@ -147,7 +147,7 @@ public function getShippingItems() $items[] = $i; } } - + return $items; } @@ -272,7 +272,7 @@ public function getTransactionGatewayCreateLink() { return Url::toInternal(['/payment/default/create', 'lpToken' => $this->getAuthToken(), 'lpKey' => $this->randomKey, 'time' => microtime(true)], true); } - + /** * Get the Payment Gateway Back link. * @@ -284,7 +284,7 @@ public function getTransactionGatewayBackLink() { return Url::toInternal(['/payment/default/back', 'lpToken' => $this->getAuthToken(), 'lpKey' => $this->randomKey, 'time' => microtime(true)], true); } - + /** * Get the Payment Gateway Fail link. * @@ -296,7 +296,7 @@ public function getTransactionGatewayFailLink() { return Url::toInternal(['/payment/default/fail', 'lpToken' => $this->getAuthToken(), 'lpKey' => $this->randomKey, 'time' => microtime(true)], true); } - + /** * Get the Payment Gateway Abort link. * @@ -308,7 +308,7 @@ public function getTransactionGatewayAbortLink() { return Url::toInternal(['/payment/default/abort', 'lpToken' => $this->getAuthToken(), 'lpKey' => $this->randomKey, 'time' => microtime(true)], true); } - + /** * Get the Payment Gateway Notify link. * diff --git a/src/base/Provider.php b/src/base/Provider.php index f1c90f1..23d2026 100644 --- a/src/base/Provider.php +++ b/src/base/Provider.php @@ -3,8 +3,8 @@ namespace luya\payment\base; use luya\helpers\ObjectHelper; -use yii\helpers\Inflector; use yii\base\BaseObject; +use yii\helpers\Inflector; /** * Payment Provider Abstraction. diff --git a/src/base/ProviderInterface.php b/src/base/ProviderInterface.php index 38f96ad..6679bd7 100644 --- a/src/base/ProviderInterface.php +++ b/src/base/ProviderInterface.php @@ -18,7 +18,6 @@ interface ProviderInterface * An unique identifier for this provider, examples: * * + strip - * + paypal * + saferpay * * @return void diff --git a/src/base/Transaction.php b/src/base/Transaction.php index 21619c2..8344114 100644 --- a/src/base/Transaction.php +++ b/src/base/Transaction.php @@ -3,10 +3,10 @@ namespace luya\payment\base; use Curl\Curl; -use yii\web\Controller; -use yii\base\BaseObject; use luya\payment\Pay; use luya\payment\PaymentException; +use yii\base\BaseObject; +use yii\web\Controller; /** * Transaction Abstraction. @@ -26,14 +26,14 @@ abstract class Transaction extends BaseObject * Creates the transaction and mostly redirects to the provider afterwards. */ abstract public function create(); - + /** * The method which is triggered when coming "back from the provider". In generall this is also success. * * Commonly call `$this->redirectApplicationSuccess()` now. */ abstract public function back(); - + /** * Some providers provide a notify link. The notify method will be called from the payment provider in the * background. In generall we want to ensure the payment is closed here. @@ -42,14 +42,14 @@ abstract public function back(); * this triggers an email) `$this-curlApplicationLink($this->getModel()->getApplicationSuccessLink())`. */ abstract public function notify(); - + /** * Redirect back to the application failure/error page * * `$this->redirectTransactionFail()` */ abstract public function fail(); - + /** * All providers provide an abort/stop link to back into the onlinestore and choose * @@ -86,7 +86,7 @@ abstract public function abort(); public $errorCloseError = "Unable to close the model as errored, maybe its already closed."; private $_model; - + /** * Setter method for payment process. * @@ -96,7 +96,7 @@ public function setModel(PayModel $model) { $this->_model = $model; } - + /** * Getter method for model * @@ -106,9 +106,9 @@ public function getModel() { return $this->_model; } - + private $_context = null; - + /** * Setter method for controller context. * @@ -118,7 +118,7 @@ public function setContext(Controller $context) { $this->_context = $context; } - + /** * Getter method for context. * @@ -207,7 +207,7 @@ public function redirectTransactionAbort() public function redirectApplicationSuccess() { $url = $this->getModel()->getApplicationSuccessLink(); - + $this->closePaymentAsSuccessful(); return $this->getContext()->redirect($url); diff --git a/src/frontend/Module.php b/src/frontend/Module.php index cc75251..fe4fa1b 100644 --- a/src/frontend/Module.php +++ b/src/frontend/Module.php @@ -2,9 +2,9 @@ namespace luya\payment\frontend; +use luya\payment\integrators\DatabaseIntegrator; use Yii; use yii\base\InvalidConfigException; -use luya\payment\integrators\DatabaseIntegrator; /** * Payment Module. @@ -43,14 +43,14 @@ class Module extends \luya\base\Module public function init() { parent::init(); - + if ($this->transaction === null) { throw new InvalidConfigException("The transaction property can not be null."); } } - + private $_transaction; - + /** * Get the transaction object * @@ -60,18 +60,10 @@ public function getTransaction() { return $this->_transaction; } - + /** * * @var array A transaction object config array for the given provider: - * + paypal: - * ```php - * 'class' => payment\transactions\PayPalTransaction::className(), - * 'clientId' => 'ClientIdFromPayPalApplication', - * 'clientSecret' => 'ClientSecretFromPayPalApplication', - * 'mode' => 'live', // 'sandbox', - * 'productDescription' => 'MyOnlineStore Order', - * ``` * + saferpay: * ```php * 'class' => payment\transactions\SaferPayTransaction::className(), @@ -109,7 +101,7 @@ public function getIntegrator() if ($this->_integrator === null) { $this->_integrator = ['class' => DatabaseIntegrator::class]; } - + // create the integrator object if not done previously. if (is_array($this->_integrator)) { $this->_integrator = Yii::createObject($this->_integrator); diff --git a/src/frontend/controllers/DefaultController.php b/src/frontend/controllers/DefaultController.php index d34e240..3f8b50b 100644 --- a/src/frontend/controllers/DefaultController.php +++ b/src/frontend/controllers/DefaultController.php @@ -3,7 +3,9 @@ namespace luya\payment\frontend\controllers; use luya\payment\base\PayModel; +use yii\base\InvalidCallException; use yii\filters\HttpCache; +use yii\web\Response; /** * Default Payment Controller. @@ -22,23 +24,21 @@ class DefaultController extends \luya\web\Controller public function behaviors() { $behaviors = parent::behaviors(); - + $behaviors[] = [ 'class' => HttpCache::class, 'cacheControlHeader' => 'no-store, no-cache', - 'lastModified' => function ($action, $params) { + 'lastModified' => function () { return time(); }, ]; - + return $behaviors; } /** - * Undocumented function - * * @param PayModel|boolean $model - * @return void + * @return bool|Response */ private function ensureModelState($model) { @@ -80,21 +80,26 @@ public function actionCreate($lpToken, $lpKey) { $integrator = $this->module->getIntegrator(); $model = $integrator->findByKey($lpKey, $lpToken); + + if (!$model) { + throw new InvalidCallException("unable to find the given model."); + } + $integrator->addTrace($model, __METHOD__); $state = $this->ensureModelState($model); if ($state !== false) { return $state; } - + $this->module->transaction->setIntegrator($integrator); $this->module->transaction->setModel($model); $this->module->transaction->setContext($this); - - + + return $this->module->transaction->create(); } - + /** * The action which is opened when coming back from the payment page. * @@ -106,20 +111,25 @@ public function actionBack($lpToken, $lpKey) { $integrator = $this->module->getIntegrator(); $model = $integrator->findByKey($lpKey, $lpToken); + + if (!$model) { + throw new InvalidCallException("unable to find the given model."); + } + $integrator->addTrace($model, __METHOD__); $state = $this->ensureModelState($model); if ($state !== false) { return $state; } - + $this->module->transaction->setIntegrator($integrator); $this->module->transaction->setModel($model); $this->module->transaction->setContext($this); - + return $this->module->transaction->back(); } - + /** * Failed payment response. * @@ -133,20 +143,25 @@ public function actionFail($lpToken, $lpKey) { $integrator = $this->module->getIntegrator(); $model = $integrator->findByKey($lpKey, $lpToken); + + if (!$model) { + throw new InvalidCallException("unable to find the given model."); + } + $integrator->addTrace($model, __METHOD__); $state = $this->ensureModelState($model); if ($state !== false) { return $state; } - + $this->module->transaction->setIntegrator($integrator); $this->module->transaction->setModel($model); $this->module->transaction->setContext($this); - + return $this->module->transaction->fail(); } - + /** * Abort button pressed by the user. * @@ -158,8 +173,13 @@ public function actionAbort($lpToken, $lpKey) { $integrator = $this->module->getIntegrator(); $model = $integrator->findByKey($lpKey, $lpToken); + + if (!$model) { + throw new InvalidCallException("unable to find the given model."); + } + $integrator->addTrace($model, __METHOD__); - + $state = $this->ensureModelState($model); if ($state !== false) { return $state; @@ -168,10 +188,10 @@ public function actionAbort($lpToken, $lpKey) $this->module->transaction->setIntegrator($integrator); $this->module->transaction->setModel($model); $this->module->transaction->setContext($this); - + return $this->module->transaction->abort(); } - + /** * Notification from the Payment Provider. * @@ -190,8 +210,13 @@ public function actionNotify($lpToken, $lpKey) $integrator = $this->module->getIntegrator(); $model = $integrator->findByKey($lpKey, $lpToken); + + if (!$model) { + throw new InvalidCallException("unable to find the given model."); + } + $integrator->addTrace($model, __METHOD__); - + $state = $this->ensureModelState($model); if ($state !== false) { return $state; @@ -200,7 +225,7 @@ public function actionNotify($lpToken, $lpKey) $this->module->transaction->setIntegrator($integrator); $this->module->transaction->setModel($model); $this->module->transaction->setContext($this); - + return $this->module->transaction->notify(); } } diff --git a/src/frontend/controllers/TestController.php b/src/frontend/controllers/TestController.php index a9cdf54..4e91daa 100644 --- a/src/frontend/controllers/TestController.php +++ b/src/frontend/controllers/TestController.php @@ -2,10 +2,10 @@ namespace luya\payment\frontend\controllers; -use Yii; use luya\payment\Pay; -use yii\filters\HttpCache; use luya\payment\PaymentException; +use Yii; +use yii\filters\HttpCache; class TestController extends \luya\web\Controller { @@ -15,7 +15,7 @@ class TestController extends \luya\web\Controller public function behaviors() { $behaviors = parent::behaviors(); - + $behaviors[] = [ 'class' => HttpCache::class, 'cacheControlHeader' => 'no-store, no-cache', @@ -23,7 +23,7 @@ public function behaviors() return time(); }, ]; - + return $behaviors; } @@ -59,7 +59,7 @@ public function actionIndex() return $process->dispatch($this); } - + public function actionTestSuccess() { if (!Pay::isSuccess(Yii::$app->session->get('storeTransactionId', 0))) { @@ -72,12 +72,12 @@ public function actionTestSuccess() return 'success!'; } - + public function actionTestError() { return 'Rendering: error action...'; } - + public function actionTestAbort() { return 'Rendering: abort action...'; diff --git a/src/frontend/stripe/transaction.php b/src/frontend/stripe/transaction.php index f270eb6..5585cfe 100644 --- a/src/frontend/stripe/transaction.php +++ b/src/frontend/stripe/transaction.php @@ -1,8 +1,8 @@ title = $title; $icons = [ @@ -36,7 +36,7 @@

x

-

formatter->asCurrency($item['total_amount']/100, $currency); ?>

+

formatter->asCurrency($item['total_amount'] / 100, $currency); ?>

@@ -49,7 +49,7 @@

x

-

formatter->asCurrency($item['total_amount']/100, $currency); ?>

+

formatter->asCurrency($item['total_amount'] / 100, $currency); ?>

@@ -63,7 +63,7 @@

x

-

formatter->asCurrency($item['total_amount']/100, $currency); ?>

+

formatter->asCurrency($item['total_amount'] / 100, $currency); ?>

@@ -75,7 +75,7 @@

-

formatter->asCurrency(($totalAmount/100), $currency); ?>

+

formatter->asCurrency(($totalAmount / 100), $currency); ?>

diff --git a/src/helpers/OrderHelper.php b/src/helpers/OrderHelper.php index 6624ea4..5b9a604 100644 --- a/src/helpers/OrderHelper.php +++ b/src/helpers/OrderHelper.php @@ -31,7 +31,7 @@ class OrderHelper */ public static function generateOrderId($id, $zeroAmount = 5, $randomString = 4, $prefix = null) { - $random = $randomString > 0 ? strtoupper(Yii::$app->security->generateRandomString($randomString)) : null; + $random = $randomString > 0 ? strtoupper(Yii::$app->security->generateRandomString($randomString)) : null; $string = $random . str_pad($id, $zeroAmount, '0', STR_PAD_LEFT); return $prefix . str_replace(['-', '_'], rand(0, 9), $string); diff --git a/src/integrators/DatabaseIntegrator.php b/src/integrators/DatabaseIntegrator.php index b31e67b..40cdf60 100644 --- a/src/integrators/DatabaseIntegrator.php +++ b/src/integrators/DatabaseIntegrator.php @@ -2,7 +2,6 @@ namespace luya\payment\integrators; -use Yii; use luya\payment\base\IntegratorInterface; use luya\payment\base\PayModel; use luya\payment\models\Process; @@ -70,6 +69,8 @@ public function findByKey($key, $token) $model->setAuthToken($token); return $model; } + + return false; } /** @@ -112,7 +113,7 @@ public function closeModel(PayModel $model, $state) $process->is_closed = 1; $process->close_state = $state; $process->close_timestamp = time(); - + return $process->update(true, ['is_closed', 'close_state', 'close_timestamp']); } @@ -171,7 +172,7 @@ private function createPayModel(Process $process) foreach ($process->items as $item) { $model->addItem($item->name, $item->qty, $item->amount, $item->total_amount, $item->is_shipping, $item->is_tax); } - + if ($model->validate()) { return $model; } diff --git a/src/integrators/HeadlessIntegrator.php b/src/integrators/HeadlessIntegrator.php index e94c7cf..0893559 100644 --- a/src/integrators/HeadlessIntegrator.php +++ b/src/integrators/HeadlessIntegrator.php @@ -2,14 +2,14 @@ namespace luya\payment\integrators; +use luya\headless\Client; use luya\payment\base\IntegratorInterface; use luya\payment\base\PayModel; -use luya\headless\Client; -use luya\payment\PaymentException; use luya\payment\integrators\headless\ApiPaymentProcess; +use luya\payment\integrators\headless\ApiPaymentProcessTrace; use luya\payment\Pay; +use luya\payment\PaymentException; use yii\base\BaseObject; -use luya\payment\integrators\headless\ApiPaymentProcessTrace; /** * Headless Payment: @@ -22,7 +22,7 @@ class HeadlessIntegrator extends BaseObject implements IntegratorInterface { public $accessToken; - + public $serverUrl; private $_client; @@ -185,7 +185,7 @@ private static function createPayModel(ApiPaymentProcess $process) foreach ($process->items as $item) { $model->addItem($item['name'], $item['qty'], $item['amount'], $item['total_amount'], $item['is_tax'], $item['is_shipping']); } - + $model->closeState = $process->close_state; $model->isClosed = $process->is_closed; if ($model->validate()) { diff --git a/src/models/Process.php b/src/models/Process.php index 1f0c1d7..7aaf181 100644 --- a/src/models/Process.php +++ b/src/models/Process.php @@ -2,11 +2,11 @@ namespace luya\payment\models; -use Yii; -use luya\admin\ngrest\base\NgRestModel; use luya\admin\aws\DetailViewActiveWindow; +use luya\admin\ngrest\base\NgRestModel; use luya\behaviors\JsonBehavior; use luya\payment\PaymentException; +use Yii; use yii\helpers\VarDumper; /** @@ -40,13 +40,13 @@ */ class Process extends NgRestModel { - const STATE_PENDING = 0; + public const STATE_PENDING = 0; - const STATE_SUCCESS = 1; + public const STATE_SUCCESS = 1; - const STATE_ERROR = 2; + public const STATE_ERROR = 2; - const STATE_ABORT = 3; + public const STATE_ABORT = 3; public $auth_token; @@ -65,7 +65,7 @@ public static function ngRestApiEndpoint() { return 'api-payment-process'; } - + public function behaviors() { return [ @@ -274,7 +274,7 @@ public function ngRestRelations() /** * Get related items * - * @return void + * @return ProcessItem[] */ public function getItems() { @@ -284,7 +284,7 @@ public function getItems() /** * Get related trace events * - * @return void + * @return ProcessTrace[] */ public function getTraces() { @@ -323,26 +323,26 @@ public function createTokens() $inputKey = $this->order_id; $security = Yii::$app->security; - + // random string $random = $security->generateRandomString(32); - + // generate the auth token based from the random string and the inputKey $this->auth_token = $security->generatePasswordHash($random . $inputKey); // random salt string $this->salt = $security->generateRandomString(32); - + // generate a hash to compare the auth token from the salt and auth token $this->hash = $security->generatePasswordHash($this->salt . $this->auth_token); // encode the token with base 64 in order to remove conflicting http url signs $this->auth_token = base64_encode($this->auth_token); - + // generate a random key to add for for the transaction itself. $this->random_key = md5($security->generaterandomKey()); } - + /** * Validate the auth token against model hash * diff --git a/src/models/ProcessItem.php b/src/models/ProcessItem.php index 0a73f2b..82f3c34 100644 --- a/src/models/ProcessItem.php +++ b/src/models/ProcessItem.php @@ -2,8 +2,8 @@ namespace luya\payment\models; -use Yii; use luya\admin\ngrest\base\NgRestModel; +use Yii; /** * Process Item. diff --git a/src/models/ProcessTrace.php b/src/models/ProcessTrace.php index 900273f..e2c3919 100644 --- a/src/models/ProcessTrace.php +++ b/src/models/ProcessTrace.php @@ -2,10 +2,10 @@ namespace luya\payment\models; -use Yii; +use luya\admin\aws\DetailViewActiveWindow; use luya\admin\ngrest\base\NgRestModel; use luya\helpers\Json; -use luya\admin\aws\DetailViewActiveWindow; +use Yii; /** * Process Trace. @@ -49,7 +49,7 @@ public static function ngRestApiEndpoint() public function init() { parent::init(); - + $this->on(self::EVENT_BEFORE_VALIDATE, [$this, 'assignEnvValues']); } diff --git a/src/providers/PayPalProvider.php b/src/providers/PayPalProvider.php deleted file mode 100644 index 0ae2718..0000000 --- a/src/providers/PayPalProvider.php +++ /dev/null @@ -1,166 +0,0 @@ - $this->mode]; - - if ($this->mode == PayPalTransaction::MODE_SANDBOX) { - $config['log.LogEnabled'] = true; - $config['log.FileName'] = Yii::getAlias('@runtime/PayPal.log'); - $config['log.LogLevel'] = 'DEBUG'; - } - - return $config; - } - - public function callCreate($clientId, $clientSecret, $orderId, $amount, $currency, $description, $returnUrl, $cancelUrl, array $items, array $taxes, array $shipping) - { - $oauthCredential = new OAuthTokenCredential($clientId, $clientSecret); - - $apiContext = new ApiContext($oauthCredential); - $apiContext->setConfig($this->getConfigArray()); - - $payer = new Payer(); - $payer->setPaymentMethod('paypal'); - - // $items - /* - $item = new Item(); - $item->setName($description); - $item->setCurrency($currency); - $item->setPrice($amount); - $item->setQuantity(1); - */ - $products = []; - $itemTotalAmount = 0; - foreach ($items as $item) { - $i = new Item(); - $i->setName($item['name']); - $i->setCurrency($currency); - $i->setPrice(PayPalTransaction::floatAmount($item['amount'])); - $i->setQuantity($item['qty']); - $products[] = $i; - $itemTotalAmount += $item['total_amount']; - } - - $taxAmount = 0; - foreach ($taxes as $tax) { - $taxAmount += $tax['amount']; - } - - $shippingAmount = 0; - foreach ($shipping as $ship) { - $shippingAmount += $ship['amount']; - } - - $details = false; - if ($shippingAmount || $taxAmount) { - $details = new Details(); - if ($shippingAmount) { - $details->setShipping(PayPalTransaction::floatAmount($shippingAmount)); - } - if ($taxAmount) { - $details->setTax(PayPalTransaction::floatAmount($taxAmount)); - } - $details->setSubtotal(PayPalTransaction::floatAmount($itemTotalAmount)); - } - - - $itemList = new ItemList(); - $itemList->setItems($products); - - $amountObject = new Amount(); - $amountObject->setCurrency($currency); - $amountObject->setTotal(PayPalTransaction::floatAmount($amount)); - if ($details) { - $amountObject->setDetails($details); - } - - $transaction = new Transaction(); - $transaction->setItemList($itemList); - $transaction->setAmount($amountObject); - $transaction->setDescription($description); - $transaction->setInvoiceNumber($orderId); - - $redirectUrls = new RedirectUrls(); - $redirectUrls->setReturnUrl($returnUrl)->setCancelUrl($cancelUrl); - - $payment = new Payment(); - $payment->setIntent('sale'); - $payment->setPayer($payer); - $payment->setRedirectUrls($redirectUrls); - $payment->setTransactions(array($transaction)); - - try { - $payment->create($apiContext); - } catch (\Exception $e) { - throw new PaymentException('PayPal Exception: '. $e->getMessage()); - } - - $approvalUrl = $payment->getApprovalLink(); - - return $approvalUrl; - } - - public function callExecute($clientId, $clientSecret, $paymentId, $payerId, $amount, $currency) - { - $oauthCredential = new OAuthTokenCredential($clientId, $clientSecret); - - $apiContext = new ApiContext($oauthCredential); - $apiContext->setConfig($this->getConfigArray()); - - $payment = Payment::get($paymentId, $apiContext); - - $execution = new PaymentExecution(); - $execution->setPayerId($payerId); - - $result = $payment->execute($execution, $apiContext); - - try { - $payment = Payment::get($paymentId, $apiContext); - } catch (\Exception $e) { - throw new PaymentException('unable to find payment: ' . $e->getMessage()); - } - - if ($payment->state == 'approved') { - return true; - } - - return false; - } -} diff --git a/src/providers/SaferPayLegacyProvider.php b/src/providers/SaferPayLegacyProvider.php deleted file mode 100644 index 9b31679..0000000 --- a/src/providers/SaferPayLegacyProvider.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @since 1.0.0 - * @deprecated Deprectated since version 2.0 will be removed in version 4.0. The SaferPay HTTPS interface will shutdown on December 2020. - */ -class SaferPayLegacyProvider extends Provider implements ProviderInterface -{ - public $mode; - - public function getId() - { - return 'saferpay'; - } - - public function getBaseUrl() - { - if ($this->mode === SaferPayTransaction::MODE_LIVE) { - return 'https://www.saferpay.com/'; - } - - return 'https://test.saferpay.com/'; - } - - public function callCreate($accountId, $amount, $currency, $description, $orderId, $successLink, $failLink, $backLink, $notifyUrl) - { - $curl = new Curl(); - $curl->post($this->getBaseUrl() . 'hosting/CreatePayInit.asp', [ - 'ACCOUNTID' => $accountId, - 'AMOUNT' => $amount, - 'CURRENCY' => $currency, - 'DESCRIPTION' => $description, - 'ORDERID' => $orderId, - 'SUCCESSLINK' => $successLink, - 'FAILLINK' => $failLink, - 'BACKLINK' => $backLink, - 'NOTIFYURL' => $notifyUrl, - 'AUTOCLOSE' => '0', - ]); - - if (!$curl->error) { - return $curl->response; - } - - throw new PaymentException($curl->error_message); - } - - public function callConfirm($data, $signature) - { - $curl = new Curl(); - $curl->post($this->getBaseUrl() . 'hosting/VerifyPayConfirm.asp', [ - 'DATA' => $data, - 'SIGNATURE' => $signature, - ]); - - if (!$curl->error) { - return $curl->response; - } - - throw new PaymentException("payconfirm error"); - } - - public function callComplete($id, $token, $amount, $action, $accountId, $spPassword = null) - { - $data = [ - 'ID' => $id, - 'TOKEN' => $token, - 'AMOUNT' => $amount, - 'ACTION' => $action, - 'ACCOUNTID' => $accountId, - ]; - - if (!empty($spPassword)) { - $data['spPassword'] = $spPassword; - } - - $curl = new Curl(); - $curl->post($this->getBaseUrl() . 'hosting/PayCompleteV2.asp', $data); - - if (!$curl->error) { - return $curl->response; - } - - throw new PaymentException("payconfirm error"); - } -} diff --git a/src/providers/SaferPayProvider.php b/src/providers/SaferPayProvider.php index e9fa8c4..35f0c28 100644 --- a/src/providers/SaferPayProvider.php +++ b/src/providers/SaferPayProvider.php @@ -12,15 +12,15 @@ /** * Safer Pay Provider. - * + * * @author Basil Suter * @since 3.0 */ class SaferPayProvider extends Provider { - const PRODUCTION_URL = 'https://www.saferpay.com/api'; + public const PRODUCTION_URL = 'https://www.saferpay.com/api'; - const TEST_URL = 'https://test.saferpay.com/api'; + public const TEST_URL = 'https://test.saferpay.com/api'; /** * @var string The api specification version. @@ -186,4 +186,4 @@ private function postCurl($url, array $values) return $curl; } -} \ No newline at end of file +} diff --git a/src/providers/StripeProvider.php b/src/providers/StripeProvider.php index 380c0bb..762daab 100644 --- a/src/providers/StripeProvider.php +++ b/src/providers/StripeProvider.php @@ -3,9 +3,9 @@ namespace luya\payment\providers; use Exception; -use Yii; use luya\payment\base\Provider; use Stripe\PaymentIntent; +use Yii; /** * Strip Provider diff --git a/src/transactions/PayPalTransaction.php b/src/transactions/PayPalTransaction.php deleted file mode 100644 index 7a0ff83..0000000 --- a/src/transactions/PayPalTransaction.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @since 1.0.0 - */ -class PayPalTransaction extends Transaction -{ - /** - * @var string Production mode - */ - const MODE_LIVE = 'live'; - - /** - * @var string Sandbox/Testing mode - */ - const MODE_SANDBOX = 'sandbox'; - - /** - * @var string The client id - */ - public $clientId; - - /** - * @var string the Client secret. - */ - public $clientSecret; - - /** - * @var string The mode in which the api should be called `live` or `sandbox`. Default is live. Previous knonw as `sandboxMode`. - */ - public $mode = self::MODE_LIVE; - - /** - * @var string The PayPal interface displays a name for the Amount of the ordering, this is the product text. - */ - public $productDescription; - - /** - * {@inheritDoc} - */ - public function init() - { - parent::init(); - - if ($this->clientId === null || $this->clientSecret === null) { - throw new InvalidConfigException("the paypal clientId and clientSecret properite can not be null!"); - } - } - - /** - * Get the PayPal Provider - * - * @return PayPalProvider - */ - public function getProvider() - { - return new PayPalProvider([ - 'mode' => $this->mode, - ]); - } - - private function getOrderDescription() - { - if (empty($this->productDescription)) { - return $this->getModel()->getOrderId(); - } - - return $this->productDescription; - } - - /** - * As all amounts are provided in cents we have to calculate them to not cents - * - * @param unknown $amount - */ - public static function floatAmount($value) - { - return number_format($value / 100, 2, '.', ''); - } - - /** - * {@inheritDoc} - */ - public function create() - { - $url = $this->getProvider()->call('create', [ - 'clientId' => $this->clientId, - 'clientSecret' => $this->clientSecret, - 'orderId' => $this->getModel()->getOrderId(), - 'amount' => $this->getModel()->getTotalAmount(), - 'currency' => $this->getModel()->getCurrency(), - 'description' => $this->getOrderDescription(), - 'returnUrl' => $this->getModel()->getTransactionGatewayBackLink(), - 'cancelUrl' => $this->getModel()->getTransactionGatewayAbortLink(), - // add new items informations - 'items' => $this->getModel()->getProductItems(), - 'taxes' => $this->getModel()->getTaxItems(), - 'shipping' => $this->getModel()->getShippingItems(), - ]); - - return $this->getContext()->redirect($url); - } - - /** - * {@inheritDoc} - */ - public function back() - { - $response = $this->getProvider()->call('execute', [ - 'clientId' => $this->clientId, - 'clientSecret' => $this->clientSecret, - 'paymentId' => Yii::$app->request->get('paymentId', false), - 'payerId' => Yii::$app->request->get('PayerID', false), - 'amount' => $this->getModel()->getTotalAmount(), - 'currency' => $this->getModel()->getCurrency(), - ]); - - if ($response) { - return $this->redirectApplicationSuccess(); - } - - return $this->redirectTransactionFail(); - } - - /** - * {@inheritDoc} - */ - public function notify() - { - throw new PaymentException('PayPal notify action is not implemented.'); - } - - /** - * {@inheritDoc} - */ - public function fail() - { - return $this->redirectApplicationError(); - } - - /** - * {@inheritDoc} - */ - public function abort() - { - return $this->redirectApplicationAbort(); - } -} diff --git a/src/transactions/SaferPayLegacyTransaction.php b/src/transactions/SaferPayLegacyTransaction.php deleted file mode 100644 index 505ea72..0000000 --- a/src/transactions/SaferPayLegacyTransaction.php +++ /dev/null @@ -1,172 +0,0 @@ - This legacy implementation should not be used anymore as the SaferPay HTTP Service is discontinued. - * - * > SaferPay: The deprecated interfaces HTTPS Interface (HI) and Saferpay Clients (Lib/SCAI) will be discontinued - * > at the end of 2020. Please switch your systems to the current interface JSON API in good time. Further - * > information on the replacement of deprecated interfaces. - * - * ```php - * 'class' => 'luya\payment\transactions\SaferPayTransaction', - * 'accountId' => '401860-17795278', - * 'spPassword' => '8e7Yn5yk', - * 'mode' => 'sandbox', - * ``` - * - * @author Basil Suter - * @since 3.0.0 - * @deprecated Deprectated since version 2.0 will be removed in version 4.0. The SaferPay HTTPS interface will shutdown on December 2020. - */ -class SaferPayLegacyTransaction extends Transaction -{ - /** - * @var string Production mode - */ - const MODE_LIVE = 'live'; - - /** - * @var string Sandbox/Testing mode - */ - const MODE_SANDBOX = 'sandbox'; - - /** - * @var string The accountId value from the safer pay backend. - */ - public $accountId; - - /** - * @param string Test account spPassword (from the docs: Die Übergabe des Parameters spPassword ist nur beim Testkonto erforderlich. Für produktive Konten wird - * dieser Parameter nicht benötigt!) - */ - public $spPassword; - - /** - * @param string The mode which changes the urls for sandbox or live - */ - public $mode = self::MODE_LIVE; - - /** - * {@inheritDoc} - */ - public function init() - { - parent::init(); - - if (empty($this->accountId)) { - throw new InvalidConfigException("accountId must be set in your saferpay transaction"); - } - } - - /** - * Get the safer pay provider object. - * - * @return SaferPayProvider - */ - public function getProvider() - { - return new SaferPayLegacyProvider([ - 'mode' => $this->mode, - ]); - } - - /** - * {@inheritDoc} - */ - public function create() - { - $url = $this->getProvider()->call('create', [ - 'accountId' => $this->accountId, - 'amount' => $this->getModel()->getTotalAmount(), - 'currency' => $this->getModel()->getCurrency(), - 'orderId' => $this->getModel()->getOrderId(), - 'description' => $this->getModel()->getOrderId(), - 'successLink' => $this->getModel()->getTransactionGatewayBackLink(), - 'failLink' => $this->getModel()->getTransactionGatewayFailLink(), - 'backLink' => $this->getModel()->getTransactionGatewayAbortLink(), - 'notifyUrl' => $this->getModel()->getTransactionGatewayNotifyLink(), - ]); - - // the response status is 200 but the content is not a valid URL - // therefore trhow an exception with the content. Example value could be: - // `ERROR: Missing or wrong ACCOUNTID attribute` - if (!filter_var($url, FILTER_VALIDATE_URL)) { - throw new PaymentException("Invalid URL: " . $url); - } - - return $this->getContext()->redirect($url); - } - - /** - * {@inheritDoc} - */ - public function back() - { - $signature = Yii::$app->request->get('SIGNATURE', false); - $data = Yii::$app->request->get('DATA', false); - - $confirmResponse = $this->getProvider()->call('confirm', [ - 'data' => $data, - 'signature' => $signature, - ]); - - $parts = explode(":", $confirmResponse); - - if (isset($parts[0]) && $parts[0] == 'OK' && $parts[1]) { - - // create $TOKEN and $ID variable - parse_str($parts[1]); - - $completeResponse = $this->getProvider()->call('complete', [ - 'id' => $ID, - 'token' => $TOKEN, - 'amount' => $this->getModel()->getTotalAmount(), - 'action' => 'Settlement', - 'accountId' => $this->accountId, - 'spPassword' => $this->spPassword, - ]); - - $completeParts = explode(":", $completeResponse); - - if (isset($completeParts[0]) && $completeParts[0] == 'OK') { - return $this->redirectApplicationSuccess(); - } - } - - return $this->redirectTransactionFail(); - } - - /** - * {@inheritDoc} - */ - public function notify() - { - return $this->redirectApplicationSuccess(); - } - - /** - * {@inheritDoc} - */ - public function fail() - { - return $this->redirectApplicationError(); - } - - /** - * {@inheritDoc} - */ - public function abort() - { - return $this->redirectApplicationAbort(); - } -} diff --git a/src/transactions/SaferPayTransaction.php b/src/transactions/SaferPayTransaction.php index f5fe456..d88dea2 100644 --- a/src/transactions/SaferPayTransaction.php +++ b/src/transactions/SaferPayTransaction.php @@ -9,9 +9,9 @@ /** * Safer Pay API Transaction. - * + * * Example integration: - * + * * ```php * 'transaction' => [ * 'class' => 'luya\payment\transactions\SaferPayTransaction', @@ -27,17 +27,17 @@ */ class SaferPayTransaction extends Transaction { - const STATUS_CAPTURED = 'CAPTURED'; + public const STATUS_CAPTURED = 'CAPTURED'; /** * @var string Production mode */ - const MODE_LIVE = 'live'; + public const MODE_LIVE = 'live'; /** * @var string Sandbox/Testing mode */ - const MODE_SANDBOX = 'sandbox'; + public const MODE_SANDBOX = 'sandbox'; /** * @var string The mode in which the api should be called `live` or `sandbox`. Default is live. Previous knonw as `sandboxMode`. @@ -45,7 +45,7 @@ class SaferPayTransaction extends Transaction public $mode = self::MODE_LIVE; /** - * @var number A numeric value with 8 digits `12345678` + * @var number A numeric value with 8 digits `12345678` */ public $terminalId; @@ -78,7 +78,7 @@ public function init() /** * Get Provider Object. - * + * * @return SaferPayProvider */ public function getProvider() @@ -133,7 +133,7 @@ public function fail() { return $this->redirectApplicationError(); } - + /** * {@inheritDoc} */ @@ -169,7 +169,7 @@ private function assertAndCapture() if (isset($data['capture']) && isset($data['capture']['Status']) && $data['capture']['Status'] == self::STATUS_CAPTURED) { return true; } - + // capture $capture = $this->getProvider()->capture($this->getModel()->getOrderId() . uniqid(), $assert['Transaction']['Id']); @@ -185,7 +185,7 @@ private function assertAndCapture() if (!isset($capture['Status'])) { throw new PaymentException("Caputre response has missing Status information."); } - + return $capture['Status'] == self::STATUS_CAPTURED; } -} \ No newline at end of file +} diff --git a/src/transactions/StripeTransaction.php b/src/transactions/StripeTransaction.php index 602e101..24f2dad 100644 --- a/src/transactions/StripeTransaction.php +++ b/src/transactions/StripeTransaction.php @@ -3,14 +3,14 @@ namespace luya\payment\transactions; use Exception; -use Yii; -use Stripe\Stripe; -use luya\payment\PaymentException; +use luya\helpers\Html; use luya\payment\base\Transaction; +use luya\payment\frontend\Module; +use luya\payment\PaymentException; use luya\payment\providers\StripeProvider; -use luya\helpers\Html; +use Stripe\Stripe; +use Yii; use yii\base\InvalidConfigException; -use luya\payment\frontend\Module; /** * Stripe Transaction. diff --git a/src/widgets/SubmitFormButtonWidget.php b/src/widgets/SubmitFormButtonWidget.php index 798ad27..5ca81e2 100644 --- a/src/widgets/SubmitFormButtonWidget.php +++ b/src/widgets/SubmitFormButtonWidget.php @@ -3,8 +3,8 @@ namespace luya\payment\widgets; use luya\base\Widget; -use luya\helpers\Html; use luya\helpers\ArrayHelper; +use luya\helpers\Html; use yii\base\InvalidConfigException; use yii\web\JsExpression; @@ -29,7 +29,7 @@ class SubmitFormButtonWidget extends Widget * @var string The label which should be displayed on button. */ public $label; - + /** * @var string The label which should be visible when the button is pushed. for example `... sending`. */ diff --git a/tests/BasePaymentTestCase.php b/tests/BasePaymentTestCase.php index 3bedfb5..91064e0 100644 --- a/tests/BasePaymentTestCase.php +++ b/tests/BasePaymentTestCase.php @@ -2,14 +2,14 @@ namespace luya\payment\tests; -use luya\testsuite\cases\WebApplicationTestCase; -use luya\testsuite\fixtures\ActiveRecordFixture; -use luya\payment\models\Process; -use luya\payment\models\ProcessTrace; -use luya\payment\models\ProcessItem; use luya\payment\base\PayModel; use luya\payment\frontend\controllers\DefaultController; +use luya\payment\models\Process; +use luya\payment\models\ProcessItem; +use luya\payment\models\ProcessTrace; use luya\payment\tests\data\DummyIntegrator; +use luya\testsuite\cases\WebApplicationTestCase; +use luya\testsuite\fixtures\ActiveRecordFixture; class BasePaymentTestCase extends WebApplicationTestCase { @@ -39,9 +39,9 @@ public function getConfigArray() public $fixtureProcessModel; public $fixtureProcessItemModel; - + public $fixtureProcessTraceModel; - + public function afterSetup() { parent::afterSetup(); diff --git a/tests/data/DummyIntegrator.php b/tests/data/DummyIntegrator.php index 223f9d7..2b70c97 100644 --- a/tests/data/DummyIntegrator.php +++ b/tests/data/DummyIntegrator.php @@ -10,7 +10,7 @@ class DummyIntegrator implements IntegratorInterface public $createModelResponse = true; public $closeModelResponse = true; - + /** * {@inheritDoc} */ diff --git a/tests/data/DummyTransaction.php b/tests/data/DummyTransaction.php index a29863f..70fac93 100644 --- a/tests/data/DummyTransaction.php +++ b/tests/data/DummyTransaction.php @@ -3,30 +3,29 @@ namespace luya\payment\tests\data; use luya\payment\base\Transaction; -use luya\payment\tests\data\DummyProvider; class DummyTransaction extends Transaction { public function create() { } - + public function back() { } - + public function notify() { } - + public function fail() { } - + public function abort() { } - + public function getProvider() { return new DummyProvider(); diff --git a/tests/src/GenericTest.php b/tests/src/GenericTest.php index 41dfaaa..680fb95 100644 --- a/tests/src/GenericTest.php +++ b/tests/src/GenericTest.php @@ -2,9 +2,9 @@ namespace luya\payment\tests; -use Yii; use luya\testsuite\traits\MessageFileCompareTrait; use luya\testsuite\traits\MigrationFileCheckTrait; +use Yii; class GenericTest extends BasePaymentTestCase { diff --git a/tests/src/PayTest.php b/tests/src/PayTest.php index b2fa357..9f0e884 100644 --- a/tests/src/PayTest.php +++ b/tests/src/PayTest.php @@ -18,7 +18,7 @@ public function testTotalAmountCalculations() $pay->setErrorLink('error'); $pay->setAbortLink('abort'); - + $pay->addItem('Product A', 2, 200); // total: 400 $pay->addItem('Rabat B', 1, -100); // total: 300 $pay->addItem('Free X', 1, 0); // 300 @@ -45,7 +45,7 @@ public function testInvalidAmount() $pay->setErrorLink('error'); $pay->setAbortLink('abort'); - + $pay->addItem('Product A', 2, 200); // total: 400 $pay->addItem('Rabat B', 1, -100); // total: 300 $pay->addItem('Free X', 1, 0); // 300 @@ -67,14 +67,14 @@ public function testInvalidModelValidation() $pay->setErrorLink('error'); $pay->setAbortLink('abort'); - + $pay->addItem('Product A', 2, 200); // total: 400 $pay->addItem('Rabat B', 1, -100); // total: 300 $pay->addItem('Free X', 1, 0); // 300 $pay->addTax('VAT', 20); // total 320; $pay->addShipping('Shipping', 80); // total 400 $pay->setTotalAmount(400); - + $this->expectException(PaymentException::class); $pay->getId(); } @@ -96,7 +96,7 @@ public function testCreateIntegratorModelError() $pay->setErrorLink('error'); $pay->setAbortLink('abort'); - + $pay->addItem('Product A', 2, 200); // total: 400 $pay->addItem('Rabat B', 1, -100); // total: 300 $pay->addItem('Free X', 1, 0); // 300 diff --git a/tests/src/PaymentProcessTest.php b/tests/src/PaymentProcessTest.php index 3edb74b..19061a4 100644 --- a/tests/src/PaymentProcessTest.php +++ b/tests/src/PaymentProcessTest.php @@ -2,11 +2,8 @@ namespace luya\payment\tests; -use Yii; -use luya\payment\tests\data\DummyTransaction; use luya\payment\models\Process; use luya\payment\Pay; -use luya\payment\integrators\DatabaseIntegrator; class PaymentProcessTest extends BasePaymentTestCase { @@ -16,7 +13,7 @@ public function testInitException() $process = new Pay(); $process->getId(); } - + public function testPaymentProcessObject() { $object = new Pay(); @@ -44,26 +41,26 @@ public function testPaymentProcessObject() $this->assertInstanceOf('\luya\payment\base\TransactionInterface', $transaction); */ - - + + $processId = $object->getId(); - + $this->assertNotFalse($processId); - + $int = $this->app->getModule('payment')->getIntegrator(); $model = $int->findByKey($object->getRandomKey(), $object->getAuthToken()); $this->assertInstanceOf('\luya\payment\base\PayModel', $model); - + $token = $model->getAuthToken(); - + $randomKey = $model->randomKey; - + // find payment process by processId $object2 = Pay::findById($processId); - + $this->assertInstanceOf('\luya\payment\base\PayModel', $object2); - + $this->assertSame($processId, $object2->getId()); // this mus throw an exception //$this->assertSame(null, $object2->getAuthToken()); // as the token can not be reassigned, it must be null @@ -71,7 +68,7 @@ public function testPaymentProcessObject() // find payment by token: $object3 = $int->findByKey($randomKey, $token); - + $this->assertInstanceOf('\luya\payment\base\PayModel', $object3); $this->assertSame($processId, $object3->getId()); $this->assertSame($token, $object3->getAuthTOken()); @@ -79,14 +76,14 @@ public function testPaymentProcessObject() // there is not redirect trough the payment process and therefore the model is not set to success! $this->assertFalse(Pay::isSuccess($processId)); } - + public function testErrorAmountProcess() { $this->expectException('luya\payment\PaymentException'); $object = new Pay(); $object->getId(); } - + public function testUrlRules() { $_SERVER['HTTP_HOST'] = 'localhost'; diff --git a/tests/src/controllers/DefaultControllerTest.php b/tests/src/controllers/DefaultControllerTest.php index 42b89ba..f61c80e 100644 --- a/tests/src/controllers/DefaultControllerTest.php +++ b/tests/src/controllers/DefaultControllerTest.php @@ -26,4 +26,4 @@ public function testControllerActions() $response = $ctrl->actionFail(0, 0); $this->assertNull($response); } -} \ No newline at end of file +} diff --git a/tests/src/helpers/OrderHelperTest.php b/tests/src/helpers/OrderHelperTest.php index 48872f5..f24e822 100644 --- a/tests/src/helpers/OrderHelperTest.php +++ b/tests/src/helpers/OrderHelperTest.php @@ -3,8 +3,8 @@ namespace luya\payment\tests\helpers; use luya\helpers\StringHelper; -use luya\payment\tests\BasePaymentTestCase; use luya\payment\helpers\OrderHelper; +use luya\payment\tests\BasePaymentTestCase; class OrderHelperTest extends BasePaymentTestCase { @@ -15,13 +15,13 @@ public function testGenerateOrderId() $this->assertStringContainsString('00004', OrderHelper::generateOrderId(4, 5)); - for ($i=1;$i<=100;$i++) { + for ($i = 1;$i <= 100;$i++) { $string = OrderHelper::generateOrderId(1, 5, 10); $this->assertFalse(StringHelper::contains(['-', '_'], $string)); } } - + public function testGenerateOrderIdZeros() { $this->assertStringContainsString('0000004', OrderHelper::generateOrderId(4, 7)); diff --git a/tests/src/integrators/HeadlessIntegratorTest.php b/tests/src/integrators/HeadlessIntegratorTest.php index 19abf07..663ed6c 100644 --- a/tests/src/integrators/HeadlessIntegratorTest.php +++ b/tests/src/integrators/HeadlessIntegratorTest.php @@ -4,7 +4,6 @@ use luya\headless\exceptions\RequestException; use luya\payment\base\PayModel; -use luya\payment\integrators\DatabaseIntegrator; use luya\payment\integrators\HeadlessIntegrator; use luya\payment\PaymentException; use luya\payment\tests\BasePaymentTestCase; diff --git a/tests/src/providers/SaferPayProviderTest.php b/tests/src/providers/SaferPayProviderTest.php index 358fe8f..dff253c 100644 --- a/tests/src/providers/SaferPayProviderTest.php +++ b/tests/src/providers/SaferPayProviderTest.php @@ -40,4 +40,4 @@ public function testCaptureCall() $this->assertSame('AUTHENTICATION_FAILED', $x['ErrorName']); } -} \ No newline at end of file +} diff --git a/tests/src/providers/StripeProviderTest.php b/tests/src/providers/StripeProviderTest.php index 859f239..f8e7872 100644 --- a/tests/src/providers/StripeProviderTest.php +++ b/tests/src/providers/StripeProviderTest.php @@ -2,10 +2,9 @@ namespace luya\payment\tests\providers; -use luya\payment\tests\BasePaymentTestCase; use luya\payment\providers\StripeProvider; +use luya\payment\tests\BasePaymentTestCase; use Stripe\PaymentIntent; -use Stripe\StripeObject; class StripeProviderTest extends BasePaymentTestCase { @@ -27,7 +26,7 @@ public function testVerifySuccessIntent() { $provider = new StripeProvider(); $response = $provider->callVerifySuccessIntent(0); - + $this->assertFalse($response); } diff --git a/tests/src/transaction/GenericTransactionTest.php b/tests/src/transaction/GenericTransactionTest.php index 72aedbd..6f2ff35 100644 --- a/tests/src/transaction/GenericTransactionTest.php +++ b/tests/src/transaction/GenericTransactionTest.php @@ -15,7 +15,7 @@ class GenericTransactionTest extends BasePaymentTestCase */ private function getTransaction() { - return new class extends Transaction { + return new class () extends Transaction { public function create() { } @@ -63,7 +63,7 @@ public function testGenericMethods() $transaction->setModel($this->generatePayModel()); $transaction->setContext($this->generateContextController()); - + $this->assertEmpty($transaction->create()); $this->assertEmpty($transaction->back()); $this->assertEmpty($transaction->notify()); diff --git a/tests/src/transaction/PayPalTransactionTest.php b/tests/src/transaction/PayPalTransactionTest.php deleted file mode 100644 index 9d2f0a4..0000000 --- a/tests/src/transaction/PayPalTransactionTest.php +++ /dev/null @@ -1,25 +0,0 @@ - 'clientid', - 'clientSecret' => 'secret', - 'mode' => PayPalTransaction::MODE_LIVE, - ]); - - $paypal->setModel($this->generatePayModel()); - $paypal->setContext($this->generateContextController()); - - $this->assertNotEmpty($paypal->getProvider()); - $this->expectExceptionMessage('PayPal Exception: Got Http response code 401 when accessing https://api.paypal.com/v1/oauth2/token'); - $paypal->create(); - } -} diff --git a/tests/src/transaction/SaferPayLegacyTransactionTest.php b/tests/src/transaction/SaferPayLegacyTransactionTest.php deleted file mode 100644 index 8f3e621..0000000 --- a/tests/src/transaction/SaferPayLegacyTransactionTest.php +++ /dev/null @@ -1,22 +0,0 @@ - 123, - ]); - $saferPay->setModel($this->generatePayModel()); - $saferPay->setContext($this->generateContextController()); - $this->assertNotEmpty($saferPay->getProvider()); - $this->expectException(PaymentException::class); - $r = $saferPay->create(); - } -} diff --git a/tests/src/transaction/StripeTransactionTest.php b/tests/src/transaction/StripeTransactionTest.php index 572a42f..7b7cfba 100644 --- a/tests/src/transaction/StripeTransactionTest.php +++ b/tests/src/transaction/StripeTransactionTest.php @@ -2,13 +2,12 @@ namespace luya\payment\tests\transaction; -use Yii; use luya\payment\tests\BasePaymentTestCase; +use luya\payment\tests\data\DummyIntegrator; use luya\payment\transactions\StripeTransaction; -use yii\web\Controller; +use Yii; use yii\base\Response; -use luya\payment\integrators\DatabaseIntegrator; -use luya\payment\tests\data\DummyIntegrator; +use yii\web\Controller; class StripeTransactionTest extends BasePaymentTestCase {