wxpay 下载账单存入note

feature/pay
lyt 6 years ago
parent 176d1313fd
commit 67b67e0cad

@ -7,6 +7,7 @@ $config["method_code"] = 15016;
/*! /*!
* 各账号的设置 * 各账号的设置
*/ */
$config['all_account'] = "cht,trippest";
// test // test
$config['test']["notify_url"] = "https://www.mycht.cn/webht.php/apps/pay/wxpayservice/notify/test"; $config['test']["notify_url"] = "https://www.mycht.cn/webht.php/apps/pay/wxpayservice/notify/test";
$config['test']["app_id"] = "wx426b3015555a46be"; $config['test']["app_id"] = "wx426b3015555a46be";

@ -24,7 +24,7 @@ class WxpayService extends CI_Controller {
public function notify($site='cht') public function notify($site='cht')
{ {
error_reporting(0); error_reporting(0);
log_message('error','notify begin ----'); // log_message('error','notify begin ----');
$response['return_code'] = 'FAIL'; $response['return_code'] = 'FAIL';
$response['return_msg'] = ''; $response['return_msg'] = '';
$GLOBALS['__WX_SITE_NAME__'] = $site; $GLOBALS['__WX_SITE_NAME__'] = $site;
@ -48,7 +48,7 @@ log_message('error','notify begin ----');
$response['return_msg'] = 'OK'; $response['return_msg'] = 'OK';
} else { } else {
$xml_arr['total_fee'] = bcdiv($xml_arr['total_fee'], $this->config->item('currency_unit', 'wxpay')); $xml_arr['total_fee'] = bcdiv($xml_arr['total_fee'], $this->config->item('currency_unit', 'wxpay'));
$ssje = $this->account_model->get_ssje($xml_arr['total_fee'], $xml_arr['fee_type'], $this->config->item('currency_unit', 'wxpay')); $ssje = $this->account_model->get_ssje($xml_arr['total_fee'], str_replace("CNY", "RMB", strtoupper($xml_arr['fee_type'])), $this->config->item('method_code', 'wxpay'));
$save_column = array(); $save_column = array();
$save_column['OPN_transactionId'] = $xml_arr['transaction_id']; $save_column['OPN_transactionId'] = $xml_arr['transaction_id'];
$save_column['OPN_orderId'] = $xml_arr['out_trade_no']; $save_column['OPN_orderId'] = $xml_arr['out_trade_no'];
@ -85,12 +85,78 @@ log_message('error','notify begin ----');
return $this->response_to_wx($response); return $this->response_to_wx($response);
} }
public function download_all_bill()
{
$all_account = explode(",", $this->config->item('all_account', 'wxpay'));
foreach ($all_account as $account) {
$this->download_bill($account);
}
return;
}
public function download_bill($target_account)
{
$GLOBALS['__WX_SITE_NAME__'] = $target_account;
$bill_date = $this->input->get_post("date");
$bill_date = $bill_date ? $bill_date : date("Ymd", strtotime("-1 day"));
$bill_type = 'ALL';
$this->load->model('WxpayQueryContentBuilder', 'query_builder');
$this->query_builder->set_bill_date($bill_date);
$this->query_builder->set_bill_type($bill_type);
$this->load->library('Wxpay_call');
$result = $this->wxpay_call->get_bill_data($this->query_builder);
if ($result['status'] !== true) {
log_message('error',"get wxpay bill failed. $target_account $bill_date");
}
foreach ($result['data'] as $key => $row) {
$save_column = array();
$save_column['OPN_accountMethod'] = $this->config->item('method_code', 'wxpay');
if ($row['refund_id'] != '0') {
// 退款
$ssje = $this->account_model->get_ssje($row['settlement_refund_fee'], str_replace("CNY", "RMB", strtoupper($row['currency_type'])), $save_column['OPN_accountMethod']);
$save_column['OPN_transactionId'] = $row['refund_id'];
$save_column['OPN_orderAmount'] = "-" . $row['settlement_refund_fee'];
$save_column['OPN_payAmount'] = "-" . $row['settlement_refund_fee'];
$save_column['OPN_resultCode'] = $row['refund_status'];
$save_column['OPN_resultMsg'] = $row['refund_status'];
$save_column['OPN_entryAmountCNY'] = floatval("-" . $ssje);
$save_column['OPN_noticeType'] = 'refund';
} else {
// 收款
$ssje = $this->account_model->get_ssje($row['settlement_total_fee'], str_replace("CNY", "RMB", strtoupper($row['currency_type'])), $save_column['OPN_accountMethod']);
$save_column['OPN_transactionId'] = $row['transaction_id'];
$save_column['OPN_orderAmount'] = $row['settlement_total_fee'];
$save_column['OPN_payAmount'] = $row['settlement_total_fee'];
$save_column['OPN_resultCode'] = $row['trade_state'];
$save_column['OPN_resultMsg'] = $row['trade_state'];
$save_column['OPN_entryAmountCNY'] = floatval($ssje);
$save_column['OPN_noticeType'] = 'pay';
}
$save_column['OPN_noticeSendStatus'] = 'unsend';
$save_column['OPn_transactionResult'] = 'completed';
$save_column['OPN_orderId'] = $row['out_trade_no'];
$save_column['OPN_rawOrderId'] = $row['out_trade_no'];
$save_column['OPN_invoiceId'] = $row['out_trade_no'];
$save_column['OPN_subject'] = $row['item_name'];
$save_column['OPN_currency'] = $row['currency_type'];
$save_column['OPN_acquiringTime'] = date('Y-m-d H:i:s',strtotime($row['complete_time']));
$save_column['OPN_completeTime'] = date('Y-m-d H:i:s',strtotime($row['complete_time']));
$save_column['OPN_remark'] = $row['attach'];
$save_column['OPN_payerLogId'] = $row['openid'];
$save_column['OPN_fundSource'] = $row['trade_type'] . "-" .$row['bank_type'];
$save_column['OPN_rawContent'] = json_encode($row);
$save_column['OPN_noticeTime'] = date('Y-m-d H:i:s');
$this->note_model->insert_note($save_column) ;
}
return;
}
public function response_to_wx($response_arr) public function response_to_wx($response_arr)
{ {
$response_body = to_xml($response_arr); $response_body = to_xml($response_arr);
// log_message('error',var_export($response_body, 1));
echo $response_body; echo $response_body;
# exit(); // end
} }
public function check_sign($xml_arr) public function check_sign($xml_arr)

@ -0,0 +1,282 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Wxpay_call
{
protected $ci;
private $api_info_arr = array();
public function __construct()
{
$this->ci =& get_instance();
$this->ci->load->helper('payment');
$this->ci->config->load('wxpay', true);
// $this->ci->load->model('WxpayQueryContentBuilder', 'query_builder');
}
private function init_api()
{
$this->wx_site_config = $this->ci->config->item($GLOBALS['__WX_SITE_NAME__'], 'wxpay');
$this->api_info_arr['appid'] = $this->wx_site_config['app_id'];
$this->api_info_arr['mch_id'] = $this->wx_site_config['mch_id'];
$this->api_info_arr['key'] = $this->wx_site_config['key'];
$this->api_info_arr['app_secret'] = $this->wx_site_config['app_secret'];
}
/**
* 下载对账单WxPayDownloadBill中bill_date为必填参数
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayDownloadBill $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public function get_bill_data($query_content)
{
$ret = array('status'=>false, 'data'=>array());
$this->init_api();
// return false;
$url = "https://api.mch.weixin.qq.com/pay/downloadbill";
$query_content_input = $query_content->getBizContent(true);
//检测必填参数
if(!$query_content_input['bill_date']) {
throw new WxPayException("对账单接口中缺少必填参数bill_date");
}
$this->api_info_arr['nonce_str'] = ($this->get_nonce_str());//随机字符串
$this->api_info_arr['sign'] = $this->make_sign(array_merge($this->api_info_arr, $query_content_input));//签名
$xml = to_xml(array_merge($this->api_info_arr, $query_content_input));
$response = $this->post_xml_curl($this->api_info_arr, $xml, $url, 6);
if(substr($response, 0 , 5) == "<xml>"){
log_message('error',"Wxpay bill error \r\n" . var_export($response, 1));
return $ret;
}
$ret['status'] = true;
$response_arr = explode("\n",$response);
$data_title = $this->bill_data_title();
for ($i=1; $i < count($response_arr)-1; $i++) {
if (empty($response_arr[$i])) {
continue;
}
$row = explode(",", $response_arr[$i]);
$row_arr = array();
foreach ($data_title as $key => $title) {
if ( ! isset($row[$key])) {
continue;
}
$row_arr[$title] = str_replace("`","",trim($row[$key]));
}
!empty($row_arr['trade_type']) ? $ret['data'][] = $row_arr : false;
}
return $ret;
}
/*!
* @Author: LYT
* @Date: 2019-06-18 15:23:15
* @Desc: 账单数据的格式
* 交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注
*/
private function bill_data_title()
{
return array(
"complete_time", // 交易时间
"app_id", // 公众账号ID
"mch_id", // 商户号
"special_mch_id", // 特约商户号
"device_info", // 设备号
"transaction_id", // 微信订单号
"out_trade_no", // 商户订单号
"openid", // 用户标识
"trade_type", // 交易类型
"trade_state", // 交易状态
"bank_type", // 付款银行
"currency_type", // 货币种类
"settlement_total_fee", // 应结订单金额
"coupon_fee", // 代金券金额
"refund_id", // 微信退款单号
"out_refund_id",// 商户退款单号
"settlement_refund_fee", // 退款金额
"refund_coupon_fee", // 充值券退款金额
"refund_type", // 退款类型
"refund_status", // 退款状态
"item_name", // 商品名称
"attach", // 商户数据包
"wxpay_fee", // 手续费
"rate", // 费率
"total_fee", // 订单金额
"call_refund_fee", // 申请退款金额
"rate_memo" // 费率备注
);
}
/**
* 以post方式提交xml到对应的接口url
*
* @param WxPayConfigInterface $config 配置对象
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second url执行超时时间默认30s
* @throws WxPayException
*/
private function post_xml_curl($config, $xml, $url, $second = 30)
{
$ch = curl_init();
$curlVersion = curl_version();
$ua = "WXPaySDK/3.0.9 (".PHP_OS.") PHP/".PHP_VERSION." CURL/".$curlVersion['version']." "
.$config['mch_id'];
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch,CURLOPT_URL, $url);
// curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
// curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
if(stripos($url,"https://")!==FALSE){
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
} else {
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
}
curl_setopt($ch,CURLOPT_USERAGENT, $ua);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
log_message('error',"curl出错错误码:$error " . curl_error($ch));
}
}
public function check_sign($xml_arr)
{
if ( ! array_key_exists('sign', $xml_arr)) {
log_message('error','Wxpay notify error: no sign.');
return false;
}
if ($this->make_sign($xml_arr) !== $xml_arr['sign']) {
log_message('error','Wxpay notify error: sign.' . $this->make_sign($xml_arr));
return false;
}
if ($this->wx_site_config['app_id'] !== $xml_arr['appid']) {
log_message('error','Wxpay notify error: appid.');
return false;
}
if ($this->wx_site_config['mch_id'] !== $xml_arr['mch_id']) {
log_message('error','Wxpay notify error: mch_id.');
return false;
}
return true;
}
public function make_sign($xml_arr, $needSignType = false)
{
//签名步骤一:按字典序排序参数
ksort($xml_arr);
$string = $this->to_url_params($xml_arr);
//签名步骤二在string后加入KEY
$string = $string . "&key=" . $this->wx_site_config['key'];
//签名步骤三MD5加密或者HMAC-SHA256
if(!isset($xml_arr['sign']) || strlen($xml_arr['sign']) <= 32){
//如果签名小于等于32个,则使用md5验证
$string = md5($string);
} else {
//是用sha256校验
$string = hash_hmac("sha256", $string , $this->wx_site_config['key']);
}
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 格式化参数格式化成url参数
*/
public function to_url_params($xml_arr)
{
$buff = "";
foreach ($xml_arr as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 产生随机字符串不长于32位
* @param int $length
* @return 产生的随机字符串
*/
public static function get_nonce_str($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
protected function curl($url, $postFields = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$postBodyString = "";
if (is_array($postFields) && 0 < count($postFields)) {
foreach ($postFields as $k => $v) {
if ("@" != substr($v, 0, 1)) //判断是不是文件上传
{
$postBodyString .= "$k=" . urlencode($this->characet($v, "UTF-8")) . "&";
}
}
unset($k, $v);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1));
}
$headers = array('content-type: application/x-www-form-urlencoded;charset=UTF-8');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$reponse = curl_exec($ch);
if (curl_errno($ch)) {
log_message('error', " iPayLinks curl error code: ".curl_error($ch)."; curl postBodyString: ".substr($postBodyString, 0, -1));
} else {
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode) {
log_message('error', " iPayLinks Request html Status Code: ".$httpStatusCode."; curl postBodyString: ".substr($postBodyString, 0, -1));
}
}
curl_close($ch);
return $reponse;
}
}
/* End of file Wxpay_call.php */

@ -17,6 +17,7 @@ class Online_payment_account_model extends CI_Model {
$sql = "SELECT dbo.GetSSJEFromSQJE(?, ?, ?) as ssje"; $sql = "SELECT dbo.GetSSJEFromSQJE(?, ?, ?) as ssje";
$query = $this->HT->query($sql,array($code, $currency, $amount)); $query = $this->HT->query($sql,array($code, $currency, $amount));
$result = $query->result(); $result = $query->result();
if ( ! empty($result)) { if ( ! empty($result)) {
return $result[0]->ssje; return $result[0]->ssje;
} }

@ -0,0 +1,56 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class WxpayQueryContentBuilder extends CI_Model
{
private $appid; // 微信分配的公众账号ID
private $mch_id; // 微信支付分配的商户号
private $nonce_str; // 随机字符串不长于32位。推荐随机数生成算法
private $sign; // 签名,详见签名生成算法
private $bill_date; // 下载对账单的日期格式20140603
private $bill_type;
/*
ALL默认值返回当日所有订单信息不含充值退款订单
SUCCESS返回当日成功支付的订单不含充值退款订单
REFUND返回当日退款订单不含充值退款订单
RECHARGE_REFUND返回当日充值退款订单
*/
private $tar_type; // 非必传参数固定值GZIP返回格式为.gzip的压缩包账单。不传则默认为数据流形式。
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent($arr=false)
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr); // 5.4增加的常量 JSON_UNESCAPED_UNICODE
}
$ret = ($arr===false) ? $this->bizContent : $this->bizContentarr ;
return $ret;
}
public function set_bill_date($bill_date)
{
$this->bill_date = $bill_date;
$this->bizContentarr['bill_date'] = $bill_date;
}
public function set_bill_type($bill_type)
{
$this->bill_type = $bill_type;
$this->bizContentarr['bill_type'] = $bill_type;
}
public function set_tar_type($tar_type)
{
$this->tar_type = $tar_type;
$this->bizContentarr['tar_type'] = $tar_type;
}
}
/* End of file WxpayQueryContentBuilder.php */
?>
Loading…
Cancel
Save