APP微信支付接口

来源:互联网 发布:网络大电影拍摄合同 编辑:程序博客网 时间:2024/04/30 09:03

刚到这家新公司的时候、上来就给我一个APP接口的项目、因为之前并没有写过接口、之前都是做web的、至于如何去写APP接口、详细的文档还没整理、今天先给大家分享一个APP微信支付接口实例、写这个接口的时候、当时废了特别的大工夫、但是后来终于给写出了、只要把里面的配置改下、就可以直接用了、但是我这个有个问题、就是APP调起微信支付的时候特别慢、不知道是我这个代码问题、还是怎么回事、如果有哪位大神精通这块、可以指点一下、

有时间我会再把微信提现的代码也分享一下、希望对这块有需求的朋友有所帮助、写的不好、各位大神不要喷

我用的是tp框架、下面是控制器的代码、

<?phpnamespace Home\Controller;use Think\Controller;header('Content-type:text/html;charset=utf-8');class ShoppingController extends Controller {     public $enableCsrfValidation = false;    /*     配置参数   */    protected $config = array(        'appid' => "",                  /*微信开放平台上的应用id*/        'mch_id' => "",                 /*微信申请成功之后邮件中的商户id*/        'api_key' => "",                /*在微信商户平台上自己设定的api密钥 32*/        'notify_url' => 'http://服务器网址/wxpay.php'             /*自定义的回调程序地址id*/    );    public function actionPays(){        header("Content-type: text/html; charset=utf-8");        //$bm_number = 'Cs123456';                //订单ID        //$uid='123456';                          //uid        //$price='1';                                //价格        //$reannumb = $this->randomkeys(4).time().$uid.$this->randomkeys(4);   //获取随机的订单号        $order_id = I('order_id');   //这里是我接收的APP的订单ID        if($order_id == 0){            json_encode('非法数据',0);        }//        }        $order = D('order');        $order_info = $order->where('order_id="'.$order_id.'"')->find(); //通过订单ID吧订单信息查出来        //建立请求        //show_bug($order_info);        $out_trade_no = $order_info['order_sn'];        $price =$order_info['order_price'];   //付款金额        //$body = $order_info['order_name'];  //商品详情        //$order_sn = I('order_sn');        $response = $this->getPrePayOrder('商品订单支付',$out_trade_no,$price);        $x = $this->getOrder($response['prepay_id']);   //返回给客户的二次签名        exit(json_encode(array('response'=>$response,'x'=>$x,'status'=>1)));     //x返回的是APP需要的数据    }    //获取预支付订单    public function getPrePayOrder($body, $out_trade_no, $total_fee){        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";        $notify_url = $this->config["notify_url"];        $onoce_str = $this->getRandChar(32);        $data["appid"] = $this->config["appid"];        $data["body"] = $body;        $data["mch_id"] = $this->config['mch_id'];        $data["nonce_str"] = $onoce_str;        $data["notify_url"] = $notify_url;        $data["out_trade_no"] = $out_trade_no;        $data["spbill_create_ip"] = $this->get_client_ip();        $data["total_fee"] = $total_fee*100;        $data["trade_type"] = "APP";        $s = $this->getSign($data, false);        $data["sign"] = $s;        $xml = $this->arrayToXml($data);        $response = $this->postXmlCurl($xml, $url);        //将微信返回的结果xml转成数组        return $this->xmlstr_to_array($response);    }    //执行第二次签名,才能返回给客户端使用    public function getOrder($prepayId){        $data["appid"] = $this->config["appid"];        $data["noncestr"] = $this->getRandChar(32);;        $data["package"] = "Sign=WXPay";        $data["partnerid"] = $this->config['mch_id'];        $data["prepayid"] = $prepayId;        $data["timestamp"] = time();        $s = $this->getSign($data, false);        $data["sign"] = $s;        return $data;    }    /*        生成签名    */    function getSign($Obj)    {        foreach ($Obj as $k => $v)        {            $Parameters[strtolower($k)] = $v;        }        //签名步骤一:按字典序排序参数        ksort($Parameters);        $String = $this->formatBizQueryParaMap($Parameters, false);        //echo "string =".$String."</br>";        //签名步骤二:在string后加入KEY        $String = $String."&key=".$this->config['api_key'];        //echo "<textarea style='width: 50%; height: 150px;'>$String</textarea> <br />";        //签名步骤三:MD5加密        $result_ = strtoupper(md5($String));        return $result_;    }    /**     *    作用:产生随机字符串,不长于32     */    public function randomkeys($length)    {        $pattern = '1234567890123456789012345678905678901234';        $key = null;        for ($i = 0; $i < $length; $i++) {            $key .= $pattern{mt_rand(0, 30)};    //生成php随机数        }        return $key;    }    //获取指定长度的随机字符串    function getRandChar($length){        $str = null;        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";        $max = strlen($strPol)-1;        for($i=0;$i<$length;$i++){            $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于minmax两个数之间的一个随机整数        }        return $str;    }    //数组转xml    function arrayToXml($arr)    {        $xml = "<xml>";        foreach ($arr as $key=>$val)        {            if (is_numeric($val))            {                $xml.="<".$key.">".$val."</".$key.">";            }            else                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";        }        $xml.="</xml>";        return $xml;    }    //post https请求,CURLOPT_POSTFIELDS xml格式    function postXmlCurl($xml,$url,$second=30)    {        //初始化curl        $ch = curl_init();        //超时时间        curl_setopt($ch,CURLOPT_TIMEOUT,$second);        //这里设置代理,如果有的话        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);        curl_setopt($ch,CURLOPT_URL, $url);        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);        //设置header        curl_setopt($ch, CURLOPT_HEADER, FALSE);        //要求结果为字符串且输出到屏幕上        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);        //post提交方式        curl_setopt($ch, CURLOPT_POST, TRUE);        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);        //运行curl        $data = curl_exec($ch);        //返回结果        if($data)        {            curl_close($ch);            return $data;        }        else        {            $error = curl_errno($ch);            //echo "curl出错,错误码:$error"."<br>";            return json_encode(array('code'=>$error,'status'=>0));            //return false;        }    }    /*        获取当前服务器的IP    */    function get_client_ip()    {        if ($_SERVER['REMOTE_ADDR']) {            $cip = $_SERVER['REMOTE_ADDR'];        } elseif (getenv("REMOTE_ADDR")) {            $cip = getenv("REMOTE_ADDR");        } elseif (getenv("HTTP_CLIENT_IP")) {            $cip = getenv("HTTP_CLIENT_IP");        } else {            $cip = "unknown";        }        return $cip;    }    //将数组转成uri字符串    function formatBizQueryParaMap($paraMap, $urlencode)    {        $buff = "";        ksort($paraMap);        foreach ($paraMap as $k => $v)        {            if($urlencode)            {                $v = urlencode($v);            }            $buff .= strtolower($k) . "=" . $v . "&";        }        $reqPar=null;        if (strlen($buff) > 0)        {            $reqPar = substr($buff, 0, strlen($buff)-1);        }        return $reqPar;    }    /**    xml转成数组     */    function xmlstr_to_array($xmlstr) {        //XML转为array        return json_decode(json_encode(simplexml_load_string($xmlstr, 'SimpleXMLElement',LIBXML_NOCDATA)), true);    }    function domnode_to_array($node) {        $output = array();        switch ($node->nodeType) {            case XML_CDATA_SECTION_NODE:            case XML_TEXT_NODE:                $output = trim($node->textContent);                break;            case XML_ELEMENT_NODE:                for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) {                    $child = $node->childNodes->item($i);                    $v = $this->domnode_to_array($child);                    if(isset($child->tagName)) {                        $t = $child->tagName;                        if(!isset($output[$t])) {                            $output[$t] = array();                        }                        $output[$t][] = $v;                    }                    elseif($v) {                        $output = (string) $v;                    }                }                if(is_array($output)) {                    if($node->attributes->length) {                        $a = array();                        foreach($node->attributes as $attrName => $attrNode) {                            $a[$attrName] = (string) $attrNode->value;                        }                        $output['@attributes'] = $a;                    }                    foreach ($output as $t => $v) {                        if(is_array($v) && count($v)==1 && $t!='@attributes') {                            $output[$t] = $v[0];                        }                    }                }                break;        }        return $output;    }}下面是回调的页面、我做了一个中间页面、通过这个页面跳转到、回调的处理业务逻辑的页面【wxpay.php】这个页面主要我用日志功能、生产日志之后可以查看、拼接的数据是不是正确、
<?php$xml = file_get_contents("php://input");logResult($xml);function logResult($word='') {    date_default_timezone_set("PRC");    $fp = fopen("log.txt","a");    flock($fp, LOCK_EX) ;    fwrite($fp,"执行日期:".strftime("%Y%m%d%H%M%S",time())."\n".$word."\n");    flock($fp, LOCK_UN);    fclose($fp);}$url = 'http://网址/index.php/Home/Callback/wxpay';$ch = curl_init();curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //get the response as a string from curl_exec(), rather than echoing it curl_setopt($ch, CURLOPT_URL, $url );curl_setopt($ch, CURLOPT_POST, 1 );curl_setopt($ch, CURLOPT_POSTFIELDS,$xml);//取到的$info 即为拿到的script 信息 $info =     curl_exec($ch) ;curl_close($ch);    //close the handleecho $info; //输出下面是回调页面的处理业务逻辑的代码这里面还带有极光推送
<?phpnamespace Home\Controller;use Think\Controller;class CallbackController extends Controller{   // 微信支付回调  注意回调中接收收订单号要处理自己的业务逻辑     public function wxpay(){        $xml = file_get_contents("php://input");        $log = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);        //show_bug($log);        $id = $log['out_trade_no'];        //show_bug($id);        $order = D('order')->where(array('order_sn' => $id))->find();        //show_bug($order);        if ($order['order_state'] == 0) {            $data['pay_time'] = date('y-m-d H:i:s');            $data['order_state'] = 1;            $rst = D('order')->where(array('order_id' => $order['order_id']))->save($data);            if ($rst) {                //给发布服务方推送                //1.获取发布服务方ID,购买服务方ID                $order = M('order');                $data = $order->where('order_id="'.$order['order_id'].'"')->find();                $from_user_id = $data['from_userid'];                $buy_user_id  = $data['buy_userid'];                //2.根据ID查询发布服务方JPush_id,购买服务方信息                $seller = M('member');                $seller_info = $seller->where("user_id = {$from_user_id}")->find();                $buyer_info = $seller->where("user_id = {$buy_user_id}")->find();                $JPush_id = $seller_info['jpush_id'];                $buyer_phone = $buyer_info['user_tel'];                //3.回应信息拼接                $msg = '您的服务已被【'.$buyer_info['username'].'】用户预约,资金已托管到平台';                $arr = array(                    'buy_info' => '被购买',                    'order_id' => $order['order_id'],                );                $JPush = new JpushController();                $JPush->push($JPush_id ,$msg,$arr);                $data['dem_state'] = 1;                $dem = D('demand')->where("dem_id ={$order['demand_id']}")->save($data);                $data2['out_price'] = $data['order_price'];                $data2['pay_type'] = '微信支付';                $data2['user_id'] = $data['buy_userid'];                $data2['income_time'] = date('Y-m-d H:i:s');                $res = D('income')->add($data2);                $output = array('code' => 1, 'date' => $rst, 'info' => '支付成功');                exit('success');            }        }    }}



 

2 0
原创粉丝点击