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'; } } 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'); async_curl('https://www.mycht.cn/download_statement/download_files.php'); // iPaylinks日账单 /** * 每月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 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; } }