本文实例讲述了PHP版微信js-sdk支付接口类用法。分享给大家供大家参考,具体如下:
这个支付类是根据官方的文档修改而来!主要实现生成JS API 、Native的package签名包和Native响应的XML格式数据。注释都标上了各方法的用意。由于package包签名,略复杂,这个要自己多花时间去对应去看和log出文件来一一对比!当然只要你用上教程的类,设置好对应的参数就可以正确的生成package参数等
PHP;">
= 1 && $argv[0] == __FILE__) {
//初始化pay的必要信息
$pay = new WechatPay(array(
WechatPay::APPID => 'wx99dabzpiuq83985b8',WechatPay::APPSERCER => 'ac12e7e4abaer63hkoa0cc36a9663fa',WechatPay::PARTNERKEY => 'bae4sfa3562rsfaq23s2045',WechatPay::PARTNERID => '1268969802',WechatPay::PAYSIGNKEY => '9Fqsxb3PK4IVOCEc4yCquy5zecS9LeeMjF2Nn4B4YKoOxPwaQdFwMezKT8oNlBYaWcuT',WechatPay::SIGNTYPE => 'sha1',));
//设置package 必要的参数 jsapi native都通用
$pay->setParams(WechatPay::BANK_TYPE,"WX");
$pay->setParams(WechatPay::BODY,"test");
$pay->setParams(WechatPay::PARTNER,$pay->partnerid);
$pay->setParams(WechatPay::OUT_TRADE_NO,commonUtil::createNoncestr());
$pay->setParams(WechatPay::TOTAL_FEE,"1");
$pay->setParams(WechatPay::FEE_TYPE,"1");
$pay->setParams(WechatPay::TIMESTAMP,time());
$pay->setParams(WechatPay::NOTIFY_URL,"http://www.demo.com/notify");
$pay->setParams(WechatPay::SPBILL_CREATE_IP,"127.0.0.1");
$pay->setParams(WechatPay::INPUT_CHARSET,"UTF-8");
//JSAPI的签名json
print_r($pay->createJsApiPackage());
//生成native XML
print_r($pay->createNativePackage());
//生成native URL
print_r($pay->createNativeUrl("9701"));
}
JS API生成的package签名包参数:
Native 响应的XML格式:
Native的URL链接:
weixin://wxpay/bizpayurl?appid=wx9998ff5f4dede5b7&noncestr=VY7cVA6mtVrc1BVq&productid=9701&sign=43508b65b50e1d7e1089be66d55a709469155d73×tamp=1409296323
无论哪一种方式,我们都要通过setParams来设置必要初始化参数和商品价格和状态等!
WechatPay class:
_appid = $options[self::APPID];
$this->_appkey = $options[self::PAYSIGNKEY];
$this->_signtype = $options[self::SIGNTYPE];
$this->_partnerkey = $options[self::PARTNERKEY];
$this->_appsercer = $options[self::APPSERCER];
$this->partnerid = $options[self::APPID];
}
public function setParams($param,$paramValue) {
$this->params[CommonUtil::trimString($param)] = CommonUtil::trimString($paramValue);
}
public function getParams($param) {
return $this->params[$param];
}
protected function createNoncestr( $length = 16 ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str.= substr($chars,mt_rand(0,strlen($chars)-1),1);
}
return $str;
}
public function checkParams(){
//必要的9个参与签名的参数
if($this->params[self::BANK_TYPE] == null || $this->params[self::BODY] == null || $this->params[self::PARTNER] == null ||
$this->params[self::OUT_TRADE_NO] == null || $this->params[self::TOTAL_FEE] == null || $this->params[self::FEE_TYPE] == null ||
$this->params[self::NOTIFY_URL] == null || $this->params[self::SPBILL_CREATE_IP] == null || $this->params[self::INPUT_CHARSET] == null
) {
return false;
}
return true;
}
/*
* 生成package包
* @params 初始化类时用setParams方法定义必要的9个参数
* 排序后格式化url query形式 再md5SignUtil类签名,再给合URL
*/
protected function getPackageSign(){
try {
if (null == $this->_partnerkey || "" == $this->_partnerkey ) {
throw new Exception("密钥不能为空!" . "
"); } $commonUtil = new CommonUtil(); ksort($this->params); $unSignParaString = $commonUtil->formatUrlQuery($this->params,false); $paraString = $commonUtil->formatUrlQuery($this->params,true); $md5SignUtil = new MD5SignUtil(); return $paraString . "&sign=" . $md5SignUtil->sign($unSignParaString,commonUtil::trimString($this->_partnerkey)); } catch (Exception $e) { echo ($e->getMessage()); } } /* * 生成签名方法 * @params appid appkey package timestamp noncestr 等参数而native事例代码中加上retcode reterrmsg两个参数 */ public function getPaySign($signObj){ foreach ($signObj as $k => $v){ $signParams[strtolower($k)] = $v; } try { if ($this->_appkey == "") { throw new Exception("APPKEY为空!" . "
"); } $signParams["appkey"] = $this->_appkey; ksort($signParams,SORT_STRING); $commonUtil = new CommonUtil(); $signString = $commonUtil->formatPayUrlQuery($signParams,false); return sha1($signString); } catch (Exception $e) { echo ($e->getMessage()); } } //JS API 签名 其中nonceStr是作为订单号 灌穿整个支付流程 public function createJsApiPackage(){ try { if($this->checkParams() == false) { throw new Exception("生成package参数缺失!" . "
"); } $payObj["appId"] = $this->_appid; $payObj["package"] = $this->getPackageSign(); $payObj["timeStamp"] = $this->getParams(self::TIMESTAMP); $payObj["nonceStr"] = $this->getParams(self::OUT_TRADE_NO); $payObj["paySign"] = $this->getPaySign($payObj); $payObj["signType"] = $this->_signtype; return json_encode($payObj); } catch (Exception $e) { die($e->getMessage()); } } /* * 构建发货状态数组 主要三个参数openid transid orderid */ public function createDeliverPost(Array $params) { $deliver = array(); $deliver['appid'] = $this->_appid; $deliver['openid'] = $params['openid']; $deliver['transid'] = $params['transid']; $deliver['out_trade_no'] = $params['out_trade_no']; $deliver['deliver_timestamp'] = current_time('timestamp'); $deliver['deliver_status'] = 1; $deliver['deliver_msg'] = 'OK'; $deliver['app_signature'] = $this->getPaySign($deliver); $deliver['sign_method'] = 'sha1'; return $deliver; } /* * 生成扫描或者点击原生URL后,响应的XML格式 * @params $retcode $reterrmsg 定义该商品的状态 */ public function createNativePackage($retcode = 0,$reterrmsg = "ok") { try { if ($this->checkParams() == false && $retcode == 0) { //如果是正常的返回, 检查财付通的参数 throw new Exception("生成package参数缺失!" . "
"); } $nativeObj["AppId"] = $this->_appid; $nativeObj["Package"] = $this->getPackageSign(); $nativeObj["TimeStamp"] = $this->getParams(self::TIMESTAMP); $nativeObj["NonceStr"] = $this->getParams(self::OUT_TRADE_NO); $nativeObj["RetCode"] = $retcode; $nativeObj["RetErrMsg"] = $reterrmsg; $nativeObj["AppSignature"] = $this->getPaySign($nativeObj); $nativeObj["SignMethod"] = $this->_signtype; $commonUtil = new CommonUtil(); $xml = $commonUtil->arrayToXml($nativeObj); exit($xml); }catch (Exception $e) { echo ($e->getMessage()); } } /* * 生成原生URL 以订单号为参数 这是灌穿整个支付流程 */ public function createNativeUrl($productid) { $commonUtil = new CommonUtil(); $nativeObj["appid"] = $this->_appid; $nativeObj["productid"] = urlencode($productid); $nativeObj["timestamp"] = time(); $nativeObj["nonceStr"] = commonUtil::createNoncestr(); $nativeObj["sign"] = $this->getPaySign($nativeObj); $nativeString = $commonUtil->formatPayUrlQuery($nativeObj,false); return "weixin://wxpay/bizpayurl?".$nativeString; } /* * 取IP地址 */ public function getIp(){ switch(true) { case !empty($_SERVER["HTTP_CLIENT_IP"]): $ip = $_SERVER["HTTP_CLIENT_IP"]; break; case !empty($_SERVER["HTTP_X_FORWARDED_FOR"]): $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; break; case !empty($_SERVER["REMOTE_ADDR"]): $ip = $_SERVER["REMOTE_ADDR"]; break; default: $ip = "127.0.0.1"; } return $ip; } } class MD5SignUtil { public function sign($content,$key) { try { if (null == $key) { throw new Exception("财付通签名key不能为空!" . "
"); } if (null == $content) { throw new Exception("财付通签名内容不能为空" . "
"); } $signStr = $content . "&key=" . $key; return strtoupper(md5($signStr)); } catch (Exception $e) { echo ($e->getMessage()); } } public static function verifySignature($content,$sign,$md5Key) { $signStr = $content . "&key=" . $md5Key; $calculateSign = strtolower(md5($signStr)); $tenpaySign = strtolower($sign); return $calculateSign == $tenpaySign; } } class CommonUtil { public function genAllUrl($toURL,$paras) { $allUrl = null; if (null == $toURL) { die("toURL is null"); } if (strripos($toURL,"?") =="") { $allUrl = $toURL . "?" . $paras; } else { $allUrl = $toURL . "&" . $paras; } return $allUrl; } //订单号,可根据实际自定义 static public function createOrderNo() { $nonce = CommonUtil::createNoncestr(4); return strtoupper(date('ymds').substr(microtime(),2,4).$nonce); } //随机字符串 static public function createNoncestr( $length = 16 ) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str.= substr($chars,1); } return $str; } public function splitParaStr($src,$token) { $resMap = array(); $items = explode($token,$src); foreach ($items as $item){ $paraAndValue = explode("=",$item); if ($paraAndValue != "") { $resMap[$paraAndValue[0]] = $paraAndValue[1]; } } return $resMap; } static function trimString($value) { $ret = null; if (null != $value) { $ret = $value; if (strlen($ret) == 0) { $ret = null; } } return $ret; } public function formatUrlQuery($paraMap,$urlencode) { $buff = ""; ksort($paraMap,SORT_STRING); foreach ($paraMap as $k => $v) { if (null != $v && "null" != $v && "sign" != $k) { if($urlencode) { $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } } $reqPar = ''; if (strlen($buff) > 0) { $reqPar = substr($buff,strlen($buff)-1); } return $reqPar; } public function formatPayUrlQuery($paraMap,SORT_STRING); foreach ($paraMap as $k => $v) { if($urlencode){ $v = urlencode($v); } $buff .= strtolower($k) . "=" . $v . "&"; } $reqPar = ''; if (strlen($buff) > 0) { $reqPar = substr($buff,strlen($buff)-1); } return $reqPar; } /* * 输出一级数组的xml格式 */ public function arrayToXml($arr) { $xml = "";
foreach ($arr as $key=>$val) {
if ($key == 'TimeStamp' || $key == 'RetCode') {
$xml.="<".$key.">".$val."".$key.">";
} else
$xml.="<".$key.">".$key.">";
}
$xml .= " ";
return $xml;
}
}
"); } $commonUtil = new CommonUtil(); ksort($this->params); $unSignParaString = $commonUtil->formatUrlQuery($this->params,false); $paraString = $commonUtil->formatUrlQuery($this->params,true); $md5SignUtil = new MD5SignUtil(); return $paraString . "&sign=" . $md5SignUtil->sign($unSignParaString,commonUtil::trimString($this->_partnerkey)); } catch (Exception $e) { echo ($e->getMessage()); } } /* * 生成签名方法 * @params appid appkey package timestamp noncestr 等参数而native事例代码中加上retcode reterrmsg两个参数 */ public function getPaySign($signObj){ foreach ($signObj as $k => $v){ $signParams[strtolower($k)] = $v; } try { if ($this->_appkey == "") { throw new Exception("APPKEY为空!" . "
"); } $signParams["appkey"] = $this->_appkey; ksort($signParams,SORT_STRING); $commonUtil = new CommonUtil(); $signString = $commonUtil->formatPayUrlQuery($signParams,false); return sha1($signString); } catch (Exception $e) { echo ($e->getMessage()); } } //JS API 签名 其中nonceStr是作为订单号 灌穿整个支付流程 public function createJsApiPackage(){ try { if($this->checkParams() == false) { throw new Exception("生成package参数缺失!" . "
"); } $payObj["appId"] = $this->_appid; $payObj["package"] = $this->getPackageSign(); $payObj["timeStamp"] = $this->getParams(self::TIMESTAMP); $payObj["nonceStr"] = $this->getParams(self::OUT_TRADE_NO); $payObj["paySign"] = $this->getPaySign($payObj); $payObj["signType"] = $this->_signtype; return json_encode($payObj); } catch (Exception $e) { die($e->getMessage()); } } /* * 构建发货状态数组 主要三个参数openid transid orderid */ public function createDeliverPost(Array $params) { $deliver = array(); $deliver['appid'] = $this->_appid; $deliver['openid'] = $params['openid']; $deliver['transid'] = $params['transid']; $deliver['out_trade_no'] = $params['out_trade_no']; $deliver['deliver_timestamp'] = current_time('timestamp'); $deliver['deliver_status'] = 1; $deliver['deliver_msg'] = 'OK'; $deliver['app_signature'] = $this->getPaySign($deliver); $deliver['sign_method'] = 'sha1'; return $deliver; } /* * 生成扫描或者点击原生URL后,响应的XML格式 * @params $retcode $reterrmsg 定义该商品的状态 */ public function createNativePackage($retcode = 0,$reterrmsg = "ok") { try { if ($this->checkParams() == false && $retcode == 0) { //如果是正常的返回, 检查财付通的参数 throw new Exception("生成package参数缺失!" . "
"); } $nativeObj["AppId"] = $this->_appid; $nativeObj["Package"] = $this->getPackageSign(); $nativeObj["TimeStamp"] = $this->getParams(self::TIMESTAMP); $nativeObj["NonceStr"] = $this->getParams(self::OUT_TRADE_NO); $nativeObj["RetCode"] = $retcode; $nativeObj["RetErrMsg"] = $reterrmsg; $nativeObj["AppSignature"] = $this->getPaySign($nativeObj); $nativeObj["SignMethod"] = $this->_signtype; $commonUtil = new CommonUtil(); $xml = $commonUtil->arrayToXml($nativeObj); exit($xml); }catch (Exception $e) { echo ($e->getMessage()); } } /* * 生成原生URL 以订单号为参数 这是灌穿整个支付流程 */ public function createNativeUrl($productid) { $commonUtil = new CommonUtil(); $nativeObj["appid"] = $this->_appid; $nativeObj["productid"] = urlencode($productid); $nativeObj["timestamp"] = time(); $nativeObj["nonceStr"] = commonUtil::createNoncestr(); $nativeObj["sign"] = $this->getPaySign($nativeObj); $nativeString = $commonUtil->formatPayUrlQuery($nativeObj,false); return "weixin://wxpay/bizpayurl?".$nativeString; } /* * 取IP地址 */ public function getIp(){ switch(true) { case !empty($_SERVER["HTTP_CLIENT_IP"]): $ip = $_SERVER["HTTP_CLIENT_IP"]; break; case !empty($_SERVER["HTTP_X_FORWARDED_FOR"]): $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; break; case !empty($_SERVER["REMOTE_ADDR"]): $ip = $_SERVER["REMOTE_ADDR"]; break; default: $ip = "127.0.0.1"; } return $ip; } } class MD5SignUtil { public function sign($content,$key) { try { if (null == $key) { throw new Exception("财付通签名key不能为空!" . "
"); } if (null == $content) { throw new Exception("财付通签名内容不能为空" . "
"); } $signStr = $content . "&key=" . $key; return strtoupper(md5($signStr)); } catch (Exception $e) { echo ($e->getMessage()); } } public static function verifySignature($content,$sign,$md5Key) { $signStr = $content . "&key=" . $md5Key; $calculateSign = strtolower(md5($signStr)); $tenpaySign = strtolower($sign); return $calculateSign == $tenpaySign; } } class CommonUtil { public function genAllUrl($toURL,$paras) { $allUrl = null; if (null == $toURL) { die("toURL is null"); } if (strripos($toURL,"?") =="") { $allUrl = $toURL . "?" . $paras; } else { $allUrl = $toURL . "&" . $paras; } return $allUrl; } //订单号,可根据实际自定义 static public function createOrderNo() { $nonce = CommonUtil::createNoncestr(4); return strtoupper(date('ymds').substr(microtime(),2,4).$nonce); } //随机字符串 static public function createNoncestr( $length = 16 ) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str.= substr($chars,1); } return $str; } public function splitParaStr($src,$token) { $resMap = array(); $items = explode($token,$src); foreach ($items as $item){ $paraAndValue = explode("=",$item); if ($paraAndValue != "") { $resMap[$paraAndValue[0]] = $paraAndValue[1]; } } return $resMap; } static function trimString($value) { $ret = null; if (null != $value) { $ret = $value; if (strlen($ret) == 0) { $ret = null; } } return $ret; } public function formatUrlQuery($paraMap,$urlencode) { $buff = ""; ksort($paraMap,SORT_STRING); foreach ($paraMap as $k => $v) { if (null != $v && "null" != $v && "sign" != $k) { if($urlencode) { $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } } $reqPar = ''; if (strlen($buff) > 0) { $reqPar = substr($buff,strlen($buff)-1); } return $reqPar; } public function formatPayUrlQuery($paraMap,SORT_STRING); foreach ($paraMap as $k => $v) { if($urlencode){ $v = urlencode($v); } $buff .= strtolower($k) . "=" . $v . "&"; } $reqPar = ''; if (strlen($buff) > 0) { $reqPar = substr($buff,strlen($buff)-1); } return $reqPar; } /* * 输出一级数组的xml格式 */ public function arrayToXml($arr) { $xml = "
更多关于PHP相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》、《》及《》
希望本文所述对大家PHP程序设计有所帮助。