微信扫码支付Native支付

微信扫码支付Native支付
框架tp5.1
1.统一下单返回支付二维码路径
2.生成二维码 展示
使用到phpqrcode.php 微信支付demo 里面的
在这里插入图片描述

<?php
/**
 * Author  : 魔十七
 * Date    : 2021/2/6 15:57
 * QQ      : 3125888309
 * explain : 微信Native支付
 */

namespace app\rent\controller;
use think\Controller;
require_once "./extend/phpqrcode/phpqrcode.php";
class WxPay extends Controller
{
    protected $appid="appid";//小程序id
    protected $mchid="mchid";//商户id
    protected $key="";//密钥  微信商户api安全 ->api密钥  设置
    public function index()
    {
        $backArray=['code'=>1,'msg'=>'','src'=>''];
        $backData=$this->unifiedOrder(time(),'测试商品',0,"回调地址");
        if($backData['return_code'] == "SUCCESS"){
            $url = urldecode($backData['code_url']);
            //生成二维码
            $level = 'L';// 纠错级别:L、M、Q、H  密集度
            $size = 6;// 点的大小:1到10,小方块的大小
            $QRcode = new \QRcode();
            $QRcode->png(urldecode($url),false,$level,$size);
            $data = ob_get_contents();//返回输出缓冲区的内容
            ob_end_clean();//缓冲区并关闭输出缓冲
            $code_url =  "data:image/jpeg;base64,".base64_encode($data);
            $backArray['code'] = 0;
            $backArray['msg']  = "ok";
            $backArray['src']  = $code_url;
        }else{
            $backArray['msg']=$backData['invalid total_fee'];
        }
        exit(json_encode($backArray));
    }

    public function CallBack(){
        $param = file_get_contents("php://input");
        $jsonxml = json_encode(simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA));
        $result = json_decode($jsonxml, true);//转成数组,
        $order_sn = $result['out_trade_no'];
        echo "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA]></return_msg></xml>";
    }
        /**
     * 统一下单
     * @param $out_trade_no  商户订单号
     * @param $body  描述
     * @param $total_fee  金额(分)
     * @param string $notify_url  回调地址
     * @param string $trade_type  支付类型  NATIVE
     * @return mixed
     */
    protected function unifiedOrder($out_trade_no,$body,$total_fee,$notify_url="",$trade_type="NATIVE"){
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $parameters=[
            'appid'=>$this->appid,
            'mch_id'=>$this->mchid,
            'nonce_str'=>$this->createNoncestr(),//随机字符串
            'body'=>$body,//商品描述
            'out_trade_no'=>$out_trade_no,//商户订单号
            'total_fee'=>$total_fee,//标价金额
            'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],//终端IP
            'notify_url'=>$notify_url,//回调地址
            'trade_type'=>'NATIVE',
        ];
        $parameters['sign'] = $this->getSign($parameters);
        $xmlData = $this->arrayToXml($parameters);
        $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url,60));
        return $return;
    }

    //作用:产生随机字符串,不长于32位
    private function createNoncestr($length = 32) {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    //作用:生成签名
    private function getSign($Obj) {
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        //签名步骤一:按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //签名步骤二:在string后加入KEY
        $String = $String . "&key=".$this->key;
        //签名步骤三:MD5加密
        $String = md5($String);
        //签名步骤四:所有字符转为大写
        $result_ = strtoupper($String);
        return $result_;
    }
    ///作用:格式化参数,签名过程需要使用
    private function formatBizQueryParaMap($paraMap, $urlencode) {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }
    //xml转换成数组
    private function xmlToArray($xml) {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $val = json_decode(json_encode($xmlstring), true);
        return $val;
    }
    //数组转换成xml
    private function arrayToXml($arr) {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_array($val)) {
                $xml .= "<".$key .">".$this->arrayToXml($val)."</".$key.">";
            } else {
                $xml .= "<".$key.">".$val."</".$key.">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    //向微信发送请求
    private static function postXmlCurl($xml, $url, $second = 30)
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
        curl_setopt($ch, CURLOPT_TIMEOUT, 40);
        set_time_limit(0);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            throw new WxPayException("curl出错,错误码:$error");
        }
    }
}

前端

function wxPay() {
    $.ajax({
        type:"post",
        url:url,
        data: {},
        dataType:"json",
        success:function(res){
            if(res.code == 0){
                $('#wxImg').attr('src',res.src)
            }else{
                alert(res.msg);
            }
        }
    });
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Python代码示例,用于实现微信扫码支付: ```python import requests # 微信扫码支付接口地址 wechat_api_url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' # 商户号 mch_id = 'your_mch_id' # 应用ID appid = 'your_appid' # 商户密钥 mch_key = 'your_mch_key' # 生成签名函数 def generate_sign(params): # 按照参数名的ASCII码从小到大排序 sorted_params = sorted(params.items(), key=lambda x:x[0], reverse=False) # 拼接参数名与参数值 sign_str = '&'.join([f'{key}={value}' for key, value in sorted_params]) # 拼接商户密钥 sign_str += f'&key={mch_key}' # 计算签名(使用MD5加密) import hashlib m = hashlib.md5() m.update(sign_str.encode('utf-8')) return m.hexdigest().upper() # 构建请求参数 params = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': 'your_nonce_str', # 随机字符串 'body': 'your_order_description', # 订单描述 'out_trade_no': 'your_out_trade_no', # 商户订单号 'total_fee': 'your_total_fee', # 订单总金额(单位:分) 'spbill_create_ip': 'your_spbill_create_ip', # 终端IP 'notify_url': 'your_notify_url', # 接收微信支付异步通知回调地址 'trade_type': 'NATIVE', # 交易类型为扫码支付 } # 生成签名 params['sign'] = generate_sign(params) # 发起请求 response = requests.post(wechat_api_url, data=params) # 解析响应结果 import xml.etree.ElementTree as ET root = ET.fromstring(response.content) return_code = root.find('return_code').text result_code = root.find('result_code').text if return_code == 'SUCCESS' and result_code == 'SUCCESS': # 获取二维码链接 code_url = root.find('code_url').text print(f'请使用微信扫描以下二维码进行支付:{code_url}') else: # 支付失败处理逻辑 err_code = root.find('err_code').text err_msg = root.find('err_code_des').text print(f'支付失败,错误代码:{err_code},错误信息:{err_msg}') ``` 请注意,上述代码仅为示例,实际应用中需要根据自己的业务需求进行适当的修改和完善。 另外,该示例代码中使用了第三方库`requests`和`xml.etree.ElementTree`,请确保这两个库已经安装在你的Python环境中。你可以使用`pip install requests`和`pip install xml.etree.ElementTree`命令进行安装。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值