<?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 = "***";
$this->mchid = "***";//商户号
$this->keys = "***";
}
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;
}
}
上面是接口类,需要自己先获取openid后,拉起支付接口
$openid=$_GET["openid"]; //获取openid
require_once('WeixinPay.php');//调用类文件
$wxPayJsApi = new WxPayJsApi();
$data = array('body'=>'test', 'total_fee'=>1, 'openid'=>$openid, 'orderId'=>'16855');
$parameters = $wxPayJsApi->unifiedorder($data);
echo $parameters;//这里是输出给前后端分离的接口用的,非接口的直接return就行。