这两天完成了公司网站手机和PC端的支付对接,就是支付宝和微信.

对接完后有所感触,我们来聊一聊,微信支付的坑,为什么这么说呢,因为我在对接完支付宝后是很愉快的,基本上在demo上稍加修改就ok了,

对于支付宝我觉得基本上都没什么可以说的,而微信支付...

网上搜了一下,基本上没有看到有针对h5支付的成功教程,全都是复制粘贴官方文档,有意思吗.

恰好今天空了,来聊一聊微信支付的坑,当然本文也不是光吐槽了事,我会把完整的代码放到文末尾处,并加以适当的注释.

------------------------------

首先第一步去微信商户平台开通h5支付的.

因为公司的app中的微信支付是我对接的,所以在开始做手机网站的微信支付前,我首先想到去微信开放平台,新建了一个网站应用,

最后审核下来居然没有支付接口,只有获取用户信息的接口,我有点蒙笔,然后我打了一下客服电话,那边客服说h5支付在公众号平台中完成(注意:这里客服mm向我扔了一个巨坑,接着往下看

既然这样,我就去了微信公众号平台,我们有服务号,拿着appid和mch_id就开始搞,一切都很好,但是提示[商户号该产品权限预开通中,请等待产品开通后重试],

我赶紧登录商户平台看一下,确定h5是开通的没问题,这个时候我注意到一个问题,就是我的公众号平台中的商户号和商户平台中的商户号不一致,我检查了公司信息,邮箱,手机号,两者都是完全一样的.

这个时候我把代码中的商户号(微信公众号平台的)改成了商户平台的商户号,请求接口返回[商户号和appid不匹配],我再次坚定,应该用微信公众号平台的商户号,因为appid是用的微信公众号平台的.

这个时候我陷入了焦灼,网上找了很久,没有搜到任何跟[商户号该产品权限预开通中,请等待产品开通后重试] 有关的结果,我给微信支付技术发了一封邮件,阐述了我遇到的问题,

第二天技术回复了我,说 "你开通h5支付的商户号是这个(商户平台的),而不是你现在用这个(微信公众号平台的)",这就是前面那个客服mm给我扔的大坑!!

邮件中还告诉我,我开通h5支付的商户号对应的appid是这个[appid**],而这个appid是我在开放平台中以前建的移动应用,也就是我们之前的app中用的...此时一万只草泥马在开始奔腾.

前后跨度太大,让我一时无法接受这个事实,

你先告诉我,h5支付为什么跟移动应用扯上关系了,其次你文档中提到了一星半点吗,没有!,客服mm也是调皮,动不动就h5支付跟开放平台没关系,只需要公众号平台.

还有 你微信产品真多 微信公众号平台(配置),微信开放平台(文档),微信商户平台(配置),我对接个微信支付要在三大平台之间来回切换,你真的666!!!

---------------------------------

平复一下心情,来看一下h5支付的流程,整个逻辑是这样的,首先用户打开手机网站某个服务页面

点击开通某个产品时,此时通过ajax请求带上产品价格,名称等参数来请求一个php脚本(wxpay_wap.php),

这个脚本根据官方文档要求的参数,组合,生成签名,请求统一下单接口,

返回一个支付url,然后用js生成一个a标签并模拟点击或者直接location.href应该都是可以的,

就会调起微信支付,支付完成后微信会发送一个请求到你设定的回调脚本(wxpay_wap_notify.php),在回调脚本里写业务逻辑

大体就是这样的,以下代码稍加修改就可以直接用了

---------------------------------

wxpay_wap.php

 // 文档中说的,价格 单位是分
$money = $_POST['money']*100; //商品价格
// 前台请求的参数
$title = $_POST['title']; //商品名称
$userid = $_POST['userid']; //用户id $time = time(); $nonce_str = "hcuasduvihasdiovjerjgvujsaru"; //随机字符串
$appid = "wx**************33"; //在微信开放平台中的 appid(先要创建一个移动应用)
$mch_id = "147****642"; //商户号,在商户平台中查看
$key = "51b*************************f15e"; //在微信开放平台中的 
$notify_url = "http://www.xxx.com/xxx/wxnotify.php"; //用户支付完后微信会来触发这个脚本,是处理业务逻辑的地方
//订单号可以灵活使用,比如我这个地方把userid加进去,在异步回调的时候方便直接操作用户
$out_trade_no = $time."__".$userid; // 下面的参数含义直接看文档
$tmpArr = array(
'appid'=>$appid, //不要填成了 公众号原始id
'attach'=>$title, 
'body'=>$title,
'mch_id'=>$mch_id,
'nonce_str'=>$nonce_str,
'notify_url'=>$notify_url,
'out_trade_no'=>$out_trade_no,
'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],
'total_fee'=>$money,
'trade_type'=>'MWEB'
);
// 签名逻辑官网有说明,签名步骤就不解释了
ksort($tmpArr); $buff = "";
foreach ($tmpArr as $k => $v)
{
$buff .= $k . "=" . $v . "&";
}
$buff = trim($buff, "&");
$stringSignTemp=$buff."&key=51b3363e91fe317fc346526f5933f15e";
$sign= strtoupper(md5($stringSignTemp)); //签名 $xml = "<xml>
<appid>".$appid."</appid>
<attach>".$title."</attach>
<body>".$title."</body>
<mch_id>".$mch_id."</mch_id>
<nonce_str>".$nonce_str."</nonce_str>
<notify_url>".$notify_url."</notify_url>
<out_trade_no>".$out_trade_no."</out_trade_no>
<spbill_create_ip>".$_SERVER['REMOTE_ADDR']."</spbill_create_ip>
<total_fee>".$money."</total_fee>
<trade_type>MWEB</trade_type>
<sign>".$sign."</sign>
</xml> "; $posturl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; $ch = curl_init($posturl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$response = curl_exec($ch);
curl_close($ch); $xmlobj = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA )));
exit($xmlobj->mweb_url);

------------------------------------------

wxpay_wap_notify.php

 // 本脚本的业务逻辑只是个例子,仅供参考

 // 拿到原始数据并通过xml类解析为对象
$postObj = simplexml_load_string(file_get_contents("php://input"), 'SimpleXMLElement', LIBXML_NOCDATA );
// 你可以通过下面这种方式来看一下微信究竟返回了那些参数,请保证log.php存在并且有写权限
// file_put_contents(dirname(__file__)."/log.php",file_get_contents("php://input"));
$arr = array();
foreach ($postObj as $key => $value) {
$arr[$key] = $value;
}
// 订单状态
$status = $arr['result_code']; if(trim($status) == "SUCCESS") {
// 微信订单
$out_trade_no = $arr['transaction_id']; // 价格
$money = $arr['total_fee']/100;
// 在商户订单号中提取用户id,上一个脚本中我说了这个商户订单号可以灵活使用
$uid = explode("__", $arr['out_trade_no'])[1]; // 在数据库中检查这个订单号是否已经处理过了 以免重复处理,因为很多原因微信可能多次触发本脚本
// checkrepeat(orderid); /////////////////////////////////////////////////////////////
//// /////
//// 这里处理业务逻辑.... /////
//// /////
///////////////////////////////////////////////////////////// // 处理完逻辑 返回这个xml数据,告诉微信服务器,这个订单号已经处理完了 不要在来骚扰我了
$xml = "
<xml>
<return_code><![CDATA[".$status."]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>";
echo $xml; }

如果需要微信扫码支付或者支付宝支付相关文章,请在我的php分类中查看

微信支付之h5方式(非微信内置浏览器中支付)的更多相关文章

  1. 微信内置浏览器中,点击下拉框出现页面乱跳转现象(iphone)

    微信内置浏览器中,点击下拉框出现页面乱跳转现象(iphone) 前言: 这是小菜博客的第三篇文章.一直认为自己可以表达的东西太过简单,难以上台面,总是吝啬地不肯写.就算是写,也不知道从何开始.在同事的 ...

  2. 微信内置浏览器中的cookie很诡异呀

    微信内置浏览器中的cookie很诡异呀 这是设置和删除COOKIE的代码 function set_cookie($var ,$value = '' ,$expire = 0){ $path = '/ ...

  3. 用js限制网页只能在微信内置浏览器或支付宝内置浏览器中打开

    function is_weixinOrAli(){ var ua = navigator.userAgent.toLowerCase(); //判断浏览器的类型 if (ua.match(/Micr ...

  4. MyEclipse中的内置浏览器中的历史记录怎么清除

    eclipse内置浏览器的访问记录是存储在对应的工程目录下的.metadata配置中,也就是说你新建一个工程的话就没有了. 如果确实要删除那就找到工作空间中的org.eclipse.ui.browse ...

  5. 清除Eclipse中的内置浏览器中的历史记录

    eclipse内置浏览器的访问记录是存储在对应的工程目录下的.metadata配置中, 也就是说你新建一个工程的话就没有了. 如果确实要删除那就找到工作空间中的org.eclipse.ui.brows ...

  6. PHP限制网页只能在微信内置浏览器中查看并显示

    微信现在算是火了,围绕微信开发的应用也越来越多了,前段时间,自己公司需要,用PHP写了一个微信应用,为了防止自己辛苦写成的PHP应用被盗用,于是 通过PHP做了限制,只能在微信自带的浏览器中才能打开本 ...

  7. 解决 iOS 9.1 微信内置浏览器中html audio 不能自动播放的问题

    使用微信现在提供过的微信js-sdk 在ready中进行播放便可. 首先引用js : <script src="http://res.wx.qq.com/open/js/jweixin ...

  8. 微信内置浏览器的JS API

    /**! * 微信内置浏览器的Javascript API,功能包括: * * 1.分享到微信朋友圈 * 2.分享给微信好友 * 3.分享到腾讯微博 * 4.新的分享接口,包含朋友圈.好友.微博的分享 ...

  9. 2017年05月10日记一次微项目投产 | 安卓版微信内置浏览器不能解析gzip压缩过的mp4视频的问题

    前言 今天投产了一个小项目,一个很简单的H5,有播放视频功能,使用了videojs插件. 之前也做过数个视频播放,视频的转压都按照既定流程进行,文件放到FTP后,iphone和安卓机测试下来都没有问题 ...

随机推荐

  1. 中了J.Fla的毒!

    中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒!中了J.Fla的毒! ...

  2. css 找到隐藏元素个数

    <form>   <input type="hidden" name="email" />   <input type=" ...

  3. Python验证码通过pytesser识别

    Python安装包: 需要安装的包主要有两个: PIL 和 pytesser .tesseract (1).安装PIL:下载地址:http://www.pythonware.com/products/ ...

  4. Chome——扩展程序,获取更多扩展程序报错

    修改/替换hosts文件 地址:c:/windows/system32/drivers/etc hosts:可从网上搜索下载或网盘下载(链接: http://pan.baidu.com/s/1bpu6 ...

  5. 走近RDD

    RDD(Resilient Distributed Datasets)弹性分布式数据集.RDD可以看成是一个简单的"数组",对其进行操作也只需要调用有限的"数组" ...

  6. Spring Cloud在国内中小型公司能用起来吗?

    今天吃完饭休息的时候瞎逛知乎,突然看到这个一个问题Spring Cloud在国内中小型公司能用起来吗?,吸引了我的注意.仔细的看了题主的问题,发现这是一个好问题,题主经过了一番思考,并且用图形全面的将 ...

  7. [转]Java7中的ForkJoin并发框架初探(下)—— ForkJoin的应用

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp86   前两篇文章已经对Fork Join的设计和JDK中源码的简要分析 ...

  8. CurrentCulture和CurrentUICulture的区别

    CurrentCulture 这个属性用来表示和改变使用者要使用的“地区属性”,地区属性改变后,数字.日期时间等表示格式也随之改变. 注意:一定是“地区属性”,如"zh-cn".& ...

  9. python 求解线性方程组

    Python线性方程组求解 求解线性方程组比较简单,只需要用到一个函数(scipy.linalg.solve)就可以了.比如我们要求以下方程的解,这是一个非齐次线性方程组: 3x_1 + x_2 - ...

  10. 王者荣耀是怎样炼成的(一)《王者荣耀》用什么开发,游戏入门,unity3D介绍

    在国内,如果你没有听说过<王者荣耀>,那你一定是古董级的人物了. <王者荣耀>(以下简称“农药”),专注于移动端(Android.IOS)的MOBA游戏.笔者看到这么火爆,就萌 ...