记住用户名密码
class WeiXinPay { //----- [基本信息设置] ----- //微信公众号身份的唯一标识 protected $APPID = 'wx056xxxxxxxxa02';//填写您的appid。微信公众平台里的 protected $APPSECRET = '4c11xxxxx5451f6508a7c'; //受理商ID,身份标识 protected $MCHID = 155xxx1 ;//商户id //商户支付密钥Key protected $KEY = 'ASASDF542xxxxxWE45123ZX4C78F789'; //回调通知接口 protected $APPURL = 'https://wbstp.xxx.cn/xcxhome/payNotify'; //交易类型 protected $TRADETYPE = 'JSAPI'; //商品类型信息 protected $BODY = 'wx/book' ; //微信支付类的构造函数 function __construct($openid, $outTradeNo, $totalFee) { $this->openid = $openid; //用户唯一标识 $this->outTradeNo = $outTradeNo; //商户订单号 $this->totalFee = $totalFee; //总价 } //微信支付类向外暴露的支付接口 public function pay() { $result = $this->weixinapp(); return $result; } //对微信统下单接返回的支付相关 数据进行处理 private function weixinapp() { $unifiedorder = $this ->unifiedorder(); $parameters = array( 'appId' =>$this ->APPID, //小程序ID 'timeStamp'=> '' .time().'', //时间戳 'nonceStr' =>$this->createNoncestr(), //随机串 'package' => 'prepay_id=' . $unifiedorder['prepay_id'],//数据包 'signType' => 'MD5'//签名方式 ); $parameters['paySign']=$this->getSign($parameters); unset($parameters['appId']); return $parameters; } //请求微信统下单接口 private function unifiedorder() { $parameters = array( 'appid' => $this->APPID,//小程序id 'mch_id' => $this->MCHID,//商户id 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],//终端ip 'notify_url' =>$this->APPURL, //通知地址 'nonce_str'=> $this->createNoncestr(),//随机字符串 'out_trade_no' =>$this->outTradeNo,//商户订单编号 'total_fee' =>floatval($this->totalFee), //总金额 'openid' =>$this->openid,//用户openid 'trade_type' =>$this->TRADETYPE,//交易类型 'body' =>$this->BODY, //商品信息 ); $parameters['sign'] = $this->getSign($parameters); $xmlData = $this ->arrayToXml($parameters); $xml_result = $this->postXmlCurl($xmlData, 'https://api.mch.weixin.qq.com/pay/unifiedorder',60); $result = $this->xmlToArray($xml_result); //var_dump($result); return $result; } //数组转xml字符串方法 protected function arrayToXml($arr) { $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; } //xml转数组 protected function xmlToArray($xml) { $array_data = json_decode(json_encode(simplexml_load_string($xml,'SimpleXmlElement',LIBXML_NOCDATA)),true); return $array_data; } //发送xm1请求方法 private static function postXmlCurl($xml, $url, $second = 30) { $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch, CURLOPT_URL ,$url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验 //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串目输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); curl_setopt($ch, CURLOPT_TIMEOUT, 40); set_time_limit(0); //运行curl $data = curl_exec($ch); //var_dump($data); //返回结果 if ($data) { curl_close($ch); return $data; } else { $error = curl_error($ch); curl_close($ch); throw new Exception("curl出错错误码$error",500); } } //对要发送到微信统一下单接口的数据进行签名 protected function getSign($obj) { foreach ($obj as $k => $v){ $Parameters[$k] = $v; } //签名步骤一:按字典字排序参数 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //签名步骤二:在string后加入KEY $String = $String. "&key=" .$this->KEY; //签名步骤三: MD5加密 $String = md5($String); //签名步骤四:所有字符转为大写 $result_ = strtoupper($String); return $result_; } //排序并格式化参数方法,签名时需要使用 protected function formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap ); foreach ($paraMap as $k => $v){ if ($urlencode ){ $v = urlencode($v); } $buff .= $k . "=" .$v . "&"; } $reqPar = ''; if (strlen($buff) > 0){ $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; } protected function createNoncestr($length = 32){ $str = ''; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; $max = strlen($strPol) - 1; for ($i = 0; $i < $length; $i++) { $str .= $strPol[rand(0, $max)]; } return $str; } }
use think\facade\Log; class WeiXinRefund extends WeiXinPay { protected $sslCertPath = __DIR__. '/cert/apiclient_cert.pem';//正书路径 protected $sslKeyPath = __DIR__.'/cert/apiclient_key.pem';//证书路径 function __construct($openid, $transactionId, $totalFee, $outRefundNo, $refundFee) { //初始化退款类需要的变量 $this->openid = $openid; $this->transactionId = $transactionId; $this->totalFee = $totalFee; $this->outRefundNo = $outRefundNo; $this->refundFee = $refundFee; } public function refund() { //对外暴露的退款接口 $result = $this->wxRefundApi(); return $result; } private function wxRefundApi() { //通过微信api进行退款流程 $param = array( 'appid' => $this->APPID, 'mch_id' => $this->MCHID, 'nonce_str' => $this->createNoncestr(), 'out_refund_no' => $this->outRefundNo, 'transaction_id' => $this->transactionId, 'total_fee' => $this->totalFee, 'refund_fee' => $this->refundFee, ); $param['sign'] = $this->getsign($param); $xmlData = $this->arrayToXml($param); $xmlResult = $this->postXmlSSLCurl($xmlData, 'https://api.mch.weixin.qq.com/secapi/pay/refund'); $result = $this->xmlToArray($xmlResult); return $result; } //需要使用证书的请求 private function postXmlSSLCurl($xml, $url, $second=30) { $ch = curl_init(); //超时时间 curl_setopt ($ch, CURLOPT_TIMEOUT, $second); //这里设置代理,如果有的话 //curl setopt(Sch,CURLOPT PROXY, '8.8.8.8'); //curl setopt($ch,CURLOPT PROXYPORT, 8080); curl_setopt ($ch,CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE); //设header curl_setopt($ch, CURLOPT_HEADER,FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //设置证书 //使用证书: cert 与key分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch, CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch, CURLOPT_SSLCERT, $this->sslCertPath); //默认格式为PEM,可以注释 curl_setopt($ch, CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch, CURLOPT_SSLKEY, $this->sslKeyPath); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; }else { $error = curl_error($ch); Log::write( 'curl出错,错误内容:'.$error) ; curl_close($ch); return false; } } }
亲测运行可用,代码有待改进
目前有 0 条留言 其中:访客:0 条, 博主:0 条