WxPay.Api.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. require_once IA_ROOT . "/addons/zh_jdgjb/cert/WxPay.Exception.php";
  3. require_once IA_ROOT . "/addons/zh_jdgjb/cert/WxPay.Data.php";
  4. /**
  5. *
  6. * 接口访问类,包含所有微信支付API列表的封装,类中方法为static方法,
  7. * 每个接口有默认超时时间(除提交被扫支付为10s,上报超时时间为1s外,其他均为6s)
  8. * @author widyhu
  9. *
  10. */
  11. class WxPayApi
  12. {
  13. /**
  14. *
  15. * 查询订单,WxPayOrderQuery中out_trade_no、transaction_id至少填一个
  16. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  17. * @param WxPayOrderQuery $inputObj
  18. * @param int $timeOut
  19. * @throws WxPayException
  20. * @return 成功时返回,其他抛异常
  21. */
  22. public static function orderQuery($inputObj, $timeOut = 6,$key)
  23. {
  24. $url = "https://api.mch.weixin.qq.com/pay/orderquery";
  25. //检测必填参数
  26. if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
  27. throw new WxPayException("订单查询接口中,out_trade_no、transaction_id至少填一个!");
  28. }
  29. $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
  30. $inputObj->SetSign($key);//签名
  31. $xml = $inputObj->ToXml();
  32. $startTimeStamp = self::getMillisecond();//请求开始时间
  33. $response = self::postXmlCurl($xml, $url, false, $timeOut,'1','2');
  34. $result = WxPayResults::Init($response);
  35. return $result;
  36. }
  37. /**
  38. *
  39. *退款接口
  40. *
  41. */
  42. public static function refund($inputObj, $timeOut = 6,$f1,$f2,$key)
  43. {
  44. global $_W,$_GPC;
  45. $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  46. //检测必填参数
  47. if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
  48. throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!");
  49. }else if(!$inputObj->IsOut_refund_noSet()){
  50. throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!");
  51. }else if(!$inputObj->IsTotal_feeSet()){
  52. throw new WxPayException("退款申请接口中,缺少必填参数total_fee!");
  53. }else if(!$inputObj->IsRefund_feeSet()){
  54. throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!");
  55. }else if(!$inputObj->IsOp_user_idSet()){
  56. throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!");
  57. }
  58. $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
  59. $inputObj->SetSign($key);//签名
  60. $xml = $inputObj->ToXml();
  61. $startTimeStamp = self::getMillisecond();//请求开始时间
  62. $response = self::postXmlCurl($xml, $url, true, $timeOut,$f1,$f2);
  63. $result = WxPayResults::Init($response);
  64. return $result;
  65. }
  66. /**
  67. *
  68. * 产生随机字符串,不长于32位
  69. * @param int $length
  70. * @return 产生的随机字符串
  71. */
  72. public static function getNonceStr($length = 32)
  73. {
  74. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  75. $str ="";
  76. for ( $i = 0; $i < $length; $i++ ) {
  77. $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  78. }
  79. return $str;
  80. }
  81. /**
  82. * 以post方式提交xml到对应的接口url
  83. *
  84. * @param string $xml 需要post的xml数据
  85. * @param string $url url
  86. * @param bool $useCert 是否需要证书,默认不需要
  87. * @param int $second url执行超时时间,默认30s
  88. * @throws WxPayException
  89. */
  90. private static function postXmlCurl($xml, $url, $useCert, $second = 30,$f1,$f2)
  91. {
  92. $ch = curl_init();
  93. //设置超时
  94. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  95. // //如果有配置代理这里就设置代理
  96. // if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
  97. // && WxPayConfig::CURL_PROXY_PORT != 0){
  98. // curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
  99. // curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
  100. // }
  101. curl_setopt($ch,CURLOPT_URL, $url);
  102. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  103. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验
  104. //设置header
  105. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  106. //要求结果为字符串且输出到屏幕上
  107. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  108. if($useCert == true){
  109. //设置证书
  110. //使用证书:cert 与 key 分别属于两个.pem文件
  111. curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
  112. curl_setopt($ch,CURLOPT_SSLCERT, $f1);
  113. curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
  114. curl_setopt($ch,CURLOPT_SSLKEY, $f2);
  115. }
  116. //post提交方式
  117. curl_setopt($ch, CURLOPT_POST, TRUE);
  118. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  119. //运行curl
  120. $data = curl_exec($ch);
  121. //返回结果
  122. if($data){
  123. curl_close($ch);
  124. return $data;
  125. } else {
  126. $error = curl_errno($ch);
  127. curl_close($ch);
  128. message("退款失败,CURL出错,错误码:".$error);exit;
  129. // throw new WxPayException("curl出错,错误码:$error");
  130. }
  131. }
  132. /**
  133. * 获取毫秒级别的时间戳
  134. */
  135. private static function getMillisecond()
  136. {
  137. //获取毫秒的时间戳
  138. $time = explode ( " ", microtime () );
  139. $time = $time[1] . ($time[0] * 1000);
  140. $time2 = explode( ".", $time );
  141. $time = $time2[0];
  142. return $time;
  143. }
  144. }