thinkPHP + easywechat 小程序支付(含回调)
thinkPHP 框架+easywechat扩展包,composer下载
$ composer require overtrue/wechat:~5.0 -vvv
composer安装扩展包,这里就不说了,可以看官方文档。
注意:微信小程序支付验证签名失败 EasyWeChat 需要二次签名!
必须使用二次签名 必须使用二次签名 必须使用二次签名 重要的事情说三遍!!!
先建一个php文件
<?php namespace wechat; use EasyWeChat\Factory; /* * 支付 * */ class WeChat extends Base { //小程序支付使用JSAPI public function pay(){ //必要配置 $config = [ 'app_id' => 'wx1234556677888', 'mch_id' => '1232545667', 'key' => '95e26976346a8431d89569c0f742', 'notify_url' => "http://www.xxx.com/pay/notify" ]; $app = Factory::payment($config); $pay_info = [ 'trade_type' => 'JSAPI', // 支付方式,小程序支付使用JSAPI 'body' => '测试订单', // 订单说明 'out_trade_no' => 'wx35465768535', // 自定义订单号 'total_fee' => 1 * 100, // 单位:分 'openid' => $openid // 当前用户的openId ] $result = $app->order->unify($pay_info); if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { // $prepayId = $result['prepay_id']; //$jssdk = $app->jssdk; // $config = $jssdk->sdkConfig($prepayId); //不能使用返回的配置参数,否则会报签名错误 //必须使用二次签名 $appId = $result['appid']; $nonceStr = $result['nonce_str']; $prepay_id = $result['prepay_id']; $timeStamp = time(); $key = $payment['app_key']; $paySign = md5("appId=$appId&nonceStr=$nonceStr&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$timeStamp&key=$key"); // 这个地方就是我所说的二次签名! // 返回给小程序使用 $config=[]; $config['nonceStr']=$nonceStr; $config['timeStamp']=strval($timeStamp); // 小程序支付的timeStamp参数,必须使用这个 timeStamp,因为已经计算到了paySign中 $config['package']="prepay_id=".$prepay_id; $config['paySign']=$paySign; $config['signType']='MD5'; return $success('成功', ['config'=>$config, 'url' => "http://www.xxx.com/pay/notify"]); } if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) { return $fail('错误:' . $result['return_msg']); } return $fail('错误' . $result['err_code_des']); } //支付回调 public function notify() { //必要配置 $config = [ 'app_id' => 'wx1234556677888', 'mch_id' => '1232545667', 'key' => '95e26976346a8431d89569c0f742', 'notify_url' => "http://www.xxx.com/pay/notify" ]; $app = Factory::payment($config); $response = $app->handlePaidNotify(function($message, $fail){ // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单 $order = 查询订单($message['out_trade_no']); if (!$order || $order->paid_at) { // 如果订单不存在 或者 订单已经支付过了 return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 } ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况,确认是已经支付 ///////////// if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态 // 用户是否支付成功 if (array_get($message, 'result_code') === 'SUCCESS') { $order->paid_at = time(); // 更新支付时间为当前时间 $order->status = 'paid'; // 用户支付失败 } elseif (array_get($message, 'result_code') === 'FAIL') { $order->status = 'paid_fail'; } } else { return $fail('通信失败,请稍后再通知我'); } $order->save(); // 保存订单 return true; // 返回处理完成 }); $response->send(); // return $response; } }