├── .github └── FUNDING.yml ├── .gitignore ├── composer.json ├── config └── payjs.php ├── readme.md └── src ├── Facades └── Payjs.php ├── Payjs.php └── PayjsServiceProvider.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: # Replace with a single Patreon username 4 | open_collective: # Replace with a single Open Collective username 5 | ko_fi: # Replace with a single Ko-fi username 6 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 7 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 8 | liberapay: # Replace with a single Liberapay username 9 | issuehunt: # Replace with a single IssueHunt username 10 | otechie: # Replace with a single Otechie username 11 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 12 | custom: ["https://payjs.cn/sponsor/dajjxz"] 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xhat/payjs-laravel", 3 | "description": "基于 PAYJS 的 API 开发的 Composer Laravel Package,可直接用于生产环境 https://payjs.cn", 4 | "type": "library", 5 | "license": "MIT", 6 | "minimum-stability": "dev", 7 | "authors": [ 8 | { 9 | "name": "xhat", 10 | "email": "andy@popfeng.com" 11 | } 12 | ], 13 | "autoload": { 14 | "psr-4": { 15 | "Xhat\\Payjs\\": "src/" 16 | } 17 | }, 18 | "extra": { 19 | "laravel": { 20 | "providers": [ 21 | "Xhat\\Payjs\\PayjsServiceProvider" 22 | ], 23 | "aliases": { 24 | "Payjs": "Xhat\\Payjs\\Facades\\Payjs" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /config/payjs.php: -------------------------------------------------------------------------------- 1 | '', 5 | 'key' => '', 6 | 7 | // 此地址一般无需更改 8 | 'api_url' => 'https://payjs.cn/api/', 9 | ]; 10 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 |

PAYJS Wechat Payment Laravel Package

5 |

6 | 7 | 8 | Latest Stable Version 9 | 10 | 11 | 12 | Total Downloads 13 | 14 | 15 | 16 | License 17 | 18 |

19 | 20 | ## 简介 21 | 本项目是基于 PAYJS 的 API 开发的 Laravel Package,可直接用于生产环境 22 | 23 | PAYJS 针对个人主体提供微信支付接入能力,是经过检验的正规、安全、可靠的微信支付个人开发接口 24 | 25 | 其它版本: [PAYJS 通用开发包](https://github.com/xhat/payjs) 26 | 27 | 支持Laravel 5.x、Laravel 6.x、Laravel 7.x、Laravel 8.x 28 | 29 | 30 | ## 安装 31 | 32 | 通过 Composer 安装 33 | 34 | ```bash 35 | $ composer require xhat/payjs-laravel 36 | ``` 37 | 38 | ## 使用方法 39 | 40 | ### 一、发布并修改配置文件 41 | 42 | - 发布配置文件 43 | ```shell 44 | php artisan vendor:publish --provider="Xhat\Payjs\PayjsServiceProvider" 45 | ``` 46 | - 编辑配置文件 `config/payjs.php` 配置商户号和通信密钥 47 | ```php 48 | return [ 49 | 'mchid' => '', // 填写商户号 50 | 'key' => '', // 填写通信KEY 51 | ]; 52 | ``` 53 | 54 | ### 二、在业务中使用 55 | 56 | 首先在业务模块中引入门面 57 | 58 | ```php 59 | use Xhat\Payjs\Facades\Payjs; 60 | ``` 61 | 62 | - 扫码支付 63 | 64 | ```php 65 | // 构造订单基础信息 66 | $data = [ 67 | 'body' => '订单测试', // 订单标题 68 | 'total_fee' => 2, // 订单标题 69 | 'out_trade_no' => time(), // 订单号 70 | 'attach' => 'test_order_attach', // 订单附加信息(可选参数) 71 | 'notify_url' => 'https://www.baidu.com/notify', // 异步通知地址(可选参数) 72 | ]; 73 | return Payjs::native($data); 74 | ``` 75 | 76 | - 收银台模式支付(直接在微信浏览器打开) 77 | 78 | ```php 79 | // 构造订单基础信息 80 | $data = [ 81 | 'body' => '订单测试', // 订单标题 82 | 'total_fee' => 2, // 订单金额 83 | 'out_trade_no' => time(), // 订单号 84 | 'attach' => 'test_order_attach', // 订单附加信息(可选参数) 85 | 'notify_url' => 'https://www.baidu.com/notify', // 异步通知地址(可选参数) 86 | 'callback_url' => 'https://www.baidu.com/callback', // 支付后前端跳转地址(可选参数) 87 | ]; 88 | $url = Payjs::cashier($data); 89 | return redirect($url); 90 | ``` 91 | 92 | - JSAPI模式支付 93 | 94 | ```php 95 | // 构造订单基础信息 96 | $data = [ 97 | 'body' => '订单测试', // 订单标题 98 | 'total_fee' => 2, // 订单金额 99 | 'out_trade_no' => time(), // 订单号 100 | 'attach' => 'test_order_attach', // 订单附加信息(可选参数) 101 | 'openid' => 'xxxxxxxxxxxxxxxxx', // 订单附加信息(可选参数) 102 | 'notify_url' => 'https://www.baidu.com/notify', // 异步通知地址(可选参数) 103 | ]; 104 | return Payjs::jsapi($data); 105 | ``` 106 | 107 | - H5支付 108 | 109 | ```php 110 | // 构造订单基础信息 111 | $data = [ 112 | 'body' => '订单测试', // 订单标题 113 | 'total_fee' => 2, // 订单金额 114 | 'out_trade_no' => time(), // 订单号 115 | 'attach' => 'test_order_attach', // 订单附加信息(可选参数) 116 | 'notify_url' => 'https://www.baidu.com/notify', // 异步通知地址(可选参数) 117 | 'callback_url' => 'https://www.baidu.com', // 前端跳转地址(可选参数) 118 | ]; 119 | return Payjs::mweb($data); 120 | ``` 121 | 122 | - 投诉查询 123 | 124 | ```php 125 | // 构造订单基础信息 126 | $data = [ 127 | 'mchid' => '123123', // 商户号 128 | ]; 129 | return Payjs::complaint($data); 130 | ``` 131 | 132 | - 查询订单 133 | 134 | ```php 135 | // 根据订单号查询订单状态 136 | $payjs_order_id = '****************'; 137 | return Payjs::check($payjs_order_id); 138 | ``` 139 | 140 | - 关闭订单 141 | 142 | ```php 143 | // 根据订单号关闭订单 144 | $payjs_order_id = '****************'; 145 | return Payjs::close($payjs_order_id); 146 | ``` 147 | 148 | - 退款 149 | 150 | ```php 151 | // 根据订单号退款 152 | $payjs_order_id = '****************'; 153 | return Payjs::refund($payjs_order_id); 154 | ``` 155 | 156 | - 获取商户资料 157 | 158 | 159 | ```php 160 | // 返回商户基础信息 161 | return Payjs::info(); 162 | ``` 163 | 164 | - 获取用户资料 165 | 166 | ```php 167 | // 根据订单信息中的 OPENID 查询用户资料 168 | $openid = '***************'; 169 | return Payjs::user($openid); 170 | ``` 171 | 172 | - 查询银行名称 173 | 174 | ```php 175 | // 根据订单信息中的银行编码查询银行中文名称 176 | $bank = '***************'; 177 | return Payjs::bank($bank); 178 | ``` 179 | 180 | - 接收异步通知 181 | 182 | ```php 183 | // 接收异步通知,无需关注验签动作,已自动处理 184 | $notify_info = Payjs::notify(); 185 | Log::info($notify_info); 186 | ``` 187 | 188 | ## 更新日志 189 | Version 1.5.0 190 | 增加投诉API、H5支付API 191 | 192 | Version 1.4 193 | 修正空值参数的过滤问题 194 | 195 | ## 安全相关 196 | 如果您在使用过程中发现各种 bug,请积极反馈,我会尽早修复 197 | 198 | -------------------------------------------------------------------------------- /src/Facades/Payjs.php: -------------------------------------------------------------------------------- 1 | mchid = config('payjs.mchid'); 25 | $this->key = config('payjs.key'); 26 | $api_url = config('payjs.api_url'); 27 | 28 | $this->api_url_native = $api_url . 'native'; 29 | $this->api_url_cashier = $api_url . 'cashier'; 30 | $this->api_url_refund = $api_url . 'refund'; 31 | $this->api_url_close = $api_url . 'close'; 32 | $this->api_url_check = $api_url . 'check'; 33 | $this->api_url_user = $api_url . 'user'; 34 | $this->api_url_info = $api_url . 'info'; 35 | $this->api_url_bank = $api_url . 'bank'; 36 | $this->api_url_jsapi = $api_url . 'jsapi'; 37 | $this->api_url_facepay = $api_url . 'facepay'; 38 | $this->api_url_complaint = $api_url . 'complaint'; 39 | $this->api_url_mweb = $api_url . 'mweb'; 40 | } 41 | 42 | // 扫码支付 43 | public function native(array $data) 44 | { 45 | $this->url = $this->api_url_native; 46 | return $this->post($data); 47 | } 48 | 49 | // 收银台模式 50 | public function cashier(array $data) 51 | { 52 | $this->url = $this->api_url_cashier; 53 | $data = $this->sign($data); 54 | $url = $this->url . '?' . http_build_query($data); 55 | return $url; 56 | } 57 | 58 | // JASAPI 59 | public function jsapi(array $data) 60 | { 61 | $this->url = $this->api_url_jsapi; 62 | return $this->post($data); 63 | } 64 | 65 | // 退款 66 | public function refund($payjs_order_id) 67 | { 68 | $this->url = $this->api_url_refund; 69 | $data = ['payjs_order_id' => $payjs_order_id]; 70 | return $this->post($data); 71 | } 72 | 73 | // 人脸支付 74 | public function facepay(array $data) 75 | { 76 | $this->url = $this->api_url_facepay; 77 | return $this->post($data); 78 | } 79 | 80 | // 投诉订单 81 | public function complaint(array $data) 82 | { 83 | $this->url = $this->api_url_complaint; 84 | return $this->post($data); 85 | } 86 | 87 | // MWEB(H5) 支付 88 | public function mweb(array $data) 89 | { 90 | $this->url = $this->api_url_mweb; 91 | return $this->post($data); 92 | } 93 | 94 | // 关闭订单 95 | public function close($payjs_order_id) 96 | { 97 | $this->url = $this->api_url_close; 98 | $data = ['payjs_order_id' => $payjs_order_id]; 99 | return $this->post($data); 100 | } 101 | 102 | // 检查订单 103 | public function check($payjs_order_id) 104 | { 105 | $this->url = $this->api_url_check; 106 | $data = ['payjs_order_id' => $payjs_order_id]; 107 | return $this->post($data); 108 | } 109 | 110 | // 用户资料 111 | public function user($openid) 112 | { 113 | $this->url = $this->api_url_user; 114 | $data = ['openid' => $openid]; 115 | return $this->post($data); 116 | } 117 | 118 | // 商户资料 119 | public function info() 120 | { 121 | $this->url = $this->api_url_info; 122 | $data = []; 123 | return $this->post($data); 124 | } 125 | 126 | // 银行资料 127 | public function bank($name) 128 | { 129 | $this->url = $this->api_url_bank; 130 | $data = ['bank' => $name]; 131 | return $this->post($data); 132 | } 133 | 134 | // 异步通知接收 135 | public function notify() 136 | { 137 | $data = request()->all(); 138 | if ($this->checkSign($data) === true) { 139 | return $data; 140 | } else { 141 | return '验签失败'; 142 | } 143 | } 144 | 145 | // 数据签名 146 | public function sign(array $data) 147 | { 148 | $data['mchid'] = $this->mchid; 149 | $data = array_filter($data); 150 | ksort($data); 151 | $data['sign'] = strtoupper(md5(urldecode(http_build_query($data) . '&key=' . $this->key))); 152 | return $data; 153 | } 154 | 155 | // 校验数据签名 156 | public function checkSign($data) 157 | { 158 | $in_sign = data_get($data, 'sign'); 159 | unset($data['sign']); 160 | $data = array_filter($data); 161 | ksort($data); 162 | $sign = strtoupper(md5(urldecode(http_build_query($data) . '&key=' . $this->key))); 163 | return $in_sign == $sign ? true : false; 164 | } 165 | 166 | // 数据发送 167 | public function post($data) 168 | { 169 | $data = $this->sign($data); 170 | $client = new \GuzzleHttp\Client([ 171 | 'header' => ['User-Agent' => 'PAYJS Larevel Http Client'], 172 | 'timeout' => 10, 173 | 'http_errors' => false, 174 | 'defaults' => ['verify' => false], 175 | ]); 176 | 177 | $rst = $client->request('POST', $this->url, ['form_params' => $data]); 178 | return json_decode($rst->getBody()->getContents(), true); 179 | } 180 | 181 | } 182 | -------------------------------------------------------------------------------- /src/PayjsServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadTranslationsFrom(__DIR__.'/../resources/lang', 'xhat'); 17 | // $this->loadViewsFrom(__DIR__.'/../resources/views', 'xhat'); 18 | // $this->loadMigrationsFrom(__DIR__.'/../database/migrations'); 19 | // $this->loadRoutesFrom(__DIR__.'/routes.php'); 20 | 21 | // Publishing is only necessary when using the CLI. 22 | if ($this->app->runningInConsole()) { 23 | 24 | // Publishing the configuration file. 25 | $this->publishes([ 26 | __DIR__.'/../config/payjs.php' => config_path('payjs.php'), 27 | ], 'payjs.config'); 28 | 29 | // Publishing the views. 30 | /*$this->publishes([ 31 | __DIR__.'/../resources/views' => base_path('resources/views/vendor/xhat'), 32 | ], 'payjs.views');*/ 33 | 34 | // Publishing assets. 35 | /*$this->publishes([ 36 | __DIR__.'/../resources/assets' => public_path('vendor/xhat'), 37 | ], 'payjs.views');*/ 38 | 39 | // Publishing the translation files. 40 | /*$this->publishes([ 41 | __DIR__.'/../resources/lang' => resource_path('lang/vendor/xhat'), 42 | ], 'payjs.views');*/ 43 | 44 | // Registering package commands. 45 | // $this->commands([]); 46 | } 47 | } 48 | 49 | /** 50 | * Register any package services. 51 | * 52 | * @return void 53 | */ 54 | public function register() 55 | { 56 | $this->mergeConfigFrom(__DIR__.'/../config/payjs.php', 'payjs'); 57 | 58 | // Register the service the package provides. 59 | $this->app->singleton('payjs', function ($app) { 60 | return new Payjs; 61 | }); 62 | } 63 | 64 | /** 65 | * Get the services provided by the provider. 66 | * 67 | * @return array 68 | */ 69 | public function provides() 70 | { 71 | return ['payjs']; 72 | } 73 | } --------------------------------------------------------------------------------