18910140161

PHP完成微信小程序在线支付功能

顺晟科技

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 ');

相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航