/** * @param $log * @return js payment object */ public function payWeixin($log) { self::loadSettings(); $setting = C('PAY'); $pay = $setting[self::OPT_WEIXIN]; $a = new Account(); $account = $a->getAccount($pay['account']); $pay['appid'] = $account['appid']; $pay['secret'] = $account['secret']; $wOpt = array(); $m = new Member(); $fan = $m->fetchFan($log['uid'], $pay['account']); $package = array(); $package['appid'] = $pay['appid']; $package['mch_id'] = $pay['mchid']; $package['nonce_str'] = util_random(8); $package['body'] = $log['title']; $package['attach'] = $log['plid']; $package['out_trade_no'] = md5($log['plid']); $package['total_fee'] = $log['fee'] * 100; $package['spbill_create_ip'] = get_client_ip(); $package['time_start'] = date('YmdHis', TIMESTAMP); $package['time_expire'] = date('YmdHis', TIMESTAMP + 600); $package['notify_url'] = __HOST__ . U('wander/payment/weixin/t/notify'); $package['trade_type'] = 'JSAPI'; $package['openid'] = $fan['openid']; ksort($package, SORT_STRING); $string1 = ''; foreach ($package as $key => $v) { $string1 .= "{$key}={$v}&"; } $string1 .= "key={$pay['key']}"; $package['sign'] = strtoupper(md5($string1)); $dat = util_2xml($package); $response = Net::httpPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $dat); if (is_error($response)) { return $response; } $xml = '<?xml version="1.0" encoding="utf-8"?>' . $response; $dom = new \DOMDocument(); if (!$dom->loadXML($xml)) { return error(-1, 'error response'); } $xpath = new \DOMXPath($dom); if ($xpath->evaluate("string(//xml/return_code)") == 'FAIL') { return error(-2, $xpath->evaluate("string(//xml/return_msg)")); } if ($xpath->evaluate("string(//xml/result_code)") == 'FAIL') { return error(-3, $xpath->evaluate("string(//xml/err_code_des)")); } $prepayid = $xpath->evaluate("string(//xml/prepay_id)"); $wOpt['appId'] = $pay['appid']; $wOpt['timeStamp'] = TIMESTAMP; $wOpt['nonceStr'] = util_random(8); $wOpt['package'] = 'prepay_id=' . $prepayid; $wOpt['signType'] = 'MD5'; ksort($wOpt, SORT_STRING); $string = ''; foreach ($wOpt as $key => $v) { $string .= "{$key}={$v}&"; } $string .= "key={$pay['key']}"; $wOpt['paySign'] = strtoupper(md5($string)); return $wOpt; }
/** * 将一个数组转换为 XML 结构的字符串 * * @param array $arr 要转换的数组 * @param int $isRoot 节点层级, 1 为 Root. * @return string XML 结构的字符串 */ function util_2xml($arr, $isRoot = 1) { $s = $isRoot == 1 ? "<xml>" : ''; foreach ($arr as $tagname => $value) { if (is_numeric($tagname)) { $tagname = $value['TagName']; unset($value['TagName']); } if (!is_array($value)) { $s .= "<{$tagname}>" . (!is_numeric($value) ? '<![CDATA[' : '') . $value . (!is_numeric($value) ? ']]>' : '') . "</{$tagname}>"; } else { $s .= "<{$tagname}>" . util_2xml($value, $isRoot + 1) . "</{$tagname}>"; } } $s = preg_replace("/([-\v-\f-])+/", ' ', $s); return $isRoot == 1 ? $s . "</xml>" : $s; }