小程序发起微信支付(使用jiaweixs)

首先引用一下微信官方文档的业务流程时序图,这是最简洁明了的:

商户系统和微信支付系统主要交互:

    1、小程序内调用登录接口,获取到用户的openid,api参见公共api【小程序登录API

    2、商户server调用支付统一下单,api参见公共api【统一下单API

    3、商户server调用再次签名,api参见公共api【再次签名

    4、商户server接收支付通知,api参见公共api【支付结果通知API

    5、商户server查询支付结果,api参见公共api【查询订单API



其次,我们需要使用小程序提供的API,发起微信支付。以下是详细的接口文档:

wx.requestPayment(OBJECT)

Object参数说明:

参数类型必填说明
timeStampString时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间
nonceStrString随机字符串,长度为32个字符以下。
packageString统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
signTypeString签名算法,暂支持 MD5
paySignString签名,具体签名方案参见小程序支付接口文档;
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

了解更多信息,请查看微信支付接口文档

回调结果:

回调类型errMsg说明
successrequestPayment:ok调用支付成功
failrequestPayment:fail cancel用户取消支付
failrequestPayment:fail (detail message)调用支付失败,其中 detail message 为后台返回的详细失败原因

示例代码:

wx.requestPayment({
   'timeStamp': '',
   'nonceStr': '',
   'package': '',
   'signType': 'MD5',
   'paySign': '',
   'success':function(res){
   },
   'fail':function(res){
   }
})
Bug & Tip
  1. bug: 6.5.2 及之前版本中,用户取消支付不会触发 fail 回调,只会触发 complete 回调,回调 errMsg 为 'requestPayment:cancel'

现在给出实际开发代码的一个例子:

①:小程序发起微信支付与回调处理的代码:

//购买
  pay: function (e) {
    var id = e.currentTarget.dataset.id;
    var that = this;
    request.post({
      url: '/api/mime/createOrder',
      data: {
        id: id,
      },
      success: function (res) {
        console.log(res);
        var result = res.data.result;
        wx.requestPayment({
          timeStamp: result.time.toString(),
          nonceStr: result.nonce_str,
          package: 'prepay_id=' + result.prepay_id,
          signType: 'MD5',
          paySign: result.sign,
          success: function (res) {
            that.confirmOrder(result.orderNo);
          },
          fail: function (res) {
            console.log(res);
          }
        })
      },
      fail: function (e) {
        wx.showToast({
          title: '请求失败!',
          duration: 2000
        });
      },
    });
  },
  //付款成功
  confirmOrder: function () {
    var that = this;
    request.post({
      url: '/api/mime/confirmOrder',
      data: {},
      success: function (res) {
        wx.showToast({
          title: '成功开通会员',
          duration: 2000
        });
        setTimeout(function(){
          wx.switchTab({
            url: '../mine/mine'
          })
        },2000);
      },
      fail: function (e) {
        wx.showToast({
          title: '请求失败!',
          duration: 2000
        });
      },
    });
  },

②:然后是用php写的处理生成订单的接口,这里我使用的是jiaweixs的组件

    在composer的配置文件中加入配置,也可以直接用composer命令直接添加

    

/**
     * 微信统一下单
     *
     */
    public function createOrder()
    {
        $id = trim($_POST['id']);
        $config = MemberCostConfig::get($id);
        $userId = $this->user->id;
        //生成订单
        $memberRecord = new MemberRecord();
        $data = array();
        $orderNo = 'W'.date('YmdHis',time()).mt_rand(10000, 99999);
        $data['orderNo'] = $orderNo;
        $data['status'] = 0;
        $data['user_id'] = $userId;
        $data['star_id'] = 0;
        $data['money'] = $config['price'];
        $data['duration'] = $config['duration'];
        $data['vip_day'] = $config['days'];
        $data['create_time'] = date("Y-m-d H:i:s");
        $data['update_time'] = date("Y-m-d H:i:s");
        $memberRecord->save($data);

        $money = (float)$config['price']*100;
        $unifiedorder = new Unifiedorder(APPID, MCHID, KEY);    //Unifiedorder是jiaweixs封装可以直接使用的
        $openid = $this->user->openid;
        // 必填
        $unifiedorder->set('body',          '充值会员');
        $unifiedorder->set('total_fee',     $money);
        $unifiedorder->set('openid',        $openid);
        $unifiedorder->set('trade_type',    'JSAPI');
        $unifiedorder->set('out_trade_no',  date('YmdHis').mt_rand(10000, 99999));
        $unifiedorder->set('notify_url',    BUY_MEMBER_URL);    //这里是微信支付回调地址

        // 选填
        $unifiedorder->set('attach',        $orderNo);
        $unifiedorder->set('time_start',    date("YmdHis")); //订单生成时间
        $unifiedorder->set('time_expire',   date("YmdHis", time() + 600)); //订单失效时间

        $response = $unifiedorder->getResponse();
        $res =  $response->toArray();
        $time = Time();
        $str = 'appId='.$res['appid'].'&nonceStr='.$res['nonce_str'].'&package=prepay_id='.$res['prepay_id'].'&signType=MD5&timeStamp='.$time;
        //重新生成签名
        $res['sign']=strtoupper(md5($str.'&key='.KEY));
        $res['time'] = $time;
        $res['orderNo'] =$orderNo;

        // 下单结果
        return $this->api_success('success', 200, $res);
    }

    /**
     * 修改订单状态
     *
     */
    public function confirmOrder()
    {
        $orderNo = trim($_POST['orderNo']);
        //修改订单状态
        $rechargeRecord = new RechargeRecord();
        $order = $rechargeRecord->where('orderNo', 'eq', $orderNo)->find();
        if ($order) {
            $data['number'] = $order['love_number'];
            return $this->api_success('success', 200, $data);
        } else {
            return $this->api_error('订单不存在',100);
        }
    }

③:最后就是微信支付的回调通知:

/**
     * 开通会员成功支付回调 接口
     */
    public function member()
    {
        $post = file_get_contents("php://input");
        $post_data = $this->xml_to_array($post);   //微信支付成功,返回回调地址url的数据:XML转数组Array

        $postSign = $post_data['sign'];
        unset($post_data['sign']);
        $record = new MemberRecord();
        $order = $record->where('orderNo', 'eq', $post_data['attach'])->find();

        if ($post_data['return_code'] == 'SUCCESS' && $postSign) {
            if ($order['status'] == '0') {
                $record->save(array('status' => 1,'update_time'=>date('Y-m-d H:i:s')), array('orderNo' => $post_data['attach']));

                $user = User::get($order['user_id']);
                $user['recharge_times'] = $user['recharge_times'] + 1;
                $user['recharge_money'] = $user['recharge_money'] + $order['money'];
                $user->save();

                $memberRecord = new MemberRecord();
                $record = $memberRecord->field('')
                    ->where('user_id','eq',$user->id)
                    ->where('end_time','>',date('Y-m-d H:i:s'))
                    ->order('end_time desc')
                    ->limit(1)
                    ->select();
                $order['start_time'] = count($record) > 0 ? $record[0]['end_time'] : date("Y-m-d H:i:s");
                $order['end_time'] = date("Y-m-d H:i:s",(strtotime($order['start_time']) + 3600*24*$order['vip_day']));    //天数
                $order['update_time'] = date("Y-m-d H:i:s");
                $order['status'] = '1';
                $order->save();

                // 对应的渠道增加佣金
                $channel = Channel::get(['id'=> $user['channel_id']]);
                if ($channel) {
                    $brokerage = $channel['brokerage'];
                    $channel['total_brokerage'] = $channel['total_brokerage'] + ( $order['money'] * ($brokerage / 100));
                    $channel->save();
                }
            }
            $this->return_success();
        } else {
            echo '微信支付失败';
        }
    }
/**
     * 将xml转为array
     */
    public function xml_to_array($xml)
    {
        if (!$xml) {
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }

    /**
     * 给微信发送确认订单金额和签名正确,SUCCESS信息 -xzz0521
     */
    private function return_success()
    {
        $return['return_code'] = 'SUCCESS';
        $return['return_msg'] = 'OK';
        $xml_post = '<xml>
                    <return_code>' . $return['return_code'] . '</return_code>
                    <return_msg>' . $return['return_msg'] . '</return_msg>
                    </xml>';
        echo $xml_post;
        exit;
    }












老规矩,先看本节效果图我们实现这个支付功能完全是借助小程序云开发实现的,不用搭建自己的服务器,不用买域名,不用备案域名,不用支持https。只需要一个简单的云函数,就可以轻松的实现微信小程序支付功能。核心代码就下面这些一,创建一个云开发小程序关于如何创建云开发小程序,这里我就不再做具体讲解。不知道怎么创建云开发小程序的同学,可以去翻看我之前的文章,或者看下我录制的视频:https://edu.csdn.net/course/play/9604/204528创建云开发小程序有几点注意的1,一定不要忘记在app.js里初始化云开发环境。2,创建完云函数后,一定要记得上传二, 创建支付的云函数1,创建云函数pay三,引入三方依赖tenpay我们这里引入三方依赖的目的,是创建我们支付时需要的一些参数。我们安装依赖是使用里npm 而npm必须安装node,关于如何安装node,我这里不做讲解,百度一下,网上一大堆。1,首先右键pay,然后选择在终端中打开2,我们使用npm来安装这个依赖。在命令行里执行 npm i tenpay安装完成后,我们的pay云函数会多出一个package.json 文件到这里我们的tenpay依赖就安装好了。四,编写云函数pay完整代码如下//云开发实现支付 const cloud = require('wx-server-sdk')cloud.init() //1,引入支付的三方依赖 const tenpay = require('tenpay'); //2,配置支付信息 const config = ;exports.main = async(event, context) => 一定要注意把appid,mchid,partnerKey换成你自己的。到这里我们获取小程序支付所需参数的云函数代码就编写完成了。不要忘记上传这个云函数。出现下图就代表上传成功五,写一个简单的页面,用来提交订单,调用pay云函数。这个页面很简单,1,自己随便编写一个订单号(这个订单号要大于6位)2,自己随便填写一个订单价(单位是分)3,点击按钮,调用pay云函数。获取支付所需参数。下图是官方支付api所需要的一些必须参数。下图是我们调用pay云函数获取的参数,和上图所需要的是不是一样。六,调用wx.requestPayment实现支付下图是官方的示例代码这里不在做具体讲解了,完整的可以看视频。实现效果1,调起支付键盘2,支付完成3,log日志,可以看出不同支付状态的回调上图是支付成功的回调,我们可以在支付成功回调时,改变订单支付状态。下图是支付失败的回调,下图是支付完成的状态。到这里我们就轻松的实现了微信小程序的支付功能了。是不是很简单啊,完整的讲解可以看视频。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值