顺晟科技
2021-06-16 10:50:49
221
微信支付现在用到的地方越来越多,从公众号支付,扫码支付一直到现在的小程序支付等等六种快捷支付方式,公司要求开发小程序商城,就只能我上手处理接口支付问题了,使用最常规的第三方模式,第三方帮特约商户申请商户号并为他进行支付开发,第三方本身不经手资金,支付成功后资金直接进入特约商户商户号。
废话不多说直接上代码。
小程序访问地址:payfee.php如果使用东帝汶的网络域名代号框架处理后台的话,写成方法即可
包括weixinpay。PHP ';
$ appid=//小程序应用编号
$ open id=$ _ POST[' id '];
$ mch _ id=//微信支付商户支付号
$ key=//Api密钥
$out_trade_no=$mch_id .time();
$ total _ fee=$ _ POST[' fee '];
if(空($total_fee)) { //押金
$body='充值押金;
$ total _ fee=float val(99 * 100);
} else {
$body='充值余额;
$ total _ fee=float val($ total _ fee * 100);
}
$weixinpay=new WeixinPay($appid,$openid,$mch_id,$key,$out_trade_no,$body,$ total _ fee);
$ return=$ weixin pay-pay();
echo JSON _ encode($ return);
WeixinPay.php微信小程序支付类所有微信小程序需要的参数都已经写入
/*
* 小程序微信支付
*/
班级微信{
受保护的$ appid
受保护的$ mch _ id
受保护的$ key
受保护的$ openid
受保护$ out _ trade _ no
受保护的$ body
受保护$ total _ fee
function __construct($appid,$openid,$mch_id,$key,$out_trade_no,$body,$total_fee) {
$ this-appid=$ appid;
$ this-open id=$ open id;
$ this-mch _ id=$ mch _ id;
$ this-key=$ key;
$ this-out _ trade _ no=$ out _ trade _ no;
$ this-body=$ body;
$ this-total _ fee=$ total _ fee;
}
公共职能工资(){
//统一下单接口
$ return=$ this-weixinapp();
退货$退货
}
//统一下单接口
私有函数unifiedorder() {
$ URL='https://api.mch.weixin.qq.com/pay/unifiedorder';
$parameters=array(
appid'=$this-appid,//小程序身份
mch_id'=$this-mch_id,//商户号
nonce _ str '=$ this-create non estr(),//随机字符串
//'body'='test ',//商品描述
body'=$this-body,
//' out _ trade _ no '=' 2018013106125348 ',//商户订单号
out _ trade _ no '=$ this-out _ trade _ no,
//' total _ fee '=浮点值(0.01 * 100),//总金额单位分
total_fee'=$this-total_fee,
sp bill _ create _ IP '=$ _ SERVER[' REMOTE _ ADDR '],//终端互联网协议(互联网协议)
//' sp bill _ create _ IP '=' 192。168 .0 .161 ',//终端互联网协议(互联网协议)
notify _ URL '=' https://www .微信。QQ。com/wx pay/notify。PHP ',//通知地址确保外网能正常访问
openid'=$this-openid,//用户编号
trade_type'='JSAPI'//交易类型
);
//统一下单签名
$ parameters[' sign ']=$ this-GetSign($ parameters);
$ XMldata=$ this-Arraytomxml($ parameters);
$ return=$ this-XMLToarray($ this-PostXMLCURl($ XMLData,$url,60));
退货$退货
}
私有静态函数postXmlCurl($xml,$url,$second=30)
{
$ ch=curl _ init();
//设置超时
curl_setopt($ch,CURLOPT_TIMEOUT,$ second);
curl_setopt($ch,CURLOPT_URL,$ URL);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验
//设置页眉
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_setopt($ch,CURLOPT _ CONNECTTIMEOUT,20);
curl_setopt($ch,CURLOPT_TIMEOUT,40);
set _ time _ limit(0);
//运行卷曲
$ data=curl _ exec($ ch);
//返回结果
if ($data) {
curl _ close($ ch);
返回$数据
} else {
$ error=curl _ errno($ ch);
curl _ close($ ch);
抛出新的WxPayException('curl出错,错误码: $ error ');
}
}
//数组转换成可扩展标记语言
私有函数Arraytomxml($ arr){
$ xml=' xml
foreach ($arr as $key=$val) {
if (is_array($val)) {
$xml .='' .$key .'' .arrayToXml($val).'/' .$key .'';
} else {
$xml .='' .$key .'' .$瓦尔。'/' .$key .'';
}
}
$xml .='/XML ';
返回$ xml
}
//xml转换成数组
私有函数xmlToArray($xml) {
//禁止引用外部可扩展标记语言实体
libxml _ disable _ entity _ loader(true);
$ XML string=simple XML _ load _ string($ XML,' SimpleXMLElement ',LIBXML _ NOCData);
$ val=JSON _ decode(JSON _ encode($ xmlstring),true);
返回$ val
}
//微信小程序接口
私有函数weixinapp() {
//统一下单接口
$ United order=$ this-unified order();
//print _ r($统一订单);
$parameters=array(
appId'=$this-appid,//小程序身份
时间戳'=' .时间()。'', //时间戳
non estr '=$ this-create non estr(),//随机串
包"="预付款_id=" .$unifiedorder['预付款_id'],//数据包
符号TYPe=' MD5 '//签名方式
);
//签名
$ parameters[' paySign ']=$ this-getSign($ parameters);
退货$参数;
}
//作用:产生随机字符串,不长于32 位
私有函数createnonestr($ length=32){
$ chars=' abcdefghijklmnopqrstuvwxyz 0123456789 ';
$ str=
for($ I=0;$ i $长度;$i ) {
$str .=substr($chars,mt_rand(0,strlen($chars) - 1),1);
}
返回$ str
}
//作用:生成签名
私有函数getSign($Obj) {
foreach ($Obj as $k=$v) {
$ Parameters[$ k]=$ v;
}
//签名步骤一:按字典序排序参数
ksort($ Parameters);
$ String=$ this-formatBizQueryParaMap($ Parameters,false);
//签名步骤二:在线后加入键
$字符串=$字符串.key=' .$ this-key;
//签名步骤三:MD5加密
$ String=MD5($ String);
//签名步骤四:所有字符转为大写
$ result _=strtopher($ String);
返回$ result _;
}
///作用:格式化参数,签名过程需要使用
私有函数formatBizQueryParaMap($paraMap,$urlencode) {
$ buff=
k sort($ ParAmap);
foreach ($paraMap as $k=$v) {
if ($urlencode) {
$ v=URL编码($ v);
}
$buff .=$ k .'='。$ v . ';
}
$ reqPar=
if (strlen($buff) 0) {
$reqPar=substr($buff,0,strlen($ buff)-1);
}
返回$ reqPar
}
}
小程序页面请求处理:
wx.request({
URL : ' https://您的主机。com/wx pay/pay fee。PHP ',//改成你自己的链接
数据:{
id: app.globalData.openid,//获取用户信息
fee:100 //商品价格
},
header: {
内容类型' : '应用程序
},
方法: '开机自检,
成功:功能(res) {
控制台。日志(资源数据);
console.log('调起支付');
wx.requestPayment({
时间戳' : RES . data。timeStamp,
非estr ' : RES .数据。非estr,
package': res.data.package,
签名类型: 'MD5 ',
paySign': res.data.paySign,
成功' :功能(res) {
控制台。日志(“成功”);
wx.showToast({
标题: '支付成功,
图标: '成功,
工期: 3000
});
},
失败' :功能(res) {
控制台。日志(RES);
},
完成' :功能(res) {
控制台。日志('完成');
}
});
},
fail:功能(res) {
console.log(res.data)
}
});
回调URL:notify.php
$ PostXML=$ GLOBALS[' HTTP _ RAW _ POST _ DATA '];//接收微信参数
//接受不到参数可以使用file _ get _ contents(' PHP ://input ');服务器端编程语言(专业超文本预处理器的缩写)高版本中$GLOBALS好像已经被废弃了
if(空($postXml)) {
返回错误的
}
//将可扩展标记语言格式转换成数组
函数xmlToArray($xml) {
//禁止引用外部可扩展标记语言实体
libxml _ disable _ entity _ loader(true);
$ XML string=simple XML _ load _ string($ XML,' SimpleXMLElement ',LIBXML _ NOCData);
$ val=JSON _ decode(JSON _ encode($ xmlstring),true);
返回$ val
}
$ attr=XMltoarray($ PostXMl);
$ total _ fee=$ attr[' total _ fee '];
$ open _ id=$ attr[' open id '];
$ out _ trade _ no=$ attr[' out _ trade _ no '];
$ time=$ attr[' time _ end '];
我测试过的代码都可以成功付费,希望对有需要的人有帮助~
2018年2月3日15:08:52补充:
当异步回调取值时,总是调用异步回调,使得我的数据在数据库中重复存储。官方文件也解释了这个问题
支付完成后,微信会将相关支付结果和用户信息发送给商家,商家需要接收处理并回复。
在与后台通知交互时,如果微信收到商家未成功或超时的响应,微信认为通知失败,会通过一定策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终会成功。(通知频率为15/15/30/180/1800/1800/1800/3600,单位:秒)
注意:同一通知可能会多次发送到商户系统。商户系统必须能够正确处理重复通知。
推荐的方法是在收到通知进行处理时,检查相应业务数据的状态,判断通知是否已经处理;如果尚未处理,将再次处理;如果已经处理,结果将直接返回。在检查和处理业务数据的状态之前,应该使用数据锁进行并发控制,以避免由于函数重新进入而导致的数据混乱。
所以:微信异步通知后,我们也需要回一条消息给微信服务器,但是微信的所有数据格式都是xml,所以我们可以回一条数据给微信。
echo exit('xmlreturn_code![CData[SUCCESS]]/return _ codereturn _ msg![CData[确定]]/return _ msg/XML ');
11
2022-12
04
2022-06
17
2022-03
18
2021-11
19
2021-06
16
2021-06