宝哥软件园

微信支付(jsapi支付)流程教程ThinkPHP实现详解

编辑:宝哥软件园 来源:互联网 时间:2021-09-01

我写了一篇关于用PHP实现微信支付(jsapi支付)的过程的文章。详见文章:用PHP实现微信支付(jsapi支付)。

当时的环境没有使用框架。它是通过直接在域名指向的目录下新建一个目录,然后访问该目录来实现的。然而,当应用到框架中时,仍然存在一些问题。在ThinkPHP中,因为路由规则不同于支付授权目录,所以会报告错误。本文讲的是在TP中整合微信支付的过程。

鹅厂生产的SDK和文档只是让你无法理解,要下大力气绕过去。文档和SDK不应该尽可能简单易懂吗?只有通过艰苦的改造,才能在鹅厂展现程的精湛工艺吗?嗯.这暴露了我的菜鸟属性吗.其实SDK还是挺好用的,但是正如我在上一篇文章中看到的,在支付完成的回调函数中,真的是让人摸不着头脑。

对于不想被官方绕过,想用微信在TP支付的人,可以看看一个TP的支付SDK,是大神自己根据官方文件重构精简的。我下载并阅读了源代码。代码写得优雅简洁,过程简单易懂。见博文:http://baijunyao.com/article/78

我还是皱了皱眉头,用了官方的SDK,成功实现了支付。让我们与您分享这一过程:

1.软件开发工具包下载和修改

这个我就不多说了。如果你不知道,可以参考我上一篇文章:PHP实现了微信(jsapi)的支付流程,详细说明了哪些下载的文件需要修改。

2.微信官方账号设置

A.还需要设置网页授权域名,没什么特别的;

B.注意这里的支付授权目录。很多使用TP的人在使用REWRITE模式的同时使用REWRITE模式或者使用伪静态模式。此时生成的链接为:http://ServerName/Home/blog/Read/ID/1;

如果使用PATHINFO模式,生成的链接为:http://servername/index . PHP/Home/Blog/read/id/1,例如在Home模块下的Blog控制器中以一定的方法进行支付。我们支付的授权目录应该是http://serverName/Home/Blog/或http://servername/index . PHP/Home/Blog/,这取决于我们自己的TP设置的URL模式。

3.支付过程

(1)统一秩序

下单的支付参数配置和上一篇文章提到的基本一致。重点是支付回拨验证环节。因为需要多次调用,所以会在application/common/common/function . PHP中直接打包参数配置,我的SDK放在项目根目录下的Api目录中,所以在介绍SDK时不使用Vendor函数。

/** * 微信支付* @ param string $ OpenID OpenID * @ param string $ goods商品名称* @param字符串$attach附加参数,我们可以选择传递一个参数,比如订单ID * @param字符串$order_sn订单号* @param字符串$总额_费用金额*/function wxpay($openId,$goods,$order_sn,$total_fee,$attach){ require_once APP_ROOT ./Api/wxpay/lib/WxPay .API。PHP ';需要一次应用根./Api/wxpay/payment/WxPay .jsapipaye。PHP ';需要一次应用根./Api/wx pay/payment/log。PHP ';//初始化日志$ logHandler=新的CLogFileHandler(APP _ ROOT ./Api/wxpay/logs/' .日期(' Y-m-d '). log ');$ log=log : init($ log handler,15);$ tools=new JSapiPay();如果(空($ OpenID))$ OpenID=$ tools-GetOpenID();$ input=new wxpayunifieorder();$输入集正文($ goods);//商品名称$ input-SetAttach($ attach);//附加参数,可填可不填,填写的话,里边字符串不能出现空格$ input-Setout _ trade _ no($ order _ sn);//订单号$ input-SetTotal _ fee($ total _ fee);//支付金额,单位:分$ input-SetTime _ start(date(' YmdHis '));//支付发起时间$ input-SetTime _ expire(date(' YmdHis ',time()600));//支付超时$ input-SetGoods _ tag(' test3 ');//$input-SetNotify_url('http://' .$_SERVER['HTTP_HOST']./付款。PHP’);//支付回调验证地址$input-SetNotify_url('http://' .$_SERVER['HTTP_HOST']./付款。PHP/WexinApi/weixinay/notify’);$ input-set rade _ type(' JSAPI ');//支付类型$ input-SetUnid($ OpenID);//用户openID $ order=wxpayapi :统一订单($ input);//统一下单$ jsApiParameters=$ tools-GetJsApiParameters($ order);返回$ jsApiParameters}注意,注意,敲黑板划重点了:

支付回调验证链接,必须是没有权限验证的,如果你自己访问那个链接,还需要登录注册验证的,就不要尝试了,必须要可以无障碍访问的链接,而且也不要有一连串的参数传递。

最好就是简单粗暴的http://serverName/xxx.php,我在跟目录下,类似于index.php,重新写了一个专门的供支付回调的入口文件payment.php,和它对应的应用程序/目录下的模块(WexinApi)、控制器(韦新培)及方法(通知):

//检测服务器端编程语言(专业超文本预处理器的缩写)环境if(version_compare(PHP_VERSION,' 5.3.0 ',' ')die('要求PHP 5.3.0!');//$ _ GET[' m ']=' Admin ';//开启调试模式建议开发阶段开启部署阶段注释或者设为false define('APP_DEBUG ',True);//指定模块控制器和方法$ _ GET[' m ']=' WexinApi ';$ _ GET[' c ']=' weixinay ';$ _ GET[' a ']=' notify ';//定义应用目录定义(' APP_PATH ',' ./Application/');定义(' APP_ROOT ',目录名(_ _ FILE _ _));//引入ThinkPHP入口文件要求/ThinkCore/ThinkCore。PHP ';//亲^_^ 后面不需要任何代码了就是如此简单现在访问http://serverName/payment.php,就会直接进入到http://服务器名/支付。PHP/WexinApi/weixinay/notify,这样回调验证链接可以写http://serverName/payment.php,也可以写http://服务器名/支付。PHP/WexinApi/weixinay/notify。

(2)发起支付

照样很简单:

/** * 支付测试* 微信访问:http://道石。sdxichengxu。com/付款。PHP/WexinApi/weixinay/pay */public function pay(){ $ order _ sn=getrand _ num(true);$ OpenID=$ JSapiParameters=wx pay($ OpenID,)江南极客,$order_sn,1);$this-assign(数组(' data '=$ JSapiParameters));$ this-display();} html head meta http-equiv=' content-type ' content=' text/html;charset=utf-8 '/meta name=' viewport ' content=' width=device-width,initial-scale=1'/title小尤支付测试/title脚本类型='text/javascript' //调用微信文档支付函数JSapiCall(){ var data={ $ data };维信桥。invoke(' getBrandWCPayRequest ',data,function(RES){ weixinsbridge。日志(RES . err _ msg);//alert(' err _ code : ' RES . err _ code ' err _ desc : ' RES . err _ desc ' err _ msg : ' RES . err _ msg);//alert(RES . err _ code RES . err _ desc RES . err _ msg);//alert(RES);if(RES . err _ msg==' get _ brand _ wcpay _ request : ok '){ alert('支付成功!');窗户。位置。href=' http://m。博客。csdn。网/文章/详情?id=72765676 ' rel='外部无跟随';} else if(RES . err _ msg==' get _ brand _ wcpay _ request : cancel '){ alert('用户取消支付!');}else{ alert('支付失败!');} } );}函数callpay() { if(类型为weixin bridge==' undefined '){ if(document。addeventlistener){ document。addeventlistener(' weixinsbridgeready ',jsApiCall,false);} else if(文档。attachevent){ document。attach event(' weixinsbridgeready ',JSapicall);文件。attach event(' on weixinsbridgeready ',JSapicall);} } else { JSapiCall();} }/脚本/头体br/font color='#9ACD32 '该笔订单支付金额为span style=' color : # f00 font-size :50 px ' 1分/span钱/font br/br/font color=' # 9ACD 32 ' span style=' color : # f00;font-size :50 px"左边距-:40%;"一分/span钱也是爱/fontbr/br/div align='center '按钮样式=' width:210px高度:50 px边框半径: 15px背景色-: # FE6714;border:0px #FE6714固体;光标:指针;颜色:白色;'font-size :16 pxtype='button' onclick='callpay()'果断买买买^_^/button /div /body /html不过支付页面的统一资源定位器要注意了,因为支付页面的统一资源定位器肯定带有不少参数,刚才说了东帝汶的网络域名代号中使用的重写模式,你的链接为类似[http://服务器名/主页/博客/阅读/id/1 ]这样的,可能带有更多参数,这时候微信支付会认为你的支付授权目录是[http://服务器名/主页/博客/已读/id/],但是你真实的授权目录是[http://服务器名/主页/博客/],所以就会报错。处理方法就是,在进入支付页面的时候,重构网址,写成普通模式,即为[http://服务器名/主页/博客/阅读?id=1),这样就可以了。

(3)支持成功回调

现在支付完成,就会进入到之前写好的链接对应的方法,即[http://服务器名/支付。PHP/WexinApi/weixinay/notify]:

//微信支付回拨验证公共函数notify(){ $ XML=$ globals[' http _ raw _ post _ data '];//这句话file_put_contents用于查看服务器返回的XML数据。测试后,file _ put _ contents('。/API/wxpay/logs/log.txt ',$ XML,file _ append)可以删除。//将服务器返回的XML数据转换为数组//$ data=JSON _ decode(JSON _ encode(SimpleXML _ load _ string($ XML,' SimpleXML Element ',libxml _ nocata)),true);$ data=XMltoarray($ XML);//保存微信服务器返回的签名符号$ data _ sign=$ data[' sign '];//sign不参与签名算法unset($ data[' sign ']);$ sign=$ this-MakeSign($ data);//如果($ sign==$ data _ sign)($ data[' return _ code ']==' success ')($ data[' result _ code ']==' success '){ $ result=$ data,则判断签名是否正确并判断付款状态;//这句话file_put_contents用于查看服务器返回的XML数据。测试后,file _ put _ contents('。/API/wxpay/logs/log1.txt ',$ XML,file _ append)可以删除。//获取服务器返回的数据$ order _ sn=$ data[' out _ trade _ no '];//订单号$ order _ id=$ data[' attach '];//附加参数,选择调拨订单ID $ OpenID=$ data[' OpenID '];//付款人OpenID $ total _ fee=$ data[' total _ fee '];//支付金额//更新数据库$ this-updatedb ($ order _ id,$ order _ sn,$ OpenID,$ total _ fee);} else { $ result=false}//如果($ result) {$ str=' xmlreturn _ code![CData[SUCCESS]]/return _ codereturn _ msg![CData[确定]]/return _ msg/XML ';}else{ $str='xmlreturn_code![CData[FAIL]]/return _ codereturn _ msg![CDATA[签名失败]]/return _ msg/XML ';} echo $ str返回$ result}为了安全起见,请重新验证返回的签名:

/* * *生成签名* @返回签名,此函数不覆盖签名成员变量*/受保护函数签名($ data){//获取微信支付密钥require _ once app _ root。/API/wx pay/lib/wx pay . API . PHP ';$ key= wxpayconfig : key;//empty $ data=array _ filter($ data);//签名步骤1:按字典顺序对参数ksort($data)进行排序;$ string _ a=http _ build _ query($ data);$ string _ a=URL decode($ string _ a);//签名步骤2:在字符串后添加KEY//$ config=$ this-config;$ string _ sign _ temp=$ string _ a . ' key='。$ key//签名步骤3: MD5加密$ sign=MD5($ string _ sign _ temp);//签名步骤4:所有字符大写$ result=strtopper($ sign);返回$ result}至此,TP中的微信支付结算完毕。这是通过集成官方的SDK实现的。如果不使用SDK,可以使用更简单的方法。见:PHP实现微信支付(jsapi支付)和退款(无需集成支付SDK)

摘要

以上是边肖介绍的ThinkPHP实现微信支付(jsapi payment)流程教程的详细讲解,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

更多资讯
游戏推荐
更多+