1,使用composer在thinkphp5项目的根目录安装easywechat:
composer require endroid/qrcode 安装endroid/qrcode
- $ composer require overtrue/wechat:~3.1 -vvv
① 配置,我这里的相关配置项是放在extra目录的wechat.php,内容如下:
return [
/**
* Debug 模式,bool 值:true/false
*
* 当值为 false 时,所有的日志都不会记录
*/
'debug' => true,
/**
* 账号基本信息,请从微信公众平台/开放平台获取
*/
'app_id' => 'wx851*****5f7e8', // AppID
'secret' => 'fdb592c******3828fdfd273', // AppSecret
'token' => 'TOKEN', // Token
'aes_key' => '', // EncodingAESKey,安全模式下请一定要填写!!!
/**
* 日志配置
*
* level: 日志级别, 可选为:
* debug/info/notice/warning/error/critical/alert/emergency
* permission:日志文件权限(可选),默认为null(若为null值,monolog会取0644)
* file:日志文件位置(绝对路径!!!),要求可写权限
*/
'log' => [
'level' => 'debug',
'permission' => 0777,
'file' => ROOT_PATH . 'runtime/wechat/easywechat.log',
],
/**
* OAuth 配置
*
* scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
* callback:OAuth授权完成后的回调页地址
*/
'oauth' => [
'scopes' => ['snsapi_userinfo'],
'callback' => '/examples/oauth_callback.php',
],
/**
* 微信支付
*/
'payment' => [
'merchant_id' => '135*****602',
'key' => '80b8682*****8fdac7784',
'cert_path' => ROOT_PATH . 'public/certs/wechat/apiclient_cert.pem', // XXX: 绝对路径!!!!
'key_path' => ROOT_PATH . 'public/certs/wechat/apiclient_key.pem', // XXX: 绝对路径!!!!
'notify_url' => 'http://*******/notify/wxpay',
],
/**
* Guzzle 全局设置
*
* 更多请参考: http://docs.guzzlephp.org/en/latest/request-options.html
*/
'guzzle' => [
'timeout' => 3.0, // 超时时间(秒)
//'verify' => false, // 关掉 SSL 认证(强烈不建议!!!)
],
];
扫码支付主要需要的配置是appid 已经payment相关的配置项,配置好之后,在控制器内开始使用:
②控制器代码:
- <?php
- /**
- * FileName:Pay.php
- * Author:Graent <1466409@qq.com> at www.diyi01.com
- * Copyright:
- * CreateTime:2017/10/12 18:43
- * Description:
- */
- namespace app\payment\controller;
- use EasyWeChat\Foundation\Application;
- use EasyWeChat\Payment\Order;
- use Endroid\QrCode\QrCode;
- use Endroid\QrCode\ErrorCorrectionLevel;
- class Wxpay extends Prepay
- {
- public function index(){
- //获取微信配置
- $wxConf = config('wechat');
- //实例化easyWeChat
- $wxApp = new Application($wxConf);
- //支付订单参数
- $attributes = [
- 'trade_type' => 'NATIVE', // JSAPI,NATIVE,APP...
- 'body' => '这里是body',
- 'detail' => '这里是detail,可选',
- 'out_trade_no' => '自己生成自己站点的唯一单号',
- 'total_fee' => 1 * 100, // 单位:分// 支付结果通知网址,如果不设置则会使用配置里的默认地址
- ];
- //初始化订单
- $order = new Order($attributes);
- //实例化支付
- $payment = $wxApp->payment;
- //预支付
- $result = $payment->prepare($order);
- if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
- $prepayId = $result->prepay_id;
- $codeUrl = $result->code_url;
- //生成二维码
- $Qr = new QrCode($codeUrl);
- $Qr->setSize(300)
- ->setWriterByName('png')
- ->setMargin(10)
- ->setEncoding('utf-8')
- ->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH)
- ->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0])
- ->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255])
- // ->setLogoPath(ROOT_PATH . 'template/common/images/wxpay.png')
- // ->setLogoWidth(65)
- ->setValidateResult(false);
- $Qr->writeFile(ROOT_PATH . "uploads/qrcode.png");
- $imgData= imgToBase64(ROOT_PATH . "uploads/qrcode.png");
- return json(['errcode'=>0,'msg'=>'发起支付成功','imgData'=>$imgData]);
- }else{
- return json(['errcode'=>1,'msg'=>'发起支付失败,稍后再试吧']);
- }
- }
- }
代码中使用的是Endroid生成的二维码,预支付成功之后微信支付服务器返回的是用于生成二维码的内容(code_url),可以自己通过一些类库生成二维码展现给客户扫描就可以了,我这里生成二维码之后转换成了base64返回前端的,也可以不这样,看你自己的需求吧,这样发起支付基本就可以工作了,最后就是回调通知,这一步是必须的,用户支付完成后微信支付服务器会发post请求到商户设置的notify_url通知商户支付状态已经传回诸如商户单号等参数,方便商户操作站点内的订单的状态等:
- <?php
- /**
- * FileName:Notify.php
- * Author:Graent <1466409@qq.com> at www.diyi01.com
- * Copyright:
- * CreateTime:2017/10/14 13:18
- * Description:
- */
- namespace app\payment\controller;
- use app\payment\model\MemberFreezingAmount;
- use EasyWeChat\Foundation\Application;
- use think\Db;
- class Notify extends Prepay
- {
- public function notify(){
- $payType = input('paytype');
- if($payType == 'wxpay'){
- //微信支付notify
- $wxConf = config('wechat');
- $wxApp = new Application($wxConf);
- $response = $wxApp->payment->handleNotify(function ($notify,$successful){
- if($successful){
- $rstArr = json_decode($notify,true);
- $ord = (new MemberFreezingAmount())
- ->where('trade_no','=',$rstArr['out_trade_no'])
- ->find();
- if($ord['status'] != 0){
- Db::name('member_freezing_amount')
- ->where('trade_no','=',$rstArr['out_trade_no'])
- ->update([
- 'status' => 0,
- 'transaction_id' => $rstArr['transaction_id'],
- 'pay_time' => time()
- ]);
- Db::name('mht_goods')
- ->where('id','=',$ord['gid'])
- ->setInc('bmnum');
- }
- return true;
- }else{
- return false;
- }
- });
- return $response;
- }else{
- //预留处理
- return false;
- }
- }
- }
注意,在发起支付的时候很多人遇到过签名错误的问题,一般情况仔细检查下商户的支付key是一下是否一致,一般就可以解决这个问题,好了,另外微信返回的二维码有效期是2个小时,朋友们可以自行处理,微信扫码支付就这么做完了,希望可以给一些朋友提供一些参考。