上一篇写了支付宝支付,然后这段时间我又把微信支付给接上了,作为萌新的我还是很有成就感的,哈哈~~好了,该写正事了。
第一步:创建应用及配配置
首先到微信的官方平台注册应用https://pay.weixin.qq.com/index.php/core/info(我这个我我们产品经理注册的,具体步骤就不说了啊,慢慢捣鼓吧)
注册完应用有一个APPID和一个API密钥(需设置),主要是这两个;
第二步:引入easywechat这个包
composer require "overtrue/laravel-wechat:~4.0"
这个步骤安装查看他的官方文档https://www.easywechat.com/
记得生成wechat.php配置文件,里面的回调地址notify_url你自己设置就好了,不需要像支付宝那样去官网设置的。
1 <?php 2 3 /* 4 * This file is part of the overtrue/laravel-wechat. 5 * 6 * (c) overtrue <i@overtrue.me> 7 * 8 * This source file is subject to the MIT license that is bundled 9 * with this source code in the file LICENSE. 10 */ 11 12 return [ 13 \'secret\' => env(\'WECHAT_SECRET\', \'\'), 14 /* 15 * 默认配置,将会合并到各模块中 16 */ 17 \'defaults\' => [ 18 /* 19 * 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名 20 */ 21 \'response_type\' => \'array\', 22 23 /* 24 * 使用 Laravel 的缓存系统 25 */ 26 \'use_laravel_cache\' => true, 27 28 /* 29 * 日志配置 30 * 31 * level: 日志级别,可选为: 32 * debug/info/notice/warning/error/critical/alert/emergency 33 * file:日志文件位置(绝对路径!!!),要求可写权限 34 */ 35 \'log\' => [ 36 \'level\' => env(\'WECHAT_LOG_LEVEL\', \'debug\'), 37 \'file\' => env(\'WECHAT_LOG_FILE\', storage_path(\'logs/wechat.log\')), 38 ], 39 ], 40 41 /* 42 * 路由配置 43 */ 44 \'route\' => [ 45 /* 46 * 开放平台第三方平台路由配置 47 */ 48 // \'open_platform\' => [ 49 // \'uri\' => \'serve\', 50 // \'action\' => Overtrue\LaravelWeChat\Controllers\OpenPlatformController::class, 51 // \'attributes\' => [ 52 // \'prefix\' => \'open-platform\', 53 // \'middleware\' => null, 54 // ], 55 // ], 56 ], 57 58 /* 59 * 公众号 60 */ 61 \'official_account\' => [ 62 \'default\' => [ 63 \'app_id\' => env(\'WECHAT_OFFICIAL_ACCOUNT_APPID\', \'your-app-id\'), // AppID 64 \'secret\' => env(\'WECHAT_OFFICIAL_ACCOUNT_SECRET\', \'your-app-secret\'), // AppSecret 65 \'token\' => env(\'WECHAT_OFFICIAL_ACCOUNT_TOKEN\', \'your-token\'), // Token 66 \'aes_key\' => env(\'WECHAT_OFFICIAL_ACCOUNT_AES_KEY\', \'\'), // EncodingAESKey 67 68 /* 69 * OAuth 配置 70 * 71 * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login 72 * callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。) 73 */ 74 // \'oauth\' => [ 75 // \'scopes\' => array_map(\'trim\', explode(\',\', env(\'WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES\', \'snsapi_userinfo\'))), 76 // \'callback\' => env(\'WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK\', \'/examples/oauth_callback.php\'), 77 // ], 78 ], 79 ], 80 81 /* 82 * 开放平台第三方平台 83 */ 84 // \'open_platform\' => [ 85 // \'default\' => [ 86 // \'app_id\' => env(\'WECHAT_OPEN_PLATFORM_APPID\', \'\'), 87 // \'secret\' => env(\'WECHAT_OPEN_PLATFORM_SECRET\', \'7795af6a2da27474b025b2cbfe83ad51\'), 88 // \'token\' => env(\'WECHAT_OPEN_PLATFORM_TOKEN\', \'\'), 89 // \'aes_key\' => env(\'WECHAT_OPEN_PLATFORM_AES_KEY\', \'\'), 90 // ], 91 // ], 92 93 /* 94 * 小程序 95 */ 96 // \'mini_program\' => [ 97 // \'default\' => [ 98 // \'app_id\' => env(\'WECHAT_MINI_PROGRAM_APPID\', \'\'), 99 // \'secret\' => env(\'WECHAT_MINI_PROGRAM_SECRET\', \'\'), 100 // \'token\' => env(\'WECHAT_MINI_PROGRAM_TOKEN\', \'\'), 101 // \'aes_key\' => env(\'WECHAT_MINI_PROGRAM_AES_KEY\', \'\'), 102 // ], 103 // ], 104 105 /* 106 * 微信支付 107 */ 108 \'payment\' => [ 109 \'default\' => [ 110 \'sandbox\' => env(\'WECHAT_PAYMENT_SANDBOX\', false), 111 \'app_id\' => env(\'WECHAT_PAYMENT_APPID\', \'\'), 112 \'mch_id\' => env(\'WECHAT_PAYMENT_MCH_ID\', \'\'), 113 \'key\' => env(\'WECHAT_PAYMENT_KEY\', \'\'), 114 \'cert_path\' => env(\'WECHAT_PAYMENT_CERT_PATH\', \'path/to/cert/apiclient_cert.pem\'), // XXX: 绝对路径!!!! 115 \'key_path\' => env(\'WECHAT_PAYMENT_KEY_PATH\', \'path/to/cert/apiclient_key.pem\'), // XXX: 绝对路径!!!! 116 \'notify_url\' => \'http://test.com/payments/wechat-notify\', // 默认支付结果通知地址 117 ], 118 // ... 119 ], 120 121 /* 122 * 企业微信 123 */ 124 // \'work\' => [ 125 // \'default\' => [ 126 // \'corp_id\' => \'xxxxxxxxxxxxxxxxx\', 127 /// \'agent_id\' => 100020, 128 // \'secret\' => env(\'WECHAT_WORK_AGENT_CONTACTS_SECRET\', \'\'), 129 // //... 130 // ], 131 // ], 132 ];
第三步:创建WechatController控制器
先生成实例,我是先参考的easyWeChat的方法,
1 use EasyWeChat\Factory; 2 3 $config = [ 4 // 必要配置 5 \'app_id\' => \'xxxx\', 6 \'mch_id\' => \'your-mch-id\', 7 \'key\' => \'key-for-signature\', // API 密钥 8 9 // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书) 10 \'cert_path\' => \'path/to/your/cert.pem\', // XXX: 绝对路径!!!! 11 \'key_path\' => \'path/to/your/key\', // XXX: 绝对路径!!!! 12 13 \'notify_url\' => \'默认的订单回调地址\', // 你也可以在下单时单独设置来想覆盖它 14 ]; 15 16 $app = Factory::payment($config);
然后生成订单
1 $result = $app->order->unify([ 2 \'body\' => \'腾讯充值中心-QQ会员充值\', 3 \'out_trade_no\' => \'20150806125346\', 4 \'total_fee\' => 88, 5 \'spbill_create_ip\' => \'123.12.12.123\', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址 6 \'notify_url\' => \'https://pay.weixin.qq.com/wxpay/pay.action\', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 7 \'trade_type\' => \'JSAPI\', 8 \'openid\' => \'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o\', 9 ]);
结果一直报错,原因还没查明,
后来我换了个实例化的方法
1 $app = app(\'wechat.payment\');
然后就正常了。
上面的result返回类似
1 [ 2 "return_code" => "SUCCESS" 3 "return_msg" => "OK" 4 "appid" => "wx24b673e63c158b89" 5 "mch_id" => "1502479801" 6 "nonce_str" => "721IkW6I2rokEEgz" 7 "sign" => "D85AACC9B51BD59E4011F36042BA362D" 8 "result_code" => "SUCCESS" 9 "prepay_id" => "wx10145943342718f4169407463160082537" 10 "trade_type" => "APP" 11 ]
这些信息返回给APP还是不行的,因为需要二次签名!!!我就是忘记二次签名了,结果APP一直报签名错误,找了半天的原因,结果是少了一次签名。
1 if( $result[\'return_code\'] == \'SUCCESS\' && $result[\'result_code\'] == \'SUCCESS\'){ 2 $result = $app->jssdk->appConfig($result[\'prepay_id\']);//第二次签名 3 return [ 4 \'code\' => \'success\', 5 \'msg\' => $result 6 ]; 7 }else{ 8 Log::error(\'微信支付签名失败:\'.var_export($result,1)); 9 return false; 10 }
再去调用方法再签一次就好了。这样把$result里面的信息返回给APP就可以了!
第四步:处理回调
再APP完成支付后,微信服务器会发送一个post请求,请求地址为你未知文件中填写的notify_url
1 Route::any(\'payments/wechat-notify\', \'WeChatController@paySuccess\');
一定要是any,因为微信服务器先get请求一次数据,然后会再post请求一次
然后处理回调
1 public function paySuccess(){ 2 3 $app = app(\'wechat.payment\'); 4 $response = $app->handlePaidNotify(function ($message, $fail) { //处理订单等,你的业务逻辑 54 return true; 55 } 56 // 或者错误消息 57 $fail(\'Order not exists.\'); 58 }); 59 60 return $response; 61 }
$message的数据类似
这样完整的微信支付就完成了!