提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

项目介绍:
前端:uniapp;
后端:thinkphp6;
数据库:mysql;
项目成品:微信小程序。


提示:以下是本篇文章正文内容,下面案例可供参考

一、微信支付流程

详情可查看微信官方提供的接入指引

二、接入步骤

1.前端请求下单并支付

	request.post('Wxpay/index', {//请求服务端生成预支付订单
		openId: openid,//用户的openid,该处参数根据开发者需要自行修改
	}).then(res => {//订单生成成功
		let data = res.data;
		//调用uniapp提供的支付api
		uni.requestPayment({
			"provider": "wxpay", //固定值为"wxpay"
			"timeStamp": data.timeStamp,
			"nonceStr": data.nonceStr,
			"package": data.package,
			"signType": data.signType,
			"paySign": data.paySign,
			success: function(res) {
				console.log("支付成功");
			},
			fail: function(err) {
				console.log('支付失败:');
			}
		});
	})

2.后端生成预支付订单

代码如下:

<?php
class Wxpay
{
    //生成预支付订单
    public function index()
    {
        //接受参数
        $openid = input('post.openId');//用户openId
        //读取支付配置
        $appid ='';//平台appid
        $mch_id =''; //商户号
        $nonce_str = $this->nonce_str();//随机字符串
        $fee = 1;//订单费用
        $body ='测试';//订单描述
        $notify_url = ''; //回调的url【自己填写】
        $out_trade_no = $this->order_number($openid);//商户订单号
        $spbill_create_ip = '';//服务器的ip【自己填写】;
        $total_fee = $fee * 100;// 微信支付单位是分,所以这里需要*100
        $trade_type = 'JSAPI';//交易类型 默认

        //这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
        $post['appid'] = $appid;
        $post['body'] = $body;
        $post['mch_id'] = $mch_id;
        $post['nonce_str'] = $nonce_str;//随机字符串
        $post['notify_url'] = $notify_url;
        $post['openid'] = $openid;
        $post['out_trade_no'] = $out_trade_no;
        $post['spbill_create_ip'] = $spbill_create_ip;//终端的ip
        $post['total_fee'] = $total_fee;//总金额
        $post['trade_type'] = $trade_type;
        $sign = $this->sign($post);//签名
        $post_xml = '<xml>
                    <appid>' . $appid . '</appid>
                    <body>' . $body . '</body>
                    <mch_id>' . $mch_id . '</mch_id>
                    <nonce_str>' . $nonce_str . '</nonce_str>
                    <notify_url>' . $notify_url . '</notify_url>
                    <openid>' . $openid . '</openid>
                    <out_trade_no>' . $out_trade_no . '</out_trade_no>
                    <spbill_create_ip>' . $spbill_create_ip . '</spbill_create_ip>
                    <total_fee>' . $total_fee . '</total_fee>
                    <trade_type>' . $trade_type . '</trade_type>
                    <sign>' . $sign . '</sign>
                </xml> ';

        //统一接口prepay_id
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $xml = $this->http_request($url, $post_xml);

        $array = $this->xml($xml);//全要大写

        if ($array['return_code'] == 'SUCCESS' && $array['result_code'] == 'SUCCESS') {
            $time = time();
            $tmp = array();//临时数组用于签名
            $tmp['appId'] = $appid;
            $tmp['nonceStr'] = $nonce_str;
            $tmp['package'] = 'prepay_id=' . $array['prepay_id'];
            $tmp['signType'] = 'MD5';
            $tmp['timeStamp'] = "$time";
            //返回的订单数据
            $data['appid'] = $appid;//商家号
            $data['partnerid'] = $mch_id;//商家号
            $data['timeStamp'] = "$time";//时间戳
            $data['nonceStr'] = $nonce_str;//随机字符串
            $data['signType'] = 'MD5';
            $data['package'] = 'prepay_id=' . $array['prepay_id'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
            $data['sign'] = 'Sign=WXPay';
            $data['paySign'] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
            $data['orderId'] = $out_trade_no;//服务器中的订单id
            $this->model->save([
                'appid' => $openid,
                'orderId' => $out_trade_no,
                'fee' => $fee*100
            ]);

        } else {
            $data['state'] = 0;
            $data['text'] = "错误";
            $data['return_code'] = $array['return_code'];
            $data['return_msg'] = $array['return_msg'];
            return json(['code' => 400, 'data' => $data]);
        }
        return json(['code' => 200, 'data' => $data]);
    }

   
    //随机32位字符串
    private function nonce_str()
    {
        $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
        $result='';
        for ($i = 0; $i < 32; $i++) {
            $result.= $str[rand(0, 48)];
        }
        return $result;
    }


    //生成订单号
    private function order_number($openid)
    {
        //date('Ymd',time()).time().rand(10,99);//18位
        return md5($openid . time() . rand(10, 99));//32位
    }


    //签名 $data要先排好顺序
    private function sign($data)
    {
        $stringA = '';
        foreach ($data as $key => $value) {
            if (!$value) continue;
            if ($stringA) $stringA .= '&' . $key . "=" . $value;
            else $stringA = $key . "=" . $value;
        }
        $wx_key = '';//申请支付后有给予一个商户账号和密码,登陆后自己设置的key
        $stringSignTemp = $stringA . '&key=' . $wx_key;
        return strtoupper(md5($stringSignTemp));
    }


    //curl请求
    public function http_request($url, $data = null, $headers = array())
    {
        $curl = curl_init();
        if (count($headers) >= 1) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

    //xml转数组
    public function xml($xml)
    {
        if ($xml == '') return '';
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $arr;
    }

}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐