天天看点

thinkphp5使用easywechat集成微信扫码支付

   微信扫码支付用起来还是很方便的,如果使用微信支付官方的sdk开发也是可以的,不过还是选择了easywechat,主要还是因为easywechat集成了各种功能,基本上和微信相关的接口都做了比较不错的封装,因为要同时使用很多功能,索性微信扫码支付也一并用easywechat做了,而且不得不说使用方法是十分的简单,不多说了直接上步骤:

    1,使用composer在thinkphp5项目的根目录安装easywechat:

$ composer require overtrue/wechat:~3.1 -vvv
           

     2,安装好之后在控制器中开始使用,示例代码:

① 配置,我这里的相关配置项是放在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 <[email protected]> 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 <[email protected]> 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;
        }
    }
}
           

easywechat帮我们封装了回调的处理直接使用即可 $response = $wxApp->payment->handleNotify(function ($notify,$successful){})其中$notify就是微信支付返回的信息,$successful是状态,true即为成功,那么商户就可以进行自己的业务操作了,参考上面的带可以实现基本的处理,如果有更多自己的逻辑自己在对应的位置增加自己的处理即可。

注意,在发起支付的时候很多人遇到过签名错误的问题,一般情况仔细检查下商户的支付key是一下是否一致,一般就可以解决这个问题,好了,另外微信返回的二维码有效期是2个小时,朋友们可以自行处理,微信扫码支付就这么做完了,希望可以给一些朋友提供一些参考。

最后贴一张效果截图:

thinkphp5使用easywechat集成微信扫码支付

原创文字,转载请注明出处。

继续阅读