当前位置:首页 > PHP教程 > php高级应用 > 列表

php版本微信js-sdk支付接口类例子

发布:smiling 来源: PHP粉丝网  添加日期:2018-10-30 10:17:13 浏览: 评论:0 

这个支付类是根据官方的文档修改而来!主要实现生成JS API 、Native的package签名包和Native响应的XML格式数据。注释都标上了各方法的用意。由于package包签名,略复杂,这个要自己多花时间去对应去看和log出文件来一一对比!当然只要你用上教程的类,设置好对应的参数就可以正确的生成package参数等

  1. if (isset($argc)  && $argc >= 1 && $argv[0] == __FILE__) { 
  2.     //初始化pay的必要信息 
  3.     $pay = new WechatPay(array
  4.         WechatPay::APPID => 'wx99dabzpiuq83985b8'
  5.         WechatPay::APPSERCER => 'ac12e7e4abaer63hkoa0cc36a9663fa'
  6.         WechatPay::PARTNERKEY => 'bae4sfa3562rsfaq23s2045'
  7.         WechatPay::PARTNERID => '1268969802'
  8.         WechatPay::PAYSIGNKEY => '9Fqsxb3PK4IVOCEc4yCquy5zecS9LeeMjF2Nn4B4YKoOxPwaQdFwMezKT8oNlBYaWcuT'
  9.         WechatPay::SIGNTYPE => 'sha1'
  10.     )); 
  11.     //设置package 必要的参数 jsapi native都通用 
  12.     $pay->setParams(WechatPay::BANK_TYPE, "WX"); 
  13.     $pay->setParams(WechatPay::BODY, "test"); 
  14.     $pay->setParams(WechatPay::PARTNER, $pay->partnerid); 
  15.     $pay->setParams(WechatPay::OUT_TRADE_NO, commonUtil::createNoncestr()); 
  16.     $pay->setParams(WechatPay::TOTAL_FEE, "1"); 
  17.     $pay->setParams(WechatPay::FEE_TYPE, "1"); 
  18.     $pay->setParams(WechatPay::TIMESTAMP, time()); 
  19.     $pay->setParams(WechatPay::NOTIFY_URL, "http://www.demo.com/notify"); 
  20.     $pay->setParams(WechatPay::SPBILL_CREATE_IP, "127.0.0.1"); 
  21.     $pay->setParams(WechatPay::INPUT_CHARSET, "UTF-8"); 
  22.  
  23.     //JSAPI的签名json 
  24.     print_r($pay->createJsApiPackage()); 
  25.  
  26.     //生成native XML 
  27.     print_r($pay->createNativePackage()); 
  28.  
  29.     //生成native URL 
  30.     print_r($pay->createNativeUrl("9701")); 

JS API生成的package签名包参数:

  1.     "appId":"wx9998ff5f4dede5b7", 
  2.     "package":"bank_type=WX&body=test&fee_type=1&input_charset=UTF-8&notify_url=http%3A%2F%2Fwww.demo.com%2Fnotify&out_trade_no=Vf5qsSwtu0hc2loH&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1&timestamp=1409295711&total_fee=1&sign=FEE0167BD0D89A88BF6850590EA889B6", 
  3.     "timeStamp":1409295711, 
  4.     "nonceStr":"Vf5qsSwtu0hc2loH", 
  5.     "paySign":"f816264c750923863c370a1739640244b0c2d39c", 
  6.     "signType":"sha1" 

Native 响应的XML格式:

  1. <xml> 
  2.     <AppId><![CDATA[wx9998ff5f4dede5b7]]></AppId> 
  3.     <Package> 
  4.         <![CDATA[bank_type=WX&body=test&fee_type=1&input_charset=UTF-8&notify_url=http%3A%2F%2Fwww.demo.com%2Fnotify&out_trade_no=GDl3what4sALDEAd&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1&timestamp=1409296124&total_fee=1&sign=BF949B85570644B939B369FD44B0C4A9]]> 
  5.     </Package> 
  6.     <TimeStamp>1409296124</TimeStamp> 
  7.     <NonceStr><![CDATA[GDl3what4sALDEAd]]></NonceStr> 
  8.     <RetCode>0</RetCode> 
  9.     <RetErrMsg><![CDATA[ok]]></RetErrMsg> 
  10.     <AppSignature><![CDATA[ca4a2467b817a62c38a9801fcf451f51692027bf]]></AppSignature> 
  11.     <SignMethod><![CDATA[sha1]]></SignMethod> 
  12. </xml> 

Native的URL链接:

weixin://wxpay/bizpayurl?appid=wx9998ff5f4dede5b7&noncestr=VY7cVA6mtVrc1BVq&productid=9701&sign=43508b65b50e1d7e1089be66d55a709469155d73&timestamp=1409296323

无论哪一种方式,我们都要通过setParams来设置必要初始化参数和商品价格和状态等!

WechatPay class:

  1. class WechatPay { 
  2.     const 
  3.         BANK_TYPE = 'bank_type'
  4.         BODY = 'body'
  5.         PARTNER = 'partner'
  6.         OUT_TRADE_NO = 'out_trade_no'
  7.         TIMESTAMP = 'timestamp'
  8.         TOTAL_FEE = 'total_fee'
  9.         FEE_TYPE = 'fee_type'
  10.         NOTIFY_URL = 'notify_url'
  11.         SPBILL_CREATE_IP = 'spbill_create_ip'
  12.         INPUT_CHARSET = 'input_charset'
  13.         APPID = 'appid'
  14.         APPSERCER = 'appsercer'
  15.         PAYSIGNKEY = 'appkey'
  16.         PARTNERID = 'partnerid'
  17.         PARTNERKEY = 'partnerkey'
  18.         SIGNTYPE = 'signtype'
  19.  
  20.     public 
  21.         $params = array(), $partnerid = ''
  22.  
  23.     static protected 
  24.         $_instance
  25.  
  26.     protected 
  27.         $_appid$_appkey$_signtype$_partnerkey$_appsercer
  28.  
  29.     static public function getInstance(array $options = array()) { 
  30.         if (emptyempty(self::$_instance)) { 
  31.             self::$_instance = new self ($options); 
  32.         } 
  33.         return self::$_instance
  34.     } 
  35.  
  36.     public function __construct(array $options = array()){ 
  37.         $this->_appid = $options[self::APPID]; 
  38.         $this->_appkey = $options[self::PAYSIGNKEY]; 
  39.         $this->_signtype = $options[self::SIGNTYPE]; 
  40.         $this->_partnerkey = $options[self::PARTNERKEY]; 
  41.         $this->_appsercer = $options[self::APPSERCER]; 
  42.         $this->partnerid = $options[self::APPID]; 
  43.     } 
  44.  
  45.     public function setParams($param$paramValue) { 
  46.         $this->params[CommonUtil::trimString($param)] = CommonUtil::trimString($paramValue); 
  47.     } 
  48.  
  49.     public function getParams($param) { 
  50.         return $this->params[$param]; 
  51.     } 
  52.  
  53.     protected function createNoncestr( $length = 16 ) { 
  54.         $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  55.         $str =""
  56.         for ( $i = 0; $i < $length$i++ )  { 
  57.             $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); 
  58.         } 
  59.         return $str
  60.     } 
  61.  
  62.     public function checkParams(){ 
  63.         //必要的9个参与签名的参数 
  64.         if($this->params[self::BANK_TYPE] == null || $this->params[self::BODY] == null || $this->params[self::PARTNER] == null || 
  65.             $this->params[self::OUT_TRADE_NO] == null || $this->params[self::TOTAL_FEE] == null || $this->params[self::FEE_TYPE] == null || 
  66.             $this->params[self::NOTIFY_URL] == null || $this->params[self::SPBILL_CREATE_IP] == null || $this->params[self::INPUT_CHARSET] == null 
  67.         ) { 
  68.             return false; 
  69.         } 
  70.         return true; 
  71.     } 
  72.  
  73.     /* 
  74.      * 生成package包 
  75.      * @params 初始化类时用setParams方法定义必要的9个参数 
  76.      * 排序后格式化url query形式 再md5SignUtil类签名,再给合URL 
  77.      */ 
  78.     protected function getPackageSign(){ 
  79.         try { 
  80.             if (null == $this->_partnerkey || "" == $this->_partnerkey ) { 
  81.                 throw new Exception("密钥不能为空!" . "<br>"); 
  82.             } 
  83.             $commonUtil = new CommonUtil(); 
  84.             ksort($this->params); 
  85.             $unSignParaString = $commonUtil->formatUrlQuery($this->params, false); 
  86.             $paraString = $commonUtil->formatUrlQuery($this->params, true); 
  87.             $md5SignUtil = new MD5SignUtil(); 
  88.             return $paraString . "&sign=" . $md5SignUtil->sign($unSignParaString,commonUtil::trimString($this->_partnerkey)); 
  89.         } catch (Exception $e) { 
  90.             echo ($e->getMessage()); 
  91.         } 
  92.     } 
  93.  
  94.     /* 
  95.      * 生成签名方法 
  96.      * @params appid appkey package timestamp noncestr 等参数而native事例代码中加上retcode reterrmsg两个参数 
  97.      */ 
  98.     public function getPaySign($signObj){ 
  99.         foreach ($signObj as $k => $v){ 
  100.             $signParams[strtolower($k)] = $v
  101.         } 
  102.         try { 
  103.             if ($this->_appkey == "") { 
  104.                 throw new Exception("APPKEY为空!" . "<br>"); 
  105.             } 
  106.             $signParams["appkey"] = $this->_appkey; 
  107.             ksort($signParams, SORT_STRING); 
  108.             $commonUtil = new CommonUtil(); 
  109.             $signString = $commonUtil->formatPayUrlQuery($signParams, false); 
  110.             return sha1($signString); 
  111.         } catch (Exception $e) { 
  112.             echo ($e->getMessage()); 
  113.         } 
  114.     } 
  115.     //JS API 签名 其中nonceStr是作为订单号 灌穿整个支付流程 
  116.     public function createJsApiPackage(){ 
  117.         try { 
  118.             if($this->checkParams() == false) { 
  119.                 throw new Exception("生成package参数缺失!" . "<br>"); 
  120.             } 
  121.             $payObj["appId"] = $this->_appid; 
  122.             $payObj["package"] = $this->getPackageSign(); 
  123.             $payObj["timeStamp"] = $this->getParams(self::TIMESTAMP); 
  124.             $payObj["nonceStr"] = $this->getParams(self::OUT_TRADE_NO); 
  125.             $payObj["paySign"] = $this->getPaySign($payObj); 
  126.             $payObj["signType"] = $this->_signtype; 
  127.             return json_encode($payObj); 
  128.         } catch (Exception $e) { 
  129.             die($e->getMessage()); 
  130.         } 
  131.     } 
  132.  
  133.     /* 
  134.      * 构建发货状态数组 主要三个参数openid transid orderid 
  135.      */ 
  136.     public function createDeliverPost(Array $params) { 
  137.         $deliver = array(); 
  138.         $deliver['appid'] = $this->_appid; 
  139.         $deliver['openid'] = $params['openid']; 
  140.         $deliver['transid'] = $params['transid']; 
  141.         $deliver['out_trade_no'] = $params['out_trade_no']; 
  142.         $deliver['deliver_timestamp'] = current_time('timestamp'); 
  143.         $deliver['deliver_status'] = 1; 
  144.         $deliver['deliver_msg'] = 'OK'
  145.         $deliver['app_signature'] = $this->getPaySign($deliver); 
  146.         $deliver['sign_method'] = 'sha1'
  147.         return $deliver
  148.     } 
  149.  
  150.     /* 
  151.      * 生成扫描或者点击原生URL后,响应的XML格式 
  152.      * @params $retcode $reterrmsg 定义该商品的状态 
  153.      */ 
  154.     public function createNativePackage($retcode = 0, $reterrmsg = "ok") { 
  155.         try { 
  156.             if ($this->checkParams() == false && $retcode == 0) {   //如果是正常的返回, 检查财付通的参数 
  157.                 throw new Exception("生成package参数缺失!" . "<br>"); 
  158.             } 
  159.             $nativeObj["AppId"] = $this->_appid; 
  160.             $nativeObj["Package"] = $this->getPackageSign(); 
  161.             $nativeObj["TimeStamp"] = $this->getParams(self::TIMESTAMP); 
  162.             $nativeObj["NonceStr"] = $this->getParams(self::OUT_TRADE_NO); 
  163.             $nativeObj["RetCode"] = $retcode
  164.             $nativeObj["RetErrMsg"] = $reterrmsg
  165.             $nativeObj["AppSignature"] = $this->getPaySign($nativeObj); 
  166.             $nativeObj["SignMethod"] = $this->_signtype; 
  167.             $commonUtil = new CommonUtil(); 
  168.             $xml = $commonUtil->arrayToXml($nativeObj); 
  169.             exit($xml); 
  170.         }catch (Exception $e) { 
  171.             echo ($e->getMessage()); 
  172.         } 
  173.     } 
  174.  
  175.     /* 
  176.      * 生成原生URL 以订单号为参数 这是灌穿整个支付流程 
  177.      */ 
  178.     public function createNativeUrl($productid) { 
  179.         $commonUtil = new CommonUtil(); 
  180.         $nativeObj["appid"] = $this->_appid; 
  181.         $nativeObj["productid"] = urlencode($productid); 
  182.         $nativeObj["timestamp"] = time(); 
  183.         $nativeObj["nonceStr"] = commonUtil::createNoncestr(); 
  184.         $nativeObj["sign"] = $this->getPaySign($nativeObj); 
  185.         $nativeString = $commonUtil->formatPayUrlQuery($nativeObj, false); 
  186.         return "weixin://wxpay/bizpayurl?".$nativeString
  187.     } 
  188.  
  189.     /* 
  190.      * 取IP地址 
  191.      */ 
  192.     public function getIp(){ 
  193.         switch(true) { 
  194.             case !emptyempty($_SERVER["HTTP_CLIENT_IP"]): 
  195.                 $ip = $_SERVER["HTTP_CLIENT_IP"]; 
  196.                 break
  197.             case !emptyempty($_SERVER["HTTP_X_FORWARDED_FOR"]): 
  198.                 $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
  199.                 break
  200.             case !emptyempty($_SERVER["REMOTE_ADDR"]): 
  201.                 $ip = $_SERVER["REMOTE_ADDR"]; 
  202.                 break
  203.             default
  204.                 $ip = "127.0.0.1"
  205.         } 
  206.         return $ip
  207.     } 
  208.  
  209. class MD5SignUtil { 
  210.     public function sign($content$key) { 
  211.         try { 
  212.             if (null == $key) { 
  213.                 throw new Exception("财付通签名key不能为空!" . "<br>"); 
  214.             } 
  215.             if (null == $content) { 
  216.                 throw new Exception("财付通签名内容不能为空" . "<br>"); 
  217.             } 
  218.             $signStr = $content . "&key=" . $key
  219.             return strtoupper(md5($signStr)); 
  220.         } catch (Exception $e) { 
  221.             echo ($e->getMessage()); 
  222.         } 
  223.     } 
  224.  
  225.     public static function verifySignature($content$sign$md5Key) { 
  226.         $signStr = $content . "&key=" . $md5Key
  227.         $calculateSign = strtolower(md5($signStr)); 
  228.         $tenpaySign = strtolower($sign); 
  229.         return $calculateSign == $tenpaySign
  230.     } 
  231.  
  232. class CommonUtil { 
  233.     public function genAllUrl($toURL$paras) { 
  234.         $allUrl = null; 
  235.         if (null == $toURL) { 
  236.             die("toURL is null"); 
  237.         } 
  238.         if (strripos($toURL,"?") =="") { 
  239.             $allUrl = $toURL . "?" . $paras
  240.         } else { 
  241.             $allUrl = $toURL . "&" . $paras
  242.         } 
  243.         return $allUrl
  244.     } 
  245.  
  246.     //订单号,可根据实际自定义 
  247.     static public function createOrderNo() { 
  248.         $nonce = CommonUtil::createNoncestr(4); 
  249.         return strtoupper(date('ymds').substr(microtime(),2,4).$nonce); 
  250.     } 
  251.  
  252.     //随机字符串 
  253.     static public function createNoncestr( $length = 16 ) { 
  254.         $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  255.         $str =""
  256.         for ( $i = 0; $i < $length$i++ )  { 
  257.             $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); 
  258.         } 
  259.         return $str
  260.     } 
  261.  
  262.     public function splitParaStr($src$token) { 
  263.         $resMap = array(); 
  264.         $items = explode($token,$src); 
  265.         foreach ($items as $item){ 
  266.             $paraAndValue = explode("=",$item); 
  267.             if ($paraAndValue != "") { 
  268.                 $resMap[$paraAndValue[0]] = $paraAndValue[1]; 
  269.             } 
  270.         } 
  271.         return $resMap
  272.     } 
  273.  
  274.     static function trimString($value) { 
  275.         $ret = null; 
  276.         if (null != $value) { 
  277.             $ret = $value
  278.             if (strlen($ret) == 0) { 
  279.                 $ret = null; 
  280.             } 
  281.         } 
  282.         return $ret
  283.     } 
  284.  
  285.     public function formatUrlQuery($paraMap$urlencode) { 
  286.         $buff = ""
  287.         ksort($paraMap, SORT_STRING); 
  288.         foreach ($paraMap as $k => $v) { 
  289.             if (null != $v && "null" != $v && "sign" != $k) { 
  290.                 if($urlencode) { 
  291.                     $v = urlencode($v); 
  292.                 } 
  293.                 $buff .= $k . "=" . $v . "&"
  294.             } 
  295.         } 
  296.         $reqPar = ''
  297.         if (strlen($buff) > 0) { 
  298.             $reqPar = substr($buff, 0, strlen($buff)-1); 
  299.         } 
  300.         return $reqPar
  301.     } 
  302.  
  303.     public function formatPayUrlQuery($paraMap$urlencode) { 
  304.         $buff = ""
  305.         ksort($paraMap, SORT_STRING); 
  306.         foreach ($paraMap as $k => $v) { 
  307.             if($urlencode){ 
  308.                 $v = urlencode($v); 
  309.             } 
  310.             $buff .= strtolower($k) . "=" . $v . "&"
  311.         } 
  312.         $reqPar = ''
  313.         if (strlen($buff) > 0) { 
  314.             $reqPar = substr($buff, 0, strlen($buff)-1); 
  315.         } 
  316.         return $reqPar
  317.     } 
  318.  
  319.     /* 
  320.      * 输出一级数组的xml格式 
  321.      */ 
  322.     public function arrayToXml($arr) { 
  323.         $xml = "<xml>"
  324.         foreach ($arr as $key=>$val) { 
  325.             if ($key == 'TimeStamp' || $key == 'RetCode') { 
  326.                 $xml.="<".$key.">".$val."</".$key.">"
  327.             } else 
  328.                 $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"
  329.         } //phpfensi.com 
  330.         $xml .= "</xml>"
  331.         return $xml
  332.     } 

Tags: php微信 js-sdk

分享到: