如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人。谢谢大家!❤

如果解决不了,可以在文末进群交流。

如果对你有帮助的话麻烦点个【推荐】~最好还可以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:支付者的身份标识
再看不懂请到顶部看我给的链接。
*/

微信支付接口--超详细带注释代码--Demo的更多相关文章

  1. 微信JS支付代码_前端调用微信支付接口

    转自:http://dditblog.com/itshare_553.html 跟大家分享一段微信支付的js代码片段.V3版的微信支付没有paySignKey参数.基本上是直接复制就可以使用了.改一改 ...

  2. 超详细的Xcode代码格式化教程,可自定义样式。

    超详细的Xcode代码格式化教程,可自定义样式. 为什么要格式化代码 当团队内有多人开发的时候,每个人写的代码格式都有自己的喜好,也可能会忙着写代码而忽略了格式的问题.在之前,我们可能会写完代码后,再 ...

  3. php微信支付接口开发程序

    php微信支付接口开发程序讲解 微信支付接口现在也慢慢的像支付宝一个可以利用api接口来实现第三方网站或应用进行支付了, 下文整理了一个php微信支付接口开发程序并且己测试,有兴趣的朋友可进入参考. ...

  4. JAVA微信支付接口开发——支付

    微信支付接口开发--支付 这几天在做支付服务,系统接入了支付宝.微信.银联三方支付接口.个人感觉支付宝的接口开发较为简单,并且易于测试. 关于数据传输,微信是用xml,所以需要对xml进行解析. 1. ...

  5. php微信支付接口开发程序(流程已通)

    php微信支付接口开发程序(流程已通) 来源:未知    时间:2014-12-11 17:11   阅读数:11843   作者:xxadmin [导读] 微信支付接口现在也慢慢的像支付宝一个可以利 ...

  6. 如何使用 RESTClient 调试微信支付接口

    我们知道微信支付使用http协议进行api调用,body 使用xml格式,使用的一般http在线调试工具,无法进行xml数据的post. RESTClient 做的很好,支持各种http 方法,bod ...

  7. 微信小程序PHP 微信支付接口调用

    小程序端 /** * 微信支付接口 */ wxPaymoney:function (out_trade_no, true_money){ //out_trade_no 后台统一下单接口需要用 var ...

  8. 关于微信支付接口,curl错误代码58

    微信支付接口,curl错误代码58 之前的微信付款到用户零钱都是好好的,今天运营来找我, 我想了了下,就是进行了网站搬家 看了下 微信支付相关的证书配置文件 知道了,在这个 要改下证书的路径 WxPa ...

  9. 微信支付接口,curl错误代码58

    微信支付接口,curl错误代码58 之前的微信付款到用户零钱都是好好的,今天运营来找我, 我想了了下,就是进行了网站搬家 看了下 微信支付相关的证书配置文件 知道了,在这个 要改下证书的路径 WxPa ...

随机推荐

  1. docker 安装redis cluster集群

    安装Redis镜像 docker pull yyyyttttwwww/redis 创建redis容器 docker run -it -d --name r1 -p 5001:6379 --net=ne ...

  2. iOS - 点击按钮实现简单的复制功能

    UIPasteboard使用 基本使用: - (void)copyClick { UIPasteboard *pab = [UIPasteboard generalPasteboard]; pab.s ...

  3. 根据本地/服务器时间获取指定时区时间 new Date指定时区时间

    1.代码 function getTimeByTimeZone(timeZone){ var d=new Date(); localTime = d.getTime(), localOffset=d. ...

  4. 【C/C++开发】C++实现字符串替换的两种方法

    替换字符串replace() erase() //C++ 第一种替换字符串的方法用replace()|C++ 第二种替换字符串的方法用erase()和insert()[ C++string|C++ r ...

  5. 高级UI-高级渲染

    在使用了Panit画笔之后,可以对其进行渲染,从而达到更加人性化的方式 渲染分类 按常用渲染方式可以分为以下几种: BimapShader位图的图像渲染器 LinearGradient线性渲染 Rad ...

  6. TCP协议有几大计时器?

    1)超时重传计时器 目的:避免无限等待确认报文 创建时间:在发送TCP报文段时,会为该报文段设置一个超时重传计时器 可能发生的情况:在超时时间到达之前,收到了该报文段的确认则撤销计时器,否则重传该报文 ...

  7. Linux学习-防火墙-Selinux-配置本地YUM源

    关闭防火墙并设置开机不启动 systemctl status firewalld.service #查看firewalld状态systemctl stop firewalld #关闭systemctl ...

  8. 关于MySQL的内连接,外连接的总结

    首先创建两个数据库表,用户表u,账户表a 先看一下数据库表: u表: a表: 1. 内连接.    关键字:inner join SQL语句: select u.*,a.ID as aid,a.mon ...

  9. 函数的学习3——传递任意数量的实参&将函数存储在模块——参考Python编程从入门到实践

    传递任意数量的实参 形参前加一个 * ,Python会创建一个已形参为名的空元组,将所有收到的值都放到这个元组中: def make_pizza(*toppings): print("\nM ...

  10. tft_LCD一些引脚极性设置方法:vsync, hsync, VBLANK

    转载:https://blog.csdn.net/u014170207/article/details/52662988/ 在RGB模式中,LCD数据的扫描是以行为单位的.HSYNC是水平同步信号.P ...