欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

APP 调微信支付功能

程序员文章站 2022-04-14 19:09:24
...
<?php
namespace Api\Controller;
use Think\Controller;
/**
 * 用别的框架改改也可以用
 * 微信APP 支付 + 回调  适用于TP3.2
 *     控制器名::WeChatPayController.class.php
 */

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

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

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

	}

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




	 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['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
		//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 'Errno' . 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['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
			$ip = $_SERVER['REMOTE_ADDR'];
		else
			$ip = "unknown";
		return ($ip);
	}

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

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

		//$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 = '<xml>';
		foreach ($array as $key => $value) {
			$xml .= '<' . $key . '>' . $value . '</' . $key . '>';
		}
		$xml .= '</xml>';
		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, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		return $array_data;
	}

}

以上就是APP 调微信支付功能的详细内容,更多请关注其它相关文章!