您现在的位置是:网站首页>>微信>>微信公众号

Yii使用easywechat实现微信支付

发布时间:2019-04-30 11:43:07作者:wangjian浏览量:913点赞量:0

    一:微信公众号申请微信支付申请

    微信公众号的微信支付申请这里就不进行叙述了

    二:yii配置支付配置

    1: yii中安装easywechat可参考:https://www.easywechat.com/docs/4.1/integration

    这里我使用的是max-wen/yii2-easy-wechat,所以这里我参考的是3.X版本的文档

    2:微信支付配置

    'WECHAT' => [
            /**
             * Debug 模式,bool 值:true/false
             *
             * 当值为 false 时,所有的日志都不会记录
             */
            'debug'  => false,
            /**
             * 账号基本信息,请从微信公众平台/开放平台获取
             */
            'app_id' => 'xxx', // AppID
            'secret' => 'xxx', // AppSecret
            'token' => '', // Token
            'aes_key' => '', // EncodingAESKey,兼容与安全模式下请一定要填写!!!
            /**
             * 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
             * 使用自定义类名时,构造函数将会接收一个 `EasyWeChat\Kernel\Http\Response` 实例
             */
            'response_type' => 'array',
            /**
             * 日志配置
             *
             * level: 日志级别, 可选为:debug/info/notice/warning/error/critical/alert/emergency
             * permission:日志文件权限(可选),默认为null(若为null值,monolog会取0644)
             * file:日志文件位置(绝对路径!!!),要求可写权限
             */
            'log' => [
                'level' => 'debug',
                'permission' => 0777,
                'file' => dirname(dirname(__DIR__)) . '/wechat.log',
            ],
            /**
             * 接口请求相关配置,超时时间等,具体可用参数请参考:
             * http://docs.guzzlephp.org/en/stable/request-config.html
             *
             * - retries: 重试次数,默认 1,指定当 http 请求失败时重试的次数。
             * - retry_delay: 重试延迟间隔(单位:ms),默认 500
             * - log_template: 指定 HTTP 日志模板,请参考:https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
             */
            'http' => [
                'retries' => 1,
                'retry_delay' => 500,
                'timeout' => 5.0,
                // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri
            ],
            /**
             * OAuth 配置
             *
             * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
             * snsapi_userinfo:可以获取更详细的用户资料
             * snsapi_base:静默授权,只能获取access_token和openID
             * callback:OAuth授权完成后的回调页地址
             */
            'oauth' => [
                'scopes' => ['snsapi_base'],
                'callback' => '',
            ],
            'payment' => [
                'merchant_id'        => 'xxx',//商户号
                'key'                => 'xxx',//商户密钥
                'cert_path'          => '', // XXX: 绝对路径!!!!(前往微信公众平台上下载,正常情况下可不填,在退款等特殊操作下才必填)
                'key_path'           => '',      // XXX: 绝对路径!!!!(前往微信公众平台上下载,正常情况下可不填,在退款等特殊操作下才必填)
                'notify_url'         => 'xxx',// 支付成功回调地址,你也可以在下单时单独设置来想覆盖它
                //'sub_app_id'      => 'xxx',子商户号(在子服务商模式下才填写)
                //'sub_merchant_id' => 'xxx',//子商户密钥(在子服务商模式下才填写)
            ],
        ],

    配置项中支付配置为:

    'payment' => [
                'merchant_id'        => 'xx',//商户号
                'key'                => 'xx',//商户密钥
                'cert_path'          => '', // XXX: 绝对路径!!!!(前往微信公众平台上下载,正常情况下可不填,在退款等特殊操作下才必填)
                'key_path'           => '',      // XXX: 绝对路径!!!!(前往微信公众平台上下载,正常情况下可不填,在退款等特殊操作下才必填)
                'notify_url'         => 'xxx',// 支付成功回调地址,你也可以在下单时单独设置来想覆盖它
                //'sub_app_id'      => 'xxx',子商户号(在子服务商模式下才填写)
                //'sub_merchant_id' => 'xxx',//子商户密钥(在子服务商模式下才填写)
            ],

    yii中配置easywechat的详细说明参考:https://www.wj0511.com/site/detail.html?id=298

    三:实现微信支付

    1:微信支付接口(PayController.php):

    $wechatConfig = Yii::$app->params['WECHAT'];
    $app = new EasyWeChat\Foundation\Application($wechatConfig);
    $payment = $app->payment;

    $attributes = [
       'trade_type'       => "JSAPI", //微信公众号支付填JSAPI(JSAPI,NATIVE,APP)
       'body'             => '',订单主题
       'detail'           => '',//订单说明
       'out_trade_no'     => '', // 这是自己ERP系统里的订单ID,不重复就行。
       'total_fee'        => 8888, // 金额,这里是8888分人民币。单位只能是分。
       'notify_url'       => '', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
       'sub_openid'       => '支付用户的openId', // (这个不能少,少了要报错)。
    ];
    $order = new EasyWeChat\Payment\Order($attributes);
    $result = $payment->prepare($order);
    $prepayId = null;
    if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
       $prepayId = $result->prepay_id; // 这个很重要。有了这个才能调用支付。
    }
    else {
       return '支付调取失败,请稍后再试!';
    }
    $config = $payment->configForJSSDKPayment($prepayId);
    $js = $app->js;

    return $this->render('wechat-pay',['config'=>$config,'js'=>$js]);

    2:支付发起js(wechat-pay.php)

    <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript" charset="utf-8">
        //数组内为jssdk授权可用的方法,按需添加,详细查看微信jssdk的方法
        wx.config(<?php echo $js->config(array('chooseWXPay')) ?>);
        // 发起支付
        wx.chooseWXPay({
            timestamp: <?= $config['timestamp'] ?>,
            nonceStr: '<?= $config['nonceStr'] ?>',
            package: '<?= $config['package'] ?>',
            signType: '<?= $config['signType'] ?>',
            paySign: '<?= $config['paySign'] ?>', // 支付签名
            success: function (res) {
                // 支付成功后的回调函数
            }
        });
    </script>

    3:回调处理:

    $wechatConfig = Yii::$app->params['WECHAT'];
    $app = new Application($wechatConfig);
    $payment = $app->payment;
    $response = $payment->handleNotify(function($notify, $successful){
        //回调处理方法($notify->out_trade_no为你的订单号,$successful为你是否支付成功的凭证)
        return true;
    });
    return $response;

    上面微信支付接口使用的是渲染的方式调起支付js的,如果我们使用ajax去调用微信支付接口的话,微信支付接口返回值变为:

    $json = $payment->configForPayment($prepayId);
    return ['json'=>$json];

    js接收端:

    WeixinJSBridge.invoke(
       'getBrandWCPayRequest', JSON.parse(json),
       function(res){
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {
               //支付成功处理
           }else {
               Enotice.toast({type: 'error', content: '支付失败'});
           }
       }
    );

    到此微信支付实现完成

0 +1