From b4571e703bec84526da111fef8ae374b0318fe14 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 19:37:12 +0800 Subject: [PATCH 01/17] add pay package to test. --- composer.json | 3 +- composer.lock | 348 +++++++++++------- github/component/Pay/.gitignore | 2 + github/component/Pay/.php_cs | 27 ++ github/component/Pay/.travis.yml | 16 + github/component/Pay/LICENSE | 21 ++ github/component/Pay/README.md | 11 + github/component/Pay/composer.json | 45 +++ .../Pay/migrations/create_pay_tables.php.stub | 64 ++++ github/component/Pay/phpunit.xml | 29 ++ github/component/Pay/scrutinizer.yml | 30 ++ .../component/Pay/src/Charges/BaseCharge.php | 42 +++ .../Pay/src/Charges/DefaultCharge.php | 167 +++++++++ .../Pay/src/Contracts/PayChargeContract.php | 17 + github/component/Pay/src/Facades/Charge.php | 27 ++ .../Controllers/AlipayNotifyController.php | 21 ++ .../Controllers/WechatPayNotifyController.php | 21 ++ github/component/Pay/src/Models/Pay.php | 31 ++ .../component/Pay/src/PayServiceProvider.php | 83 +++++ github/component/Pay/src/config.php | 78 ++++ 20 files changed, 939 insertions(+), 144 deletions(-) create mode 100644 github/component/Pay/.gitignore create mode 100644 github/component/Pay/.php_cs create mode 100644 github/component/Pay/.travis.yml create mode 100644 github/component/Pay/LICENSE create mode 100644 github/component/Pay/README.md create mode 100644 github/component/Pay/composer.json create mode 100644 github/component/Pay/migrations/create_pay_tables.php.stub create mode 100644 github/component/Pay/phpunit.xml create mode 100644 github/component/Pay/scrutinizer.yml create mode 100644 github/component/Pay/src/Charges/BaseCharge.php create mode 100644 github/component/Pay/src/Charges/DefaultCharge.php create mode 100644 github/component/Pay/src/Contracts/PayChargeContract.php create mode 100644 github/component/Pay/src/Facades/Charge.php create mode 100644 github/component/Pay/src/Http/Controllers/AlipayNotifyController.php create mode 100644 github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php create mode 100644 github/component/Pay/src/Models/Pay.php create mode 100644 github/component/Pay/src/PayServiceProvider.php create mode 100644 github/component/Pay/src/config.php diff --git a/composer.json b/composer.json index c3cdea6..94023d2 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,8 @@ "include": [ "modules/EC.Open.Core/composer.json", "modules/EC.Open.Server/composer.json", - "modules/component/*/composer.json" + "modules/component/*/composer.json", + "github/component/*/composer.json" ], "recurse": false, "replace": true, diff --git a/composer.lock b/composer.lock index dcc948e..28c87fd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "9e6579b6e5814a1fafd3bfc50fc1b577", + "content-hash": "25e6deecc4f6d29d228956f83559c549", "packages": [ { "name": "anam/phantomjs-linux-x86-binary", @@ -952,16 +952,16 @@ }, { "name": "easywechat-composer/easywechat-composer", - "version": "1.1.2", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/mingyoung/easywechat-composer.git", - "reference": "777ce8726affd5a9a31eddb6f025e767765b8c6e" + "reference": "f0c96f2cda1e672e3ad2fd34a192a503943c69fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mingyoung/easywechat-composer/zipball/777ce8726affd5a9a31eddb6f025e767765b8c6e", - "reference": "777ce8726affd5a9a31eddb6f025e767765b8c6e", + "url": "https://api.github.com/repos/mingyoung/easywechat-composer/zipball/f0c96f2cda1e672e3ad2fd34a192a503943c69fe", + "reference": "f0c96f2cda1e672e3ad2fd34a192a503943c69fe", "shasum": "", "mirrors": [ { @@ -998,7 +998,7 @@ } ], "description": "The composer plugin for EasyWeChat", - "time": "2018-09-18T14:23:58+00:00" + "time": "2018-11-10T01:49:23+00:00" }, { "name": "egulias/email-validator", @@ -1429,6 +1429,65 @@ ], "time": "2017-03-20T17:10:46+00:00" }, + { + "name": "hidehalo/nanoid-php", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/hidehalo/nanoid-php.git", + "reference": "0f4ffdd3b56200e2a927501b01bae31b62a35df7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hidehalo/nanoid-php/zipball/0f4ffdd3b56200e2a927501b01bae31b62a35df7", + "reference": "0f4ffdd3b56200e2a927501b01bae31b62a35df7", + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "paragonie/random_compat": ">=2.0", + "php": "~5.6|~7.0" + }, + "require-dev": { + "phpunit/phpunit": ">=5.6", + "squizlabs/php_codesniffer": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hidehalo\\Nanoid\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "hidehalo", + "email": "tianchen_cc@yeah.net", + "homepage": "https://github.com/hidehalo", + "role": "Owner" + } + ], + "description": "A copy of nanoid in PHP", + "homepage": "https://github.com/hidehalo/nanoid-php", + "keywords": [ + "hidehalo", + "nanoid-php" + ], + "time": "2018-10-03T02:53:38+00:00" + }, { "name": "ibrand/laravel-cache", "version": "v1.0.0", @@ -1481,16 +1540,16 @@ }, { "name": "ibrand/laravel-miniprogram-poster", - "version": "v1.3", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/ibrandcc/laravel-miniprogram-poster.git", - "reference": "d533db7f8a0605ce40a2b073cbd7a2ebf9942747" + "reference": "e4de6162bc08cea88a3b78fe6f6f47d131bdc234" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ibrandcc/laravel-miniprogram-poster/zipball/d533db7f8a0605ce40a2b073cbd7a2ebf9942747", - "reference": "d533db7f8a0605ce40a2b073cbd7a2ebf9942747", + "url": "https://api.github.com/repos/ibrandcc/laravel-miniprogram-poster/zipball/e4de6162bc08cea88a3b78fe6f6f47d131bdc234", + "reference": "e4de6162bc08cea88a3b78fe6f6f47d131bdc234", "shasum": "", "mirrors": [ { @@ -1539,7 +1598,7 @@ "miniprogram", "poster" ], - "time": "2018-10-05T02:47:28+00:00" + "time": "2018-10-17T07:59:37+00:00" }, { "name": "ibrand/laravel-shopping-cart", @@ -1844,16 +1903,16 @@ }, { "name": "jaybizzle/crawler-detect", - "version": "v1.2.70", + "version": "v1.2.73", "source": { "type": "git", "url": "https://github.com/JayBizzle/Crawler-Detect.git", - "reference": "02ba61b12c0125ed3b5ba7a3e18908841a046fd0" + "reference": "3783b88b686dfd8f0c752f829caaf1bcace581ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/02ba61b12c0125ed3b5ba7a3e18908841a046fd0", - "reference": "02ba61b12c0125ed3b5ba7a3e18908841a046fd0", + "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/3783b88b686dfd8f0c752f829caaf1bcace581ef", + "reference": "3783b88b686dfd8f0c752f829caaf1bcace581ef", "shasum": "", "mirrors": [ { @@ -1895,7 +1954,7 @@ "crawlerdetect", "php crawler detect" ], - "time": "2018-10-10T20:50:02+00:00" + "time": "2018-10-31T13:15:59+00:00" }, { "name": "jenssegers/agent", @@ -2320,16 +2379,16 @@ }, { "name": "lcobucci/jwt", - "version": "3.2.4", + "version": "3.2.5", "source": { "type": "git", "url": "https://github.com/lcobucci/jwt.git", - "reference": "c9704b751315d21735dc98d78d4f37bd73596da7" + "reference": "82be04b4753f8b7693b62852b7eab30f97524f9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/c9704b751315d21735dc98d78d4f37bd73596da7", - "reference": "c9704b751315d21735dc98d78d4f37bd73596da7", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/82be04b4753f8b7693b62852b7eab30f97524f9b", + "reference": "82be04b4753f8b7693b62852b7eab30f97524f9b", "shasum": "", "mirrors": [ { @@ -2380,7 +2439,7 @@ "JWS", "jwt" ], - "time": "2018-08-03T11:23:50+00:00" + "time": "2018-11-11T12:22:26+00:00" }, { "name": "league/event", @@ -2674,16 +2733,16 @@ }, { "name": "marktopper/doctrine-dbal-timestamp-type", - "version": "v1.0.1", + "version": "v1.0.2", "source": { "type": "git", "url": "https://github.com/marktopper/doctrine-dbal-timestamp-type.git", - "reference": "1139c5fe1c855f7c3e329820355d2486ecc70f29" + "reference": "e028dda876204e271d0fc921f013544d58770638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/marktopper/doctrine-dbal-timestamp-type/zipball/1139c5fe1c855f7c3e329820355d2486ecc70f29", - "reference": "1139c5fe1c855f7c3e329820355d2486ecc70f29", + "url": "https://api.github.com/repos/marktopper/doctrine-dbal-timestamp-type/zipball/e028dda876204e271d0fc921f013544d58770638", + "reference": "e028dda876204e271d0fc921f013544d58770638", "shasum": "", "mirrors": [ { @@ -2715,7 +2774,7 @@ "mysql", "timestamp" ], - "time": "2016-11-28T12:42:32+00:00" + "time": "2018-11-11T09:54:26+00:00" }, { "name": "milon/barcode", @@ -2832,16 +2891,16 @@ }, { "name": "monolog/monolog", - "version": "1.23.0", + "version": "1.24.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", "shasum": "", "mirrors": [ { @@ -2912,7 +2971,7 @@ "logging", "psr-3" ], - "time": "2017-06-19T01:22:40+00:00" + "time": "2018-11-05T09:00:11+00:00" }, { "name": "mtdowling/cron-expression", @@ -2966,16 +3025,16 @@ }, { "name": "nesbot/carbon", - "version": "1.34.0", + "version": "1.35.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33" + "reference": "5c05a2be472b22f63291d192410df9f0e0de3b19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33", - "reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/5c05a2be472b22f63291d192410df9f0e0de3b19", + "reference": "5c05a2be472b22f63291d192410df9f0e0de3b19", "shasum": "", "mirrors": [ { @@ -2989,9 +3048,12 @@ "symfony/translation": "~2.6 || ~3.0 || ~4.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2", "phpunit/phpunit": "^4.8.35 || ^5.7" }, + "suggest": { + "friendsofphp/php-cs-fixer": "Needed for the `composer phpcs` command. Allow to automatically fix code style.", + "phpstan/phpstan": "Needed for the `composer phpstan` command. Allow to detect potential errors." + }, "type": "library", "extra": { "laravel": { @@ -3023,7 +3085,7 @@ "datetime", "time" ], - "time": "2018-09-20T19:36:25+00:00" + "time": "2018-11-14T21:55:58+00:00" }, { "name": "nikic/php-parser", @@ -3246,16 +3308,16 @@ }, { "name": "overtrue/wechat", - "version": "4.1.8", + "version": "4.1.11", "source": { "type": "git", "url": "https://github.com/overtrue/wechat.git", - "reference": "b9c7b780706e4a6b16658ab43d5667c57ddde498" + "reference": "ba4be8578246c9091d7ad883834c5fa84ce335d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/overtrue/wechat/zipball/b9c7b780706e4a6b16658ab43d5667c57ddde498", - "reference": "b9c7b780706e4a6b16658ab43d5667c57ddde498", + "url": "https://api.github.com/repos/overtrue/wechat/zipball/ba4be8578246c9091d7ad883834c5fa84ce335d6", + "reference": "ba4be8578246c9091d7ad883834c5fa84ce335d6", "shasum": "", "mirrors": [ { @@ -3311,7 +3373,7 @@ "weixin", "weixin-sdk" ], - "time": "2018-09-20T12:51:32+00:00" + "time": "2018-11-17T06:43:48+00:00" }, { "name": "paragonie/random_compat", @@ -3534,16 +3596,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.11", + "version": "2.0.12", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b" + "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7053f06f91b3de78e143d430e55a8f7889efc08b", - "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/8814dc7841db159daed0b32c2b08fb7e03c6afe7", + "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7", "shasum": "", "mirrors": [ { @@ -3628,7 +3690,7 @@ "x.509", "x509" ], - "time": "2018-04-15T16:55:05+00:00" + "time": "2018-11-04T05:45:48+00:00" }, { "name": "pimple/pimple", @@ -4209,16 +4271,16 @@ }, { "name": "qiniu/php-sdk", - "version": "v7.2.6", + "version": "v7.2.7", "source": { "type": "git", "url": "https://github.com/qiniu/php-sdk.git", - "reference": "305ce1c1c0c71f794661fe45a96facf61ef96c5d" + "reference": "88d11a5857ebc6871204e9be6ceec54bf5f381e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/305ce1c1c0c71f794661fe45a96facf61ef96c5d", - "reference": "305ce1c1c0c71f794661fe45a96facf61ef96c5d", + "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/88d11a5857ebc6871204e9be6ceec54bf5f381e6", + "reference": "88d11a5857ebc6871204e9be6ceec54bf5f381e6", "shasum": "", "mirrors": [ { @@ -4262,7 +4324,7 @@ "sdk", "storage" ], - "time": "2018-05-18T04:37:29+00:00" + "time": "2018-11-06T13:34:32+00:00" }, { "name": "ramsey/uuid", @@ -4476,7 +4538,7 @@ }, { "name": "symfony/cache", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", @@ -4551,16 +4613,16 @@ }, { "name": "symfony/console", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3b2b415d4c48fbefca7dc742aa0a0171bfae4e0b" + "reference": "1d228fb4602047d7b26a0554e0d3efd567da5803" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3b2b415d4c48fbefca7dc742aa0a0171bfae4e0b", - "reference": "3b2b415d4c48fbefca7dc742aa0a0171bfae4e0b", + "url": "https://api.github.com/repos/symfony/console/zipball/1d228fb4602047d7b26a0554e0d3efd567da5803", + "reference": "1d228fb4602047d7b26a0554e0d3efd567da5803", "shasum": "", "mirrors": [ { @@ -4622,11 +4684,11 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-02T16:33:53+00:00" + "time": "2018-10-30T16:50:50+00:00" }, { "name": "symfony/css-selector", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -4685,16 +4747,16 @@ }, { "name": "symfony/debug", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "0a612e9dfbd2ccce03eb174365f31ecdca930ff6" + "reference": "fe9793af008b651c5441bdeab21ede8172dab097" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/0a612e9dfbd2ccce03eb174365f31ecdca930ff6", - "reference": "0a612e9dfbd2ccce03eb174365f31ecdca930ff6", + "url": "https://api.github.com/repos/symfony/debug/zipball/fe9793af008b651c5441bdeab21ede8172dab097", + "reference": "fe9793af008b651c5441bdeab21ede8172dab097", "shasum": "", "mirrors": [ { @@ -4743,20 +4805,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-10-02T16:33:53+00:00" + "time": "2018-10-31T09:06:03+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + "reference": "552541dad078c85d9414b09c041ede488b456cd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", + "reference": "552541dad078c85d9414b09c041ede488b456cd5", "shasum": "", "mirrors": [ { @@ -4812,11 +4874,11 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-07-26T09:10:45+00:00" + "time": "2018-10-10T13:52:42+00:00" }, { "name": "symfony/finder", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -4871,16 +4933,16 @@ }, { "name": "symfony/http-foundation", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3a4498236ade473c52b92d509303e5fd1b211ab1" + "reference": "5aea7a86ca3203dd7a257e765b4b9c9cfd01c6c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3a4498236ade473c52b92d509303e5fd1b211ab1", - "reference": "3a4498236ade473c52b92d509303e5fd1b211ab1", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5aea7a86ca3203dd7a257e765b4b9c9cfd01c6c0", + "reference": "5aea7a86ca3203dd7a257e765b4b9c9cfd01c6c0", "shasum": "", "mirrors": [ { @@ -4927,20 +4989,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:48:18+00:00" + "time": "2018-10-31T08:57:11+00:00" }, { "name": "symfony/http-kernel", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "a0944a9a1d8845da724236cde9a310964acadb1c" + "reference": "4bf0be7c7fe63eff6a5eae2f21c83e77e31a56fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a0944a9a1d8845da724236cde9a310964acadb1c", - "reference": "a0944a9a1d8845da724236cde9a310964acadb1c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4bf0be7c7fe63eff6a5eae2f21c83e77e31a56fb", + "reference": "4bf0be7c7fe63eff6a5eae2f21c83e77e31a56fb", "shasum": "", "mirrors": [ { @@ -5022,11 +5084,11 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2018-10-03T12:03:34+00:00" + "time": "2018-11-03T10:03:02+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -5090,16 +5152,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "", "mirrors": [ { @@ -5151,20 +5213,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/polyfill-php70", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", "shasum": "", "mirrors": [ { @@ -5216,20 +5278,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T06:26:08+00:00" }, { "name": "symfony/process", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "1dc2977afa7d70f90f3fefbcd84152813558910e" + "reference": "35c2914a9f50519bd207164c353ae4d59182c2cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/1dc2977afa7d70f90f3fefbcd84152813558910e", - "reference": "1dc2977afa7d70f90f3fefbcd84152813558910e", + "url": "https://api.github.com/repos/symfony/process/zipball/35c2914a9f50519bd207164c353ae4d59182c2cb", + "reference": "35c2914a9f50519bd207164c353ae4d59182c2cb", "shasum": "", "mirrors": [ { @@ -5271,7 +5333,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:28:39+00:00" + "time": "2018-10-14T17:33:21+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -5342,7 +5404,7 @@ }, { "name": "symfony/routing", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", @@ -5425,16 +5487,16 @@ }, { "name": "symfony/translation", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "9f0b61e339160a466ebcde167a6c5521c810e304" + "reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/9f0b61e339160a466ebcde167a6c5521c810e304", - "reference": "9f0b61e339160a466ebcde167a6c5521c810e304", + "url": "https://api.github.com/repos/symfony/translation/zipball/aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c", + "reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c", "shasum": "", "mirrors": [ { @@ -5496,11 +5558,11 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2018-10-02T16:36:10+00:00" + "time": "2018-10-28T18:38:52+00:00" }, { "name": "symfony/var-dumper", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", @@ -5795,16 +5857,16 @@ }, { "name": "yansongda/pay", - "version": "v2.5.1", + "version": "v2.5.7", "source": { "type": "git", "url": "https://github.com/yansongda/pay.git", - "reference": "c0466d7762f5fbb761478f6b20453256fb8706f2" + "reference": "c3ded381b87834852b4002a8c506a6fde0d3222d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yansongda/pay/zipball/c0466d7762f5fbb761478f6b20453256fb8706f2", - "reference": "c0466d7762f5fbb761478f6b20453256fb8706f2", + "url": "https://api.github.com/repos/yansongda/pay/zipball/c3ded381b87834852b4002a8c506a6fde0d3222d", + "reference": "c3ded381b87834852b4002a8c506a6fde0d3222d", "shasum": "", "mirrors": [ { @@ -5847,7 +5909,7 @@ "pay", "wechat" ], - "time": "2018-10-10T16:05:22+00:00" + "time": "2018-11-12T13:49:31+00:00" }, { "name": "yansongda/supports", @@ -6030,16 +6092,16 @@ }, { "name": "barryvdh/laravel-ide-helper", - "version": "v2.5.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-ide-helper.git", - "reference": "7db1843473e1562d8e0490b51db847d3a1415140" + "reference": "981ff45b43e0cf808af0a5a5f40f6369e0e29499" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/7db1843473e1562d8e0490b51db847d3a1415140", - "reference": "7db1843473e1562d8e0490b51db847d3a1415140", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/981ff45b43e0cf808af0a5a5f40f6369e0e29499", + "reference": "981ff45b43e0cf808af0a5a5f40f6369e0e29499", "shasum": "", "mirrors": [ { @@ -6106,20 +6168,20 @@ "phpstorm", "sublime" ], - "time": "2018-09-06T18:41:09+00:00" + "time": "2018-10-06T09:35:51+00:00" }, { "name": "barryvdh/reflection-docblock", - "version": "v2.0.4", + "version": "v2.0.5", "source": { "type": "git", "url": "https://github.com/barryvdh/ReflectionDocBlock.git", - "reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c" + "reference": "64165bd4ba9a550d11ea57569463b7c722dc6b0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/3dcbd98b5d9384a5357266efba8fd29884458e5c", - "reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c", + "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/64165bd4ba9a550d11ea57569463b7c722dc6b0a", + "reference": "64165bd4ba9a550d11ea57569463b7c722dc6b0a", "shasum": "", "mirrors": [ { @@ -6161,20 +6223,20 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2016-06-13T19:28:20+00:00" + "time": "2018-10-25T19:09:52+00:00" }, { "name": "composer/ca-bundle", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0" + "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/46afded9720f40b9dc63542af4e3e43a1177acb0", - "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660", + "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660", "shasum": "", "mirrors": [ { @@ -6223,20 +6285,20 @@ "ssl", "tls" ], - "time": "2018-08-08T08:57:40+00:00" + "time": "2018-10-18T06:09:13+00:00" }, { "name": "composer/composer", - "version": "1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2" + "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/576aab9b5abb2ed11a1c52353a759363216a4ad2", - "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2", + "url": "https://api.github.com/repos/composer/composer/zipball/e965b9aaa8854c3067f1ed2ae45f436572d73eb7", + "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7", "shasum": "", "mirrors": [ { @@ -6309,7 +6371,7 @@ "dependency", "package" ], - "time": "2018-08-16T14:57:12+00:00" + "time": "2018-11-01T09:05:06+00:00" }, { "name": "composer/semver", @@ -6381,16 +6443,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b" + "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b", - "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2", + "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2", "shasum": "", "mirrors": [ { @@ -6444,7 +6506,7 @@ "spdx", "validator" ], - "time": "2018-04-30T10:33:04+00:00" + "time": "2018-11-01T09:45:54+00:00" }, { "name": "composer/xdebug-handler", @@ -6558,16 +6620,16 @@ }, { "name": "filp/whoops", - "version": "2.2.1", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311" + "reference": "bc0fd11bc455cc20ee4b5edabc63ebbf859324c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/e79cd403fb77fc8963a99ecc30e80ddd885b3311", - "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311", + "url": "https://api.github.com/repos/filp/whoops/zipball/bc0fd11bc455cc20ee4b5edabc63ebbf859324c7", + "reference": "bc0fd11bc455cc20ee4b5edabc63ebbf859324c7", "shasum": "", "mirrors": [ { @@ -6621,7 +6683,7 @@ "throwable", "whoops" ], - "time": "2018-06-30T13:14:06+00:00" + "time": "2018-10-23T09:00:00+00:00" }, { "name": "fzaninotto/faker", @@ -8540,16 +8602,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5" + "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981", + "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981", "shasum": "", "mirrors": [ { @@ -8592,7 +8654,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-10-30T13:18:25+00:00" }, { "name": "symfony/thanks", diff --git a/github/component/Pay/.gitignore b/github/component/Pay/.gitignore new file mode 100644 index 0000000..88e99d5 --- /dev/null +++ b/github/component/Pay/.gitignore @@ -0,0 +1,2 @@ +vendor +composer.lock \ No newline at end of file diff --git a/github/component/Pay/.php_cs b/github/component/Pay/.php_cs new file mode 100644 index 0000000..4d4f91e --- /dev/null +++ b/github/component/Pay/.php_cs @@ -0,0 +1,27 @@ + + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +EOF; +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setRules(array( + '@Symfony' => true, + 'header_comment' => array('header' => $header), + 'array_syntax' => array('syntax' => 'short'), + 'ordered_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'php_unit_construct' => true, + 'php_unit_strict' => true, + )) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('vendor') + ->in(__DIR__) + ) +; \ No newline at end of file diff --git a/github/component/Pay/.travis.yml b/github/component/Pay/.travis.yml new file mode 100644 index 0000000..e5faf0e --- /dev/null +++ b/github/component/Pay/.travis.yml @@ -0,0 +1,16 @@ +language: php + +php: + # using major version aliases + + # aliased to a recent 7.x version + - 7.0 + # aliased to a recent 7.x version + - 7.1 + # aliased to a recent 7.x version + - 7.2 + + +before_script: + - composer self-update + - composer install --prefer-source --no-interaction --dev diff --git a/github/component/Pay/LICENSE b/github/component/Pay/LICENSE new file mode 100644 index 0000000..63b97df --- /dev/null +++ b/github/component/Pay/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 https://www.ibrand.cc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/github/component/Pay/README.md b/github/component/Pay/README.md new file mode 100644 index 0000000..af3228a --- /dev/null +++ b/github/component/Pay/README.md @@ -0,0 +1,11 @@ +# iBrand Address Component + +Address Component for iBrand Application. + +[![Build Status](https://travis-ci.org/ibrandcc/address.svg?branch=master)](https://travis-ci.org/ibrandcc/address) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ibrandcc/address/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/ibrandcc/address/?branch=master) +[![Code Coverage](https://scrutinizer-ci.com/g/ibrandcc/address/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/ibrandcc/address/?branch=master) +[![Build Status](https://scrutinizer-ci.com/g/ibrandcc/address/badges/build.png?b=master)](https://scrutinizer-ci.com/g/ibrandcc/address/build-status/master) +[![Latest Stable Version](https://poser.pugx.org/ibrand/address/v/stable)](https://packagist.org/packages/ibrand/address) +[![Latest Unstable Version](https://poser.pugx.org/ibrand/address/v/unstable)](https://packagist.org/packages/ibrand/address) +[![License](https://poser.pugx.org/ibrand/address/license)](https://packagist.org/packages/ibrand/address) \ No newline at end of file diff --git a/github/component/Pay/composer.json b/github/component/Pay/composer.json new file mode 100644 index 0000000..d182dcc --- /dev/null +++ b/github/component/Pay/composer.json @@ -0,0 +1,45 @@ +{ + "name": "ibrand/pay", + "type": "library", + "description": "ibrand pay component", + "keywords": [ + "iBrand", + "pay", + "component" + ], + "license": "MIT", + "authors": [ + { + "name": "shjchen", + "email": "ibrand.shjchen@foxmail.com" + } + ], + "require": { + "php": ">=7.0", + "hidehalo/nanoid-php": "^1.1", + "yansongda/pay": "^2.5" + }, + "require-dev": { + "mockery/mockery": "~1.0", + "phpunit/phpunit": "~6.0", + "orchestra/testbench": "~3.5", + "orchestra/database": "~3.5" + }, + "autoload": { + "psr-4": { + "iBrand\\Component\\Pay\\": "src/" + } + }, + "extra": { + "laravel": { + "providers": [ + "iBrand\\Component\\Pay\\PayServiceProvider" + ], + "aliases": { + "Pay": "iBrand\\Component\\Pay\\Facades\\Pay" + } + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/github/component/Pay/migrations/create_pay_tables.php.stub b/github/component/Pay/migrations/create_pay_tables.php.stub new file mode 100644 index 0000000..ac4f0de --- /dev/null +++ b/github/component/Pay/migrations/create_pay_tables.php.stub @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class CreatePayTables extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::create('ibrand_pay', function (Blueprint $table) { + $table->increments('id'); + $table->string('charge_id')->unique(); + $table->string('app'); //具体支付配置 + $table->string('type'); //业务类型 + $table->boolean('paid')->default(false); + $table->boolean('refunded')->default(false); + $table->boolean('reversed')->default(false); + $table->string('channel'); + $table->string('order_no'); + $table->string('client_ip'); + $table->integer('amount'); + $table->string('currency')->default('cny'); + $table->string('subject'); + $table->string('body'); + $table->string('extra')->nullable(); + $table->timestamp('time_paid')->nullable(); + $table->timestamp('time_expire')->nullable(); + $table->string('transaction_no'); + $table->text('transaction_meta')->nullable(); + $table->text('metadata')->nullable(); + $table->text('credential')->nullable(); + $table->text('description')->nullable(); + $table->string('failure_code')->nullable(); + $table->text('failure_msg')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('ibrand_pay'); + } +} diff --git a/github/component/Pay/phpunit.xml b/github/component/Pay/phpunit.xml new file mode 100644 index 0000000..2f16e34 --- /dev/null +++ b/github/component/Pay/phpunit.xml @@ -0,0 +1,29 @@ + + + + + ./tests/ + vendor + + + + + src/ + + vendor/ + + + + + + + + \ No newline at end of file diff --git a/github/component/Pay/scrutinizer.yml b/github/component/Pay/scrutinizer.yml new file mode 100644 index 0000000..7592fd3 --- /dev/null +++ b/github/component/Pay/scrutinizer.yml @@ -0,0 +1,30 @@ +checks: + php: + code_rating: true + duplication: true + +tools: + # external_code_coverage: true + php_mess_detector: true + php_code_sniffer: true + sensiolabs_security_checker: true + # php_code_coverage: true + php_pdepend: true + php_loc: + enabled: true + excluded_dirs: [vendor, tests] +filter: + excluded_paths: + - 'tests/*' + +build: + dependencies: + before: + - composer install + tests: + override: + - + command: vendor/bin/phpunit --coverage-clover=my-coverage-file + coverage: + file: my-coverage-file + format: clover \ No newline at end of file diff --git a/github/component/Pay/src/Charges/BaseCharge.php b/github/component/Pay/src/Charges/BaseCharge.php new file mode 100644 index 0000000..2e90881 --- /dev/null +++ b/github/component/Pay/src/Charges/BaseCharge.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Charges; + +use Hidehalo\Nanoid\Client; +use iBrand\Component\Pay\Contracts\PayChargeContract; + +abstract class BaseCharge implements PayChargeContract +{ + + protected function getWxPayCode($order_sn, $channel) + { + switch ($channel) { + case 'wx_pub': + case 'wx_pub_qr': + case 'wx_lite': + $client = new Client(); + + return 'wx_'.$client->generateId($size = 24); + default: + return $order_sn; + } + } + + protected function validateParams($params = null) + { + if ($params && !is_array($params)) { + $message = 'You must pass an array as the first argument to pay API ' + .'method calls.'; + throw new \InvalidArgumentException($message); + } + } +} diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php new file mode 100644 index 0000000..b599e21 --- /dev/null +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -0,0 +1,167 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Charges; + +use Carbon\Carbon; +use iBrand\Component\Pay\Contracts\PayChargeContract; +use iBrand\Component\Pay\Models\Pay as PayModel; +use Yansongda\Pay\Pay; + +class DefaultCharge extends BaseCharge implements PayChargeContract +{ + public function create(array $data, $type = 'default', $app = 'default') + { + $this->validateParams($data); + + if (!in_array($data['channel'], ['wx_pub', 'wx_pub_qr', 'wx_lite', 'alipay_wap', 'alipay_pc_direct'])) { + throw new \InvalidArgumentException("Unsupported channel [{$data['channel']}]"); + } + + $modelData = array_merge(['app' => $app], array_pluck($data, ['type', 'channel', 'order_no', 'client_ip', 'subject', 'body', 'extra', 'time_expire', 'metadata', 'description'])); + + $payModel = PayModel::create($modelData); + + try { + $credential = null; + + switch ($data['channel']) { + case 'wx_pub': + case 'wx_pub_qr': + case 'wx_lite': + $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.'.$app)); + break; + case 'alipay_wap': + case 'alipay_pc_direct': + /*return $this->createAliCharge($user_id, $channel, $type, $order_no, $amount, $subject, $body, $ip, $openid, $extra, $submit_time);*/ + } + + $payModel->credential = json_encode($credential); + $payModel->save(); + + return $payModel; + } catch (\Exception $exception) { + } + } + + /** + * @param $data + * @param $config + * @return array|null + */ + protected function createWechatCharge($data, $config) + { + $chargeData = [ + 'body' => mb_strcut($data['body'], 0, 32, 'UTF-8'), + 'out_trade_no' => $this->getWxPayCode($data['order_no'], $data['channel']), + 'total_fee' => abs($data['amount']), + 'spbill_create_ip' => $data['client_ip'], + ]; + + if (isset($data['time_expire'])) { + $chargeData['time_expire'] = $data['time_expire']; + } + + if (isset($data['metadata'])) { + $chargeData['attach'] = json_encode($data['metadata']); + } + + switch ($data['channel']) { + case 'wx_pub_qr': + $pay = Pay::wechat($config)->scan($chargeData); + + return ['wechat' => $pay]; + case 'wx_pub': + $chargeData['openid'] = $data['extra']['openid']; + $pay = Pay::wechat($config)->mp($chargeData); + + return ['wechat' => $pay]; + + case 'wx_lite': + $chargeData['openid'] = $data['extra']['openid']; + $pay = Pay::wechat($config)->miniapp($chargeData); + + return ['wechat' => $pay]; + default: + return null; + } + } + + protected function createAliCharge($user_id, $channel, $type = 'order', $order_no, $amount, $subject, $body, $ip = '127.0.0.1', $openid = '', $extra = [], $submit_time = '') + { + $config = $this->getConfig('alipay'); + + $delayTime = app('system_setting')->getSetting('order_auto_cancel_time') ? app('system_setting')->getSetting('order_auto_cancel_time') : 1440; + $time_expire = $delayTime.'m'; + if ($submit_time and ($gap = Carbon::now()->timestamp - strtotime($submit_time)) > 0) { + $time_expire = ($delayTime - floor($gap / 60)).'m'; + } + + $extra = $this->createExtra($channel, '', $extra, $type); + + $amount = $amount / 100; + + $chargeData = [ + 'body' => mb_strcut($body, 0, 32, 'UTF-8'), + 'out_trade_no' => $order_no, + 'total_amount' => number_format($amount, 2, '.', ''), + 'subject' => mb_strcut($subject, 0, 32, 'UTF-8'), + 'client_ip' => $ip, + 'timeout_express' => $time_expire, + 'passback_params' => json_encode(['user_id' => $user_id, 'order_sn' => $order_no, 'type' => $type, 'channel' => $channel]), + ]; + + if (!empty($extra['cancel_url'])) { + $chargeData['quit_url'] = $extra['cancel_url']; + } + + $return_url = $extra['success_url'].$order_no; + $return_url = str_replace('/', '~', $return_url); + $return_url = str_replace('?', '@', $return_url); + $return_url = str_replace('#', '*', $return_url); + + $config['return_url'] = $config['return_url'].'/'.$return_url; //同步通知url + $config['notify_url'] = $config['notify_url']; //异步通知url + + $ali_pay = []; + if ('alipay_pc_direct' == $channel) { + //unset($chargeData['passback_params']); + $ali_pay = Pay::alipay($config)->web($chargeData); + $key = base64_encode($order_no); + \Cache::put($order_no, html_entity_decode($ali_pay), 1); + $this->createPaymentLog('create_charge', Carbon::now(), $order_no, $chargeData['out_trade_no'], '', $amount * 100, $channel, $type, 'SUCCESS', $user_id, $ali_pay); + + return [ + 'type' => $type, + 'order_no' => $order_no, + 'channel' => $channel, + 'pay_scene' => 'live', + 'key' => $key, + ]; + } + + if ('alipay_wap' == $channel) { + $ali_pay = Pay::alipay($config)->wap($chargeData); + $this->createPaymentLog('create_charge', Carbon::now(), $order_no, $chargeData['out_trade_no'], '', $amount * 100, $channel, $type, 'SUCCESS', $user_id, $ali_pay); + + return [ + 'type' => $type, + 'order_no' => $order_no, + 'channel' => $channel, + 'pay_scene' => 'live', + 'form' => html_entity_decode($ali_pay), + ]; + } + + return null; + } + +} diff --git a/github/component/Pay/src/Contracts/PayChargeContract.php b/github/component/Pay/src/Contracts/PayChargeContract.php new file mode 100644 index 0000000..0d470c2 --- /dev/null +++ b/github/component/Pay/src/Contracts/PayChargeContract.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Contracts; + +interface PayChargeContract +{ + public function create(array $data, $type = 'default', $app = 'default'); +} diff --git a/github/component/Pay/src/Facades/Charge.php b/github/component/Pay/src/Facades/Charge.php new file mode 100644 index 0000000..e8acecf --- /dev/null +++ b/github/component/Pay/src/Facades/Charge.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Facades; + +use Illuminate\Support\Facades\Facade; + +class Charge extends Facade +{ + /** + * Return the facade accessor. + * + * @return string + */ + public static function getFacadeAccessor() + { + return 'ibrand.charge'; + } +} diff --git a/github/component/Pay/src/Http/Controllers/AlipayNotifyController.php b/github/component/Pay/src/Http/Controllers/AlipayNotifyController.php new file mode 100644 index 0000000..3ca65a5 --- /dev/null +++ b/github/component/Pay/src/Http/Controllers/AlipayNotifyController.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Http\Controllers; + +use Illuminate\Routing\Controller; + +class AlipayNotifyController extends Controller +{ + public function notify() + { + } +} diff --git a/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php new file mode 100644 index 0000000..baf1893 --- /dev/null +++ b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Http\Controllers; + +use Illuminate\Routing\Controller; + +class WechatPayNotifyController extends Controller +{ + public function notify() + { + } +} diff --git a/github/component/Pay/src/Models/Pay.php b/github/component/Pay/src/Models/Pay.php new file mode 100644 index 0000000..b961c94 --- /dev/null +++ b/github/component/Pay/src/Models/Pay.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Models; + +use Hidehalo\Nanoid\Client; +use Illuminate\Database\Eloquent\Model; + +class Pay extends Model +{ + protected $table = 'ibrand_pay'; + + protected $guarded = ['id']; + + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + + $client = new Client(); + + $this->charge_id = 'ch_'.$client->generateId($size = 24); + } +} diff --git a/github/component/Pay/src/PayServiceProvider.php b/github/component/Pay/src/PayServiceProvider.php new file mode 100644 index 0000000..811cdae --- /dev/null +++ b/github/component/Pay/src/PayServiceProvider.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay; + +use iBrand\Component\Pay\Charges\DefaultCharge; +use iBrand\Component\Pay\Contracts\PayChargeContract; +use Illuminate\Routing\Route; +use Illuminate\Support\ServiceProvider; +use InvalidArgumentException; + +/** + * Created by PhpStorm. + * User: Administrator + * Date: 2018-11-19 + * Time: 12:21. + */ +class PayServiceProvider extends ServiceProvider +{ + protected $namespace = 'iBrand\Component\Pay\Http\Controllers'; + + /** + * Boot the service provider. + */ + public function boot() + { + if (!class_exists('CreatePayTables')) { + $timestamp = date('Y_m_d_His', time()); + $this->publishes([ + __DIR__.'/../migrations/create_pay_tables.php.stub' => database_path()."/migrations/{$timestamp}_create_pay_tables.php", + ], 'migrations'); + } + + if ($this->app->runningInConsole()) { + $this->publishes([ + __DIR__.'/config.php' => config_path('ibrand/pay.php'), + ]); + } + + $this->loadRoutes(); + } + + /** + * Register the service provider. + */ + public function register() + { + $this->mergeConfigFrom( + __DIR__.'/config.php', 'ibrand.pay' + ); + + $config = config('ibrand.pay'); + + $this->app->singleton(PayChargeContract::class, function () use ($config) { + switch ($config['driver']) { + case 'default': + return new DefaultCharge(); + } + + throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]"); + }); + + $this->app->alias(PayChargeContract::class, 'ibrand.charge'); + } + + public function loadRoutes() + { + $routeAttr = config('ibrand.pay.route', []); + + Route::group(array_merge(['namespace' => $this->namespace], $routeAttr), function ($router) { + $router->post('wechat', 'WechatPayNotifyController@notify'); + $router->post('alipay', 'AliPayNotifyController@notify'); + }); + } +} diff --git a/github/component/Pay/src/config.php b/github/component/Pay/src/config.php new file mode 100644 index 0000000..43d15e9 --- /dev/null +++ b/github/component/Pay/src/config.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +return [ + 'route' => [ + 'prefix' => 'notify', + 'middleware' => ['api'], + ], + + 'driver' => 'default', + + 'default' => [ + 'alipay' => [ + 'default' => [ + // 支付宝分配的 APPID + 'app_id' => env('ALI_APP_ID', ''), + // 支付宝异步通知地址 + 'notify_url' => '', + // 支付成功后同步通知地址 + 'return_url' => '', + // 阿里公共密钥,验证签名时使用 + 'ali_public_key' => env('ALI_PUBLIC_KEY', ''), + // 自己的私钥,签名时使用 + 'private_key' => env('ALI_PRIVATE_KEY', ''), + // optional,默认 warning;日志路径为:sys_get_temp_dir().'/logs/yansongda.pay.log' + 'log' => [ + 'file' => storage_path('logs/alipay.log'), + // 'level' => 'debug' + 'type' => 'single', // optional, 可选 daily. + 'max_file' => 30, + ], + // optional,设置此参数,将进入沙箱模式 + // 'mode' => 'dev', + ], + ], + + 'wechat' => [ + 'default' => [ + // 公众号 APPID + 'app_id' => env('WECHAT_APP_ID', ''), + // 小程序 APPID + 'miniapp_id' => env('WECHAT_MINIAPP_ID', ''), + // APP 引用的 appid + 'appid' => env('WECHAT_APPID', ''), + // 微信支付分配的微信商户号 + 'mch_id' => env('WECHAT_MCH_ID', ''), + // 微信支付异步通知地址 + 'notify_url' => '', + // 微信支付签名秘钥 + 'key' => env('WECHAT_KEY', ''), + // 客户端证书路径,退款、红包等需要用到。请填写绝对路径,linux 请确保权限问题。pem 格式。 + 'cert_client' => '', + // 客户端秘钥路径,退款、红包等需要用到。请填写绝对路径,linux 请确保权限问题。pem 格式。 + 'cert_key' => '', + // optional,默认 warning;日志路径为:sys_get_temp_dir().'/logs/yansongda.pay.log' + 'log' => [ + 'file' => storage_path('logs/wechat.log'), + // 'level' => 'debug' + 'type' => 'single', // optional, 可选 daily. + 'max_file' => 30, + ], + // optional + // 'dev' 时为沙箱模式 + // 'hk' 时为东南亚节点 + // 'mode' => 'dev', + ], + // ... + ], + ], +]; From 115893f5065623fe5d284ddbb5ad165f008ccdaf Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 19:43:11 +0800 Subject: [PATCH 02/17] add PayServiceProvider to app config. --- config/app.php | 3 +++ github/component/Pay/composer.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/config/app.php b/config/app.php index e876814..81caa78 100644 --- a/config/app.php +++ b/config/app.php @@ -180,6 +180,8 @@ Prettus\Repository\Providers\RepositoryServiceProvider::class, + iBrand\Component\Pay\PayServiceProvider::class, + iBrand\EC\Open\Core\Providers\AppServiceProvider::class, iBrand\EC\Open\Server\Providers\ServerServiceProvider::class, @@ -241,6 +243,7 @@ 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, + 'Charge'=> iBrand\Component\Pay\Facades\Charge::class, ], ]; diff --git a/github/component/Pay/composer.json b/github/component/Pay/composer.json index d182dcc..25d63df 100644 --- a/github/component/Pay/composer.json +++ b/github/component/Pay/composer.json @@ -36,7 +36,7 @@ "iBrand\\Component\\Pay\\PayServiceProvider" ], "aliases": { - "Pay": "iBrand\\Component\\Pay\\Facades\\Pay" + "Charge": "iBrand\\Component\\Pay\\Facades\\Charge" } } }, From ab9198bea8befefd565967bd76099434d357ae66 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 19:46:07 +0800 Subject: [PATCH 03/17] fix Route using bug. --- github/component/Pay/src/PayServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/component/Pay/src/PayServiceProvider.php b/github/component/Pay/src/PayServiceProvider.php index 811cdae..0ad57fe 100644 --- a/github/component/Pay/src/PayServiceProvider.php +++ b/github/component/Pay/src/PayServiceProvider.php @@ -13,7 +13,7 @@ use iBrand\Component\Pay\Charges\DefaultCharge; use iBrand\Component\Pay\Contracts\PayChargeContract; -use Illuminate\Routing\Route; +use Illuminate\Support\Facades\Route; use Illuminate\Support\ServiceProvider; use InvalidArgumentException; From 372d39fb90e306ce02f724268bcc3f14b1144354 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 19:55:52 +0800 Subject: [PATCH 04/17] update .env name. --- github/component/Pay/src/config.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/github/component/Pay/src/config.php b/github/component/Pay/src/config.php index 43d15e9..7705b8a 100644 --- a/github/component/Pay/src/config.php +++ b/github/component/Pay/src/config.php @@ -21,21 +21,21 @@ 'alipay' => [ 'default' => [ // 支付宝分配的 APPID - 'app_id' => env('ALI_APP_ID', ''), + 'app_id' => env('ALI_PAYMENT_APP_ID', ''), // 支付宝异步通知地址 'notify_url' => '', // 支付成功后同步通知地址 'return_url' => '', // 阿里公共密钥,验证签名时使用 - 'ali_public_key' => env('ALI_PUBLIC_KEY', ''), + 'ali_public_key' => env('ALI_PAYMENT_PUBLIC_KEY', ''), // 自己的私钥,签名时使用 - 'private_key' => env('ALI_PRIVATE_KEY', ''), + 'private_key' => env('ALI_PAYMENT_PRIVATE_KEY', ''), // optional,默认 warning;日志路径为:sys_get_temp_dir().'/logs/yansongda.pay.log' 'log' => [ 'file' => storage_path('logs/alipay.log'), // 'level' => 'debug' - 'type' => 'single', // optional, 可选 daily. - 'max_file' => 30, + 'type' => 'single', // optional, 可选 daily. + 'max_file' => 30, ], // optional,设置此参数,将进入沙箱模式 // 'mode' => 'dev', @@ -45,17 +45,17 @@ 'wechat' => [ 'default' => [ // 公众号 APPID - 'app_id' => env('WECHAT_APP_ID', ''), + 'app_id' => env('WECHAT_PAYMENT_APP_ID', ''), // 小程序 APPID - 'miniapp_id' => env('WECHAT_MINIAPP_ID', ''), + 'miniapp_id' => env('WECHAT_PAYMENT_MINIAPP_ID', ''), // APP 引用的 appid - 'appid' => env('WECHAT_APPID', ''), + 'appid' => env('WECHAT_PAYMENT_APPID', ''), // 微信支付分配的微信商户号 - 'mch_id' => env('WECHAT_MCH_ID', ''), + 'mch_id' => env('WECHAT_PAYMENT_MCH_ID', ''), // 微信支付异步通知地址 - 'notify_url' => '', + 'notify_url' => '/notify/wechat', // 微信支付签名秘钥 - 'key' => env('WECHAT_KEY', ''), + 'key' => env('WECHAT_PAYMENT_KEY', ''), // 客户端证书路径,退款、红包等需要用到。请填写绝对路径,linux 请确保权限问题。pem 格式。 'cert_client' => '', // 客户端秘钥路径,退款、红包等需要用到。请填写绝对路径,linux 请确保权限问题。pem 格式。 @@ -64,8 +64,8 @@ 'log' => [ 'file' => storage_path('logs/wechat.log'), // 'level' => 'debug' - 'type' => 'single', // optional, 可选 daily. - 'max_file' => 30, + 'type' => 'single', // optional, 可选 daily. + 'max_file' => 30, ], // optional // 'dev' 时为沙箱模式 From 7a3080e2210bbffdb17106ce211031c6fb7b2c91 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 20:14:26 +0800 Subject: [PATCH 05/17] fix pay charge bug. --- .../Pay/migrations/create_pay_tables.php.stub | 4 ++-- github/component/Pay/src/Charges/DefaultCharge.php | 13 +++++++------ .../src/Http/Controllers/WechatPayController.php | 11 +++++++++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/github/component/Pay/migrations/create_pay_tables.php.stub b/github/component/Pay/migrations/create_pay_tables.php.stub index ac4f0de..7c8e59c 100644 --- a/github/component/Pay/migrations/create_pay_tables.php.stub +++ b/github/component/Pay/migrations/create_pay_tables.php.stub @@ -32,7 +32,7 @@ class CreatePayTables extends Migration $table->boolean('reversed')->default(false); $table->string('channel'); $table->string('order_no'); - $table->string('client_ip'); + $table->string('client_ip')->default('127.0.0.1'); $table->integer('amount'); $table->string('currency')->default('cny'); $table->string('subject'); @@ -40,7 +40,7 @@ class CreatePayTables extends Migration $table->string('extra')->nullable(); $table->timestamp('time_paid')->nullable(); $table->timestamp('time_expire')->nullable(); - $table->string('transaction_no'); + $table->string('transaction_no')->nullable(); $table->text('transaction_meta')->nullable(); $table->text('metadata')->nullable(); $table->text('credential')->nullable(); diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index b599e21..dbb917d 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -26,7 +26,8 @@ public function create(array $data, $type = 'default', $app = 'default') throw new \InvalidArgumentException("Unsupported channel [{$data['channel']}]"); } - $modelData = array_merge(['app' => $app], array_pluck($data, ['type', 'channel', 'order_no', 'client_ip', 'subject', 'body', 'extra', 'time_expire', 'metadata', 'description'])); + $modelData = array_merge(['app' => $app, 'type' => $type], array_pluck($data, ['channel', 'order_no', 'client_ip', 'subject','amount', + 'body', 'extra', 'time_expire', 'metadata', 'description'])); $payModel = PayModel::create($modelData); @@ -37,7 +38,7 @@ public function create(array $data, $type = 'default', $app = 'default') case 'wx_pub': case 'wx_pub_qr': case 'wx_lite': - $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.'.$app)); + $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.' . $app)); break; case 'alipay_wap': case 'alipay_pc_direct': @@ -100,9 +101,9 @@ protected function createAliCharge($user_id, $channel, $type = 'order', $order_n $config = $this->getConfig('alipay'); $delayTime = app('system_setting')->getSetting('order_auto_cancel_time') ? app('system_setting')->getSetting('order_auto_cancel_time') : 1440; - $time_expire = $delayTime.'m'; + $time_expire = $delayTime . 'm'; if ($submit_time and ($gap = Carbon::now()->timestamp - strtotime($submit_time)) > 0) { - $time_expire = ($delayTime - floor($gap / 60)).'m'; + $time_expire = ($delayTime - floor($gap / 60)) . 'm'; } $extra = $this->createExtra($channel, '', $extra, $type); @@ -123,12 +124,12 @@ protected function createAliCharge($user_id, $channel, $type = 'order', $order_n $chargeData['quit_url'] = $extra['cancel_url']; } - $return_url = $extra['success_url'].$order_no; + $return_url = $extra['success_url'] . $order_no; $return_url = str_replace('/', '~', $return_url); $return_url = str_replace('?', '@', $return_url); $return_url = str_replace('#', '*', $return_url); - $config['return_url'] = $config['return_url'].'/'.$return_url; //同步通知url + $config['return_url'] = $config['return_url'] . '/' . $return_url; //同步通知url $config['notify_url'] = $config['notify_url']; //异步通知url $ali_pay = []; diff --git a/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php b/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php index 074cc8d..8a664ae 100644 --- a/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php +++ b/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php @@ -16,6 +16,7 @@ use iBrand\Component\Order\Repositories\OrderRepository; use iBrand\Component\Payment\Models\Payment; use Illuminate\Http\Request; +use iBrand\Component\Pay\Facades\Charge; class WechatPayController extends Controller { @@ -48,8 +49,14 @@ public function createCharge() return $this->failed('无法支付,需支付金额为零'); } + $charge = Charge::create(['channel' => 'wx_lite', 'order_no' => $order_no, 'amount' => $order->getNeedPayAmount(), + 'client_ip' => \request()->getClientIp(), 'subject' => $order->getSubject() + , 'body' => $order->getSubject(), 'extra' => ['openid' => \request('openid')]]); + + $this->success(compact('charge')); + //openid 和 订单编号 - $payment = EasyWeChat::payment(); + /*$payment = EasyWeChat::payment(); $data = $payment->order->unify([ 'body' => $order->getSubject(), @@ -73,6 +80,6 @@ public function createCharge() } elseif ('FAIL' == $data['result_code']) { return $this->failed($data['err_code_des']); } - return $this->failed('支付未知错误'); + return $this->failed('支付未知错误');*/ } } From c28281d2f48567692995923aacda3c6c158d9b13 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 20:22:15 +0800 Subject: [PATCH 06/17] fix model save bug. --- github/component/Pay/src/Charges/DefaultCharge.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index dbb917d..cc3b352 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -26,9 +26,12 @@ public function create(array $data, $type = 'default', $app = 'default') throw new \InvalidArgumentException("Unsupported channel [{$data['channel']}]"); } - $modelData = array_merge(['app' => $app, 'type' => $type], array_pluck($data, ['channel', 'order_no', 'client_ip', 'subject','amount', + $modelData = array_merge(['app' => $app, 'type' => $type], array_only($data, ['channel', 'order_no', 'client_ip', 'subject','amount', 'body', 'extra', 'time_expire', 'metadata', 'description'])); + $modelData['extra'] = json_encode($data['extra']); + $modelData['metadata'] = json_encode($data['metadata']); + $payModel = PayModel::create($modelData); try { From 313235ab2545651cb14effaeb1625e1e5b257eed Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 20:26:10 +0800 Subject: [PATCH 07/17] fix model bug. --- .../component/Pay/src/Charges/DefaultCharge.php | 6 +++--- github/component/Pay/src/Models/Pay.php | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index cc3b352..e47c94f 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -26,11 +26,11 @@ public function create(array $data, $type = 'default', $app = 'default') throw new \InvalidArgumentException("Unsupported channel [{$data['channel']}]"); } - $modelData = array_merge(['app' => $app, 'type' => $type], array_only($data, ['channel', 'order_no', 'client_ip', 'subject','amount', + $modelData = array_merge(['app' => $app, 'type' => $type], array_only($data, ['channel', 'order_no', 'client_ip', 'subject', 'amount', 'body', 'extra', 'time_expire', 'metadata', 'description'])); - $modelData['extra'] = json_encode($data['extra']); - $modelData['metadata'] = json_encode($data['metadata']); + /*$modelData['extra'] = isset($data['extra']) ?? json_encode($data['extra']); + $modelData['metadata'] = isset($data['metadata']) ?? json_encode($data['metadata']);*/ $payModel = PayModel::create($modelData); diff --git a/github/component/Pay/src/Models/Pay.php b/github/component/Pay/src/Models/Pay.php index b961c94..4802cfa 100644 --- a/github/component/Pay/src/Models/Pay.php +++ b/github/component/Pay/src/Models/Pay.php @@ -26,6 +26,20 @@ public function __construct(array $attributes = []) $client = new Client(); - $this->charge_id = 'ch_'.$client->generateId($size = 24); + $this->charge_id = 'ch_' . $client->generateId($size = 24); + } + + public function setMetadataAttribute($value) + { + if (!empty($value)) { + $this->attributes['metadata'] = json_encode($value); + } + } + + public function setExtraAttribute($value) + { + if (!empty($value)) { + $this->attributes['extra'] = json_encode($value); + } } } From 064e251f4107fd378cec9bc4daa9ad60d20b424c Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 20:30:00 +0800 Subject: [PATCH 08/17] fix bug. --- .../EC.Open.Server/src/Http/Controllers/WechatPayController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php b/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php index 8a664ae..413caa4 100644 --- a/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php +++ b/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php @@ -53,7 +53,7 @@ public function createCharge() 'client_ip' => \request()->getClientIp(), 'subject' => $order->getSubject() , 'body' => $order->getSubject(), 'extra' => ['openid' => \request('openid')]]); - $this->success(compact('charge')); + return $this->success(compact('charge')); //openid 和 订单编号 /*$payment = EasyWeChat::payment(); From 7aab598f67a384e3b7ffec335a0309cbfaa0b130 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 20:43:53 +0800 Subject: [PATCH 09/17] get attribute for pay model. --- github/component/Pay/src/Models/Pay.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/github/component/Pay/src/Models/Pay.php b/github/component/Pay/src/Models/Pay.php index 4802cfa..6514255 100644 --- a/github/component/Pay/src/Models/Pay.php +++ b/github/component/Pay/src/Models/Pay.php @@ -42,4 +42,18 @@ public function setExtraAttribute($value) $this->attributes['extra'] = json_encode($value); } } + + public function getMetadataAttribute($value){ + if (!empty($value)) { + $value = json_decode($value,true); + } + return $value; + } + + public function getExtraAttribute($value){ + if (!empty($value)) { + $value = json_decode($value,true); + } + return $value; + } } From a080b9ed85757724821248e12441ae9f7b30af24 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 20:46:37 +0800 Subject: [PATCH 10/17] set credential attribute for pay model. --- github/component/Pay/src/Charges/DefaultCharge.php | 12 +++++------- github/component/Pay/src/Models/Pay.php | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index e47c94f..33c27c5 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -29,12 +29,9 @@ public function create(array $data, $type = 'default', $app = 'default') $modelData = array_merge(['app' => $app, 'type' => $type], array_only($data, ['channel', 'order_no', 'client_ip', 'subject', 'amount', 'body', 'extra', 'time_expire', 'metadata', 'description'])); - /*$modelData['extra'] = isset($data['extra']) ?? json_encode($data['extra']); - $modelData['metadata'] = isset($data['metadata']) ?? json_encode($data['metadata']);*/ - $payModel = PayModel::create($modelData); - try { + /*try {*/ $credential = null; switch ($data['channel']) { @@ -48,12 +45,13 @@ public function create(array $data, $type = 'default', $app = 'default') /*return $this->createAliCharge($user_id, $channel, $type, $order_no, $amount, $subject, $body, $ip, $openid, $extra, $submit_time);*/ } - $payModel->credential = json_encode($credential); + $payModel->credential = $credential; $payModel->save(); return $payModel; - } catch (\Exception $exception) { - } + /*} catch (\Exception $exception) { + + }*/ } /** diff --git a/github/component/Pay/src/Models/Pay.php b/github/component/Pay/src/Models/Pay.php index 6514255..fb1d7ea 100644 --- a/github/component/Pay/src/Models/Pay.php +++ b/github/component/Pay/src/Models/Pay.php @@ -56,4 +56,18 @@ public function getExtraAttribute($value){ } return $value; } + + public function setCredentialAttribute($value) + { + if (!empty($value)) { + $this->attributes['credential'] = json_encode($value); + } + } + + public function getCredentialAttribute($value){ + if (!empty($value)) { + $value = json_decode($value,true); + } + return $value; + } } From 1d0dfe0c22c9a9d2a586a15f772471c1c3c6dcc3 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Mon, 19 Nov 2018 21:06:55 +0800 Subject: [PATCH 11/17] update pay . --- .../Pay/migrations/create_pay_tables.php.stub | 1 + .../component/Pay/src/Charges/BaseCharge.php | 5 +-- .../Pay/src/Charges/DefaultCharge.php | 42 ++++++++++--------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/github/component/Pay/migrations/create_pay_tables.php.stub b/github/component/Pay/migrations/create_pay_tables.php.stub index 7c8e59c..001f50a 100644 --- a/github/component/Pay/migrations/create_pay_tables.php.stub +++ b/github/component/Pay/migrations/create_pay_tables.php.stub @@ -32,6 +32,7 @@ class CreatePayTables extends Migration $table->boolean('reversed')->default(false); $table->string('channel'); $table->string('order_no'); + $table->string('out_trade_no')->nullable(); $table->string('client_ip')->default('127.0.0.1'); $table->integer('amount'); $table->string('currency')->default('cny'); diff --git a/github/component/Pay/src/Charges/BaseCharge.php b/github/component/Pay/src/Charges/BaseCharge.php index 2e90881..016b2b4 100644 --- a/github/component/Pay/src/Charges/BaseCharge.php +++ b/github/component/Pay/src/Charges/BaseCharge.php @@ -24,8 +24,7 @@ protected function getWxPayCode($order_sn, $channel) case 'wx_pub_qr': case 'wx_lite': $client = new Client(); - - return 'wx_'.$client->generateId($size = 24); + return 'wx_' . $client->formatedId('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz-',24); default: return $order_sn; } @@ -35,7 +34,7 @@ protected function validateParams($params = null) { if ($params && !is_array($params)) { $message = 'You must pass an array as the first argument to pay API ' - .'method calls.'; + . 'method calls.'; throw new \InvalidArgumentException($message); } } diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index 33c27c5..3e89987 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -32,23 +32,25 @@ public function create(array $data, $type = 'default', $app = 'default') $payModel = PayModel::create($modelData); /*try {*/ - $credential = null; - - switch ($data['channel']) { - case 'wx_pub': - case 'wx_pub_qr': - case 'wx_lite': - $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.' . $app)); - break; - case 'alipay_wap': - case 'alipay_pc_direct': - /*return $this->createAliCharge($user_id, $channel, $type, $order_no, $amount, $subject, $body, $ip, $openid, $extra, $submit_time);*/ - } - - $payModel->credential = $credential; - $payModel->save(); - - return $payModel; + $credential = null; + $out_trade_no = null; + + switch ($data['channel']) { + case 'wx_pub': + case 'wx_pub_qr': + case 'wx_lite': + $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.' . $app),$out_trade_no); + break; + case 'alipay_wap': + case 'alipay_pc_direct': + /*return $this->createAliCharge($user_id, $channel, $type, $order_no, $amount, $subject, $body, $ip, $openid, $extra, $submit_time);*/ + } + + $payModel->credential = $credential; + $payModel->out_trade_no = $out_trade_no; + $payModel->save(); + + return $payModel; /*} catch (\Exception $exception) { }*/ @@ -59,11 +61,13 @@ public function create(array $data, $type = 'default', $app = 'default') * @param $config * @return array|null */ - protected function createWechatCharge($data, $config) + protected function createWechatCharge($data, $config, &$out_trade_no) { + $out_trade_no = $this->getWxPayCode($data['order_no'], $data['channel']); + $chargeData = [ 'body' => mb_strcut($data['body'], 0, 32, 'UTF-8'), - 'out_trade_no' => $this->getWxPayCode($data['order_no'], $data['channel']), + 'out_trade_no' => $out_trade_no, 'total_fee' => abs($data['amount']), 'spbill_create_ip' => $data['client_ip'], ]; From 5b971b73fdf3880b11289ff1ee8fe03c29fd187b Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Tue, 20 Nov 2018 14:46:38 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E5=B0=81=E8=A3=85=E5=92=8C=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=BC=82=E5=B8=B8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Exceptions/Handler.php | 5 +++ .../Pay/src/Charges/DefaultCharge.php | 43 +++++++++++-------- .../Pay/src/Exceptions/GatewayException.php | 10 +++++ 3 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 github/component/Pay/src/Exceptions/GatewayException.php diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 7e2563a..fc97f59 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -4,6 +4,7 @@ use Exception; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; +use Illuminate\Http\Response; class Handler extends ExceptionHandler { @@ -48,6 +49,10 @@ public function report(Exception $exception) */ public function render($request, Exception $exception) { + if(config('app.debug') || $request->isJson()){ + return new Response(['status' => false, 'code' => 400, 'message' => $exception->getMessage()] + ); + } return parent::render($request, $exception); } } diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index 3e89987..3343c84 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -13,6 +13,7 @@ use Carbon\Carbon; use iBrand\Component\Pay\Contracts\PayChargeContract; +use iBrand\Component\Pay\Exceptions\GatewayException; use iBrand\Component\Pay\Models\Pay as PayModel; use Yansongda\Pay\Pay; @@ -31,29 +32,33 @@ public function create(array $data, $type = 'default', $app = 'default') $payModel = PayModel::create($modelData); - /*try {*/ - $credential = null; - $out_trade_no = null; + try { - switch ($data['channel']) { - case 'wx_pub': - case 'wx_pub_qr': - case 'wx_lite': - $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.' . $app),$out_trade_no); - break; - case 'alipay_wap': - case 'alipay_pc_direct': - /*return $this->createAliCharge($user_id, $channel, $type, $order_no, $amount, $subject, $body, $ip, $openid, $extra, $submit_time);*/ - } + $credential = null; + $out_trade_no = null; + + switch ($data['channel']) { + case 'wx_pub': + case 'wx_pub_qr': + case 'wx_lite': + $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.' . $app), $out_trade_no); + break; + case 'alipay_wap': + case 'alipay_pc_direct': + /*return $this->createAliCharge($user_id, $channel, $type, $order_no, $amount, $subject, $body, $ip, $openid, $extra, $submit_time);*/ + } - $payModel->credential = $credential; - $payModel->out_trade_no = $out_trade_no; - $payModel->save(); + $payModel->credential = $credential; + $payModel->out_trade_no = $out_trade_no; + $payModel->save(); - return $payModel; - /*} catch (\Exception $exception) { + return $payModel; - }*/ + } catch (\Yansongda\Pay\Exceptions\Exception $exception) { + throw new GatewayException('支付通道错误'); + } catch (\Exception $exception){ + throw new GatewayException('支付失败'); + } } /** diff --git a/github/component/Pay/src/Exceptions/GatewayException.php b/github/component/Pay/src/Exceptions/GatewayException.php new file mode 100644 index 0000000..8bad316 --- /dev/null +++ b/github/component/Pay/src/Exceptions/GatewayException.php @@ -0,0 +1,10 @@ + Date: Tue, 20 Nov 2018 14:59:27 +0800 Subject: [PATCH 13/17] remove unused code. formtter error code. --- app/Exceptions/Handler.php | 5 ----- config/api.php | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index fc97f59..7e2563a 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -4,7 +4,6 @@ use Exception; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; -use Illuminate\Http\Response; class Handler extends ExceptionHandler { @@ -49,10 +48,6 @@ public function report(Exception $exception) */ public function render($request, Exception $exception) { - if(config('app.debug') || $request->isJson()){ - return new Response(['status' => false, 'code' => 400, 'message' => $exception->getMessage()] - ); - } return parent::render($request, $exception); } } diff --git a/config/api.php b/config/api.php index 18bfb22..e5b5c86 100644 --- a/config/api.php +++ b/config/api.php @@ -138,10 +138,10 @@ */ 'errorFormat' => [ + 'status' => false, 'message' => ':message', 'errors' => ':errors', - 'code' => ':code', - 'status_code' => ':status_code', + 'code' => ':status_code', 'debug' => ':debug', ], From b9dad0bf4a25586d7164fad9927e21217191b3eb Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Tue, 20 Nov 2018 16:49:20 +0800 Subject: [PATCH 14/17] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E7=9A=84=E9=87=8D=E6=9E=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/app.php | 1 + .../Pay/migrations/create_pay_tables.php.stub | 2 +- .../component/Pay/src/Charges/BaseCharge.php | 6 +-- .../Pay/src/Charges/DefaultCharge.php | 34 +++++++++----- .../Pay/src/Contracts/PayNotifyContract.php | 19 ++++++++ .../Pay/src/Exceptions/GatewayException.php | 10 +++- github/component/Pay/src/Facades/Charge.php | 2 +- .../component/Pay/src/Facades/PayNotify.php | 35 ++++++++++++++ .../Controllers/WechatPayNotifyController.php | 47 ++++++++++++++++++- .../Pay/src/Models/{Pay.php => Charge.php} | 24 ++++++---- .../component/Pay/src/PayServiceProvider.php | 6 +-- github/component/Pay/src/config.php | 2 +- .../src/Providers/PaymentServiceProvider.php | 4 ++ .../Payment/src/Services/PaymentService.php | 18 +++---- 14 files changed, 170 insertions(+), 40 deletions(-) create mode 100644 github/component/Pay/src/Contracts/PayNotifyContract.php create mode 100644 github/component/Pay/src/Facades/PayNotify.php rename github/component/Pay/src/Models/{Pay.php => Charge.php} (73%) diff --git a/config/app.php b/config/app.php index 81caa78..8865cc6 100644 --- a/config/app.php +++ b/config/app.php @@ -244,6 +244,7 @@ 'View' => Illuminate\Support\Facades\View::class, 'Charge'=> iBrand\Component\Pay\Facades\Charge::class, + 'PayNotify' => iBrand\Component\Pay\Facades\PayNotify::class, ], ]; diff --git a/github/component/Pay/migrations/create_pay_tables.php.stub b/github/component/Pay/migrations/create_pay_tables.php.stub index 001f50a..a040d1e 100644 --- a/github/component/Pay/migrations/create_pay_tables.php.stub +++ b/github/component/Pay/migrations/create_pay_tables.php.stub @@ -22,7 +22,7 @@ class CreatePayTables extends Migration */ public function up() { - Schema::create('ibrand_pay', function (Blueprint $table) { + Schema::create('ibrand_pay_charge', function (Blueprint $table) { $table->increments('id'); $table->string('charge_id')->unique(); $table->string('app'); //具体支付配置 diff --git a/github/component/Pay/src/Charges/BaseCharge.php b/github/component/Pay/src/Charges/BaseCharge.php index 016b2b4..982f3b7 100644 --- a/github/component/Pay/src/Charges/BaseCharge.php +++ b/github/component/Pay/src/Charges/BaseCharge.php @@ -16,7 +16,6 @@ abstract class BaseCharge implements PayChargeContract { - protected function getWxPayCode($order_sn, $channel) { switch ($channel) { @@ -24,7 +23,8 @@ protected function getWxPayCode($order_sn, $channel) case 'wx_pub_qr': case 'wx_lite': $client = new Client(); - return 'wx_' . $client->formatedId('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz-',24); + + return 'wx_'.$client->formatedId('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz-', 24); default: return $order_sn; } @@ -34,7 +34,7 @@ protected function validateParams($params = null) { if ($params && !is_array($params)) { $message = 'You must pass an array as the first argument to pay API ' - . 'method calls.'; + .'method calls.'; throw new \InvalidArgumentException($message); } } diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index 3343c84..fb23b89 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -14,11 +14,22 @@ use Carbon\Carbon; use iBrand\Component\Pay\Contracts\PayChargeContract; use iBrand\Component\Pay\Exceptions\GatewayException; -use iBrand\Component\Pay\Models\Pay as PayModel; +use iBrand\Component\Pay\Models\Charge as PayModel; use Yansongda\Pay\Pay; class DefaultCharge extends BaseCharge implements PayChargeContract { + /** + * 创建支付请求 + * + * @param array $data 支付数据 + * @param string $type 业务类型 + * @param string $app 支付参数APP,config payments 数组中的配置项名称 + * + * @return mixed + * + * @throws GatewayException + */ public function create(array $data, $type = 'default', $app = 'default') { $this->validateParams($data); @@ -28,20 +39,22 @@ public function create(array $data, $type = 'default', $app = 'default') } $modelData = array_merge(['app' => $app, 'type' => $type], array_only($data, ['channel', 'order_no', 'client_ip', 'subject', 'amount', - 'body', 'extra', 'time_expire', 'metadata', 'description'])); + 'body', 'extra', 'time_expire', 'metadata', 'description', ])); $payModel = PayModel::create($modelData); try { - $credential = null; $out_trade_no = null; + $config = config('ibrand.pay.default.wechat.'.$app); + switch ($data['channel']) { case 'wx_pub': case 'wx_pub_qr': case 'wx_lite': - $credential = $this->createWechatCharge($data, config('ibrand.pay.default.wechat.' . $app), $out_trade_no); + $config['notify_url'] = route('pay.wechat.notify', ['app' => $app]); + $credential = $this->createWechatCharge($data, $config, $out_trade_no); break; case 'alipay_wap': case 'alipay_pc_direct': @@ -53,10 +66,9 @@ public function create(array $data, $type = 'default', $app = 'default') $payModel->save(); return $payModel; - } catch (\Yansongda\Pay\Exceptions\Exception $exception) { throw new GatewayException('支付通道错误'); - } catch (\Exception $exception){ + } catch (\Exception $exception) { throw new GatewayException('支付失败'); } } @@ -64,6 +76,7 @@ public function create(array $data, $type = 'default', $app = 'default') /** * @param $data * @param $config + * * @return array|null */ protected function createWechatCharge($data, $config, &$out_trade_no) @@ -111,9 +124,9 @@ protected function createAliCharge($user_id, $channel, $type = 'order', $order_n $config = $this->getConfig('alipay'); $delayTime = app('system_setting')->getSetting('order_auto_cancel_time') ? app('system_setting')->getSetting('order_auto_cancel_time') : 1440; - $time_expire = $delayTime . 'm'; + $time_expire = $delayTime.'m'; if ($submit_time and ($gap = Carbon::now()->timestamp - strtotime($submit_time)) > 0) { - $time_expire = ($delayTime - floor($gap / 60)) . 'm'; + $time_expire = ($delayTime - floor($gap / 60)).'m'; } $extra = $this->createExtra($channel, '', $extra, $type); @@ -134,12 +147,12 @@ protected function createAliCharge($user_id, $channel, $type = 'order', $order_n $chargeData['quit_url'] = $extra['cancel_url']; } - $return_url = $extra['success_url'] . $order_no; + $return_url = $extra['success_url'].$order_no; $return_url = str_replace('/', '~', $return_url); $return_url = str_replace('?', '@', $return_url); $return_url = str_replace('#', '*', $return_url); - $config['return_url'] = $config['return_url'] . '/' . $return_url; //同步通知url + $config['return_url'] = $config['return_url'].'/'.$return_url; //同步通知url $config['notify_url'] = $config['notify_url']; //异步通知url $ali_pay = []; @@ -174,5 +187,4 @@ protected function createAliCharge($user_id, $channel, $type = 'order', $order_n return null; } - } diff --git a/github/component/Pay/src/Contracts/PayNotifyContract.php b/github/component/Pay/src/Contracts/PayNotifyContract.php new file mode 100644 index 0000000..cdb4609 --- /dev/null +++ b/github/component/Pay/src/Contracts/PayNotifyContract.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Contracts; + +use iBrand\Component\Pay\Models\Charge; + +interface PayNotifyContract +{ + public function success(Charge $charge); +} diff --git a/github/component/Pay/src/Exceptions/GatewayException.php b/github/component/Pay/src/Exceptions/GatewayException.php index 8bad316..2eefb09 100644 --- a/github/component/Pay/src/Exceptions/GatewayException.php +++ b/github/component/Pay/src/Exceptions/GatewayException.php @@ -1,10 +1,18 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace iBrand\Component\Pay\Exceptions; use Exception; class GatewayException extends Exception { - } diff --git a/github/component/Pay/src/Facades/Charge.php b/github/component/Pay/src/Facades/Charge.php index e8acecf..d73f0e5 100644 --- a/github/component/Pay/src/Facades/Charge.php +++ b/github/component/Pay/src/Facades/Charge.php @@ -22,6 +22,6 @@ class Charge extends Facade */ public static function getFacadeAccessor() { - return 'ibrand.charge'; + return 'ibrand.pay.charge'; } } diff --git a/github/component/Pay/src/Facades/PayNotify.php b/github/component/Pay/src/Facades/PayNotify.php new file mode 100644 index 0000000..d56194f --- /dev/null +++ b/github/component/Pay/src/Facades/PayNotify.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace iBrand\Component\Pay\Facades; + +use iBrand\Component\Pay\Models\Charge; +use Illuminate\Support\Facades\Facade; + +class PayNotify extends Facade +{ + /** + * Return the facade accessor. + * + * @return string + */ + public static function getFacadeAccessor() + { + return 'ibrand.pay.notify.default'; + } + + public static function success($name = '', Charge $pay) + { + $app = $name ? app('ibrand.pay.notify.'.$name) : app('ibrand.pay.notify.default'); + + return $app->success($pay); + } +} diff --git a/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php index baf1893..bd51afe 100644 --- a/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php +++ b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php @@ -11,11 +11,56 @@ namespace iBrand\Component\Pay\Http\Controllers; +use iBrand\Component\Pay\Facades\PayNotify; use Illuminate\Routing\Controller; +use Yansongda\Pay\Pay; class WechatPayNotifyController extends Controller { - public function notify() + public function notify($app) { + $config = config('ibrand.pay.default.wechat.'.$app); + + $pay = Pay::wechat($config); + + $data = $pay->verify(); // 是的,验签就这么简单! + + if ('SUCCESS' === $data['return_code']) { // return_code 表示通信状态,不代表支付状态 + $attach = json_decode($data['attach'], true); + + if ('SUCCESS' == $data['result_code']) { + $charge = \iBrand\Component\Pay\Models\Charge::where('out_trade_no', $data['out_trade_no'])->first(); + + if (!$pay) { + return response('支付失败', 500); + } + + $charge->transaction_meta = json_encode($data); + $charge->transaction_no = $data['transaction_id']; + $charge->time_paid = strtotime($data['time_end']); + $charge->paid = 1; + $charge->save(); + + if ($charge->amount !== $data['total_fee']) { + return response('支付失败', 500); + } + + PayNotify::success($charge->type, $pay); + + return $pay->success(); + } elseif ('FAIL' == $data['result_code']) { + $charge = \iBrand\Component\Pay\Models\Charge::where('out_trade_no', $data['out_trade_no'])->first(); + + if ($charge) { + $charge->failure_code = $data['err_code']; + $charge->failure_msg = $data['err_code_des']; + $charge->save(); + } + + return response('支付失败', 500); + } + } + + return response('FAIL', 500); } } diff --git a/github/component/Pay/src/Models/Pay.php b/github/component/Pay/src/Models/Charge.php similarity index 73% rename from github/component/Pay/src/Models/Pay.php rename to github/component/Pay/src/Models/Charge.php index fb1d7ea..2c79fbe 100644 --- a/github/component/Pay/src/Models/Pay.php +++ b/github/component/Pay/src/Models/Charge.php @@ -14,9 +14,9 @@ use Hidehalo\Nanoid\Client; use Illuminate\Database\Eloquent\Model; -class Pay extends Model +class Charge extends Model { - protected $table = 'ibrand_pay'; + protected $table = 'ibrand_pay_charge'; protected $guarded = ['id']; @@ -26,7 +26,7 @@ public function __construct(array $attributes = []) $client = new Client(); - $this->charge_id = 'ch_' . $client->generateId($size = 24); + $this->charge_id = 'ch_'.$client->generateId($size = 24); } public function setMetadataAttribute($value) @@ -43,17 +43,21 @@ public function setExtraAttribute($value) } } - public function getMetadataAttribute($value){ + public function getMetadataAttribute($value) + { if (!empty($value)) { - $value = json_decode($value,true); + $value = json_decode($value, true); } + return $value; } - public function getExtraAttribute($value){ + public function getExtraAttribute($value) + { if (!empty($value)) { - $value = json_decode($value,true); + $value = json_decode($value, true); } + return $value; } @@ -64,10 +68,12 @@ public function setCredentialAttribute($value) } } - public function getCredentialAttribute($value){ + public function getCredentialAttribute($value) + { if (!empty($value)) { - $value = json_decode($value,true); + $value = json_decode($value, true); } + return $value; } } diff --git a/github/component/Pay/src/PayServiceProvider.php b/github/component/Pay/src/PayServiceProvider.php index 0ad57fe..5637146 100644 --- a/github/component/Pay/src/PayServiceProvider.php +++ b/github/component/Pay/src/PayServiceProvider.php @@ -68,7 +68,7 @@ public function register() throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]"); }); - $this->app->alias(PayChargeContract::class, 'ibrand.charge'); + $this->app->alias(PayChargeContract::class, 'ibrand.pay.charge'); } public function loadRoutes() @@ -76,8 +76,8 @@ public function loadRoutes() $routeAttr = config('ibrand.pay.route', []); Route::group(array_merge(['namespace' => $this->namespace], $routeAttr), function ($router) { - $router->post('wechat', 'WechatPayNotifyController@notify'); - $router->post('alipay', 'AliPayNotifyController@notify'); + $router->post('wechat/{app}', 'WechatPayNotifyController@notify')->name('pay.wechat.notify'); + $router->post('alipay/{app}', 'AliPayNotifyController@notify')->name('pay.alipay.notify'); }); } } diff --git a/github/component/Pay/src/config.php b/github/component/Pay/src/config.php index 7705b8a..8dfda10 100644 --- a/github/component/Pay/src/config.php +++ b/github/component/Pay/src/config.php @@ -23,7 +23,7 @@ // 支付宝分配的 APPID 'app_id' => env('ALI_PAYMENT_APP_ID', ''), // 支付宝异步通知地址 - 'notify_url' => '', + 'notify_url' => '/notify/alipay', // 支付成功后同步通知地址 'return_url' => '', // 阿里公共密钥,验证签名时使用 diff --git a/modules/component/Payment/src/Providers/PaymentServiceProvider.php b/modules/component/Payment/src/Providers/PaymentServiceProvider.php index abd68bc..bf0049a 100644 --- a/modules/component/Payment/src/Providers/PaymentServiceProvider.php +++ b/modules/component/Payment/src/Providers/PaymentServiceProvider.php @@ -11,6 +11,8 @@ namespace iBrand\Component\Payment\Providers; +use iBrand\Component\Payment\Services\PaymentService; +use Illuminate\Support\Facades\Event; use Illuminate\Support\ServiceProvider; class PaymentServiceProvider extends ServiceProvider @@ -36,5 +38,7 @@ public function register() $this->mergeConfigFrom( __DIR__.'/../../config/payment.php', 'ibrand.payment' ); + + $this->app->bind('ibrand.pay.notify.default',PaymentService::class); } } diff --git a/modules/component/Payment/src/Services/PaymentService.php b/modules/component/Payment/src/Services/PaymentService.php index 4a01b39..9b2afe1 100644 --- a/modules/component/Payment/src/Services/PaymentService.php +++ b/modules/component/Payment/src/Services/PaymentService.php @@ -14,6 +14,8 @@ use Carbon\Carbon; use iBrand\Component\Order\Models\Order; use iBrand\Component\Order\Repositories\OrderRepository; +use iBrand\Component\Pay\Contracts\PayNotifyContract; +use iBrand\Component\Pay\Models\Charge; use iBrand\Component\Payment\Models\Payment; /** @@ -22,7 +24,7 @@ * Date: 2016/10/7 * Time: 17:52. */ -class PaymentService +class PaymentService implements PayNotifyContract { private $orderRepository; @@ -31,16 +33,13 @@ public function __construct(OrderRepository $orderRepository) $this->orderRepository = $orderRepository; } - public function paySuccess(array $charge) + public function success(Charge $charge) { - $order_no = $charge['metadata']['order_no']; - - //更改订单状态 - $order = $this->orderRepository->getOrderByNo($order_no); + $order = $this->orderRepository->getOrderByNo($charge->order_no); $need_pay = $order->getNeedPayAmount(); - $pay_state = $charge['amount'] - $need_pay; + $pay_state = $charge->amount - $need_pay; $order_pay = Payment::where('channel_no', $charge['transaction_no'])->where('order_id', $order->id)->first(); @@ -49,10 +48,11 @@ public function paySuccess(array $charge) } if ($pay_state >= 0) { - $order = $this->orderRepository->getOrderByNo($order_no); + $order = $this->orderRepository->getOrderByNo($charge->order_no); $payment = new Payment(['order_id' => $order->id, 'channel' => $charge['channel'], - 'amount' => $charge['amount'], 'status' => Payment::STATUS_COMPLETED, 'channel_no' => $charge['transaction_no'], 'paid_at' => Carbon::createFromTimestamp($charge['time_paid']), 'details' => isset($charge['details']) ? $charge['details'] : '', ]); + 'amount' => $charge['amount'], 'status' => Payment::STATUS_COMPLETED, 'channel_no' => + $charge['transaction_no'], 'paid_at' => $charge['time_paid'], 'details' => isset($charge['details']) ? $charge['details'] : '', ]); $order->payments()->save($payment); From 93d11c326b688ea367411951f41ee423d8fba71a Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Tue, 20 Nov 2018 16:58:16 +0800 Subject: [PATCH 15/17] fix time bug. --- .../Pay/src/Http/Controllers/WechatPayNotifyController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php index bd51afe..e594d2a 100644 --- a/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php +++ b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php @@ -11,6 +11,7 @@ namespace iBrand\Component\Pay\Http\Controllers; +use Carbon\Carbon; use iBrand\Component\Pay\Facades\PayNotify; use Illuminate\Routing\Controller; use Yansongda\Pay\Pay; @@ -37,7 +38,7 @@ public function notify($app) $charge->transaction_meta = json_encode($data); $charge->transaction_no = $data['transaction_id']; - $charge->time_paid = strtotime($data['time_end']); + $charge->time_paid = Carbon::createFromTimestamp(strtotime($data['time_end'])); $charge->paid = 1; $charge->save(); From 0ffc23a8357d2cb6ed199b835b749168244d26fe Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Tue, 20 Nov 2018 17:36:21 +0800 Subject: [PATCH 16/17] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pay/src/Charges/DefaultCharge.php | 34 +++++++++++++++++-- .../Pay/src/Contracts/PayChargeContract.php | 2 ++ .../MiniProgramLoginController.php | 2 -- .../Http/Controllers/PaymentController.php | 32 +++++++++++------ 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/github/component/Pay/src/Charges/DefaultCharge.php b/github/component/Pay/src/Charges/DefaultCharge.php index fb23b89..bb7f6b7 100644 --- a/github/component/Pay/src/Charges/DefaultCharge.php +++ b/github/component/Pay/src/Charges/DefaultCharge.php @@ -14,7 +14,7 @@ use Carbon\Carbon; use iBrand\Component\Pay\Contracts\PayChargeContract; use iBrand\Component\Pay\Exceptions\GatewayException; -use iBrand\Component\Pay\Models\Charge as PayModel; +use iBrand\Component\Pay\Models\Charge; use Yansongda\Pay\Pay; class DefaultCharge extends BaseCharge implements PayChargeContract @@ -41,7 +41,7 @@ public function create(array $data, $type = 'default', $app = 'default') $modelData = array_merge(['app' => $app, 'type' => $type], array_only($data, ['channel', 'order_no', 'client_ip', 'subject', 'amount', 'body', 'extra', 'time_expire', 'metadata', 'description', ])); - $payModel = PayModel::create($modelData); + $payModel = Charge::create($modelData); try { $credential = null; @@ -187,4 +187,34 @@ protected function createAliCharge($user_id, $channel, $type = 'order', $order_n return null; } + + public function find($charge_id) + { + $charge = Charge::where('charge_id',$charge_id)->first(); + + $config = config('ibrand.pay.default.wechat.'.$charge->app); + + $result = Pay::wechat($config)->find($charge->out_trade_no); + + if ($result['return_code'] == 'FAIL'){ + $charge->failure_code = $result['return_code']; + $charge->failure_msg = $result['return_msg']; + $charge->save(); + return $charge; + }; + + if ($result['result_code'] == 'FAIL' || $result['trade_state'] != 'SUCCESS') { + $charge->failure_code = $result['err_code']; + $charge->failure_msg = $result['err_code_des']; + $charge->save(); + }; + + $charge->transaction_meta = json_encode($result); + $charge->transaction_no = $result['transaction_id']; + $charge->time_paid = Carbon::createFromTimestamp(strtotime($result['time_end'])); + $charge->paid = 1; + $charge->save(); + + return $charge; + } } diff --git a/github/component/Pay/src/Contracts/PayChargeContract.php b/github/component/Pay/src/Contracts/PayChargeContract.php index 0d470c2..187e6ec 100644 --- a/github/component/Pay/src/Contracts/PayChargeContract.php +++ b/github/component/Pay/src/Contracts/PayChargeContract.php @@ -14,4 +14,6 @@ interface PayChargeContract { public function create(array $data, $type = 'default', $app = 'default'); + + public function find($charge_id); } diff --git a/modules/EC.Open.Server/src/Http/Controllers/MiniProgramLoginController.php b/modules/EC.Open.Server/src/Http/Controllers/MiniProgramLoginController.php index aa6bfb4..28e36d8 100644 --- a/modules/EC.Open.Server/src/Http/Controllers/MiniProgramLoginController.php +++ b/modules/EC.Open.Server/src/Http/Controllers/MiniProgramLoginController.php @@ -101,8 +101,6 @@ public function mobileLogin() $token = $user->createToken($user->id)->accessToken; - $this->bindOpenPlatform($user->id); - $this->userService->bindPlatform($user->id, request('open_id'), config('wechat.mini_program.default.app_id'), 'miniprogram'); return $this->success(['token_type' => 'Bearer', 'access_token' => $token]); diff --git a/modules/EC.Open.Server/src/Http/Controllers/PaymentController.php b/modules/EC.Open.Server/src/Http/Controllers/PaymentController.php index 239343e..f2a780c 100644 --- a/modules/EC.Open.Server/src/Http/Controllers/PaymentController.php +++ b/modules/EC.Open.Server/src/Http/Controllers/PaymentController.php @@ -11,8 +11,11 @@ namespace iBrand\EC\Open\Server\Http\Controllers; +use Carbon\Carbon; use iBrand\Component\Order\Models\Order; use iBrand\Component\Order\Repositories\OrderRepository; +use iBrand\Component\Pay\Facades\Charge; +use iBrand\Component\Pay\Facades\PayNotify; use iBrand\Component\Payment\Models\Payment; use iBrand\Component\Payment\Services\PaymentService; use EasyWeChat; @@ -45,17 +48,26 @@ public function paidSuccess() //在pay_debug=true 状态下,可以调用此接口直接更改订单支付状态 if (config('ibrand.app.pay_debug')) { - $charge['metadata']['order_no'] = $order_no; - $charge['amount'] = $order->total; - $charge['transaction_no'] = ''; - $charge['time_paid'] = time(); - $charge['details'] = ''; - $charge['channel'] = 'test'; - - $order = $this->payment->paySuccess($charge); + + $charge = \iBrand\Component\Pay\Models\Charge::where('order_no', $order_no)->orderBy('created_at', 'desc')->first(); + $charge->transaction_no = ''; + $charge->time_paid = Carbon::now(); + $charge->paid = 1; + $charge->channel = 'test'; + $charge->amount = $order->total; + $charge->save(); + + $order = PayNotify::success($charge->type, $charge); + } else { //同步查询微信订单状态,防止异步通信失败导致订单状态更新失败 - $payment = EasyWeChat::payment(); + + $charge = Charge::find(request('charge_id')); + + $order = PayNotify::success($charge->type, $charge); + + + /*$payment = EasyWeChat::payment(); $result = $payment->order->queryByOutTradeNumber($order_no); if ('FAIL' == $result['return_code']) { @@ -77,7 +89,7 @@ public function paidSuccess() $charge['details'] = json_encode($result); $charge['channel'] = 'wx_lite'; - $order = $this->payment->paySuccess($charge); + $order = $this->payment->paySuccess($charge);*/ } if (Order::STATUS_PAY == $order->status) { From ce94ffe19da890e6a8479ed38741321ad88334f1 Mon Sep 17 00:00:00 2001 From: zidaibudai Date: Tue, 20 Nov 2018 19:57:05 +0800 Subject: [PATCH 17/17] format code. --- github/component/Pay/README.md | 212 +++++++++++++++++- .../component/Pay/src/Facades/PayNotify.php | 4 +- .../Controllers/WechatPayNotifyController.php | 4 +- github/component/Pay/src/config.php | 14 ++ .../Http/Controllers/WechatPayController.php | 11 +- 5 files changed, 229 insertions(+), 16 deletions(-) diff --git a/github/component/Pay/README.md b/github/component/Pay/README.md index af3228a..bb238ca 100644 --- a/github/component/Pay/README.md +++ b/github/component/Pay/README.md @@ -1,11 +1,205 @@ -# iBrand Address Component +# Laravel 多应用多配置支付包 -Address Component for iBrand Application. +## Feature -[![Build Status](https://travis-ci.org/ibrandcc/address.svg?branch=master)](https://travis-ci.org/ibrandcc/address) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ibrandcc/address/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/ibrandcc/address/?branch=master) -[![Code Coverage](https://scrutinizer-ci.com/g/ibrandcc/address/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/ibrandcc/address/?branch=master) -[![Build Status](https://scrutinizer-ci.com/g/ibrandcc/address/badges/build.png?b=master)](https://scrutinizer-ci.com/g/ibrandcc/address/build-status/master) -[![Latest Stable Version](https://poser.pugx.org/ibrand/address/v/stable)](https://packagist.org/packages/ibrand/address) -[![Latest Unstable Version](https://poser.pugx.org/ibrand/address/v/unstable)](https://packagist.org/packages/ibrand/address) -[![License](https://poser.pugx.org/ibrand/address/license)](https://packagist.org/packages/ibrand/address) \ No newline at end of file +1. 实现多渠道支付方式,比如:原生支付,pingxx支付,银商支付等。 +2. 实现多业务统一支付。 + +## TODO: +1. 实现退款 + +## 安装 + +``` +$ composer require ibrand/pay +$ php artisan vendor:publish +$ php artisan migrate +``` +## 使用 + +### 创建支付请求 + +发起一次支付请求时需要创建一个新的 charge 对象,获取一个可用的支付凭据用于客户端向第三方渠道发起支付请求。 + +```php + use iBrand\Component\Pay\Facades\Charge; + + $charge = Charge::create(['channel' => 'wx_lite' + , 'order_no' => $order_no + , 'amount' => $order->getNeedPayAmount() + , 'client_ip' => \request()->getClientIp() + , 'subject' => $order->getSubject() + , 'body' => $order->getSubject() + , 'extra' => ['openid' => \request('openid')] + ]); + + return $this->success(compact('charge')); +``` +创建 charge 方法定义如下: +``` +public function create(array $data, $type = 'default', $app = 'default'); +``` +- $data 参数为支付参数,请见 支付参数一节。 +- $type 为业务类型,如果只有一种支付业务,不传即可。如果存在多种业务支付类型,比如商城中存在支付订单,余额充值订单。 +- $app 具体的应用名称,比如商城APP和活动APP,可能使用不同的支付配置 + + +#### 支付参数 + +|请求参数 |类型 |必填 |描述| +|:---- |:------- |:--- |------ | +|order_no |string |是 | 商户订单号,适配每个渠道对此参数的要求,必须在商户的系统内唯一。(支付宝全渠道: 1-64 位的数字和字母组合;`wx`: 2-32 位;`wx_pub_scan、cb_wx、cb_wx_pub、cb_wx_pub_qr、cb_wx_pub_scan`:1-32 位的数字和字母组合;`bfb`: 1-20 位;银联全渠道: 8-40 位的数字和字母组合; `yeepay_wap`: 1-50 位;`jdpay_wap`: 1-30 位;`qpay`:1-30 位;`isv_qr、isv_scan、isv_wap`: 8-32 位,不重复,建议时间戳+随机数(或交易顺序号);`paypal`:1-32 位的数字和字母组合;`ccb_pay、ccb_qr`:1-30 位数字和字母组合;`cmb_wallet`: 6-32 位的数字和字母组合,一天内不能重复,订单日期+订单号唯一定位一笔订单,示例: 20170808test01)。**注:**推荐使用 8-20 位的数字和字母组合,不允许特殊字符。 | +|channel |string |是 | 已经支持值: | +|amount |int |是 | 订单总金额,必须大于0,单位为分 | +|client_ip |string |是 | 发起支付的客户端IP地址,Laravel 中 `request()->getClientIp()` | +|subject |string |是 | 商品标题,该参数最长为 32 个 Unicode 字符。银联全渠道限制在 32 个字节;支付宝部分渠道不支持特殊字符。 | +|body |string |是 | 商品描述信息,该参数最长为 128 个 Unicode 字符。`yeepay_wap` 对于该参数长度限制为 100 个 Unicode 字符;支付宝部分渠道不支持特殊字符。 | +|extra |array |是 | 在微信公众号支付,小程序支付,需要传递openid。如:`'extra' => ['openid' => \request('openid')]` | +|time_expire |timestamp |否 | 订单失效时间。时间范围在订单创建后的 1 分钟到 15 天,默认为 1 天,创建时间以 Ping++ 服务器时间为准。微信对该参数的时间范围在订单创建后的 1 分钟到 7 天,默认为 2 小时;`upacp、upacp_pc、upacp_wap、cp_b2b、applepay_upacp` 渠道对该参数的有效值限制为 1 小时内;`upacp_b2b` 对该参数的有效值限制为 1 天内;`upacp_qr` 渠道对该参数的有效期默认为 1 天,最大为 30 天。 | +|metadata |array |否 | 附属参数,会传递给微信和支付宝 | +|description |string |否 | 订单附件说明 | + +#### 返回值 + +发起支付请求后,微信通道会返回 charge 值,如下: + +``` +{ + "app": "default", // 应用名称 + "type": "default", // 业务类型, + "channel": "wx_lite", + "order_no": "O2018111919576278725", + "amount": 4900, + "client_ip": "222.247.67.172", + "subject": "【秋款】2018年儿童秋款T 儿童打底衫秋款 竹节棉阔形儿童T恤 等1件商品", + "body": "【秋款】2018年儿童秋款T 儿童打底衫秋款 竹节棉阔形儿童T恤 等1件商品", + "extra": { + "openid": "ozJEr5NrFkYrNGC5rftcOAO4c3OE" + }, + "charge_id": "ch_QAjx7VNJxp2mstAb8kPc0oZR", + "updated_at": "2018-11-20 09:36:45", + "created_at": "2018-11-20 09:36:44", + "id": 4, + "credential": { //客户端支付凭证 + "wechat": { + "appId": "wx0ae854a59b88cd63", + "timeStamp": "1542706604", + "nonceStr": "2nbKpiNEY0qHbMaM", + "package": "prepay_id=wx201736451424458ba271c9481469876463", + "signType": "MD5", + "paySign": "8677CEAEDE07E1FCB2E18A460805D98C" + } + }, + "out_trade_no": "wx_w5FZYpe0sEyxuCuXF0p3NP_b" +} +``` + +### 异步通知 + +本包会统一处理支付异步通知,可以通过配置文件来修改异步通知的 url。本报收到异步通知后,会执行 `PayNotify::success($charge->type, $charge);` 来通知业务方已经完成支付。 + +业务方在自己的代码中只需要做以下事情即可: +- 实现 `iBrand\Component\Pay\Contracts\PayNotifyContract` 接口,在 `success(Charge $charge)` 方法中完成业务订单的状态变更。 +- 在 ServiceProvider 中绑定 `PayNotifyContract` 实现。 `$this->app->bind('ibrand.pay.notify.default',StorePayNotify::class);` 其中 `default` 为业务类型值,需要保持和创建 charge 对象时传递的 `$type` 值一致。 + +### 同步查询 + +通常的业务流程中支付完成后,会跳转到支付成功页面,此时需要去主动同步查询订单状态,防止异步通信异常导致订单状态未正确变更的问题。 + +``` +$charge = Charge::find(request('charge_id')); + +$order = PayNotify::success($charge->type, $charge); +``` + +## 配置项 + +执行 `php artisan vendor:publish` 后会发布配置文件 `config/ibrand/pay.php` + +```php +return [ + + /* + * 异步通知路由参数 + */ + 'route' => [ + 'prefix' => 'notify', + 'middleware' => ['api'], + ], + + /* + * 默认的支付渠道类型,default 默认支付驱动类型基于 yansongda/pay 支付宝实现 + */ + 'driver' => 'default', + + 'default' => [ + 'alipay' => [ + + /* + * APP_NAME,不同的应用会使用不同的支付参数,举例: + * 在 iBrand 有商城订单支付,有活动报名支付,两个小程序是不同的 appid 甚至是不同的支付主体,所以需要配置不同的支付参数 + * + */ + 'default' => [ + // 支付宝分配的 APPID + 'app_id' => env('ALI_PAYMENT_APP_ID', ''), + // 支付宝异步通知地址 + 'notify_url' => '/notify/alipay', + // 支付成功后同步通知地址 + 'return_url' => '', + // 阿里公共密钥,验证签名时使用 + 'ali_public_key' => env('ALI_PAYMENT_PUBLIC_KEY', ''), + // 自己的私钥,签名时使用 + 'private_key' => env('ALI_PAYMENT_PRIVATE_KEY', ''), + // optional,默认 warning;日志路径为:sys_get_temp_dir().'/logs/yansongda.pay.log' + 'log' => [ + 'file' => storage_path('logs/alipay.log'), + // 'level' => 'debug' + 'type' => 'single', // optional, 可选 daily. + 'max_file' => 30, + ], + // optional,设置此参数,将进入沙箱模式 + // 'mode' => 'dev', + ], + ], + + 'wechat' => [ + + 'default' => [ + // 公众号 APPID + 'app_id' => env('WECHAT_PAYMENT_APP_ID', ''), + // 小程序 APPID + 'miniapp_id' => env('WECHAT_PAYMENT_MINIAPP_ID', ''), + // APP 引用的 appid + 'appid' => env('WECHAT_PAYMENT_APPID', ''), + // 微信支付分配的微信商户号 + 'mch_id' => env('WECHAT_PAYMENT_MCH_ID', ''), + // 微信支付异步通知地址 + 'notify_url' => '/notify/wechat', + // 微信支付签名秘钥 + 'key' => env('WECHAT_PAYMENT_KEY', ''), + // 客户端证书路径,退款、红包等需要用到。请填写绝对路径,linux 请确保权限问题。pem 格式。 + 'cert_client' => '', + // 客户端秘钥路径,退款、红包等需要用到。请填写绝对路径,linux 请确保权限问题。pem 格式。 + 'cert_key' => '', + // optional,默认 warning;日志路径为:sys_get_temp_dir().'/logs/yansongda.pay.log' + 'log' => [ + 'file' => storage_path('logs/wechat.log'), + // 'level' => 'debug' + 'type' => 'single', // optional, 可选 daily. + 'max_file' => 30, + ], + // optional + // 'dev' 时为沙箱模式 + // 'hk' 时为东南亚节点 + // 'mode' => 'dev', + ], + // ... + ], + ], +]; +``` + +## Resources + +[yansongda/pay](https://github.com/yansongda/pay) diff --git a/github/component/Pay/src/Facades/PayNotify.php b/github/component/Pay/src/Facades/PayNotify.php index d56194f..2dd03b2 100644 --- a/github/component/Pay/src/Facades/PayNotify.php +++ b/github/component/Pay/src/Facades/PayNotify.php @@ -26,10 +26,10 @@ public static function getFacadeAccessor() return 'ibrand.pay.notify.default'; } - public static function success($name = '', Charge $pay) + public static function success($name = '', Charge $charge) { $app = $name ? app('ibrand.pay.notify.'.$name) : app('ibrand.pay.notify.default'); - return $app->success($pay); + return $app->success($charge); } } diff --git a/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php index e594d2a..7876489 100644 --- a/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php +++ b/github/component/Pay/src/Http/Controllers/WechatPayNotifyController.php @@ -32,7 +32,7 @@ public function notify($app) if ('SUCCESS' == $data['result_code']) { $charge = \iBrand\Component\Pay\Models\Charge::where('out_trade_no', $data['out_trade_no'])->first(); - if (!$pay) { + if (!$charge) { return response('支付失败', 500); } @@ -46,7 +46,7 @@ public function notify($app) return response('支付失败', 500); } - PayNotify::success($charge->type, $pay); + PayNotify::success($charge->type, $charge); return $pay->success(); } elseif ('FAIL' == $data['result_code']) { diff --git a/github/component/Pay/src/config.php b/github/component/Pay/src/config.php index 8dfda10..cfbc9c8 100644 --- a/github/component/Pay/src/config.php +++ b/github/component/Pay/src/config.php @@ -10,15 +10,28 @@ */ return [ + + /* + * 异步通知路由参数 + */ 'route' => [ 'prefix' => 'notify', 'middleware' => ['api'], ], + /* + * 默认的支付渠道类型,default 默认支付驱动类型基于 yansongda/pay 支付宝实现 + */ 'driver' => 'default', 'default' => [ 'alipay' => [ + + /* + * APP_NAME,不同的应用会使用不同的支付参数,举例: + * 在 iBrand 有商城订单支付,有活动报名支付,两个小程序是不同的 appid 甚至是不同的支付主体,所以需要配置不同的支付参数 + * + */ 'default' => [ // 支付宝分配的 APPID 'app_id' => env('ALI_PAYMENT_APP_ID', ''), @@ -43,6 +56,7 @@ ], 'wechat' => [ + 'default' => [ // 公众号 APPID 'app_id' => env('WECHAT_PAYMENT_APP_ID', ''), diff --git a/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php b/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php index 413caa4..e6d37f8 100644 --- a/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php +++ b/modules/EC.Open.Server/src/Http/Controllers/WechatPayController.php @@ -49,9 +49,14 @@ public function createCharge() return $this->failed('无法支付,需支付金额为零'); } - $charge = Charge::create(['channel' => 'wx_lite', 'order_no' => $order_no, 'amount' => $order->getNeedPayAmount(), - 'client_ip' => \request()->getClientIp(), 'subject' => $order->getSubject() - , 'body' => $order->getSubject(), 'extra' => ['openid' => \request('openid')]]); + $charge = Charge::create(['channel' => 'wx_lite' + , 'order_no' => $order_no + , 'amount' => $order->getNeedPayAmount() + , 'client_ip' => \request()->getClientIp() + , 'subject' => $order->getSubject() + , 'body' => $order->getSubject() + , 'extra' => ['openid' => \request('openid')] + ]); return $this->success(compact('charge'));