微信app支付,后台处理(后台数据处理)

本文章将写的是微信的app支付,安卓端app是用apicloud封装的,ios端是用原生的,在这里将项目里面的微信支付后台数据处理部分拿出来(顺便复习一下),记录一下。

首先我们来看一下微信app官方给出的时序图:

APPæ¯ä»æ¶åºå¾下面直接上代码

public function wxorderOp(){
        $dataArr = array(
            'appid' => 'xxxx',
            'mch_id' => 'xxxx',
            'nonce_str' => $this->getNonceStr(),
            'body' => $pay['pay_sn'],
            'attach' => 'xxx',
            'out_trade_no' => $pay['pay_sn'],
            'total_fee' => 1,
            'spbill_create_ip' => '111.85.159.16',
            'notify_url' => 'xxxxxxxxxxx',//回调地址一定是要能访问到的
            'trade_type' => 'APP'
        );
    $sign = $this->MakeSign($dataArr);//签名生成
    $dataArr['sign'] = $sign;

    $xmlStr = $this->createXML('xml', $dataArr);//统一下单xml数据生成
    $reArr = explode('?>', $xmlStr);
    $reArr = end($reArr);
    $xml = $this->curl('https://api.mch.weixin.qq.com/pay/unifiedorder', $reArr);//发送请求 统一下单数据

    //解析返回的xml字符串
    $re = $this->xmlToObject($xml);

    //判断统一下单是否成功
    if ($re['result_code'] == 'SUCCESS') {

        //支付请求数据
        $payData = array(
            'appid' => $re['appid'],
            'partnerid' => $re['mch_id'],
            'prepayid' => $re['prepay_id'],
            'noncestr' => $this->getNonceStr(),
            'package' => 'Sign=WXPay',
            'timestamp' => time()
        );


        //生成支付请求的签名
        $paySign = $this->MakeSign($payData);

        $payData['sign'] = $paySign;

        //拼接成APICLOUD所需要支付数据请求
        $payDatas = array(
            'apiKey' => $re['appid'],
            'orderId' => $re['prepay_id'],
            'mchId' => $re['mch_id'],
            'nonceStr' => $payData['noncestr'],
            'package' => 'Sign=WXPay',
            'timeStamp' => $payData['timestamp'],
            'sign' => $paySign
        );

        //返回支付请求数据
        exit(json_encode($payDatas));
    } else {
        $re['payData'] = "error";
        exit(json_encode($re)) ;
       }
    }

 

//转XML格式
    public function createXML($rootNode, $arr)
    {
        //创建一个文档,文档时xml的,版本号为1.0,编码格式utf-8
        $xmlObj = new DOMDocument('1.0', 'UTF-8');
        //创建根节点
        $Node = $xmlObj->createElement($rootNode);
        //把创建好的节点加到文档中
        $root = $xmlObj->appendChild($Node);
        //开始把数组中的数据加入文档
        foreach ($arr as $key => $value) {
            //如果是$value是一个数组
            if (is_array($value)) {
                //先创建一个节点
                $childNode = $xmlObj->createElement($key);
                //将节点添加到$root中
                $root->appendChild($childNode);
                //循环添加数据
                foreach ($value as $key2 => $val2) {
                    //创建节点的同时添加数据
                    $childNode2 = $xmlObj->createElement($key2, $val2);
                    //将节点添加到$childNode
                    $childNode->appendChild($childNode2);
                }
            } else {
                //创建一个节点,根据键和值
                $childNode = $xmlObj->createElement($key, $value);
                //把节点加到根节点
                $root->appendChild($childNode);
            }
        }
        //把创建好的xml保存到本地
        $xmlObj->save('xml/log.xml');
        $str = $xmlObj->saveXML();
//        echo $str;
        //返回xml字符串
        return $str;
    }


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

    /**
     * 格式化参数格式化成url参数
     */
    public function ToUrlParams($arr)
    {
        $buff = "";
        foreach ($arr as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }


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


    public function curl($url, $post_data)
    {


        $headerArray = array(
            'Accept:application/json, text/javascript, */*',
            'Content-Type:application/x-www-form-urlencoded',
            'Referer:https://mp.weixin.qq.com/'
        );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        // 对认证证书来源的检查,0表示阻止对证书的合法性的检查。
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//关闭直接输出
        curl_setopt($ch, CURLOPT_POST, 1);//使用post提交数据
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);//设置 post提交的数据
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69 Safari/537.36');//设置用户代理
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);//设置头信息


        $loginData = curl_exec($ch);//这里会返回token,需要处理一下。


        return $loginData;

        $token = array_pop($token);
        curl_close($ch);


    }

    /**
     * 解析xml文档,转化为对象
     * @param  String $xmlStr xml文档
     * @return Object         返回Obj对象
     */
    public function xmlToObject($xmlStr)
    {
        if (!is_string($xmlStr) || empty($xmlStr)) {
            return false;
        }
        // 由于解析xml的时候,即使被解析的变量为空,依然不会报错,会返回一个空的对象,所以,我们这里做了处理,当被解析的变量不是字符串,或者该变量为空,直接返回false
        libxml_disable_entity_loader(true);
        $postObj = json_decode(json_encode(simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        //将xml数据转换成对象返回
        return $postObj;
    }

//回调数据处理

public function wxnotifyOp(){
    $xmldata = "
            <xml>
              <return_code><![CDATA[SUCCESS]]></return_code>
              <return_msg><![CDATA[OK]]></return_msg>
            </xml>";
    echo $xmldata;//告诉微信已接收到回调信息,如果微信收到商户的应答不符合规范或超时,微信会判定本次通知失败,重新发送通知,直到成功为止(在通知一直不成功的情况下,微信总共会发起10次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m)
    $data = array();
    $model_order = Model('order');
    $info = file_get_contents('php://input');
    $msg = (array)simplexml_load_string($info, 'SimpleXMLElement', LIBXML_NOCDATA);
    if($msg['return_code']=='SUCCESS'){
       //订单数据处理
            }else{
                
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值