zoukankan      html  css  js  c++  java
  • 微信公众号整套逻辑的支付和退款

    都已经做两遍公众号了,还是有时候总卡壳,今天把所有的问题都遇到的差不多了,咱就好好的总结总结

    先说支付问题

    申请下来公众号后,先将后台该填的都填写好

    需要用到的公众号信息

     

    下面就开始要进入代码状态了

    先说支付:

     

     需要放在function.php 里的方法

    吊起微信支付最重要的方法(一)

    /**
     * 直接生成微信jssdk_config
     * @echo string $jssdk Jssdk_config
     * @author 5heAtMin9 <sheatming@foxmail.com>
     */
    
    function wx_jssdk_config($debug='true'){
        $getSignPackage = wx_getSignPackage();
        $jssdk = '<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>';
        $jssdk .= '<script>
        wx.config({
            debug: '.$debug.', 
            appId: "'.$getSignPackage['appId'].'",
            timestamp: "'.$getSignPackage['timestamp'].'",
            nonceStr: "'.$getSignPackage['nonceStr'].'",
            signature: "'.$getSignPackage['signature'].'",
            jsApiList: ["checkJsApi","onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ", "onMenuShareWeibo","onMenuShareQZone","hideMenuItems","showMenuItems","hideAllNonBaseMenuItem","showAllNonBaseMenuItem","translateVoice","startRecord","stopRecord","onVoiceRecordEnd","playVoice","onVoicePlayEnd","pauseVoice","stopVoice","uploadVoice","downloadVoice","chooseImage","previewImage","uploadImage","downloadImage","getNetworkType","openLocation","getLocation","hideOptionMenu","showOptionMenu","closeWindow","scanQRCode","chooseWXPay","openProductSpecificView","addCard","chooseCard","openCard"],
        });
    </script>';
        echo $jssdk;
    }

    吊起微信支付最重要的方法(二)

    /**
     * 微信支付
     * @param string $openid 支付者openid
     * @param string $url 回调地址
     * @param string $od_title 订单标题
     * @param string $od_money 价格
     * @param string $od_id 订单编号
     * @return string 状态
     * @author 5heAtMin9 <sheatming@foxmail.com>
     */
    function wx_h5_pay($openid, $url, $od_title,  $od_money, $od_id)
    {
        
        if(is_null($url) || $url == ''){
            $url = 'http://'. $_SERVER['HTTP_HOST'].'/weixinpay/notify_url.php';
        }
        $pay = array(
            'appid' => C('WX_APPID'),
            'mch_id' => C('WX_MCHID'),
            'nonce_str' => getRandom(32),
            'body' => $od_title,
            'out_trade_no' => $od_id,
            'total_fee' => $od_money * 100,
            'spbill_create_ip' => get_client_ip(),
            'notify_url' => $url,//通知地址
            'trade_type' => 'JSAPI',
            'openid' => $openid,
        );
    
    
        ksort($pay);
        $string =  ToUrlParams($pay).'&key='.C('WX_PAYAPIKEY');
        $string = md5($string);
        $string = strtoupper($string);
        $pay['sign'] = $string;
        $postObj = simplexml_load_string(os_post('https://api.mch.weixin.qq.com/pay/unifiedorder', arrayToXml($pay)), 'SimpleXMLElement', LIBXML_NOCDATA);
    
        $time = time();
        $timeStamp = "$time";
        $nonceStr = getRandom(32);
        $data['package'] = 'prepay_id='.$postObj -> prepay_id;
        $data['timestamp'] = $timeStamp;
        $data['nonceStr'] = $nonceStr;
        $val = 'appId='.C('WX_APPID').'&';
        $val .='nonceStr='.$nonceStr.'&';
        $val .='package='.$data['package'].'&';
        $val .='signType=MD5&';
        $val .='timeStamp='.$timeStamp;
    
    
        $stringA = $val.'&key='.C('WX_PAYAPIKEY');
        $data['sign'] = strtoupper(MD5($stringA));
        $data['val'] = $val;
        return $data;
    }

    微信回调的方法:

    <?php
    /**
     * Created by PhpStorm.
     * User: Kuoer
     * Date: 2016/4/9
     * Time: 14:41
     */
    
    function payok($orderid, $alipayid, $openid, $total_fee, $type)
    {    
                $postUrl =  'http://'.$_SERVER['HTTP_HOST'].'/index.php?s=/Home/Pay/weixinpay';
                $curlPost = 'orderid=' . $orderid . '&alipayid=' . $alipayid . '&openid=' . $openid;
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $postUrl);                 //抓取指定网页
                curl_setopt($ch, CURLOPT_HEADER, 0);                    //设置header
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);            //要求结果为字符串且输出到屏幕上
                curl_setopt($ch, CURLOPT_POST, 1);                      //post提交方式
                curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);        // 终止从服务端进行验证
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
                curl_exec($ch);                                 //运行curl
                curl_close($ch);
    }
    
    
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Headers: X-Requested-With');
        $xml = file_get_contents("php://input");
        $xml = simplexml_load_string($xml);
        //return (string)$xml->prepay_id;
        $success = (string)$xml->return_code;
        if ($success == 'SUCCESS') {
            $out_trade_no = (string)$xml->out_trade_no;
            $trade_no = (string)$xml->transaction_id;
            $openid = (string)$xml->openid;
            $pay = (string)$xml->total_fee;
            echo payok($out_trade_no, $trade_no, $openid, $pay, 'weixin');
        } else {
            $return_code = (string)$xml->return_code;
            $return_msg = (string)$xml->return_msg;
            echo '<xml>
                      <return_code><![CDATA[' . $return_code . ']]></return_code>
                      <return_msg><![CDATA[' . $return_msg . ']]></return_msg>
                    </xml>';
        }

     

    微信回调方法处理方法  需放在function.php里

    这两个方法是处理微信给返回的一个支付成功的数据,这些数据都生成了一个txt文件

    function quzhi( $s, $xml ) {
        $str = explode( '<' . $s . '>', $xml );
        $str = explode( '</' . $s . '>', $str[ 1 ] );
        return guolv( trim( $str[ 0 ] ) );
    }
    
    function guolv( $str ) {
        $s = array( '!', '-', '[', 'CDATA', ']', '<', '>' );
        return str_replace( $s, '', $str );
    }

    微信回调,我自己设置指定的那个单独创建的控制器里的方法:

    <?php
    namespace HomeController;
    use ThinkController;
    use UserApiUserApi;
    
    class PayController extends HomeController {
         protected function _initialize(){
            
           /* 读取站点配置 */
            $config = api('Config/lists');
            C($config); //添加配置
         }
        public function weixinpay(){
            $orderid = I('orderid');
            $suijishu = rand(100000000,99999999999);
            $val = 'appid='.C('WX_APPID').'&';
            $val .='mch_id='.C('WX_MCHID').'&';
            $val .='nonce_str='.$suijishu.'&';
            $val .='out_trade_no='.$orderid;
            $stringA = $val.'&key='.C('WX_PAYAPIKEY');
            $url = 'https://api.mch.weixin.qq.com/pay/orderquery';
            $post_data = '<xml>
                               <appid>'.C('WX_APPID').'</appid>
                               <mch_id>'.C('WX_MCHID').'</mch_id>
                               <nonce_str>'.$suijishu.'</nonce_str>
                               <out_trade_no>'.$orderid.'</out_trade_no>
                               <sign>'.strtoupper(MD5($stringA)).'</sign>
                          </xml>';
    
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_HEADER, false);
            curl_setopt($ch, CURLOPT_URL,$url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不验证证书
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //不验证证书
            $res = curl_exec($ch);
            curl_close($ch);
        //上面都是固定死的,下面才开始写你要修改的数据
    if(quzhi('trade_state',$res) == 'SUCCESS'){ $orderid = I('orderid'); $data['gwc_danhao'] = I('orderid'); $data['money'] = quzhi('total_fee',$res); $data['liushui_hao'] = quzhi('transaction_id',$res); $on = M('yy_pay')->where($data)->find();//没有找到这条数据就去执行下面的添加 if(!$on){ $gwc_id['danhao'] = I('orderid'); $gwc_uid = M('yy_goumai')->where($gwc_id)->getField('uid'); $data['uid'] = $gwc_uid; $data['time'] = time(); M('yy_pay')->add($data); $price = M('yy_goumai')->where($gwc_id)->sum('zongjia'); if($price*100 != $data['money']){ $this->error('支付异常'); }else{ $gouwuche = M('yy_goumai')->where($gwc_id)->select(); foreach($gouwuche as $k=>$v){ $gwc_zt['utime']=time(); $gwc_zt['state']=1; M('yy_goumai')->where(array('id'=>$v['id']))->setField($gwc_zt); } } } } } }

    像支付就这些啦,如果有没说的地方可以联系我QQ:507285474

    检测用户是否登录

    /**
     * 检测用户是否登录
     * @return integer 0-未登录,大于0-当前登录用户ID
     * @author 麦当苗儿 <zuojiazi@vip.qq.com>
     */
    function is_login(){
        $user = session('user_auth');
        if (empty($user)) {
            return 0;
        } else {
            return session('user_auth');
        }
    }

     

     检测用户是否注册

     

    /**
     * 检测用户是否微信登录
     * @return integer 0-未登录,大于0-当前登录用户ID
     * @author 5heAtMin9 <sheatming@foxmail.com>
     */
    
    function is_wx_login(){
        $backurl = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING'];
        $puid = I('sharecode',0);
        if(!is_login()){
            
            if(I('get.code')){
                
                $code = I('get.code');
                $appid = C('WX_APPID');
                $secret = C('WX_APPSECRET');
                $api = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $secret . '&code=' . $code . '&grant_type=authorization_code';
                $json = os_get($api);
                $array = json_decode($json, true);
                //
                $openid = $array['openid'];
                $token = $array['access_token'];
                //
                $where['openid'] = $openid;
                $user = M('ucenter_member')->where($where)->find();
                if(!$user){
                    //没注册
                    $api = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $token . '&openid=' . $openid . '&lang=zh_CN';
                    $json = os_get($api);
                    $array = json_decode($json, true);
                    $tmp = rand(11111111111,99999999999);
                    $access_info = array(
                        'type' => '2', //1.普通账号  2.微信账号  3.手机号  4.邮箱
                        'username' => $tmp, //微信注册 随机分配账号
                        'openid' => $openid,
                        'email' => $tmp.'@rand.com',
                        'status' => 1,
                        'reg_time' => time(),
                    );
                    $uid = M('ucenter_member') -> add($access_info);
                    $user_info = array(
                        'uid' => $uid,
                        'openid' => $array['openid'],
                        'nickname' => $array['nickname'],
                        'sex' => $array['sex'],
                        'country' => $array['country'],
                        'city' => $array['city'],
                        'province' => $array['province'],
                        'headimgurl' => $array['headimgurl'],
                        'puid' => $puid,
                        'status' => 1
                    );
                    $re = M('member') -> add($user_info);
                    session('user_auth',$uid);
                    $url = str_replace('Home/', '', U('wechat.php?User/login', array('openid' => $openid,'backurl'=>urlencode($backurl),'y' => md5(time().'5heAtMin9'))));
                    redirect($url);
    //
                } else {
                    session('user_auth',$user['id']);
                    //注册了 跳转到登陆界面
                    $url = str_replace('Home/', '', U('wechat.php?User/login', array('openid' => $openid,'backurl'=>urlencode($backurl),'y' => md5(time().'5heAtMin9'))));
                    redirect($url);
                    return $url;
    
                }
                //return $array;
            } else {
                $appid = C('WX_APPID');
                redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.urlencode($backurl).'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect');
            }
        } else {
            
            return is_login();
        }
    }

    我们接着说退款:

    点击退款传过来值,处理一下

    最主要的是这个 function.php里的wx_tuikaun()方法  

     public function tuikuan(){
            $wher['id'] =I('id');
            $data['gwc_danhao'] = M('yy_goumai')->where($wher)->getField('danhao');
               $re = M('yy_pay')->where($data)->find();
            if($re){
                $gwc_arr['danbao'] = $re['gwc_danhao'];
                $gm = M('yy_goumai')->where($gwc_arr)->find();//退款需要用的商品总价
    //            $gwc_tui_id = M('yy_goumai')->where(array('id'=>I('id')))->find();//退款需要用的商品单价(不是加上邮费的后的总金额)
    //            dump($gwc_tui_id);die();
                $suijishu = time().rand(111111111,999999999).$gm['danhao'];//退款需要用的随机数
                //1.退款商品的单价(不是加上邮费的后的总金额),2.支付成功后生成的流水单号,3.微信支付平台上要显示的流水号,(用时间戳 + 随机数 + 用户id);4.总价格。
                
                $tuikuan = wx_tuikuan($gm['danjia'],$re['liushui_hao'],$suijishu,$gm['zongjia']);
                if($tuikuan -> result_code == 'SUCCESS'){
                    M('yy_pay')->where($data)->setField('tuikuan','1');
                    $gwc_zt['state'] = '-2';
                    $gwc_zt['utime'] = time();
                    $yes = M('yy_goumai')->where($wher)->setField($gwc_zt);
                    if($yes){
                        $this->success('退款成功');
                    }else{
                        $this->error('退款失败');
                    }
                }
                
            }else{
                $this->error('出错啦!订单号参数值不对!');
            }
        }

    function.php  里的  wx_tuikaun()方法

    /**
     * 微信退款
     * @param $od_money 退款金额
     * @param $od_id 订单编号
     * @return SimpleXMLElement
     */
    function wx_tuikuan( $od_money, $od_id, $back_id, $zhifu ) {
    
        $pay = array(
            'appid' => C( 'WX_APPID' ),
            'mch_id' => C( 'WX_MCHID' ),
            'nonce_str' => getRandom( 32 ),
            'op_user_id' => C( 'WX_MCHID' ),
            'out_refund_no' => $back_id,
            'transaction_id' => $od_id,
            'refund_fee' => $od_money * 100,
            'total_fee' => $zhifu * 100,
    
        );
    
        ksort( $pay );
        $string = ToUrlParams( $pay ) . '&key=' . C( 'WX_PAYAPIKEY' );
        $string = md5( $string );
        $string = strtoupper( $string );
        $pay[ 'sign' ] = $string;
        $tmp = zhifu( 'https://api.mch.weixin.qq.com/secapi/pay/refund', arrayToXml( $pay ) );
    //    dump($tmp);die();
        $postObj = simplexml_load_string( $tmp, 'SimpleXMLElement', LIBXML_NOCDATA );
        
        return $postObj;
        
    }
    /**
     * 微信退款
     * @param $od_money 退款金额
     * @param $od_id 订单编号
     * @return SimpleXMLElement
     */
    function wx_refund($od_money, $od_id, $back_id)
    {
    
        $pay = array(
            'appid' => C('WX_APPID'),
            'mch_id' => C('WX_MCHID'),
            'nonce_str' => getRandom(32),
            'op_user_id' => C('WX_MCHID'),
            'out_refund_no' => $back_id,
            'out_trade_no' => $od_id,
            'refund_fee' => $od_money * 100,
            'total_fee' => $od_money * 100,
    
        );
    
        ksort($pay);
        $string =  ToUrlParams($pay).'&key='.C('WX_PAYAPIKEY');
        $string = md5($string);
        $string = strtoupper($string);
        $pay['sign'] = $string;
        $tmp = zhifu('https://api.mch.weixin.qq.com/secapi/pay/refund', arrayToXml($pay));
        $postObj = simplexml_load_string($tmp, 'SimpleXMLElement', LIBXML_NOCDATA);
        return $postObj;
    }

    然后好像没有了!!!!

    再见!!!

  • 相关阅读:
    sublime text 3 常用快捷键
    PHP注释-----PHPDOC
    正则表达式
    JavaScript中常用的函数
    网站特效离不开脚本,javascript是最常用的脚本语言,我们归纳一下常用的基础函数和语法:
    ubuntu16.04LTS下安装zookeeper
    HiveQL详解
    ubuntu16.04LTS下安装hive-2.1.0
    Hadoop环境 IDE配置(在eclipse中安装hadoop-eclipse-plugin-2.7.3.jar插件)
    Hadoop 数据节点DataNode异常
  • 原文地址:https://www.cnblogs.com/zc290987034/p/7544747.html
Copyright © 2011-2022 走看看