• 微信小程序支付功能


    add_balance: function() {
      var that = this;
      var total_payed_price = this.data.recharge;
      var rc_id = this.data.rc_id;
      getData.getData('rechargePay', {
        openid: app.globalData.openid,
        total_payed_price: total_payed_price,
        rc_id: rc_id,
        method: 'POST'
      }, function(res) {
        if (res.errno) {
          wx.showToast({
            title: res.errdesc
          });
          return;
        }
        var data = res.data;
        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('支付完成');
            console.log(res);
            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;
          }
        });
    
      })
    }
    

    上述是小程序端的操作。

    下面是php的操作。

    <?php
    
    namespace ApiAction;
    
    
    use VendorFuncHttp;
    
    /**
     * 充值相关接口
     */
    class RechargeAction extends CommonAction
    {
        /**
         * 获取充值项
         */
        public function get_recharge_config(){
            $recharge_config = M('recharge_config');
            $recharge_config_list = $recharge_config->where(array('status'=>1,'is_show'=>1))->field('id,recharge,amount')->select();
    
            $this->json->setAttr('data',$recharge_config_list);
            $this->json->Send();
        }
    
        /***
         * 余额充值微信支付
         */
        public function pay(){
            if (!$openid = trim($_POST['openid'])){
                $this->json->setErr(10001,'缺少参数');
                $this->json->Send();
            }
            if(!$rc_id = $_POST['rc_id']){
                $this->json->setErr(10001,'没有余额充值id');
                $this->json->Send();
            }
            $total_payed_price = (float)$_POST['total_payed_price']; // 实际支付金额
            if ($total_payed_price <= 0){
                $this->json->setErr(10002,'支付金额不可为0或负数');
                $this->json->Send();
            }
            $recharge_config = M('recharge_config');
            $recharge_flag = $recharge_config->where(array('id'=>$rc_id,'status'=>1,'is_show'=>1))->find();
            if (!$recharge_config) {
                $this->json->setErr(10002,'充值项不存在');
                $this->json->Send();
            }
    
            $money_amount = $recharge_flag['amount']; // 应到账金额
            $user = M('user');
            $user_info = $user->where(array('openid'=>$openid))->find();
            if (!$user_info){
                $this->json->setErr(10001,'用户信息不存在');
                $this->json->Send();
            }
            $uid = $user_info['id'];
    
            $user_balance = $user_info['balance'];
            // step1 生成订单
            $order_info = $this->makeorder($uid,$total_payed_price,$money_amount,$user_balance);
            $order_num = $order_info['order_num'];
            $products_name = $order_info['products_name'];
    
            // step2  unifiedorder
            $unifiedorder = $this->unifiedorder($openid,$order_num,$total_payed_price*100,$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;
    
            // step3 将数据package下放到小程序中
            $this->json->setAttr('data',$data);
            $this->json->Send();
        }
    
    
        /***
         * 生成充值订单
         */
        private function makeorder($uid,$total_payed_price,$money_amount,$user_balance){
            $recharge_order = M('recharge_order');
            $now = time();
            $order_num = 'cz'.$uid.substr($now,3).rand(1000,9999);
            $order_add_data = [
                'order_num'          =>  $order_num,
                'amount'             =>  $money_amount,    //订单价格
                'balance'            =>  ($user_balance+$money_amount),
                'uid'                =>  $uid,
                'status'             =>  1,               //未到账
                'total_payed_price'  =>  $total_payed_price,
                'create_time'        =>  $now,            //订单生成时间
            ];
            $order_add_flag = $recharge_order->add($order_add_data);
            if (!$order_add_flag){
                $this->json->setErr(10003,'生成订单失败');
                $this->json->Send();
            }
            $return_data['order_num'] = $order_num;
            $return_data['products_name'] ='余额充值';
            return $return_data;
        }
    
    
        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('APP_NAME').'-附加信息',
                'out_trade_no'      => $trade_no,       //订单号
                'fee_type'          => 'CNY',
                'total_fee'         => $total_fee,
                'spbill_create_ip'  => $_SERVER['REMOTE_ADDR'],
                'goods_tag'         => C('APP_NAME').'-商品标记',
                'notify_url'        => C('RECHARGE_URL'),
                'trade_type'        => 'JSAPI',
                'openid'            => $openid
            ];
    
    
            $sign = $this->MakeSign($data);
            $data['sign'] = $sign;
            $xml = $this->ToXml($data);
            $result = $this->FromXml(Http::postXmlCurl($url,$xml));
            return $result;
        }
    
        public function FromXml($xml)
        {
            if(!$xml){
                throw new WxPayException("xml数据异常!");
            }
            //将XML转为array
            //禁止引用外部xml实体
            libxml_disable_entity_loader(true);
            $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            return $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 createNonceStr($length = 16) {
            $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
            $str = '';
            for ( $i = 0; $i < $length; $i++ )  {
                $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
            }
            return $str;
        }
    
        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;
        }
    
        //微信支付回调
        public function order_notice(){
            $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') ) {
                //获取服务器返回的数据
                $order_num = $data['out_trade_no'];         //订单单号
                $openid = $data['openid'];                  //付款人openID
                $total_fee = $data['total_fee'];            //付款金额
                $transaction_id = $data['transaction_id'];  //微信支付流水号
                $user = M('user');
                $user_info = $user->where(array('openid'=>$openid))->find();
                $save_data = array(
                    'total_payed_price' =>  $total_fee/100,     //实际到帐金额
                    'transaction_id'    =>  $transaction_id,
                    'pay_time'          =>  time(),
                    'status'            =>  2,
                );
    
                // 开启事务
                M()->startTrans();
                $error_count = 0;
    
                // step 1 修改充值订单数据
                $recharge_order = M('recharge_order');
                $recharge_order_info = $recharge_order->where(array('order_num'=>$order_num,'uid'=>$user_info['id']))->find();
                $recharge_amount= $recharge_order_info['amount'];
                $recharge_save_flag = $recharge_order->where(array('order_num'=>$order_num,'uid'=>$user_info['id']))->save($save_data);
                if(!$recharge_save_flag){
                    $error_count++;
                }
    
                // step 2 修改充值订单数据
                $save_balance = $user_info['balance']+$recharge_amount;
                $balance_save_flag = $user->where(array('openid'=>$openid))->save(['balance'=>$save_balance]);
                if (!$balance_save_flag) {
                    $error_count++;
                }
    
                // step 3 增加充值记录
                $balance_record = M('balance_record');
                $balance_record_data = [
                    'uid' => $user_info['id'],
                    'amount' => $recharge_amount,
                    'balance' => $save_balance,
                    'type' => 1, // 增加
                    'from' => 1, // 充值
                    'remark' => '余额充值', // 充值
                    'create_time' => time(),
                ];
    
                $add_flag = $balance_record->add($balance_record_data);
                if (!$add_flag) {
                    $error_count ++;
                }
    
                if ($error_count > 0) {
                    M()->rollback();
                    $result = -2;
                } else {
                    M()->commit();
                    $result = 0;
                }
            }else{
                $result = -1;
            }
            // 返回状态给微信服务器
            $str = '';
            if ($result === 0) { // 成功之后不会再回调
                $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            } elseif ($result === -1){ // 失败后会继续发送几次回调
                $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
            } elseif ($result === -2) { // 失败后会继续发送几次回调
                $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[操作失败]]></return_msg></xml>';
            }
            exit($str);
        }
    
    
    }
    
  • 相关阅读:
    Java实现直接插入查找
    CSS hack常用方案(摘选)
    输入一个字符串,去掉重复的字符,并按ASCII值排序-华为机试
    git操作github
    简单记录下idea上配置spring
    mysql国内镜像下载网址
    tomcat启动不成功(点击startup.bat闪退)的解决办法
    Encode and Decode TinyURL
    leetcode 4Sum II
    leetcode two sum
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/10601580.html
Copyright © 2020-2023  润新知