• 微信公众平台开发(四)——微信支付(转)


    一、JS-SDK

    公众号中的微信支付需要通过JS来实现。微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。点击查看在线文档

    1)引入JS脚本文件

    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

    2)通过config接口注入权限验证配置

    复制代码
    <script>
        wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '', // 必填,公众号的唯一标识
        timestamp: , // 必填,生成签名的时间戳
        nonceStr: '', // 必填,生成签名的随机串
        signature: '',// 必填,签名
    });
    </script>
    复制代码

    appId就是应用ID,wx打头的那串字符,timestamp在php中就用time()获取,而nonceStr就用uniqid()获取,而signature根据特定算法获取。

    复制代码
    protected function getJsapiConfig()
        {
            $weixin = new Weixin();
            $ticketMongo = new WeixinJsapiTicket();
            $data = [
                'appId' => $weixin->getAppId(),
                'noncestr' => uniqid(),
                'jsapi_ticket' => $ticketMongo->getJsapiTicket(),
                'timestamp' => time()
            ];
            //拼装原始待签名串
            $src = [
                'noncestr=' . $data['noncestr'],
                'jsapi_ticket=' . $data['jsapi_ticket'],
                'timestamp=' . $data['timestamp']
            ];
            sort($src);
            $data['signature'] = sha1(implode('&', $src));
            return $data;
        }
    复制代码

    这里说明下“jsapi_ticket”,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于有时间限制,而且获取jsapi_ticket的api调用次数非常有限,所以我会将获取到的jsapi_ticket保存到MongoDB中。

    复制代码
    /**
         * 通过access_token获取jsapi_ticket
         * @param $access_token
         * @return string | null
         */
        public function getJsapiTicket($access_token)
        {
            $url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket';
            $param = [
            'access_token' => $access_token,
            'type' => 'jsapi'
                    ];
            $res = $this->request($url, $param);
            $result = json_decode($res, true);
            if (isset($result['errcode']) && $result['errcode'] == 0 && isset($result['ticket'])) {
                return $result;
            }
            return null;
        }
    复制代码

    3)通过ready接口处理成功验证

    1)prepay_id是根据本地生成的订单号等获取的,订单号每次请求的得不一样,不然会报错的,点击查看在线文档

    2)nonceStr就用md5(uniqid('baiaimama'))获取

    3)signType使用MD5

    4)paySign根据代码的参数,排序后拼接获得。

    复制代码
    wx.chooseWXPay({
        timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
        nonceStr: '', // 支付签名随机串,不长于 32 位
        package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
        signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
        paySign: '', // 支付签名
        success: function (res) {
            // 支付成功后的回调函数
        }
    });
    复制代码
    复制代码
    /**
         * 生成jsapi需要调用的参数
         */
        public function getJsapiParam(){
            $param = [
            'appId' => $this->APPID,
            'timeStamp' => time(),
            'nonceStr' => md5(uniqid('baiaimama')),
            'package' => 'prepay_id='.$this->param['prepay_id'],
            'signType' => 'MD5'
                    ];
        
            $str = [];
            foreach($param as $k=>$v){
                if(!empty($v)){
                    $str[] = "{$k}={$v}";
                }
            }
            sort($str);
            $unsignKey = join('&', $str).'&key='.$this->KEY;
            $sign = strtoupper(md5($unsignKey));
            $param['paySign'] = $sign;
            return $param;
        }
    复制代码

    二、异步回调

    异步回调中做些修改订单状态、发送短信,推送消息等操作。

    复制代码
    /**
         * 微信支付异步回调API
         * 微信支付成功,会收到异步回调
         */
        public function actionWxpay()
        {    
            $weixinPay = new WeixinPay();
            $weixin = new Weixin();
            
            $xml = file_get_contents('php://input');
            $msg = $weixin->parseMsg($xml);
        
            //记录微信推送日志
            $notifyMongo = new WeixinPayNotify();
            $notifyMongo->logPayNotify($xml);
    
            if(!$msg || !is_object($msg)){
                $weixinPay->notifyXml('FAIL', '通知不合法');
            }
        
            if(!isset($msg->return_code) || $msg->return_code != 'SUCCESS'){
                $weixinPay->notifyXml('FAIL', '通信失败');
            }
        
            if(!isset($msg->result_code) || $msg->result_code != "SUCCESS"){
                $weixinPay->notifyXml('FAIL', '交易失败');
            }
        
            //签名验证失败
            if(!$weixinPay->checkSign($msg)){
                $weixinPay->notifyXml('FAIL', '签名验证失败');
            }
            //$notifyMongo->add($msg);
            //流程走到这里说明已经支付成功了,这里无需更新订单逻辑
            $userOrder = new UserOrder();
            //记录微信订单号
            $userOrder->pay($msg->out_trade_no, $msg->transaction_id);
        }
    复制代码

    demo下载:

    http://download.csdn.net/detail/loneleaf1/9045731

    http://www.cnblogs.com/strick/p/4754382.html

  • 相关阅读:
    全局临时表的应用 Timothy
    结合windows服务的Socket聊天室 Timothy
    阿拉伯数字转换成金额大写金额(包括小数) Timothy
    回文字符串和栈 Timothy
    SQL 读取不连续的第30到40之间的数据 Timothy
    C#中as和is关键字 Timothy
    嵌套事务和事务保存点的错误处理 Timothy
    隐式事务 Timothy
    float,double和decimal类型 Timothy
    string 值类型还是引用类型 Timothy
  • 原文地址:https://www.cnblogs.com/softidea/p/4774323.html
Copyright © 2020-2023  润新知