首页 >后端开发 >php教程 >APP 调微信支付功能

APP 调微信支付功能

WBOY
WBOY原创
2018-04-04 21:50:221785浏览

<?php
namespace Api\Controller;
use Think\Controller;
/**
 * 用别的框架改改也可以用
 * 微信APP 支付 + 回调  适用于TP3.2
 *     控制器名::WeChatPayController.class.php
 */

class WeChatPayController extends Controller {
	private $appid = &#39;###&#39;;//appID
	private $mch_id = &#39;##&#39;;//商户ID
	private $key = &#39;###&#39;;//key
	private $notify =&#39;####&#39;;//回调地址
	private $url = &#39;https://api.mch.weixin.qq.com/pay/unifiedorder&#39;;//统一下请求地址

	/**
	 * 微信统一下单接口
	 * 请求类型 :POST
	 * 所需参数 order 订单号 body 商品描述 total 金额
	 * @return json
	 *
	 * 
	 */

	public function index() {
		//订单号
		$order = I(&#39;post.order&#39;, time() . mt_rand(&#39;1000&#39;, &#39;9999&#39;));
		//内容
		$body = I(&#39;post.body&#39;, &#39;测试&#39;);
		//金额默认为0.01
		$total = ltrim(I(&#39;post.total&#39;, &#39;0.01&#39;),&#39;-&#39;) * 100;
		$array = [&#39;appid&#39; => $this -> appid,
		 &#39;mch_id&#39; => $this -> mch_id,
		  &#39;nonce_str&#39; => $this -> randomCreateStr(), 
		  &#39;body&#39; => $body, &#39;out_trade_no&#39; => $order, 
		  &#39;total_fee&#39; => $total, 
		  &#39;spbill_create_ip&#39; => $this->getIp(),
		 &#39;notify_url&#39; => $this->notify, 
		 &#39;trade_type&#39; => &#39;APP&#39;];
		
		//生成签名
		$sign = $this -> createSign($array);
		$array[&#39;sign&#39;] = $sign;
		
		//生成xml
		$xml = $this -> createXml($array);
		//发送给微信服务器
		$WeChatXml = $this -> postUrl($this -> url, $xml);
		//转为数组
		$WeChatArray = $this -> XMLDataParse($WeChatXml);
		//进行判定
		if ($WeChatArray[&#39;return_code&#39;] != &#39;SUCCESS&#39; || $WeChatArray[&#39;result_code&#39;] != &#39;SUCCESS&#39;) {
			exit(json_encode([&#39;error&#39; => 1, &#39;message&#39; => $WeChatArray], JSON_UNESCAPED_UNICODE));
		}
		//对微信返回的签名进行验证是否正确
		if (!$this -> verifySign($WeChatArray)) {
			exit(json_encode([&#39;error&#39; => 1, &#39;message&#39; => &#39;微信返回签名失败&#39;], JSON_UNESCAPED_UNICODE));
		}
		//组合要给APP 发送的数据
		
		$AppArray = [
		&#39;appid&#39; => $this -> appid,
		&#39;partnerid&#39; => $this -> mch_id,
		&#39;prepayid&#39; =>$WeChatArray[&#39;prepay_id&#39;],
		&#39;package&#39; =>&#39;Sign=WXPay&#39;,
		&#39;noncestr&#39;=>$this->randomCreateStr(),
		&#39;timestamp&#39;=>time()
		
		];
		
		//进行签名
		$sign = $this -> createSign($AppArray);
		$AppArray[&#39;sign&#39;] = $sign;
		//转换成JSON 返回给APP
		exit(json_encode($AppArray));

	}

	/**
	 *微信回调地址接口 
	 * 
	 * 
	 * 
	 */
	public function notify() {
		//接收微信xml格式信息
		 $xmlData = file_get_contents(&#39;php://input&#39;);
		 //转换为数组
		$array = json_decode($xmlData,TRUE);
		 $array = $this-> XMLDataParse($xmlData);
		 //对微信返回的签名进行验证是否正确
		if (!$this -> verifySign($array)) {
			exit(&#39;<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名不正确]]></return_msg></xml>&#39;);
		}
		
		/**
		 * !!!注意: 下面的就是连接数据库了,做进一步处理
		 * 
		 * 
		 * 
		 */
		
		//下面是处理完逻辑,返回给微信服务器的
		//exit(&#39;<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>&#39;);
		
	}




	 private function postUrl($url, $paramsArray) {
		$curl = curl_init();
		// 启动一个CURL会话
		curl_setopt($curl, CURLOPT_URL, $url);
		// 要访问的地址
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
		// 跳过证书检查
		//curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
		//curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
		//curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER[&#39;HTTP_USER_AGENT&#39;]); // 模拟用户使用的浏览器
		//curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
		curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
		// 自动设置Referer
		curl_setopt($curl, CURLOPT_POST, 1);
		// 发送一个常规的Post请求
		curl_setopt($curl, CURLOPT_POSTFIELDS, $paramsArray);
		// Post提交的数据包
		curl_setopt($curl, CURLOPT_TIMEOUT, 30);
		// 设置超时限制防止死循环
		curl_setopt($curl, CURLOPT_HEADER, 0);
		// 显示返回的Header区域内容
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		// 获取的信息以文件流的形式返回
		$tmpInfo = curl_exec($curl);
		// 执行操作
		if (curl_errno($curl)) {
			echo &#39;Errno&#39; . curl_error($curl);
			//捕抓异常
		}
		curl_close($curl);
		// 关闭CURL会话
		return $tmpInfo;
		// 返回数据,json格式

	}

	/**
	 * 获取IP 地址
	 *
	 *
	 */

	private function getIp() {
		if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
			$ip = getenv("HTTP_CLIENT_IP");
		else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
			$ip = getenv("HTTP_X_FORWARDED_FOR");
		else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
			$ip = getenv("REMOTE_ADDR");
		else if (isset($_SERVER[&#39;REMOTE_ADDR&#39;]) && $_SERVER[&#39;REMOTE_ADDR&#39;] && strcasecmp($_SERVER[&#39;REMOTE_ADDR&#39;], "unknown"))
			$ip = $_SERVER[&#39;REMOTE_ADDR&#39;];
		else
			$ip = "unknown";
		return ($ip);
	}

	/**
	 * 验证签名
	 *
	 *
	 */
	private  function verifySign($array) {
		$sign = $array[&#39;sign&#39;];
		unset($array[&#39;sign&#39;]);
		$s = $this -> createSign($array);
		return $s == $sign ? TRUE : FALSE;
	}

	/**
	 * 生成签名
	 * @param $array array 参数 以关联数组 的形势
	 *
	 * @return str 签名
	 */
	private function createSign($array) {
		ksort($array);
		$stringA = &#39;&#39;;
		foreach ($array as $ke => $value) {
			$stringA .= $ke . &#39;=&#39; . $value . &#39;&&#39;;
		}

		//$stringA = http_build_query($array);
		$stringSignTemp = $stringA . "key=" . $this -> key;
		$sign = strtoupper(md5($stringSignTemp));
		return $sign;
	}

	/**
	 * 生成XML 格式文件
	 * @param $array array 参数 以关联数组 的形势
	 *
	 * @return str xml字符串
	 */
	private function createXml($array) {
		$xml = &#39;<xml>&#39;;
		foreach ($array as $key => $value) {
			$xml .= &#39;<&#39; . $key . &#39;>&#39; . $value . &#39;</&#39; . $key . &#39;>&#39;;
		}
		$xml .= &#39;</xml>&#39;;
		return $xml;
	}

	/**
	 * 随机生成32位字符串
	 * @return str 32位字符串
	 */
	private function randomCreateStr() {
		return strtoupper(md5(microtime(TRUE) . mt_rand(0, 9999)));
	}

	/**
	 * xml格式数据解析函数
	 * @param $xml str  微信返回的xml格式字符串
	 *
	 * @return array 数组
	 */

	private function XMLDataParse($xml) {

		$array_data = json_decode(json_encode(simplexml_load_string($xml, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA)), true);
		return $array_data;
	}

}


以上是APP 调微信支付功能的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn