You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
information-system/webht/third_party/pay/controllers/WxpayService.php

224 lines
9.9 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
global $__WX_SITE_NAME__;
class WxpayService extends CI_Controller {
protected $wx_site_config;
public function __construct(){
parent::__construct();
bcscale(2);
$this->load->helper('payment');
$this->config->load('wxpay', true);
$this->load->model('Online_payment_note_model', 'note_model');
$this->load->model('Online_payment_account_model', 'account_model');
}
public function index()
{
}
public function notify($site='cht')
{
error_reporting(0);
// log_message('error','notify begin ----');
$response['return_code'] = 'FAIL';
$response['return_msg'] = '';
$GLOBALS['__WX_SITE_NAME__'] = $site;
$this->wx_site_config = $this->config->item($GLOBALS['__WX_SITE_NAME__'], 'wxpay');
$raw_post_data = file_get_contents('php://input');
// log_message('error',var_export($raw_post_data, 1));
if (empty($raw_post_data) ){
# 如果没有数据,直接返回失败
return $this->response_to_wx($response);
}
//获取通知的数据
$xml = $raw_post_data;
$xml_arr = from_xml($xml);
// log_message('error',var_export($xml_arr, 1));
if ($this->check_sign($xml_arr) !== true) {
return $this->response_to_wx($response);
}
// 入库保存异步通知
if ( strval($xml_arr['result_code']) !== "SUCCESS" ) {
$response['return_code'] = 'SUCCESS';
$response['return_msg'] = 'OK';
} else {
$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'], str_replace("CNY", "RMB", strtoupper($xml_arr['fee_type'])), $this->config->item('method_code', 'wxpay'));
$save_column = array();
$save_column['OPN_transactionId'] = $xml_arr['transaction_id'];
$save_column['OPN_orderId'] = $xml_arr['out_trade_no'];
$save_column['OPN_rawOrderId'] = $xml_arr['out_trade_no'];
$save_column['OPN_invoiceId'] = $xml_arr['out_trade_no'];
$save_column['OPN_subject'] = $xml_arr['attach'];
$save_column['OPN_currency'] = $xml_arr['fee_type'];
$save_column['OPN_orderAmount'] = $xml_arr['total_fee'];
$save_column['OPN_payAmount'] = $xml_arr['total_fee'];
$save_column['OPN_transactionResult'] = 'completed';
$save_column['OPN_resultCode'] = $xml_arr['result_code'];
$save_column['OPN_resultMsg'] = isset($xml_arr['return_msg']) ? $xml_arr['return_msg'] : $xml_arr['result_code'];
$save_column['OPN_errCode'] = isset($xml_arr['err_code']) ? $xml_arr['err_code'] : NULL;
$save_column['OPN_errMsg'] = isset($xml_arr['err_code_des']) ? $xml_arr['err_code_des'] : NULL;
$save_column['OPN_acquiringTime'] = date('Y-m-d H:i:s',strtotime($xml_arr['time_end']));
$save_column['OPN_completeTime'] = date('Y-m-d H:i:s',strtotime($xml_arr['time_end']));
$save_column['OPN_remark'] = $xml_arr['attach'];
$save_column['OPN_payerLogId'] = $xml_arr['openid'];
$save_column['OPN_payerStatus'] = $xml_arr['is_subscribe']==='Y' ? "subscribed" : NULL;
$save_column['OPN_fundSource'] = $site;
$save_column['OPN_entryAmountCNY'] = floatval($ssje);
$save_column['OPN_rawContent'] = json_encode($xml_arr);
$save_column['OPN_noticeTime'] = date('Y-m-d H:i:s');
// $save_column['OPN_noticeType'] = intval($xml_arr['total_fee'])>0 ? 'pay' : 'refund';
$save_column['OPN_noticeType'] = 'pay';
$save_column['OPN_noticeSendStatus'] = 'unsend';
$save_column['OPN_noticeSendTime'] = NULL;
$save_column['OPN_accountMethod'] = $this->config->item('method_code', 'wxpay');
if ( $this->note_model->insert_note($save_column) ) {
$response['return_code'] = 'SUCCESS';
$response['return_msg'] = 'OK';
}
}
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'] = $target_account;
$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)
{
$response_body = to_xml($response_arr);
echo $response_body;
}
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(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);
// log_message('error',$result);
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;
}
}