微信JSAPI支付,统一下单接口

今天小编给大家分享一下微信支付的统一下单接口,其实微信官网上也有SDK和DEMO下载了,但是不太好理解,小编就自己整理一份容易理解的代码,看不懂官方的,就来看看小编这份吧,哈哈~

新建一个类WxPayJsApi.php:

// +----------------------------------------------------------------------
// | 微信JSAPI支付
// +----------------------------------------------------------------------
// | Copyright (c) 2017 http://www.lrfun.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: lrfun <admin@lrfun.com>
// +----------------------------------------------------------------------
// | Date: 2017-06-12
// +----------------------------------------------------------------------
 
Class WxPayJsApi{
	protected $appid; protected $mchid;
    protected $keys;
     
    function __construct(){
        $this->appid = "xxx";
        $this->mchid = "xxx";
        $this->keys  = "xxx";
    }
	
	public function unifiedorder($data){
		$parameters = array();
		$parameters['appid']            = $this->appid;
		$parameters['mch_id']           = $this->mchid;
		$parameters['nonce_str']        = $this->getNonceStr();
		$parameters['body']             = $data['body'];
		$parameters['out_trade_no']     = $this->mchid . date("YmdHis");
		$parameters['total_fee']        = $data['total_fee'];
		$parameters['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];
		$parameters['notify_url']       = 'http://www.lrfun.com/wxPayCallback.php';
		$parameters['trade_type']       = 'JSAPI';
		$parameters['openid']           = $data['openid'];//微信用户的openid(前面有发表过如何获取openid的文章,这里不多说了)
		$parameters['time_start']       = date("YmdHis");
		$parameters['time_expire']      = date("YmdHis", time() + 3600);
		$parameters['attach']           = $data['orderId'];//订单ID,用于支付成功后,更新订单状态
		$parameters['sign']             = $this->getSign($parameters);
		
		$queryXml   = $this->arrayToXml($parameters);
		$url        = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
		$returnData = $this->httpRequest($url, $queryXml);
		$result     = $this->xmlToArray($returnData);
		$jsApiData  = $this->getJsApiParameters($result);
		return $jsApiData;
	}
	
	/***
	 * 微信支付生成签名
	 * @parameters 签名数据
	 * @return 签名字符串
	 **/
	public function getSign($parameters){
		ksort($parameters);
		$parametersUrl = urldecode(http_build_query($parameters)) .'&key='. $this->keys;
		$sign = strtoupper(md5($parametersUrl));
		return $sign;
	}
	
	/***
	 * 数组转xml
	 * @arr 数组
	 * @return xml
	 **/
	private function arrayToXml($arr){
		if(!is_array($arr) || count($arr) <= 0){
			exit("数组数据异常!");
		}
		
		$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或GET请求
     * @url 请求url
     * @data POST数据
     * @return
     **/
	private function httpRequest($url, $data = ""){
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
		if(!empty($data)){ //判断是否为POST请求
			curl_setopt($curl, CURLOPT_POST, 1);
			curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
		}
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$output = curl_exec($curl);
		curl_close($curl);
		return $output;
	}
	
    /***
     * XML转数组
     * @url XML
     * @return 数组
     **/
	private function xmlToArray($xml){
		if(!$xml){
			echo "xml数据异常!";
			exit;
		}
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		return $arr;
	}
	
    /***
     * 获取jsapi支付参数
     * @data 请求微信返回的数据
     * @return JSON
     **/
	private function getJsApiParameters($data){
		$timeStamp = time();
		$jsapi["appId"]     = $this->appid;
		$jsapi["nonceStr"]  = $this->getNonceStr();
		$jsapi["timeStamp"] = "$timeStamp";
		$jsapi["signType"]  = "MD5";
		$jsapi["package"]   = "prepay_id=".$data["prepay_id"];
		$jsapi["paySign"]   = $this->getSign($jsapi);
		$jsApiParameters    = json_encode($jsapi);
		return $jsApiParameters;
	}
	
	/***
	 * 支付成功回调函数
	 **/
	public function callback(){
		$callbackXml = file_get_contents('php://input');
		$data = json_decode(json_encode(simplexml_load_string($callbackXml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		$callbackSign = $data['sign'];
		unset($data['sign']);
		$sign = $this->getSign($data);
		if($sign == $callbackSign){
			//这里更新你的订单状态
			//根据$data['attach']获取订单信息,更新订单状态
			$returnXml = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
			echo returnXml;
		}
	}
	
    /***
     * 生成随机数
     * @length 随机字符串长度(默认32位)
     * @return
     **/
	private 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;
	}
}

新建index.php,调用代码:

<?php
	require_once('WxPay.JsApi.php');
	$wxPayJsApi = new WxPayJsApi();
	$data = array('body'=>'test', 'total_fee'=>1, 'openid'=>'ocjhxwYwEXlagni-n21fdNArvYWk', 'orderId'=>'168');
	$parameters = $wxPayJsApi->unifiedorder($data);
?>
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/> 
    <title>微信JSAPI支付样例</title>
    <script type="text/javascript">
	//调用微信JS api 支付
	function jsApiCall()
	{
		WeixinJSBridge.invoke(
			'getBrandWCPayRequest',
			<?php echo $parameters; ?>,
			function(res){
				WeixinJSBridge.log(res.err_msg);
				alert(res.err_code+res.err_desc+res.err_msg);
			}
		);
	}

	function callpay()
	{
		if (typeof WeixinJSBridge == "undefined"){
		    if( document.addEventListener ){
		        document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
		    }else if (document.attachEvent){
		        document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
		        document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
		    }
		}else{
		    jsApiCall();
		}
	}
	</script>
</head>
<body>
    <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">1分</span>钱</b></font><br/><br/>
	<div align="center">
		<button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" type="button" onclick="callpay()" >立即支付</button>
	</div>
</body>
</html>


新建回调文件callback.php:

require_once('WxPay.JsApi.php');
$wxPayJsApi = new WxPayJsApi();
$wxPayJsApi->callback();

附件下载:JSAPI-Demo.zip

欢迎转载,原文地址:http://www.lrfun.com/html/technology/PHP/2017/0612/113.html

上一篇:PayPal支付教程
下一篇:微信支付之Native扫码支付 模式二