微信支付后端交互原理
后端代码<?php
define('IN_ECS', true);
require(dirname(__FILE__) . '/includes/init.php');
// require(ROOT_PATH . 'includes/lib_license.php');
require_once('includes/cls_certificate.php');
require_once('includes/cls_json.php');
define('RETURN_TYPE', 'json');
define('GMTIME_UTC', gmtime()); // 获取 UTC 时间戳
empty($GLOBALS["HTTP_RAW_POST_DATA"]) ? $postStr = file_get_contents("php://input") : $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if(empty($postStr)){exit();}
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
//判断状态
if($postObj->result_code != 'SUCCESS'){exit();}
$oid = $postObj->out_trade_no;
//查询订单
$sql = 'SELECT * FROM ' . $GLOBALS['ecs']->table('order_info') ." WHERE order_id = ".mysql_real_escape_string($oid);
$order = $GLOBALS['db']->getRow($sql);
if(empty($order)){exit(json_encode(array('msg'=> 'error')));}
//核对交易信息
$url = 'https://api.mch.weixin.qq.com/pay/orderquery';
$array = array();
$array['appid'] = WX_APPID;
$array['mch_id'] = WX_MCHID;
$array['transaction_id'] = $postObj->transaction_id;
$array['nonce_str'] = md5(uniqid());
$array['sign'] = makeSign($array);
$xml = toXml($array);
$res = curlPost($url, $xml);
//将XML结果转换成数组
$arrOrder = xmlToArray($res);
file_put_contents('r1.txt', $res);
if($arrOrder['result_code'] != 'SUCCESS'){exit();}
if($arrOrder['trade_state'] != 'SUCCESS'){exit();}
file_put_contents('r2.txt', $res);
//更新订单
$sql = "update ".$GLOBALS['ecs']->table('order_info')." set pay_status = 2, order_status = 1 where order_id = ".$order['order_id'];
$GLOBALS['db']->query($sql);
function toXml($arr){
$xml = '';
foreach($arr as $key => $val){
if (is_numeric($val)){
$xml.="".$val."".$key.">";
}else{
$xml.="".$key.">";
}
}
$xml .= '';
return $xml;
}
function xmlToArray($xml){
libxml_disable_entity_loader(true);
$arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $arr;
}
//微信支付签名
function makeSign($array){
ksort($array);
$string = '';
foreach ($array as $k => $v){
if($k != "sign" && $v != "" && !is_array($v)){$string .= $k . "=" . $v . "&";}
}
$string = trim($string, "&");
//签名步骤二:在string后加入KEY
$string = $string . "&key=".WX_PAYSKY;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
//curl get 方式 封装
function curlGet($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER , true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , false);
curl_setopt($ch, CURLOPT_ENCODING , 'gzip,deflate');
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
/*
* curl POST 方式
* 参数1 $url
* 参数2 $data 格式 array('name'=>'test', 'age' => 18)
*/
function curlPost($url, $data){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER , true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_ENCODING , 'gzip,deflate');
$res = curl_exec($ch);
curl_close($ch);
return $res;
}