ThinkPHP V5.0 接入微信支付
微信支付接口
- 组装访问数组
1$data['body'] = '商城购买商品';//订单标题 2$data['out_trade_no'] = generate_rand_str(8, 0);//平台订单号(非小程序订单,自己平台生成的) 3$data['notify_url'] = $this->request->domain().'';//微信支付回调地址,不带参数 4$data['total_fee'] = $price;//价格,单位(元) 5$data['openid'] = $this->user['openid'];//用户openid 6$res = $this->unifiedorder($config['wechat_appid'],$config['wechat_mch_id'],$config['wechat_key'],$data);//访问统一下单
- 统一下单
1/** 2 * 统一下单方法 3 * $appid 小程序id 4 * $mchid 商户号 5 * $key 微信支付key 6 * $data 信息数组 7 * */ 8public function unifiedorder($appid,$mch_id,$key,$data) 9{ 10 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//微信统一下单访问url 11 $parameters = array( 12 'appid' => $appid, //小程序ID 13 'mch_id' => $mch_id, //商户号 14 'nonce_str' => generate_rand_str(8, 0), //随机字符串 15 'body' => $data['body'], //商品描述 16 'out_trade_no' => $data['out_trade_no'], //商户订单号 17 'total_fee' => floatval($data['total_fee'] * 100), //总金额 单位 分 18 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], //终端IP 19 'notify_url' => $data['notify_url'].'index.php/callback', //通知地址 确保外网能正常访问 20 'openid' => $data['openid'], //用户id 21 'trade_type' => 'JSAPI'//交易类型//要是返回该产品权限未开通请在产品中心开通jsAPi他包含的小程序支付 22 ); 23 //统一下单签名 24 $parameters['sign'] = $this->getSign($parameters,$key); 25 $xmlData = $this->arrayToXml($parameters); 26 $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60)); 27 return $return; 28}
生成随机数
1/** 2 * 生成随机字符串 3 * @param int $length 生成长度 4 * @param int $type 生成类型:0-小写字母+数字,1-小写字母,2-大写字母,3-数字,4-小写+大写字母,5-小写+大写+数字 5 * @return string 6 */ 7function generate_rand_str($length = 8, $type = 0) { 8 $a = 'abcdefghijklmnopqrstuvwxyz'; 9 $A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 10 $n = '0123456789'; 11 12 switch ($type) { 13 case 1: $chars = $a; break; 14 case 2: $chars = $A; break; 15 case 3: $chars = $n; break; 16 case 4: $chars = $a.$A; break; 17 case 5: $chars = $a.$A.$n; break; 18 default: $chars = $a.$n; 19 } 20 21 $str = ''; 22 for ($i = 0; $i < $length; $i++) { 23 $str .= $chars[ mt_rand(0, strlen($chars) - 1) ]; 24 } 25 return $str; 26}
生成签名
1/** 2 * 生成签名 3 * @param array $Obj 访问数组 4 * @param string $key 商户key 5 * @return string 6 */ 7public function getSign($Obj,$key) { 8 foreach ($Obj as $k => $v) { 9 $Parameters[$k] = $v; 10 } 11 //签名步骤一:按字典序排序参数 12 ksort($Parameters); 13 $String = $this->formatBizQueryParaMap($Parameters, false); 14 //签名步骤二:在string后加入KEY 15 $String = $String . "&key=" . $key; 16 //签名步骤三:MD5加密 17 $String = md5($String); 18 //签名步骤四:所有字符转为大写 19 $result_ = strtoupper($String); 20 return $result_; 21}
格式化参数,签名过程需要使用
1//作用:格式化参数,签名过程需要使用 2public function formatBizQueryParaMap($paraMap, $urlencode) { 3 $buff = ""; 4 ksort($paraMap); 5 foreach ($paraMap as $k => $v) { 6 if ($urlencode) { 7 $v = urlencode($v); 8 } 9 $buff .= $k . "=" . $v . "&"; 10 } 11 $reqPar = array(); 12 if (strlen($buff) > 0) { 13 $reqPar = substr($buff, 0, strlen($buff) - 1); 14 } 15 return $reqPar; 16}
数组转换成xml
1//数组转换成xml 2public function arrayToXml($arr) { 3 $xml = "<root>"; 4 foreach ($arr as $key => $val) { 5 if (is_array($val)) { 6 $xml .= "<" . $key . ">" . $this->arrayToXml($val) . "</" . $key . ">"; 7 } else { 8 $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; 9 } 10 } 11 $xml .= "</root>"; 12 return $xml; 13}
xml格式访问
1public function postXmlCurl($xml, $url, $second = 30) 2{ 3 $ch = curl_init(); 4 //设置超时 5 curl_setopt($ch, CURLOPT_TIMEOUT, $second); 6 curl_setopt($ch, CURLOPT_URL, $url); 7 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 8 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验 9 //设置header 10 curl_setopt($ch, CURLOPT_HEADER, FALSE); 11 //要求结果为字符串且输出到屏幕上 12 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 13 //post提交方式 14 curl_setopt($ch, CURLOPT_POST, TRUE); 15 curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 16 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); 17 curl_setopt($ch, CURLOPT_TIMEOUT, 40); 18 set_time_limit(0); 19 //运行curl 20 $data = curl_exec($ch); 21 //返回结果 22 curl_close($ch); 23 return $data; 24}
将xml转换成数组
1 public function xmlToArray($xml) { 2 //禁止引用外部xml实体 3 libxml_disable_entity_loader(true); 4 $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); 5 $val = json_decode(json_encode($xmlstring), true); 6 return $val; 7}
微信支付成功回调接口
1//微信支付回调 2public function callback() 3{ 4 $postXml = file_get_contents("php://input");//获取回调的xml格式 5 $attr = $this->xmlToArray($postXml);//将获取的xml转为数组 6 if($attr['result_code'] == 'SUCCESS'){ 7 //在此书写支付成功后的逻辑 8 return true; 9 }else{ 10 //在此书写支付失败后的逻辑 11 return false; 12 } 13}
