php微信支付JSAPI(不使用sdk)
【提示(认真脸)】支付文章仅为参考,请不要盲目相信各种攻略
语言:php
接入类型:jsapi
工作流程:
流程图
- 前期准备:配置回调地址等信息,配置公众号支付相关信息去这里,获取商户key的id和secret,开通微信支付相关功能
- 拿到用户的openid
- 商户号和商户的支付密钥(注意正确性,密钥在重新生成后会使之前的失效
- 前端调起后端处理支付信息的接口,传入用户、商品等项目相关信息,这些信息会是你支付的必要信息,例如商品价格,数量等
- 后端整合请求参数,需根据微信的要求整合成合适的形式作为参数作为数据传给获取预支付url
- 参数列表
- 随机数生成
md5(time() . mt_rand(0,1000))
- 签名(整合必填参数和需要的参数即可)
/** * KEY为商户key,MCHID为商户号 $para = array('appid' => APP_ID,'body' => $body,'detail' => $detail,'mch_id' => MCHID,'nonce_str' => $nonce_str,'notify_url' => NOTIFY_URL, //接收支付成功的回调函数'openid' => $user['open_id'],'out_trade_no' => $orderNumber, //自定义订单号'spbill_create_ip' => $userIp,'total_fee' => $money,'trade_type' => 'JSAPI'); */function getSign($para){$config = config();$str = '';foreach ((array)$para as $key => $value){$str .= $key.'='.$value.'&';}$str .= 'key='.KEY;$sign = MD5($str);return strtoupper($sign); }
- 通过请求预支付api(https://api.mch.weixin.qq.com/pay/unifiedorder)获取预支付id等信息,支付回调函数路径在此处作为参数之一传给微信端
- 整合参数(向用于生成签名的数组添加签名)
$para = array('appid' => APP_ID,'body' => $body,'detail' => $detail,'mch_id' => MCHID,'nonce_str' => $nonce_str,//接收支付成功的回调函数,注意应可被其他ip访问,url不能携带参数,不能有误导性字符(例如?)'notify_url' => NOTIFY_URL, 'openid' => $user['open_id'],'out_trade_no' => $orderNumber, //自定义订单号'spbill_create_ip' => $userIp,'total_fee' => $money,'trade_type' => 'JSAPI','sign' => $sign);
- 根据要求将参数转化成xml形式
//参数data为整合好的数组 function ToXml($data){$xml = "<xml>";foreach ($data as $key=>$val){$xml .= "<".$key."><![CDATA[".$val."]]></".$key.">";}$xml.="</xml>";return $xml; }
- 发起访问
$ch = curl_init();curl_setopt($ch,CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder');curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验//设置headercurl_setopt($ch, CURLOPT_HEADER, FALSE);//要求结果为字符串且输出到屏幕上curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);curl_setopt($ch, CURLOPT_POST, TRUE);curl_setopt($ch, CURLOPT_POSTFIELDS, $para);$data = curl_exec($ch);if($data){curl_close($ch);$data = simplexml_load_string($data,'SimpleXMLElement', LIBXML_NOCDATA);$data = (array)$data;$return['data'] = $data;return $return;} else {$error = curl_errno($ch);curl_close($ch);throw new WxPayException("curl出错,错误码:$error");}
$data就是你获取的结果,根据微信统一下单接口的描述,分别有两个状态码return_code(返回状态),result_code(业务状态),你需要根据状态码来判断不同的情况,从而更新用户支付流程的进展
更新进展后需要将获得的预支付id(prepay_id)及其他参数再次签名打包给前端,用于确保数据的安全性
//数组的值都应为string,若为其他类型可以用strval()转化$config = array('appId' => APP_ID,'nonceStr' => $noncestr,'package' => 'prepay_id=' . $prepay_id,'signType' => 'MD5','timeStamp' => strval($time));$sign = getSign($config);$config['paySign'] = $sign;//config数组是用来调起内置对象WeixinJSBridge的参数
- 整合参数(向用于生成签名的数组添加签名)
- 拼接前端调起WeixinJSBridge的参数参数文档,连同上一步获得的信息返回给前端
- 前端在WeixinJSBridge的第三个参数的函数中查询订单信息
- 因为前端WeixinJSBridge的回调函数中不保证返回值即付款状态的正确性,因此有以下几种方法参考:
- 开发后台提供订单查询接口
- 不对前端接收的支付结果进行判断,都去请求后台的订单查询接口
- 后台配置回调接口的逻辑完整性,保证接收到微信的返回信息(如果有)并加以处理
- 在生成预支付id成功后返回前端前存入本地订单信息为未支付或其他状态,接收到下一步正确信息后再予以更新
- 因为前端WeixinJSBridge的回调函数中不保证返回值即付款状态的正确性,因此有以下几种方法参考:
if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);}else if (document.attachEvent){document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);}}else{let sn = res.data.para.out_trade_noWeixinJSBridge.invoke('getBrandWCPayRequest', {"appId": res.data.config.appId, //公众号名称,由商户传入 ok"timeStamp":res.data.config.timeStamp, //时间戳,自1970年以来的秒数 ok "nonceStr": res.data.config.nonceStr, //随机串 "package": res.data.config.package,"signType": res.data.config.signType, //微信签名方式 "paySign": res.data.config.paySign //微信签名 },function(payres){if(payres.err_msg == "get_brand_wcpay_request:ok"){// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。that.checkOrder(sn) }else if(payres.err_msg == "get_brand_wcpay_request:cancel"){alert('取消支付')}else if(payres.err_msg == "get_brand_wcpay_request:fail"){alert('支付失败')}}); }
7.回调函数
public function index(){$str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';$this->load->database();$post = $_REQUEST;if ($post == null) {$post = file_get_contents("php://input");}if ($post == null) {$post = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';}$data = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);$post = (array)$data;if (empty($post) || $post == null || $post == '') {//阻止微信接口反复回调接口echo $str;exit('非法调用');}//订单号$out_trade_no = array_key_exists('out_trade_no',$post) && !empty($post['out_trade_no']) ? $post['out_trade_no'] : 0;//你的订单信息//$order_info = if (!empty($order_info)) {//接收到的签名$post_sign = $post['sign'];//重新生成签名$newSign = getSign($post);//签名统一,则更新数据库if ($post_sign == $newSign && $post['total_fee'] == $order_info['amount']*100) {//你的操作} else {//你的操作}}echo $str;}
注意事项:
- 整合请求参数时,将请求参数按参数名ascii码值从小到大拼接为字符串并生成签名签名算法,再在参数中拼接上生成的签名,一同拼接成xml格式的请求参数,并初始化一个新的会话curl_init()向微信接口提交参数,接收返回的预支付id
- 生成的签名可以先在签名校验工具中校验,成功后再进行下一步,大多数都是在参数按序排列出错
- 查询状态时,只依靠回调参数并不可靠(网络,付款延迟等意外状态),需要配合主动查询接口更新付款状态
其他:看文档之前建议先弄懂流程(同时也是给自己的建议),再去有目的性的参考文档,盲目拿来确实会有不少坑
php微信支付JSAPI(不使用sdk)相关推荐
- jsapi支付签名_PHP实现微信支付(jsapi支付)流程步骤详解
最近接触到一个项目,涉及到微信支付,搞微信开发这么久以来,还没搞过支付,之前也就搞过公众号发红包,感谢前辈们的探索,我看了他们的博文,让我少走了很多弯路. 前期准备: 1.微信认证服务号,并且开通了微 ...
- php如何接入微信支付接口,PHP实现微信支付(jsapi支付)流程的方法
最近接触到一个项目,涉及到微信支付,搞微信开发这么久以来,还没搞过支付,之前也就搞过公众号发红包,感谢前辈们的探索,我看了他们的博文,让我少走了很多弯路. 前期准备: 1.微信认证服务号,并且开通了微 ...
- ThinkPHP中实现微信支付(jsapi支付)流程
之前写过一篇文章讲了 PHP实现微信支付(jsapi支付)流程 ,详见文章: PHP实现微信支付(jsapi支付)流程. 当时的环境是没有使用框架的,直接在一个域名指向的目录下边新建目录之后访问该目录 ...
- PHP实现微信支付(jsapi支付)流程
最近接触到一个项目,涉及到微信支付,搞微信开发这么久以来,还没搞过支付,之前也就搞过公众号发红包,感谢前辈们的探索,我看了他们的博文,让我少走了很多弯路. 前期准备: 1.微信认证服务号,并且开通了 ...
- php微信支付jsapi,ThinkPHP实现微信支付(jsapi支付)
这篇文章主要介绍了ThinkPHP实现微信支付(jsapi支付)流程教程详解,需要的朋友可以参考下 之前写过一篇文章讲了PHP实现微信支付(jsapi支付)流程 ,详见文章:PHP实现微信支付(jsa ...
- 一次性解决微信支付-JSAPI支付问题(想把微信支付JSAPI文档撰写者按在地上摩擦)
最近一个项目需要接入微信支付,所以在现有的项目中接入这个功能,但是最终发现,微信支付是个大坑,至少我认为微信支付文档的撰写者应该是小学水平,又或者是幼儿园水平,写文档的能力简直无语,很多关键性的细节居 ...
- 微信支付 JSAPI
准备工作 申请微信商户号流程 PC端微信支付登录页 微信支付JSAPI开发文档 需要获取的信息 商户号 mch_id 公众号 appId 服务器地址 notify_url api证书 密钥 通知地址 ...
- php微信支付jsapi,ThinkPHP中实现微信支付(jsapi支付)流程
之前写过一篇文章讲了 PHP实现微信支付(jsapi支付)流程 ,详见文章:PHP实现微信支付(jsapi支付)流程. 当时的环境是没有使用框架的,直接在一个域名指向的目录下边新建目录之后访问该目录实 ...
- 关于IOS调用微信支付jsapi不起作用的解决方法
关于IOS调用微信支付jsapi不起作用的解决方法 参考文章: (1)关于IOS调用微信支付jsapi不起作用的解决方法 (2)https://www.cnblogs.com/randy619/p/5 ...
- jsp页面微信支付接口_微信支付 JSAPI 开发中的问题
前言:这篇文章讲的是利用微信官方提供的JSPAI接口,实现微信网页支付.希望在看之前,要确认一下几件事情,否则会让您在解决问题是很费解. ① 接口文档版本号是V3.3(在官方提供的PHP DEMO中的 ...
最新文章
- Sqli-labs less 25a
- CentOS中安装的Gitlab忘记管理员密码怎样重置密码
- Silverlight C# 游戏开发:资源的处理,图像算法(二)
- 纯HTML的个人简历,真的超简单,有源码
- 阿里云服务器如何使用
- HLW8032串口通讯芯片的三相电参数采集系统项目资料
- flac格式如何转mp3?
- 如何使用C4D的反射通道创建一个金属外观?
- 人工智能之不确定推理方法
- leejianjun的博客 PHP生成word并可下载
- J2ME--丰富多彩的领域中生机勃勃的技术
- win10如何共享打印机_局域网内,办公室USB接口打印机如何共享
- halting problem 详解
- 小程序之 一个方法中的值怎么传递到另一个方法中
- ArcGIS 字段值替换
- 2015年9月11日
- HTML+CSS+JavaScript+JQuery
- 剑三服务器在哪个文件夹,剑网3无法正常获取服务器列表解决方法
- B2B电子商务网站建设怎么做:B2B系统开发流程、语言、架构解答
- 分段线性映射PWLCM的李雅普诺夫指数Lyapunov的matlab实现