微信分账时,xml格式错误解决方法
发布于 4 年前 作者 kangxiulan 2156 次浏览 来自 分享
前两天做微信分账功能,遇到了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-&gt;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-&gt;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" . "&lt;br&gt;";

		echo "&lt;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>'&gt;错误原因查询&lt;/a&gt;&lt;/br&gt;";

		curl\_close ( $ch );

		return false;

	}

}

其它代码,网上很多,就不贴出来了。

希望能够帮助到你!
回到顶部