微信分账时,xml格式错误解决方法
前两天做微信分账功能,遇到了xml错误,看着代码,怎么看怎么正确,可是,就是报错。
最后,退而求其次,换个方法,问题解决了。
1、首先,生成xml格式字符串
关键代码:
public function toXml($arr)
{
$xml = '<xml>';
$xml .= $this->array\_to\_xml($arr);
$xml .= '</xml>';
return $xml;
}
//array转xml
public function array\_to\_xml($arr) {
$xml = '';
foreach ($arr as $key => $val) {
if (is\_array($val)) {
$xml .= '<' . $key . '>' . $this->array\_to\_xml($val) . '</' . $key . '>';
} else {
$xml .= '<' . $key . '>' . $val . '</' . $key . '>';
}
}
return $xml;
}
2、将这段文字写入xml文件
3、读取这个xml文件。代码如下:
//1.设置分账账号
$receivers = array();
foreach ($profitSharingAccounts as $profitSharingAccount)
{
$tmp = array(
'type'=>$profitSharingAccount\['type'\],
'account'=>$profitSharingAccount\['account'\],
'amount'=>intval($profitSharingAccount\['amount'\]),
'description'=>$profitSharingAccount\['description'\],
);
$receivers\[\] = $tmp;
}
$receivers = json\_encode($receivers);
$totalCount = count($profitSharingOrders);
$successCount = 0;
$failCount = 0;
$now = time();
//2.生成签名
$postArr = array(
'appid'=>$this->wxConfig\['app\_id'\],
'mch\_id'=>$this->wxConfig\['mch\_id'\],
'nonce\_str'=>md5(time() . rand(1000, 9999)),
'transaction\_id'=>$profitSharingOrders\['transaction\_id'\],
'out\_order\_no'=>$profitSharingOrders\['out\_trade\_no'\],
'receivers'=>$receivers,
);
$sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig\['md5\_key'\]);
$postArr\['sign'\] = $sign;
//3.发送请求
$url = '<a href="https://api.mch.weixin.qq.com/secapi/pay/profitsharing" rel="noopener noreferrer" target="_blank">https://api.mch.weixin.qq.com/secapi/pay/profitsharing</a>';
$postXML = $this->toXml($postArr);
//为了适应xml格式,先保存到文件,再取出,这样xml格式就能适应了。
$filename = dirname(\_\_FILE\_\_).'/xml/subledger.xml';
file\_put\_contents($filename, $postXML);
$postXML = file\_get\_contents($filename);
最后,调用post方法
$helper = new Common\_util\_pub();
$ret = $helper->postXmlSSLCurl($postXML, $url);
postXmlSSLCurl方法代码:
/\*\*
\* 作用:使用证书,以post方式提交xml到对应的接口url
\*/
function postXmlSSLCurl($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 );
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl\_setopt ( $ch, CURLOPT\_SSLCERT, dirname(\_\_FILE\_\_).'/cacert/apiclient\_cert.pem' );
curl\_setopt ( $ch, CURLOPT\_SSLKEY, dirname(\_\_FILE\_\_).'/cacert/apiclient\_key.pem' );
//证书密码
curl\_setopt($ch, CURLOPT\_SSLCERTPASSWD, WxPayConf\_pub::KEY );
//post提交方式
curl\_setopt ( $ch, CURLOPT\_POST, true );
curl\_setopt ( $ch, CURLOPT\_POSTFIELDS, $xml );
//启用时会汇报所有的信息,存放在STDERR或指定的 CURLOPT\_STDERR 中。
curl\_setopt($ch, CURLOPT\_VERBOSE, '1');
$data = curl\_exec ( $ch );
//返回结果
if ($data) {
curl\_close ( $ch );
return $data;
} else {
$error = curl\_errno ( $ch );
echo "curl出错,错误码:$error" . "<br>";
echo "<a href='<a href="http://curl.haxx.se/libcurl/c/libcurl-errors.html" rel="noopener noreferrer" target="_blank">http://curl.haxx.se/libcurl/c/libcurl-errors.html</a>'>错误原因查询</a></br>";
curl\_close ( $ch );
return false;
}
}
其它代码,网上很多,就不贴出来了。
希望能够帮助到你!