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

248 lines
11 KiB
PHTML

<?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';
}
}
6 years ago
async_curl($this->config->item('send_notify_url', 'wxpay'));
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);
}
async_curl($this->config->item('send_notify_url', 'wxpay'));
async_curl('https://www.mycht.cn/webht.php/apps/pay/alipaytradeservice/get_billfile');
/**
* 每月20号发送退款给财务
*/
if (date('d')==='20') {
async_curl('https://www.mycht.cn/webht.php/apps/pay/paymentservice/refund_finance_notify');
}
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';
$save_column['OPN_relatedId'] = $row['transaction_id'];
} 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_relatedId'] = '';
}
$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 query($target_account)
{
$GLOBALS['__WX_SITE_NAME__'] = $target_account;
$this->load->model('WxpayQueryContentBuilder', 'query_builder');
$this->query_builder->set_transaction_id($this->input->get_post('transaction_id'));
$this->load->library('Wxpay_call');
$result = $this->wxpay_call->queryorder($this->query_builder);
if ($result['status'] !== true) {
log_message('error',"get wxpay transaction failed. " . PHP_EOL . var_export($result, 1));
}
return $this->output->set_content_type('application/json')->set_output(json_encode($result));
}
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;
}
}