微信app服务端php,原生app微信支付-服务器端PHP代码(含异步通知处理)

本文详细介绍了微信支付中二次签名的过程,包括获取prepay_id时的第一次签名和返回结果时的第二次签名。强调了签名的重要性,以及签名参数、加密方式、密钥的选择。同时提供了PHP实现的示例代码,包括生成支付信息、服务器端异步回调的处理。此外,还特别指出了body参数的格式要求和注意事项。
摘要由CSDN通过智能技术生成

注意点:

1、签名是俩次签名,第一次,是获取prepay_id时候,第二次签名是最后返回结果的时候,所谓签名就是对所传递参数的一个加密操作;

2、加签方式默认md5就可以,如果要改成HMAC-SHA256,需要在第一次签名时候,传递参数:$newPara["sign_type"] = "HMAC-SHA256";  然后在签名加密的时候,使用:$String = hash_hmac("sha256",参数拼接字符串,密钥);

3、使用的密钥,不是AppSecret,而是在微信商户平台上自己设定的api密钥 32位;

4、重点:body参数格式:应用市场上的APP名字-实际商品名称,比如:天天爱消除-游戏充值。

5、安卓端可以配合下面框架使用

代码:/*

//生成支付信息

$wx = new TegWXPay();

$res = $wx->weChatPay(订单号,金额,商品名称);

echo $res;

//服务器端异步回调

$wx = new TegWXPay();

$re_arr = $wx->verifyNotify();

if($re_arr !== false){

//订单信息放在$re_arr里面,下面开始处理业务逻辑...

//下面代码告诉微信处理成功

exit('');

}else{

//下面代码告诉微信处理失败了

exit('');

}

*/

//weixinpay class

class TegWXPay{

private $config = array(

'appid' => "",    /*微信开放平台上的应用id*/

'mch_id' => "",   /*微信申请成功之后邮件中的商户id*/

'api_key' => "",    /*在微信商户平台上自己设定的api密钥 32位*/

'notify_url' => '', /*自定义的回调程序地址*/

'appname' => '' //app名称

);

//入口函数

public function weChatPay($order_num,$price,$subject)

{

$json = array();

//生成预支付交易单的必选参数:

$newPara = array();

//应用ID

$newPara["appid"] = $this->config['appid']; //商户appid;

//商品描述

$newPara["body"] = $this->config['appname']."-".$subject;

//设备号

$newPara["device_info"] = "WEB";

//商户号

$newPara["mch_id"] = $this->config['mch_id']; //商户id

//随机字符串,这里推荐使用函数生成

$newPara["nonce_str"] = $this->createNoncestr();

//通知地址,注意,这里的url里面不要加参数

$newPara["notify_url"] = $this->config['notify_url'];//支付成功后的回调地址;

//商户订单号,这里是商户自己的内部的订单号

$newPara["out_trade_no"] = $order_num;

//签名类型 HMAC-SHA256 MD5

$newPara["sign_type"] = "MD5";

//终端IP

$newPara["spbill_create_ip"] = $this->get_client_ip();

//总金额

$newPara["total_fee"] = $price;

//交易类型

$newPara["trade_type"] = "APP";

$key = $this->config['api_key']; //密钥:在商户后台个人安全中心设置

//第一次签名

$newPara["sign"] = $this->appgetSign($newPara,$key);

//echo json_encode($newPara);

//exit;

//把数组转化成xml格式

$xmlData = $this->arrayToXml($newPara);

$get_data = $this->sendPrePayCurl($xmlData);

//返回的结果进行判断。

if($get_data['return_code'] == "SUCCESS" && $get_data['result_code'] == "SUCCESS")

{

//根据微信支付返回的结果进行二次签名

//二次签名所需的随机字符串

$newPara["nonce_str"] = $this->createNoncestr();

//二次签名所需的时间戳

$newPara['timeStamp'] = time()."";

//二次签名剩余参数的补充

$secondSignArray = array(

"appid"=>$newPara['appid'],

"noncestr"=>$newPara['nonce_str'],

"package"=>"Sign=WXPay",

"prepayid"=>$get_data['prepay_id'],

"partnerid"=>$newPara['mch_id'],

"timestamp"=>$newPara['timeStamp'],

);

$json['success'] = 1;

$json['ordersn'] = $newPara["out_trade_no"]; //订单号

$json['order_arr'] = $secondSignArray;  //返给前台APP的预支付订单信息

$json['order_arr']['sign'] = $this->appgetSign($secondSignArray,$key);  //预支付订单签名

$json['data'] = "预支付完成";

//预支付完成,在下方进行自己内部的业务逻辑

/*****************************/

//return json_encode($json);

$json['order_arr']['nonce_str'] = $secondSignArray['noncestr'];

$json['order_arr']['prepay_id'] = $secondSignArray['prepayid'];

$json['order_arr']['return_code'] = 'SUCCESS';

$json['order_arr']['return_msg'] = 'OK';

$test['pay_code'] = $json['order_arr'];

return json_encode($test);

}else{

$json['success'] = 0;

$json['error'] = $get_data['return_msg'];

return json_encode($json);

}

}

//将数组转换为xml格式

public function arrayToXml($arr)

{

$xml = "";

foreach ($arr as $key=>$val)

{

//if (is_numeric($val))

if(false)

{

$xml.="".$val."".$key.">";

}

else

$xml.="".$key.">";

}

$xml.="";

return $xml;

}

//发送请求

public function sendPrePayCurl($xml,$second=30)

{

$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

$ch = curl_init();

curl_setopt($ch,CURLOPT_URL, $url);

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);

curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);

//设置header

curl_setopt($ch, CURLOPT_HEADER, FALSE);

//要求结果为字符串且输出到屏幕上

curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

//post提交方式

curl_setopt($ch, CURLOPT_POST, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

//运行curl

$data = curl_exec($ch);

curl_close($ch);

$data_xml_arr =$this->XMLDataParse($data);

if($data_xml_arr)

{

return $data_xml_arr;

}

else

{

$error = curl_errno($ch);

echo "curl出错,错误码:$error"."
";

//echo "错误原因查询";

curl_close($ch);

return false;

}

}

//xml格式数据解析函数

public function XMLDataParse($data)

{

$xml = simplexml_load_string($data,NULL,LIBXML_NOCDATA);

$array = json_decode(json_encode($xml),true);

return $array;

}

//随机字符串

public function createNoncestr( $length = 32 )

{

$chars = "abcdefghijklmnopqrstuvwxyz0123456789";

$str ="";

for ( $i = 0; $i 

$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);

}

return $str;

}

/*

* 格式化参数格式化成url参数  生成签名sign

*/

public function appgetSign($Obj,$appwxpay_key)

{

foreach ($Obj as $k => $v)

{

$Parameters[$k] = $v;

}

//签名步骤一:按字典序排序参数

ksort($Parameters);

$String = $this->formatBizQueryParaMap($Parameters, false);

//echo '【string1】'.$String.'';

//签名步骤二:在string后加入KEY

if($appwxpay_key){

$String = $String."&key=".$appwxpay_key;

}

//echo "【string2】".$String."";

//签名步骤三:MD5加密

$String = md5($String);

//HMAC-SHA256签名方式

//$String = hash_hmac("sha256",$String,$appwxpay_key);

//echo "【string3】 ".$String."";

//签名步骤四:所有字符转为大写

$result_ = strtoupper($String);

//echo "【result】 ".$result_."";

return $result_;

}

//按字典序排序参数

public function formatBizQueryParaMap($paraMap, $urlencode)

{

$buff = "";

ksort($paraMap);

foreach ($paraMap as $k => $v)

{

if($urlencode)

{

$v = urlencode($v);

}

//$buff .= strtolower($k) . "=" . $v . "&";

$buff .= $k . "=" . $v . "&";

}

$reqPar;

if (strlen($buff) > 0)

{

$reqPar = substr($buff, 0, strlen($buff)-1);

}

return $reqPar;

}

//获取当前服务器的IP

public function get_client_ip()

{

if ($_SERVER['REMOTE_ADDR']) {

$cip = $_SERVER['REMOTE_ADDR'];

} elseif (getenv("REMOTE_ADDR")) {

$cip = getenv("REMOTE_ADDR");

} elseif (getenv("HTTP_CLIENT_IP")) {

$cip = getenv("HTTP_CLIENT_IP");

} else {

$cip = "unknown";

}

return $cip;

}

//签名验证

function getVerifySign($data, $key)

{

$String = $this->formatBizQueryParaMap($data, false);

//签名步骤二:在string后加入KEY

$String = $String . "&key=" . $key;

//签名步骤三:MD5加密

$String = md5($String);

//签名步骤四:所有字符转为大写

$result = strtoupper($String);

return $result;

}

/**

* 异步通知信息验证

* @return boolean|mixed

*/

public function verifyNotify()

{

$xml = file_get_contents('php://input');

if(!$xml){

return false;

}

$wx_back = $this->XMLDataParse($xml);

if(empty($wx_back)){

return false;

}

$checkSign = $this->getVerifySign($wx_back, $this->config['api_key']);

if($checkSign=$wx_back['sign']){

return $wx_back;

}else{

return false;

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值