首页 > PHP
ThinkPHP6对接微信小程序支付
来源:TP课堂 时间:2021-02-18 点击:551

1、准备资料,略。

2、微信小程序支付用的是trade_type:JSAPI,但是这并不意味着可以直接把微信公众号支付代码拿过来,还需要重新写。

3、上demo代码,其中一些互转完全可以百度出来,比如xml转数组,数组转xml,进行post请求等。

4、不需要引入任何类,extend等都不需要


public  function wxpay()
    {
        $openid=input('post.openid');
        $mch_id     = '152223331'; //商户ID
        $pay_key     = 'c4c4238a0b923820dcc509a6f75849b'; //商户密钥
        $appid      = 'wxb707afa34a3be7b'; //微信分配的小程序ID
        $nonce_str  = md5(uniqid(md5(microtime(true)),true)); //生成随机字符串,长度要求在32位以内
        $notify_url ='https://www.xx.cn/'; //异步接收微信支付结果通知的回调地址

        $data=[
            'appid'=>$appid,
            'mch_id'=>$mch_id,
            'nonce_str'=>$nonce_str,
            'body'=>'会员充值',
            'openid'=>$openid,
            'out_trade_no'=>time(),
            'total_fee'=>1,
            'spbill_create_ip'=>$_SERVER['SERVER_ADDR'],
            'notify_url'=>$notify_url,
            'trade_type'=>'JSAPI',
        ];
        //生成支付签名
        $data['sign'] = $this->MakeSign($data,$pay_key);
        
        $post_xml =$this->arrayToXml($data); //将数组转换为数组xml数据
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $xml = $this->curl_post($url,$post_xml); //POST请求
        $return_data=$this->xmlToArray($xml); //将xml数据转换为数组
        
        if($return_data['return_code'] == 'SUCCESS'){
            $re_array=[
                        'appId'  =>$appid,
                        'nonceStr'=>$nonce_str,                      
                        'package'=>'prepay_id='.$return_data['prepay_id'],
                        'signType'=>'MD5',
                        'timeStamp'=>(String)time(), //注意要String类型
                        ];
            $re_array['paySign'] = $this->MakeSign($re_array,$pay_key);
            return json($re_array);

        }else{
            $msg = isset($return_data['return_msg']) ? $return_data['return_msg']:'发起支付失败';
            return json(['status'=>false,'msg'=>$msg,'data'=>[]]);
        }
    }


    /**
     * 生成签名
     * @param   $params 加密数组
     * @param   $KEY    支付key
     *
     * @return  $result  签名值
     * 
     */
    public function MakeSign($params, $keys)
    {
        //第一步:按字典序排序数组参数
        ksort($params);
        //参数进行拼接key=value&k=v
        $string = '';
        if (!empty($params)) {
            $array = array();
            foreach ($params as $key => $value) {
                $array[] = $key . '=' . $value;
            }
            $string = implode("&", $array);
        }
        //第二步:在string后加入keys
        $string = $string . "&key=" . $keys;
        //第三步:MD5加密
        $string = md5($string);
        //第四步:所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    public function curl_post($url , $data=array()){

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

        // POST数据

        curl_setopt($ch, CURLOPT_POST, 1);

        // 把post的变量加上

        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

        $output = curl_exec($ch);

        curl_close($ch);

        return $output;

    }

    function arrayToXml($arr) {
        $xml = "<xml>";
        foreach ($arr as $key => $val){
            if (is_numeric($val)){
                $xml.="<$key>$val</$key>";
            }
            else
                $xml.="<$key><![CDATA[$val]]></$key>";
        }
        $xml.="</xml>";
        return $xml;
    }


    function xmlToArray($xml)
    {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $values;
    }


uniapp点击支付按钮后,请求上面wxpay方法,预支付请求后返回给uniapp,uniapp接收到如下:

appId: "wxb707a6fa34a3b7b"
nonceStr: "d06c16584f1b272643d7146bca758bd9"
package: "prepay_id=wx18092258124322d8fa2c7773b91fef0000"
paySign: "3F5B1EFC7E34C3C753F41360F2669823"
signType: "MD5"
timeStamp: "1613611378"


这样即可实现支付,可用开发者本人微信进行测试支付。

参考资料:https://blog.csdn.net/qq_30006251/article/details/108242751