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)生成介于min和max两个数之间的一个随机整数 } 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
- APP微信支付接口
- 微信APP支付接口
- APP接入微信支付接口
- 微信APP支付接口文档
- PHP开发APP微信支付接口
- App微信支付 php后台接口
- PHP开发APP微信支付接口
- 微信app开发支付接口相关
- 微信APP支付接口业务流程
- php 开发微信app支付接口
- Laravel5.2微信APP支付接口
- 微信支付app支付3.0接口开发
- 支付--微信APP支付
- 微信支付app
- 微信支付app
- 微信APP支付
- app微信支付
- APP微信支付
- 比较C++中数组,vector,array
- 设置Win10防火墙规则,使得局域网能访问此电脑的Tomcat服务
- cocopods的使用
- [jzoj]3734. 【Usaco2014Open银组】双导航(gpsdual) (最短路径细节题)
- Servlet上传文件
- APP微信支付接口
- #define const and static
- 基于Problem Solving with Algorithms and Data Structures using Python的学习记录(6-1)——Tree
- dubbo的作用及理解
- 建立一个对象数组,内放5个学生的数据(学号,成绩),用指向对象的指针做函数参数,在max函数中找出5个学生中成绩最高者,并输出其学号。
- 你真的了解位运算?用了这个运算符,算法的时间复杂度竟然降了一个数量级!
- [jzoj]3729. 【NOIP2014模拟7.10】表达式的值(exp) (分块转化模型)
- 重载c++的<<操作符
- c++作业4