| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 | <?php/**** example目录下为简单的支付样例,仅能用于搭建快速体验微信支付使用* 样例的作用仅限于指导如何使用sdk,在安全上面仅做了简单处理, 复制使用样例代码时请慎重* 请勿直接直接使用样例对外提供服务* **/require_once "WxPay.Api.php";/** *  * JSAPI支付实现类 * 该类实现了从微信公众平台获取code、通过code获取openid和access_token、 * 生成jsapi支付js接口所需的参数、生成获取共享收货地址所需的参数 *  * 该类是微信支付提供的样例程序,商户可根据自己的需求修改,或者使用lib中的api自行开发 *  * @author widy * */class JsApiPay{	/**	 * 	 * 网页授权接口微信服务器返回的数据,返回样例如下	 * {	 *  "access_token":"ACCESS_TOKEN",	 *  "expires_in":7200,	 *  "refresh_token":"REFRESH_TOKEN",	 *  "openid":"OPENID",	 *  "scope":"SCOPE",	 *  "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"	 * }	 * 其中access_token可用于获取共享收货地址	 * openid是微信支付jsapi支付接口必须的参数	 * @var array	 */	public $data = null;	public function __construct($config)	{		$this->config = $config;	}		/**	 * 	 * 通过跳转获取用户的openid,跳转流程如下:	 * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize	 * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code	 * 	 * @return 用户的openid	 */	public function GetOpenid()	{		//通过code获得openid		if (!isset($_GET['code'])){			//触发微信返回code码			$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);			$url = $this->_CreateOauthUrlForCode($baseUrl);			Header("Location: $url");			exit();		} else {			//获取code码,以获取openid		    $code = $_GET['code'];			$openid = $this->getOpenidFromMp($code);			return $openid;		}	}		/**	 * 	 * 获取jsapi支付的参数	 * @param array $UnifiedOrderResult 统一支付接口返回的数据	 * @throws WxPayException	 * 	 * @return json数据,可直接填入js函数作为参数	 */	public function GetJsApiParameters($UnifiedOrderResult)	{		if(!array_key_exists("appid", $UnifiedOrderResult)		|| !array_key_exists("prepay_id", $UnifiedOrderResult)		|| $UnifiedOrderResult['prepay_id'] == "")		{			throw new WxPayException("参数错误");		}		$jsapi = new WxPayJsApiPay();		$jsapi->SetAppid($UnifiedOrderResult["appid"]);		$timeStamp = time();		$jsapi->SetTimeStamp("$timeStamp");		$jsapi->SetNonceStr(WxPayApi::getNonceStr());		$jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);		$jsapi->SetPaySign($jsapi->MakeSign($this->config));		$parameters = json_encode($jsapi->GetValues());		return $parameters;	}		/**	 * 	 * 通过code从工作平台获取openid机器access_token	 * @param string $code 微信跳转回来带上的code	 * 	 * @return openid	 */	public function GetOpenidFromMp($code)	{		$url = $this->__CreateOauthUrlForOpenid($code);		//初始化curl		$ch = curl_init();		$curlVersion = curl_version();		$ua = "WXPaySDK/3.0.9 (".PHP_OS.") PHP/".PHP_VERSION." CURL/".$curlVersion['version']." "		.$this->config->GetMerchantId();		//设置超时		curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);		curl_setopt($ch, CURLOPT_URL, $url);		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);		curl_setopt($ch, CURLOPT_USERAGENT, $ua);		curl_setopt($ch, CURLOPT_HEADER, FALSE);		curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);		$proxyHost = "0.0.0.0";		$proxyPort = 0;		$this->config->GetProxy($proxyHost, $proxyPort);		if($proxyHost != "0.0.0.0" && $proxyPort != 0){			curl_setopt($ch,CURLOPT_PROXY, $proxyHost);			curl_setopt($ch,CURLOPT_PROXYPORT, $proxyPort);		}		//运行curl,结果以jason形式返回		$res = curl_exec($ch);		curl_close($ch);		//取出openid		$data = json_decode($res,true);		$this->data = $data;		$openid = $data['openid'];		return $openid;	}		/**	 * 	 * 拼接签名字符串	 * @param array $urlObj	 * 	 * @return 返回已经拼接好的字符串	 */	private function ToUrlParams($urlObj)	{		$buff = "";		foreach ($urlObj as $k => $v)		{			if($k != "sign"){				$buff .= $k . "=" . $v . "&";			}		}				$buff = trim($buff, "&");		return $buff;	}		/**	 * 	 * 获取地址js参数	 * 	 * @return 获取共享收货地址js函数需要的参数,json格式可以直接做参数使用	 */	public function GetEditAddressParameters()	{			$getData = $this->data;		$data = array();		$data["appid"] = $this->config->GetAppId();		$data["url"] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];		$time = time();		$data["timestamp"] = "$time";		$data["noncestr"] = WxPayApi::getNonceStr();		$data["accesstoken"] = $getData["access_token"];		ksort($data);		$params = $this->ToUrlParams($data);		$addrSign = sha1($params);				$afterData = array(			"addrSign" => $addrSign,			"signType" => "sha1",			"scope" => "jsapi_address",			"appId" => $this->config->GetAppId(),			"timeStamp" => $data["timestamp"],			"nonceStr" => $data["noncestr"]		);		$parameters = json_encode($afterData);		return $parameters;	}		/**	 * 	 * 构造获取code的url连接	 * @param string $redirectUrl 微信服务器回跳的url,需要url编码	 * 	 * @return 返回构造好的url	 */	private function _CreateOauthUrlForCode($redirectUrl)	{		$urlObj["appid"] = $this->config->GetAppId();		$urlObj["redirect_uri"] = "$redirectUrl";		$urlObj["response_type"] = "code";		$urlObj["scope"] = "snsapi_base";		$urlObj["state"] = "STATE"."#wechat_redirect";		$bizString = $this->ToUrlParams($urlObj);		return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;	}		/**	 * 	 * 构造获取open和access_toke的url地址	 * @param string $code,微信跳转带回的code	 * 	 * @return 请求的url	 */	private function __CreateOauthUrlForOpenid($code)	{		$urlObj["appid"] = $this->config->GetAppId();		$urlObj["secret"] = $this->config->GetAppSecret();		$urlObj["code"] = $code;		$urlObj["grant_type"] = "authorization_code";		$bizString = $this->ToUrlParams($urlObj);		return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;	}}
 |