diff --git a/webht/third_party/pay/config/wxpay.php b/webht/third_party/pay/config/wxpay.php new file mode 100644 index 00000000..b4752bff --- /dev/null +++ b/webht/third_party/pay/config/wxpay.php @@ -0,0 +1,25 @@ +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') + { +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'); + if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) { + # 如果没有数据,直接返回失败 + return $this->response_to_wx($response); + } + //获取通知的数据 + $xml = $GLOBALS['HTTP_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'], $xml_arr['fee_type'], $this->config->item('currency_unit', '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'] = $xml_arr['bank_type']; + $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 response_to_wx($response_arr) + { + $response_body = to_xml($response_arr); +// log_message('error',var_export($response_body, 1)); + echo $response_body; + # exit(); // end + } + + public function send_notify() + { + // $save_column['OPN_accountType'] = $xml_arr['']; + // $save_column['OPN_accountStatus'] = $xml_arr['']; + // $save_column['OPN_accountTime'] = $xml_arr['']; + } + + 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.'); + 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; + } + +} + diff --git a/webht/third_party/pay/helpers/payment_helper.php b/webht/third_party/pay/helpers/payment_helper.php index 3ec1e8cc..53ceac5e 100644 --- a/webht/third_party/pay/helpers/payment_helper.php +++ b/webht/third_party/pay/helpers/payment_helper.php @@ -180,3 +180,43 @@ function analysis_orderid($note_invoice_string) { } return json_encode(array('orderid' => $pm_orderid, 'ordertype' => $ordertype)); } +/** + * 输出xml字符 + * @throws WxPayException +**/ +function to_xml($arr) +{ + if(!is_array($arr) || count($arr) <= 0) + { + return false; + } + + $xml = ""; + foreach ($arr as $key=>$val) + { + if (is_numeric($val)){ + $xml.="<".$key.">".$val.""; + }else{ + $xml.="<".$key.">"; + } + } + $xml.=""; + return $xml; +} + +/** + * 将xml转为array + * @param string $xml + * @throws WxPayException + */ +function from_xml($xml) +{ + if(!$xml){ + return false; + } + //将XML转为array + //禁止引用外部xml实体 + libxml_disable_entity_loader(true); + return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); +} + diff --git a/webht/third_party/pay/models/Online_payment_account_model.php b/webht/third_party/pay/models/Online_payment_account_model.php new file mode 100644 index 00000000..3c19ea87 --- /dev/null +++ b/webht/third_party/pay/models/Online_payment_account_model.php @@ -0,0 +1,27 @@ +HT = $this->load->database('HT', TRUE); + } + + /*! + * 调用数据库函数,生成实收金额 + * @author LYT + */ + public function get_ssje($amount, $currency='USD', $code) + { + $sql = "SELECT dbo.GetSSJEFromSQJE(?, ?, ?) as ssje"; + $query = $this->HT->query($sql,array($code, $currency, $amount)); + $result = $query->result(); + if ( ! empty($result)) { + return $result[0]->ssje; + } + return NULL; + } + +} + diff --git a/webht/third_party/pay/models/Online_payment_note_model.php b/webht/third_party/pay/models/Online_payment_note_model.php new file mode 100644 index 00000000..2c721c52 --- /dev/null +++ b/webht/third_party/pay/models/Online_payment_note_model.php @@ -0,0 +1,31 @@ +info = $this->load->database('INFO', TRUE); + } + + public function insert_note($column) + { + if ($column === null) { + return false; + } + $this->info->insert('OnlinePaymentNote', $column); + $ret = "SELECT TOP 1 * FROM OnlinePaymentNote WHERE OPN_transactionId=? ORDER BY OPN_SN DESC "; + return $this->info->query($ret, array($column['OPN_transactionId']))->row(); + } + + public function update_note($where, $column) + { + $update_str = $this->info->update_string('OnlinePaymentNote', $column, $where); + $this->info->query($update_str); + return TRUE; + } + + + +} + diff --git a/webht/third_party/pay/views/alipay_list.php b/webht/third_party/pay/views/alipay_list.php index afe0d5c2..faceb099 100644 --- a/webht/third_party/pay/views/alipay_list.php +++ b/webht/third_party/pay/views/alipay_list.php @@ -95,7 +95,7 @@
- +