如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人。谢谢大家!❤
如果解决不了,可以在文末进群交流。
如果对你有帮助的话麻烦点个【推荐】~最好还可以follow一下我的GitHub~感谢观看!
微信支付接口的成功调用,真的是我项目中一步步踩坑踩出来。微信的开发文档,别的我不知道,就看完支付接口来讲,真的是太简单了,并且很多关联的参数如何设置、校验、调用,都是没有关联的。微信支付作为各大移动支付方式之一,又不得不用。本文是我项目中自己写的代码,部分来自度娘,但是逻辑我已经搞通了。有些写的臃肿,望大家指正。希望各位能够快速上手并掌握实战"干货"。
/* 官方文档
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
◆ key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
*/
提供几个大家项目中可能会用的文档
Demo下载: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
API列表及各参数含义:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
废话不多说了,直接上代码,不懂地方可留言,或者进微信群内交流。群二维码如果过期,请加我微信:mengyilingjian.
<?php
class Wxpay{
//modify by 墜夢 2018.07.11
public function wx_Pay($appid,$payDesc,$payAmount,$mch_id,$wxpay_key,$openid,$userid){
//准备参数
$nonce_str = $this->nonce_str(); //生成随机32位字符串
$out_trade_no = $this->order_number(); //生成订单号
$spbill_create_ip = $this->get_real_ip(); //获取支付ip
$trade_type = \'JSAPI\'; //支付方式
$notify_url = "https://".$_SERVER[\'HTTP_HOST\']."/********/paySuccess.php"; //支付成功的回调地址,不能携带参数,支付成功用来更新数据库插入订单的状态
//向数据库插入数据订单信息
$insertData=array();
$insertData[\'order_no\'] = $out_trade_no; //订单编号
$insertData[\'user_id\'] = $userid; //用户id
$insertData[\'pay_price\'] = $payAmount; //支付金额
$insertData[\'order_status\'] = 1;
$insertData[\'order_time\'] = TIMESTAMP; //订单创建时间
$insertResult = DB::insert(\'*********\',$insertData,$return_insert_id = true); //创建订单到数据库
if($insertResult > 0){ //数据库数据插入成功
//配置请求参数
//文档地址: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1&index=1
$payAmount = intval($payAmount)*100; //此处需注意接口中金额的单位为分
$signdata[\'appid\'] = $appid; //小程序的appid
$signdata[\'body\'] = $payDesc; //商品描述
$signdata[\'mch_id\'] = $mch_id; //商户号请到后台配置查看
$signdata[\'nonce_str\'] = $nonce_str; //随机字符串
$signdata[\'notify_url\'] = $notify_url; //回调地址
$signdata[\'openid\'] = $openid; //小程序openid
$signdata[\'out_trade_no\'] = $out_trade_no; //自定义商户订单号规则
$signdata[\'spbill_create_ip\'] = $spbill_create_ip; //获取用户id
$signdata[\'total_fee\'] = $payAmount; //总金额
$signdata[\'trade_type\'] = $trade_type; //交易类型 默认
$sign = $this->MakeSign($signdata,$wxpay_key);
$stringXml = \'<xml>
<appid>\'.$appid.\'</appid>
<body>\'.$payDesc.\'</body>
<mch_id>\'.$mch_id.\'</mch_id>
<nonce_str>\'.$nonce_str.\'</nonce_str>
<notify_url>\'.$notify_url.\'</notify_url>
<openid>\'.$openid.\'</openid>
<out_trade_no>\'.$out_trade_no.\'</out_trade_no>
<spbill_create_ip>\'.$spbill_create_ip.\'</spbill_create_ip>
<total_fee>\'.$payAmount.\'</total_fee>
<trade_type>\'.$trade_type.\'</trade_type>
<sign>\'.$sign.\'</sign>
</xml> \';
$orderUrl = \'https://api.mch.weixin.qq.com/pay/unifiedorder\'; //统一下单url接口
$xml = $this->http_request($orderUrl,$stringXml); //请求curl
$orderInfo = $this->xmlarray($xml);//将XML数据转成array
// print_r($orderInfo);exit; //此处打开可查看接口是否走通
if(is_array($orderInfo) && $orderInfo[\'RETURN_CODE\'] == \'SUCCESS\' && $orderInfo[\'RESULT_CODE\'] == \'SUCCESS\'){
// echo 222;exit; //文档地址: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3
$tmp=array();//临时数组用于签名
$time = strval(time());
$tmp[\'appId\'] = $appid;
$tmp[\'nonceStr\'] = $nonce_str;
$tmp[\'package\'] = \'prepay_id=\'.$orderInfo[\'PREPAY_ID\'];
$tmp[\'signType\'] = \'MD5\';
$tmp[\'timeStamp\'] = $time;
//下单成功 回调地址 确认订单所需要返回的数据
$resData[\'paySign\'] = $this->MakeSign($tmp,$wxpay_key);
$resData[\'timeStamp\'] = $time;//时间戳
$resData[\'nonceStr\'] = $nonce_str;//随机字符串
$resData[\'package\'] = \'prepay_id=\'.$orderInfo[\'PREPAY_ID\'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
$resData[\'signType\'] = \'MD5\';//签名算法,暂支持,MD5
$resData[\'out_trade_no\'] = $out_trade_no;
//前端需要的参数
$resData[\'state\'] = 200;
$resData[\'text\'] = "支付成功!";
}else{
$resData[\'state\'] = 404;
$resData[\'text\'] = "支付失败,请重试"; //接口支付失败
$resData[\'msg\'] = $orderInfo[\'RETURN_MSG\'];
}
echo json_encode($resData);
}else{
$resData[\'state\'] = 400;
$resData[\'text\'] = "系统繁忙,请重试"; //数据库数据插入失败
echo json_encode($resData);
}
exit;
}
//随机32位字符串
private function nonce_str(){
$result = \'\';
$str = \'mengyilingjian890106zhuimeng8899\';
for ($i=0;$i<32;$i++){
$result .= $str[rand(0,48)];
}
return $result;
}
//生成商户订单号
private function order_number($tel){
$order_no = "JY".date("YmdHis")."-".mt_rand(111111, 666666);
return $order_no;//凑齐32位商户订单号,可自行定义
}
//签名
private function MakeSign($params,$KEY){
//签名步骤一:按字典序排序数组参数
ksort($params);
$string = $this->ToUrlParams($params); //参数进行拼接key=value&k=v
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$KEY;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
//拼接api密钥
public function ToUrlParams( $params ){
$string = \'\';
if( !empty($params) ){
$array = array();
foreach( $params as $key => $value ){
$array[] = $key.\'=\'.$value;
}
$string = implode("&",$array);
}
return $string;
}
//获取用户ip地址
private function get_real_ip(){
if(getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknow")){
$ip = getenv("HTTP_CLIENT_IP");
}else if(getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknow")){
$ip = getenv("HTTP_X_FORWARDED_FOR");
}else if(getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknow")){
$ip = getenv("REMOTE_ADDR");
}else if(isset($_SERVER["REMOTE_ADDR"]) && $_SERVER["REMOTE_ADDR"] && strcasecmp($_SERVER["REMOTE_ADDR"],"unknow")){
$ip = $_SERVER["REMOTE_ADDR"];
}else{
$ip = "unknow";
}
return $ip;
}
//curl请求
function http_request($url,$data = null,$headers=array()){
$curl = curl_init();
if( count($headers) >= 1 ){
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
//获取xml里面数据,转换成array
private function xmlarray($xml){
$p = xml_parser_create();
xml_parse_into_struct($p, $xml, $vals, $index);
xml_parser_free($p);
$data = "";
foreach ($index as $key=>$value) {
if($key == \'xml\' || $key == \'XML\') continue;
$tag = $vals[$value[0]][\'tag\'];
$value = $vals[$value[0]][\'value\'];
$data[$tag] = $value;
}
return $data;
}
}
//调用实例
$startPay = new Wxpay();
echo $startPay -> wx_Pay($appId,$payDesc,$payAmount,$mch_id,$wxpay_key,$openid,$userid);
/*
参数说明:
$appId:开发者的appid;
$payDesc:支付的商品描述;
$payAmount:支付的商品价格,单位为分
$mch_id:支付的商户号;
$wxpay_key:开发者的支付key;
$openid:用户标识,用户登陆的openid;
$userid:支付者的身份标识
再看不懂请到顶部看我给的链接。
*/