微信小程序之wx.requestPayment 发起微信支付

wx.requestPayment 发起微信支付

timeStamp 时间戳

nonceStr 随机字符串

package 统一下单接口返回的 prepay_id 参数值

signType 签名算法

paySign 支付签名

success 接口成功回调

fail 接口失败回调

complete 接口完成回调(成功,失败都执行)

1.先调用后台接口,生产基本数据

// 获取店铺信息
Api.BalancePay({
    openid: openid,
    amount: amount,
    bid: bid,
}).then(res => {
    if (res.errno) {
        wx.showToast({ title: res.errdesc });
        return;
    }
    var data = res.data;
    ...
})

具体的这个是做什么的呢?

判断用户是否存在。

判断充值id是否存在。

判断充值金额是否合法。

创建充值订单。

创建统一支付订单。

public function unifiedorder($openid,$order_num,$total_fee,$products_name){
        $trade_no = $order_num;
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $data = [
            'appid'             => C('APPID'),
            'mch_id'            => C('MCHID'),
            'nonce_str'         => $this->createNonceStr(),
            'sign_type'         => 'MD5',
            'body'              =>  $products_name,  //商品名称组合
            'attach'            => C('PAY_ATTACH_NAME'),
            'out_trade_no'      => $trade_no,        //订单号
            'fee_type'          => 'CNY',
            'total_fee'         => $total_fee,
            'spbill_create_ip'  => $_SERVER['REMOTE_ADDR'],
            'goods_tag'         => C('PAY_ATTACH_NAME'),
            'notify_url'        => 'https://a.squmo.com/'.C('PAY_URL_NAME').'/Recharge/order_notice',
            'trade_type'        => 'JSAPI',
            'openid'            => $openid
        ];

        // 获取签名
       $sign = $this->MakeSign($data);
       $data['sign'] = $sign;
       $xml = $this->ToXml($data);
       vendor('Func.Http');
       // 提交获取数据
       $result = $this->FromXml(Http::postXmlCurl($url,$xml));
       return $result;
}

一切准备就绪之后,将一些数据返回给小程序。

$unifiedorder = $this->unifiedorder($openid,$order_num,$total_price,$products_name);
$data = [
    'appId'     => C('APPID'),
    'timeStamp' => time(),
    'nonceStr'  => $this->createNonceStr(),
    'package'   => 'prepay_id='.$unifiedorder['prepay_id'],
    'signType'  => 'MD5'
];
// 获取签名
$sign = $this->MakeSign($data);
$data['sign'] = $sign;
$this->json->setAttr('data',$data);
$this->json->Send();

2.再发起微信支付

wx.requestPayment({
        'timeStamp': data.timeStamp.toString(),
        'nonceStr': data.nonceStr,
        'package': data.package,
        'signType': 'MD5',
        'paySign': data.sign,
        'success': function (res) {
            console.log('支付成功');
        },
        'fail': function (res) {
            console.log('支付失败');
            return;
        },
        'complete': function (res) {
            console.log('支付完成');
            var url = that.data.url;
            console.log('get url', url)
            if (res.errMsg == 'requestPayment:ok') {
                wx.showModal({
                    title: '提示',
                    content: '充值成功'
                });
                if (url) {
                    setTimeout(function () {
                        wx.redirectTo({
                            url: '/pages' + url
                        });
                    }, 2000)
                } else {
                    setTimeout(() => {
                        wx.navigateBack()
                    }, 2000)
                }
            }
            return;
        }
});

3.支付成功的回调(异步操作)

//微信支付回调
public function order_notice(){
    // 微信公众平台推送过来的post数据
    $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
    // 获取数据
    $data = $this->FromXml($xml);
    // 保存微信服务器返回的签名sign
    $data_sign = $data['sign'];
    // sign不参与签名算法
    unset($data['sign']);

    $sign = $this->makeSign($data);
    // 判断签名是否正确  判断支付状态
    if ( ($sign===$data_sign) && ($data['return_code']=='SUCCESS') && ($data['result_code']=='SUCCESS') ) {
        $result = $data;
        //获取服务器返回的数据
        $order_num = $data['out_trade_no'];         //订单单号
        $openid = $data['openid'];                  //付款人openID
        $total_fee = $data['total_fee'];            //付款金额
        $transaction_id = $data['transaction_id'];  //微信支付流水号
        $user = M('user');
        $user_flag = $user->where(array('openid'=>$openid))->find();
        $save_data = array(
            'total_payed_price' =>  $total_fee,     //实际到帐金额
            'transaction_id'    =>  $transaction_id,
            'paytime'           =>  time(),
            'status'            =>  2       //1未支付;2已支付;3已申请退款;4已退款;5已完成
        );
        $recharge = M('recharge');
        $recharge_flag=$recharge->where(array('recoder'=>$order_num,'uid'=>$user_flag['id']))->find();
        $recharge_amount=$recharge_flag['amount'];
        $recharge_save_flag =$recharge->where(array('recoder'=>$order_num,'uid'=>$user_flag['id']))->save($save_data);
        if($recharge_save_flag){
            $save_balance['balance']= $user_flag['balance']+$recharge_amount;
            $result_balance =$user->where(array('openid'=>$openid))->save($save_balance);
        }
    }else{
        $result = false;
    }
    // 返回状态给微信服务器
    if ($result) {
        $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
    }else{
        $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
    }
    echo $str;
    return $result;
}

其他常用函数

    public function FromXml($xml)
    {
        if(!$xml){
            throw new WxPayException("xml数据异常!");
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $this->values;
    }

    public function ToXml($array){
        if(!is_array($array)|| count($array) <= 0){
           return ;
        }
        $xml = '<xml version="1.0">';
        foreach ($array as $key=>$val){
            if (is_numeric($val)){
              $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    private function MakeSign($data)
    {
        //签名步骤一:按字典序排序参数
        ksort($data);
        $string = $this->ToUrlParams($data);
        //签名步骤二:在string后加入KEY
        $string = $string . "&key=".C('WEIXIN_PAY_KEY');
        //签名步骤三:MD5加密
        $string = md5($string);
        //签名步骤四:所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    private function ToUrlParams($array)
    {
        $buff = "";
        foreach ($array as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

原文地址:https://www.cnblogs.com/jiqing9006/p/9318852.html

时间: 2024-10-09 23:56:36

微信小程序之wx.requestPayment 发起微信支付的相关文章

微信 小程序 drawImage wx.canvasToTempFilePath wx.saveFile 获取设备宽高 尺寸问题

以下问题测试环境为微信开发者0.10.102800,手机端iphone6,如有不对敬谢指出. 根据我的测试,context.drawImage,在开发者工具中并不能画出来,只有预览到手机中显示. wx.canvasToTempFilePath wx.saveFile 官方文档中只有一行,真是坑爹啊,原来 wx.canvasToTempFilePath参数为一个对象包括canvasID,success,fail,complete,和wx.saveFile差不多: wx.canvasToTempFi

微信小程序之wx.navigateback往回携带参数

在微信小程序开发的过程当中  经常碰到一些带逻辑的一些事情 就比如 新增地址 修改地址  筛选用户条件等页面的时候  我们也可以用wx.navigateTo来跳转实现 但其中有很多问题 1.微信的十层跳转  当你用navigateTo跳转的时候跳转十次的时候就跳不动了 2.参数的传递 我们在用navigateTo跳转的时候通常带着参数来跳  试想一下 如果我们一种这么跳 那么携带的参数越来越多 这不是开发的一个好事情 所以在以上的问题上我们可以用navigateback来实现  既仅携带本次跳转

【微信小程序】 wx:if 与 hidden(隐藏元素)区别

wx:if 与 hidden 都可以控制微信小程序中元素的显示与否. 区别: wx:if 是遇 true 显示,hidden 是遇 false 显示. wx:if 在隐藏的时候不渲染,而 hidden 在隐藏时仍然渲染,只是不呈现. 所以如果频繁切换的话,用 wx:if 将会消耗更多资源,因为每次呈现的时候他都会渲染,每次隐藏的时候,他都会销毁. 如果切换并不频繁的话,用 wx:if 相对来说较好些,因为它会避免初始就一下渲染那么多. wxml: <view> <text>page

微信小程序:wx.request之post请求后端无法获取数据的问题

前言:小程序的开发中总是踩到各种坑,看文档也不知所云: 例如当我们在写微信小程序接口时,method请求方式有POST和GET两种,为了数据安全,我们会偏向于使用POST请求方式访问服务器端: 问题:当我们使用POST方式请求时,后端无法获取数据,但使用GET方式便可以获取数据?? 解决办法: 设置请求的 header: header: { "Content-Type": "application/x-www-form-urlencoded" }, 例如:

微信小程序开发系列一:微信小程序的申请和开发环境的搭建

我最近也刚刚开始微信小程序的开发,想把我自学的一些心得写出来分享给大家. 这是第一篇,从零开始学习微信小程序开发.主要是小程序的注册和开发环境的搭建. 首先我们要在下列网址申请一个属于自己的微信小程序: https://mp.weixin.qq.com/cgi-bin/wx 点击按钮"前往注册".注意我们需要使用一个没有注册过微信小程序或者微信公众号的邮箱.我用的是网易邮箱.注册之后,邮箱会收到一封激活邮件. 激活之后,就可以进入小程序主体信息登记页面了.这里需要使用×××号码和手机验

学习微信小程序系列(1) 如何注册微信小程序

目录 前言 什么是微信小程序 如何注册微信小程序 前言 去年,有一段时间,因为工作的需要,需要进行微信小程序的开发工作.刚开始接触的时候,说真的.真的5脸懵逼.工作总是这么无奈,硬生生的逼着自己从不想学,不想写.到最后,逼着自己完成了整个小程序的前后端的开发工作.又过了一段时间,再翻开回自己曾经写的代码.简直是不堪入目.于是,我又认真的学习了一下有关微信小程序的相关的基础础.ps:趁着自己脑子还行,强行mark自己是如何学习小程序的心路历程.希望,对初学者有所帮助. 什么是微信小程序 孔子都说,

微信小程序来了,整理微信小程序学习教程网站

第一,首先菜鸟教程  网址:http://www.runoob.com/ ps: 菜鸟教程(www.runoob.com)提供了最全的编程技术基础教程, 介绍了HTML.CSS.Javascript.Python,Java,Ruby,C,PHP , MySQL等各种编程语言的基础知识.菜鸟教程(www.runoob.com)提供了最全的编程技术基础教程, 介绍了HTML.CSS.Javascript.Python,Java,Ruby,C,PHP , MySQL等各种编程语言的基础知识. 同时本站

(微信小程序)一 : 初识微信小程序

首先看过angularjs的同学们在看微信小程序的创始文件应该不算很陌生吧. 需要看的 先是文件目录 看完这个目录..得知 ( 一 )    pages   他存放于多个页面 如 index ,log页面.可以把他里面的每个文件夹看成一个整体.这个整体存放着 html .css 和 数据 1:index文件夹    ---    存放的index页面的目录. 2:index.js    ---    他可以处理得到(ajax),或自定义定义的数据.把得到的值封装成一个对象 交给wxml渲染数据.

【微信小程序常识】如何绑定微信小程序体验者

转自:https://blog.csdn.net/futruejet/article/details/53223826 一.操作步骤 (1)打开微信小程序公众平台->点击右边菜单[用户身份]->点击左边选项卡[体验者]->点击[绑定]按钮 (2)小程序公众平台管理员用手机扫描二维码后手机上点击[绑定]->输入体验者微信号后点击搜索图标->点击[确认]按钮 (3)被邀请者手机微信收到邀请通知,点击[详情]->点击[确认] (4)当微信小程序公众平台[体验者]界面显示体验者