<?php
namespace addons\gaga\library\cqrs\libs;
class WxpayTransfer
{
const API_URL = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
private $_appid;
private $_merchantid;
private $_key;
private $apiclient_cert;
private $apiclient_key;
private $debug = false;
public function __construct($config)
{
$this->_appid = $config['app_id'];
$this->_merchantid = $config['mch_id'];
$this->_key = $config['api_key'];
$this->apiclient_cert = ROOT_PATH . 'public' . DS . $config['apiclient_cert'];
$this->apiclient_key = ROOT_PATH . 'public' . DS . $config['apiclient_key'];
}
function transfer($data, $check_name = true)
{
if ($this->debug) {
return ['code' => 1, 'msg' => '测试转账'];
}
$webdata = array(
'mch_appid' => $this->_appid,
'mchid' => $this->_merchantid,
'nonce_str' => $this->getNonceStr(),
'partner_trade_no' => $data['order_sn'],
'openid' => $data['openid'],
'check_name' => 'NO_CHECK',
'amount' => $data['money'] * 100,
'desc' => $data['desc'] ?? '业务退款',
'spbill_create_ip' => get_client_ip(),
);
foreach ($webdata as $k => $v) {
$tarr[] = $k . '=' . $v;
}
sort($tarr);
$sign = implode($tarr, '&');
$sign .= '&key=' . $this->_key;
$webdata['sign'] = strtoupper(md5($sign));
$wget = $this->ArrToXml($webdata);
$res = $this->postData(self::API_URL, $wget);
write_log(['$webdata' => $webdata, '$res' => $res], 'tuikuan');
if (!$res) {
$this->log('转账失败:' . json_encode($webdata));
$this->log('失败原因:不能连接到服务器');
return array('code' => 0, 'msg' => "不能连接到服务器:" . json_encode($res, JSON_UNESCAPED_UNICODE));
}
$content = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
if (strval($content->return_code) == 'FAIL') {
$this->log('转账失败:' . json_encode($webdata));
$this->log('失败原因:' . strval($content->return_msg));
return array('code' => 0, 'msg' => strval($content->return_msg));
}
if (strval($content->result_code) == 'FAIL') {
$this->log('转账失败:' . json_encode($webdata));
$this->log('失败原因:' . strval($content->err_code_des));
return array('code' => 0, 'msg' => strval($content->err_code_des));
}
$rdata = array(
'mch_appid' => strval($content->mch_appid),
'mchid' => strval($content->mchid),
'device_info' => strval($content->device_info),
'nonce_str' => strval($content->nonce_str),
'result_code' => strval($content->result_code),
'partner_trade_no' => strval($content->partner_trade_no),
'payment_no' => strval($content->payment_no),
'payment_time' => strval($content->payment_time),
);
$this->log('转账成功:' . json_encode($webdata));
$this->log('成功数据:' . json_encode($rdata));
return array('code' => 1, 'data' => $rdata);
}
protected function ArrToXml($arr)
{
if (!is_array($arr) || count($arr) == 0) return '';
$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;
}
protected function postData($url, $postfields)
{
$ch = curl_init();
$params[CURLOPT_URL] = $url;
$params[CURLOPT_HEADER] = false;
$params[CURLOPT_RETURNTRANSFER] = true;
$params[CURLOPT_FOLLOWLOCATION] = true;
$params[CURLOPT_POST] = true;
$params[CURLOPT_POSTFIELDS] = $postfields;
$params[CURLOPT_SSL_VERIFYPEER] = false;
$params[CURLOPT_SSL_VERIFYHOST] = false;
$params[CURLOPT_SSLCERTTYPE] = 'PEM';
$params[CURLOPT_SSLCERT] = $this->apiclient_cert;
$params[CURLOPT_SSLKEYTYPE] = 'PEM';
$params[CURLOPT_SSLKEY] = $this->apiclient_key;
curl_setopt_array($ch, $params);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
protected function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
private function log($content)
{
}
}