From 37bfed48ef9df263dfa0583e23f6917fc542d76b Mon Sep 17 00:00:00 2001 From: lyt Date: Fri, 21 Jun 2019 10:05:14 +0800 Subject: [PATCH] =?UTF-8?q?wxpay=20=E4=B8=8B=E8=BD=BD=E8=B4=A6=E5=8D=95;?= =?UTF-8?q?=20=E4=B8=8D=E5=8F=91=E9=80=81=E9=82=AE=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pay/controllers/PaymentService.php | 163 ++++++++++++++---- .../pay/controllers/WxpayService.php | 5 +- .../pay/helpers/payment_helper.php | 2 + .../models/Online_payment_account_model.php | 73 +++++++- 4 files changed, 201 insertions(+), 42 deletions(-) diff --git a/webht/third_party/pay/controllers/PaymentService.php b/webht/third_party/pay/controllers/PaymentService.php index 01bf18c2..4620f95c 100644 --- a/webht/third_party/pay/controllers/PaymentService.php +++ b/webht/third_party/pay/controllers/PaymentService.php @@ -6,6 +6,7 @@ class PaymentService extends CI_Controller { public function __construct(){ parent::__construct(); bcscale(2); + mb_regex_encoding("UTF-8"); $this->load->helper('payment'); $this->config->load('wxpay', true); $this->config->load('paypal', true); @@ -54,6 +55,7 @@ class PaymentService extends CI_Controller { public function send_notify($opn_id=NULL, $old_ssje=NULL) { + ignore_user_abort(true); log_message('error','send_notify begin ----'); // exit(); $data = array(); @@ -64,7 +66,7 @@ log_message('error','send_notify begin ----'); } // 待处理的 if (empty($data['unsend_list'])) { - $data['unsend_list'] = $this->note_model->unsend_note(10); + $data['unsend_list'] = $this->note_model->unsend_note(20); } //没有未处理的数据再查找处理失败的数据 if (empty($data['unsend_list'])) { @@ -73,18 +75,23 @@ log_message('error','send_notify begin ----'); // 开始处理 foreach ($data['unsend_list'] as $key => $item) { // 只处理完成状态 - if ($item->OPN_transactionResult != 'completed') { + if (mb_strtolower($item->OPN_transactionResult) !== 'completed') { continue; } - if ($item->OPN_noticeType == 'Refunded') { - // 退款处理 - continue ; + $is_refund = false; + $ht_memo = '交易号(自动录入):' . $item->OPN_transactionId; + if (mb_strtolower($item->OPN_noticeType) == 'refund') { + $is_refund = true; + $ht_memo = '(自动)退款号:' . $item->OPN_transactionId . "\n. "; + // todo: + // $ht_memo .= '原交易号:' . $parent_dealId; + // continue ; } // 提取订单号 - $orderid_info = analysis_orderid($item->OPN_orderId); // 先用已设置过的 + $orderid_info = analysis_orderid($item->OPN_orderId.'_B'); // 先用已设置过的 if (empty($orderid_info)) { - $orderid_info = $this->method_analysis_orderid($item->OPN_accountMethod, $item->OPN_rawContent); + $orderid_info = $this->method_analysis_orderid($item); if (empty($orderid_info)) { $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'sendfail'); continue; @@ -96,17 +103,20 @@ log_message('error','send_notify begin ----'); $this->note_model->set_invoice($item->OPN_SN, $orderid_info->orderid . '_' . $orderid_info->ordertype); // APP自动出票的收款 跳过 + // todo: 检测APP收款是否存在 if ($orderid_info->ordertype === 'A' && $item->OPN_noticeType === 'pay') { - $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'closed'); - continue; + // $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'closed'); + // continue; } // 开始查找订单和录入 $handpick = empty($opn_id) ? false : true; - $advisor_info = $this->account_model->get_order($orderid_info->orderid, false, $orderid_info->ordertype, $handpick); - $ssje = $this->account_model->get_ssje($item->OPN_orderAmount, mb_strtoupper($item->OPN_currency), $item->OPN_accountMethod); + $advisor_info = $this->account_model->get_order($orderid_info->orderid, true, $orderid_info->ordertype, $handpick); + // $ssje = $this->account_model->get_ssje($item->OPN_orderAmount, mb_strtoupper($item->OPN_currency), $item->OPN_accountMethod); + $ssje = $item->OPN_entryAmountCNY; $ssje = $old_ssje===NULL ? $ssje : $old_ssje; - $ht_memo = '交易号(自动录入):' . $item->OPN_transactionId; + $currencyCode = str_replace("CNY", "RMB", trim(mb_strtoupper($item->OPN_currency))); + $currencyCode = mb_strtoupper(trim($currencyCode)); if ( empty($advisor_info)) { // record fail $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'sendfail'); @@ -116,6 +126,7 @@ log_message('error','send_notify begin ----'); $update_note_column = array(); if ($advisor_info->order_type == 0) { /* 商务订单 */ + // todo: 检测收/退款是否存在 if (substr($advisor_info->COLI_WebCode, 0, 6) == 'CHTAPP') { /* APP */ $this->account_model->add_account_info_forAPP( @@ -124,7 +135,7 @@ log_message('error','send_notify begin ----'); $advisor_info->COLI_ID, $item->OPN_orderAmount, $item->OPN_completeTime, - mb_strtoupper($item->OPN_currency), + $currencyCode, $ssje, $item->OPN_completeTime, $item->OPN_completeTime, @@ -134,7 +145,8 @@ log_message('error','send_notify begin ----'); $item->OPN_transactionId, $ht_memo ); - if ($advisor_info->COLI_WebCode == 'CHTAPP' && $advisor_info->COLI_State == 11) { + if ($advisor_info->COLI_WebCode == 'CHTAPP' && $advisor_info->COLI_State == 11 + && false===$is_refund) { //只修改APP组的订单状态,并且订单进度是我的订单 $this->account_model->update_biz_coli_state($COLI_SN, 8); //把订单状态改为已付款 $this->account_model->insert_biz_order_log($COLI_SN, 'BS8'); @@ -142,9 +154,13 @@ log_message('error','send_notify begin ----'); } else { /* 其他商务订单 */ // 第一次录入收款记录时变更状态,记录日志 - if (false == $this->account_model->if_biz_gai_exists($item->OPN_transactionId) ) { + if (false == $this->account_model->if_biz_gai_exists($item->OPN_transactionId) + && false===$is_refund + ) { $this->account_model->update_biz_coli_state($COLI_SN, 13); $this->account_model->insert_biz_order_log($COLI_SN, 'BS13'); + } else { + $this->account_model->insert_biz_order_log($COLI_SN, 'Refunded'); } $this->account_model->add_account_info( $COLI_SN, @@ -152,7 +168,7 @@ log_message('error','send_notify begin ----'); $advisor_info->COLI_ID, $item->OPN_orderAmount, $item->OPN_completeTime, - mb_strtoupper($item->OPN_currency), + $currencyCode, $ssje, $item->OPN_completeTime, $item->OPN_completeTime, @@ -176,7 +192,7 @@ log_message('error','send_notify begin ----'); $item->OPN_accountMethod, $item->OPN_orderAmount, $item->OPN_completeTime, - mb_strtoupper($item->OPN_currency), + $currencyCode, $ssje, $item->OPN_completeTime, $item->OPN_completeTime, @@ -186,10 +202,12 @@ log_message('error','send_notify begin ----'); $item->OPN_transactionId, $ht_memo ); - //添加汉特的订单提醒 - $this->account_model->update_coli_introduction($COLI_SN, '已支付 ' . mb_strtoupper($item->OPN_currency) . $item->OPN_orderAmount); - // 添加HT任务 - $this->account_model->exec_addToTask($gai_sn); + if ($is_refund === false) { + //添加汉特的订单提醒 + $this->account_model->update_coli_introduction($COLI_SN, '已支付 ' . $currencyCode . $item->OPN_orderAmount); + // 收款:添加HT任务 + $this->account_model->exec_addToTask($gai_sn); + } // 更新note $update_note_column['OPN_accountType'] = 'B'; $update_note_column['OPN_accountStatus'] = 'recorded'; @@ -210,20 +228,26 @@ log_message('error','send_notify begin ----'); } //添加邮件发送记录 //给外联发送通知邮件 - $fromName = !empty($item->OPN_payerName) ? $item->OPN_payerName : ''; - $fromEmail = !empty($item->OPN_payerEmail) ? $item->OPN_payerEmail : ''; - $toName = !empty($opi_firstname) ? $opi_firstname : ''; - $toEmail = !empty($opi_email) ? $opi_email : ''; - $subject = $orderid_info->orderid . '_' . $orderid_info->ordertype . ' / ' . $item->OPN_orderAmount . $item->OPN_currency . ' / ' . $fromName; - $body = $this->load->view('mail_advisor', $item, true); //$item->pn_memo; - $M_RelatedInfo = $item->OPN_SN; - $M_AddTime = $item->OPN_completeTime; - $M_State = 0; - $this->account_model->save_automail($fromName, $fromEmail, $toName, $toEmail, $subject, $body, $M_RelatedInfo, $M_State, $M_AddTime, 'payment note', 'payment note'); - //添加邮件发送记录 end - // 2. 给客人发邮件,通知账单 todo ?? 是否需要 - - $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send'); + if ($handpick===false && $item->OPN_noticeSendStatus !== 'send' && substr($item->OPN_noticeSendStatus, 0, 5) !== 'send-') { + $fromName = !empty($item->OPN_payerName) ? $item->OPN_payerName : ''; + $fromEmail = !empty($item->OPN_payerEmail) ? $item->OPN_payerEmail : ''; + $toName = !empty($opi_firstname) ? $opi_firstname : ''; + $toEmail = !empty($opi_email) ? $opi_email : ''; + $subject = $orderid_info->orderid . '_' . $orderid_info->ordertype . ' / ' . $item->OPN_orderAmount . $item->OPN_currency . ' / ' . $fromName; + $body = $this->load->view('mail_advisor', $item, true); //$item->pn_memo; + $M_RelatedInfo = $item->OPN_SN; + $M_AddTime = $item->OPN_completeTime; + $M_State = 0; + // $this->account_model->save_automail($fromName, $fromEmail, $toName, $toEmail, $subject, $body, $M_RelatedInfo, $M_State, $M_AddTime, 'payment note', 'payment note'); + //添加邮件发送记录 end + $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send'); + } + // 2. 给客人发邮件,通知账单 + // todo:iPaylinks需要发收款, 退款发所有 + // 3. 更新是否发送财务 + if($is_refund === true ) { + $this->send_refund($item, $orderid_info, $advisor_info); + } //显示处理记录 if (empty($opn_id)) { @@ -235,6 +259,65 @@ log_message('error','send_notify begin ----'); // return $this->output->set_content_type('application/json')->set_output(json_encode($data)); } + public function send_refund($item, $orderid_info, $advisor_info) + { + // 发送客人 + if ( $item->OPN_noticeSendStatus !== 'send' && substr($item->OPN_noticeSendStatus, 0, 5) !== 'send-' ) { + // 客人邮件中的外联落款 + // $web_code = 'cht'; // 默认cht + $web_lgc = 1; + $web_code = strtolower($advisor_info->COLI_WebCode); + $site_info = $this->config->item('site'); + if (isset($site_info[$web_code])) { + $site_info = $site_info[$web_code]; + $item->site = $site_info['site_url']; + $web_lgc = $site_info['site_lgc']; + } + $advisor_detail = $this->account_model->get_advisor_detail($advisor_info->COLI_SN, $advisor_info->OPI_SN, $web_lgc); + $item->advisor_detail = $advisor_detail; + $customer_detail = $this->account_model->get_customer_detail($advisor_info->COLI_SN, $orderid_info->ordertype); + $c_fromName = $advisor_detail->fullname; + $opi_email_list = explode(";", $advisor_detail->email); // 解析外联的邮件 + $c_fromEmail = trim($opi_email_list[0]); + $c_toName = $customer_detail->fullname; + $c_toEmail = $customer_detail->email; + $c_subject = mb_strtoupper($item->OPN_currency) . " " . str_replace('-', '', $item->OPN_orderAmount) . " Refunded to your account, booking number " . $item->OPN_orderId; + // 修改一些字段名, 为了和Alipay等用同一个邮件模板 + $item->payer = $customer_detail->fullname; + $item->payer_email = $customer_detail->email; + $item->total_amount = $item->OPN_orderAmount; + $item->payment_date = $item->OPN_completeTime; + $item->payment_status = "Refunfed"; + $item->currency = mb_strtoupper($item->OPN_currency); + $item->invoice = $item->OPN_orderId; + $c_body = $this->load->view('refund_buyer', $item, true); + $c_M_RelatedInfo = $item->OPN_SN; + $c_M_AddTime = $item->OPN_completeTime; + $c_M_State = 0; + // $this->account_model->save_automail( + // $c_fromName, + // $c_fromEmail, + // $c_toName, + // $c_toEmail, + // $c_subject, + // $c_body, + // $c_M_RelatedInfo, + // $c_M_State, + // $c_M_AddTime, + // 'ChinaHighlights refund receipt', + // 'payment note'); + $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send-customer'); + } + // 更新是否需要发送财务 + $refund_finance_day = 20; + $now_day = date('d'); + $late_entry_date_set = $now_day<$refund_finance_day ? date('Y-m-01', strtotime("-1 month")) : date('Y-m-01'); + if ($this->account_model->if_finance_done($advisor_info->COLI_GRI_SN, $late_entry_date_set) === true) { + $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send-to-finance'); + } + return; + } + /** 支付方式参数对应的配置文件名 */ /** @Deprecated */ public function method_name($name) @@ -261,11 +344,12 @@ log_message('error','send_notify begin ----'); return $config_name; } - private function method_analysis_orderid($name, $raw_content) + private function method_analysis_orderid($opn_obj) { - $content_obj = json_decode($raw_content); + // $orderid_info = $this->method_analysis_orderid($item->OPN_accountMethod, $item->OPN_rawContent); + $content_obj = json_decode($opn_obj->OPN_rawContent); $orderid_info = array(); - switch (strval($name)) { + switch (strval($opn_obj->OPN_accountMethod)) { case '15002': case '15010': // paypal $orderid_info = analysis_orderid($content_obj->invoice); @@ -279,6 +363,9 @@ log_message('error','send_notify begin ----'); case '15016': // wxpay $orderid_info = analysis_orderid($content_obj->out_trade_no); + if (empty($orderid_info) && $opn_obj->OPN_fundSource==='cht' && $content_obj->trade_type==='APP') { + $orderid_info = analysis_orderid($content_obj->out_trade_no . "_A"); + } break; // TODO case '15018': // iPaylinks diff --git a/webht/third_party/pay/controllers/WxpayService.php b/webht/third_party/pay/controllers/WxpayService.php index f7490205..ff844983 100644 --- a/webht/third_party/pay/controllers/WxpayService.php +++ b/webht/third_party/pay/controllers/WxpayService.php @@ -58,7 +58,7 @@ class WxpayService extends CI_Controller { $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_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; @@ -98,6 +98,7 @@ class WxpayService extends CI_Controller { { $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'; @@ -134,7 +135,7 @@ class WxpayService extends CI_Controller { $save_column['OPN_noticeType'] = 'pay'; } $save_column['OPN_noticeSendStatus'] = 'unsend'; - $save_column['OPn_transactionResult'] = 'completed'; + $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']; diff --git a/webht/third_party/pay/helpers/payment_helper.php b/webht/third_party/pay/helpers/payment_helper.php index 15339534..27ff11e9 100644 --- a/webht/third_party/pay/helpers/payment_helper.php +++ b/webht/third_party/pay/helpers/payment_helper.php @@ -138,6 +138,8 @@ function analysis_orderid($note_invoice_string) { $ordertype = 'T'; } elseif (substr($ordertype_temp, 0, 1) == 'B') { $ordertype = 'B'; + } elseif (substr($ordertype_temp, 0, 1) == 'A') { + $ordertype = 'A'; } } // 2018.05.28 for Trippest, tourMaster的订单号是01开头 diff --git a/webht/third_party/pay/models/Online_payment_account_model.php b/webht/third_party/pay/models/Online_payment_account_model.php index 5c9195e9..599f1204 100644 --- a/webht/third_party/pay/models/Online_payment_account_model.php +++ b/webht/third_party/pay/models/Online_payment_account_model.php @@ -97,8 +97,15 @@ class Online_payment_account_model extends CI_Model { return $result; } - public function if_biz_gai_exists($GAI_AccreditNo) + public function if_biz_gai_exists($GAI_AccreditNo, $is_app=false, $coli_sn=null, $je=null, $type=null) { + if ($is_app===true && $coli_sn!==null) { + $sql = " SELECT TOP 1 1 + FROM BIZ_GroupAccountInfo + WHERE GAI_COLI_SN = ? AND GAI_SQJE=? AND DeleteFlag=0 AND GAI_Type=?"; + $result = $this->HT->query($sql, array($coli_sn, $je, $type)); + return ($result->num_rows() > 0); + } $sql = " SELECT TOP 1 1 FROM BIZ_GroupAccountInfo WHERE (GAI_AccreditNo = ? OR GAI_Memo LIKE '%$GAI_AccreditNo%') AND DeleteFlag=0"; @@ -339,7 +346,25 @@ class Online_payment_account_model extends CI_Model { inner join Tourmanager.dbo.CK_GroupInfo cgi on gz.GZD_CGI_SN=cgi.CGI_SN where ISNULL(GZD_DeleteFlag,0)=0 and isnull(DelFlag,0)=0 and cgi.CGI_GRI_SN=? "; - return $this->HT->query($sql, $gri_sn)->num_rows() > 0; + return $this->HT->query($sql, array($gri_sn))->num_rows() > 0; + } + // 商务订单没有生成团信息 + public function if_finance_done($gri_sn, $late_date) + { + $sql = "SELECT top 1 1 + from groupinfo gri + where GRI_SN=? + and GRI_EntranceDate < ? + "; + if ($this->HT->query($sql, array($gri_sn,$late_date))->num_rows() === 0) { + $sql = "SELECT top 1 1 + from BIZ_ConfirmLineInfo coli + inner join BIZ_ConfirmLineDetail cold on COLD_COLI_SN=COLI_SN and isnull(cold.DeleteFlag,0)=0 + where COLI_GRI_SN=? + and COLD_StartDateHT->query($sql, array($gri_sn,$late_date))->num_rows() > 0; + } + return false; } /*! @@ -427,5 +452,49 @@ class Online_payment_account_model extends CI_Model { return $this->HT->query($sql, $note_sn); } + public function get_advisor_detail($COLI_SN, $OPI_SN, $lgc=1) + { + $advisor_signature = $this->get_advisor_signature($COLI_SN); + if (empty($advisor_signature)) { + $sql = "SELECT OPI_SN, '+86-'+OPI_MoveTelephone mobile,'+86-773-'+OPI_Telephone tel,OPI_Email email,OPI2_Name fullname,OPI2_FirstName,OPI2_LastName + FROM [Tourmanager].[dbo].[V_Operator_Info] + where OPI_SN=? and LGC_LGC=? "; + $advisor_signature = $this->HT->query($sql, array($OPI_SN, $lgc))->row(); + } + return $advisor_signature; + } + public function get_advisor_signature($COLI_SN) + { + $sql = "SELECT top 1 dbo.agenter_user.Name fullname, dbo.agenter_user.tel, + dbo.agenter_user.Email email, dbo.agenter_user.mobile, OPI_DEI_SN, COLI_OPI_ID + FROM dbo.BIZ_ConfirmLineInfo + INNER JOIN dbo.agenter_user ON dbo.BIZ_ConfirmLineInfo.COLI_OPI_ID = dbo.agenter_user.AU_OPI_SN + AND + (dbo.BIZ_ConfirmLineInfo.COLI_WebCode = dbo.agenter_user.agenter + OR (COLI_WebCode in ('EXPCH','MESENLLA','traba','wayaway','guias') and agenter='VAC') + ) + LEFT JOIN OperatorInfo on COLI_OPI_ID = OPI_SN + WHERE (dbo.BIZ_ConfirmLineInfo.COLI_SN = ?)"; + return $this->HT->query($sql, array($COLI_SN))->row(); + } + + public function get_customer_detail($COLI_SN, $ordertype) + { + if ($ordertype === 'T') { + $sql = "SELECT mei.MEI_FirstName+' '+isnull(mei.MEI_MiddleName,'')+' '+isnull(mei.MEI_LastName,'') fullname, + mei.MEI_MailList email + FROM MEmberInfo mei + INNER JOIN CUstomerList cul on mei.MEI_SN=cul.CUL_CUI_SN --and cul.CUL_IsLinkMan=1 + WHERE CUL_COLI_SN=? and isnull(mei.MEI_MailList,'')<>'' + order by cul.CUL_IsLinkMan desc"; + return $this->HT->query($sql, $COLI_SN)->row(); + } else { + $sql = "SELECT GUT_FirstName+' '+GUT_LastName fullname,GUT_Email email from BIZ_GUEST g + INNER JOIN BIZ_ConfirmLineInfo coli on coli.COLI_GUT_SN=g.GUT_SN + WHERE COLI_SN=? "; + return $this->HT->query($sql, $COLI_SN)->row(); + } + } + }