wxpay 异步通知处理:接收推送

feature/trippest
lyt 6 years ago
parent 4ea5eb7147
commit 43e9c8a68e

@ -0,0 +1,25 @@
<?php
$config["sign_type"] = "HMAC-SHA256";
$config["trade_type"] = "NATIVE";
$config["notify_url"] = "";
$config["currency"] = "CNY";
$config["currency_unit"] = 100;
$config["method_code"] = 15016;
/*!
* 各账号的设置
*/
// test
$config['test']["app_id"] = "wx426b3015555a46be";
$config['test']["mch_id"] = "1900009851";
$config['test']["key"] = "8934e7d15453e97507ef794cf7b0519d";
$config['test']["app_secret"] = "7813490da6f1265e4901ffb80afaa36f";
// Trippest
$config['trippest']["app_id"] = "";
$config['trippest']["mch_id"] = "";
$config['trippest']["key"] = "";
$config['trippest']["app_secret"] = "";
// ChinaHighlights = China train booking
$config['cht']["app_id"] = "";
$config['cht']["mch_id"] = "";
$config['cht']["key"] = "";
$config['cht']["app_secret"] = "";

@ -0,0 +1,160 @@
<?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')
{
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;
}
}

@ -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 = "<xml>";
foreach ($arr as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</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);
}

@ -0,0 +1,27 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Online_payment_account_model extends CI_Model {
function __construct() {
parent::__construct();
$this->HT = $this->load->database('HT', TRUE);
}
/*!
* 调用数据库函数,生成实收金额
* @author LYT <lyt@hainatravel.com>
*/
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;
}
}

@ -0,0 +1,31 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Online_payment_note_model extends CI_Model {
function __construct() {
parent::__construct();
$this->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;
}
}

@ -95,7 +95,7 @@
<div class="row">
<form method="post" id="search_list" action="/webht.php/apps/pay/AlipayTradeService/note_list/">
<div class="input-group">
<input type="text" name="keywords" value="<?php echo isset($search_key) ? $search_key : ''; ?>" class="form-control" placeholder="订单号" style="height: 33px;-webkit-box-shadow: inset 0 0px 0px rgba(0,0,0,0.075);box-shadow: inset 0 0px 0px rgba(0,0,0,0.075);border-bottom:1px solid #ddd;">
<input type="text" name="keywords" value="<?php echo isset($search_key) ? $search_key : ''; ?>" class="form-control" placeholder="订单号/交易号" style="height: 33px;-webkit-box-shadow: inset 0 0px 0px rgba(0,0,0,0.075);box-shadow: inset 0 0px 0px rgba(0,0,0,0.075);border-bottom:1px solid #ddd;">
<span class="input-group-addon search-btn" onclick="$('#search_list').submit();"></span>
</div>
<div id="datepicker"></div>

Loading…
Cancel
Save