2017-09-12 17:07:55 machunlin2010 阅读数 3155
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8009 人正在学习 去看看 秦子恒

一、微信配置:
参考地址:https://testerhome.com/topics/6871

1.打开微信,设法打开网址 http://debugx5.qq.com (推荐直接把这个网址发给文件传输助手,然后就可以直接打开链接了)
2.在打开的网页中选择 【信息】->【TBS settings】,勾选 【是否打开 TBS 内核 Inspector 调试功能】,并点击提交按钮
3.微信提示需要重启,点击重启

二、手机打开USB调试功能

三、PC端配置
1.PC上安装adb驱动程序,
下载地址:https://pan.baidu.com/s/1hrRfkVi, 官网地址:http://adbdriver.com/downloads/
2.安卓手机连上PC,安装驱动

四、调试
参考:http://www.cnblogs.com/JinQingsong/p/6591830.html
1.PC连接上手机,手机允许USB调试
2.PC打开Chrome,输入:chrome://inspect/#devices
3.手机上,在微信中打开一个H5页面,就可以正常调试了
4.如果chrome inspect调试时,弹出的界面为空白,那么编辑hosts文件,添加:
61.91.161.217 chrome-devtools-frontend.appspot.com
61.91.161.217 chrometophone.appspot.com

2019-08-04 14:00:04 zwkkkk1 阅读数 507
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8009 人正在学习 去看看 秦子恒

最近在项目中接手微信环境h5页面的开发,主要的是使用微信 JS-SDK 做原有项目部分功能在微信环境下的适配。

目前项目暂时告一段落,希望可以用几篇文章记录并分享这些天来学习、开发微信h5页面的心得、体会~

由于微信环境、sdk的限制,在微信环境下如何有更加良好的调试体验还是有一些坑的,本篇将主要介绍本人在实际业务开发中使用到的微信环境下h5页面的三种调试方法(由于没有苹果手机,所以在开发自测时多以安卓系统为主要的测试环境)。

1.使用 Chrome 模拟移动设备进行调试

1.1 简单介绍

Device Mode 可以近似模拟出网页在移动设备上的显示效果,就是下面红框所示的,可以说是最常用的移动端 h5 调试方式,这里不过多进行介绍。

在这里插入图片描述

在项目中因为要在微信环境下调用sdk,其余浏览器不能调用相关sdk功能,所以会根据不同的 User Agent 将 h5 页面分为普通浏览器环境微信环境有不同的业务逻辑(当然,根据不同的系统也会分 iOSAndroid )。

然而 Chrome Device Mode 只有如下的一些预设机型:

在这里插入图片描述

1.2 添加 User Agent 模拟微信环境

所以这里我们需要自己添加机型去模拟出微信环境,打开 chrome 开发者工具下面是简单的步骤示意图:

在这里插入图片描述

在这里插入图片描述

在图2第三个红框中加上 User Agent

Mozilla/5.0 (Linux; Android 7.0; MI 5s Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/64.0.3282.137 Mobile Safari/537.36 wxwork/2.4.16 MicroMessenger/6.3.22 NetType/WIFI Language/zh

这是我用的安卓系统微信环境的 User Agent,网上还可以搜到许多,也有iOS系统微信环境的,

加上之后就可以切换到对应预设机型进行调试啦~

1.3 简单的使用体验总结

总的来说,在 Device Mode 中基本不能调试微信 js-sdk 功能,微信支付、微信授权登录一般也有限制,那么能拿它来做啥呢?

因为项目中会根据微信环境普通浏览器环境有一些不同的 UI 样式,重新加载的速度个人感觉是今天介绍的方法中算是最快的,单纯以调整 UI 的目的来说体验是最好的,而且通过修改虚拟设备的宽高调试页面在不同设备上的 UI 效果。

2. 使用微信web开发者工具

微信官方推出的 web 开发者工具,可以通过模拟微信客户端的表现,使得开发者方便地在 pc 上进行开发和调试工作,下面是官方手册地址,有详细的介绍和入门教程,这里就不多加赘述

传送门

2.1 简单地聊聊使用体验

微信web开发者工具集成了 Chrome 开发者工具,可以像上面介绍的一样用来进行一些 UI 样式的调试

在这里插入图片描述

此外微信web开发者工具最大的特点是可以模拟 JSSDK 在微信客户端中的请求,并且可以直观的看到请求结果,如下图所展示的:

在这里插入图片描述

这一点真的很赞,可以直观地看到每次调用 JSSDK api 输入参数和请求结果。虽然微信 JSSDK 也可以开启调试模式,不过它是将调用的 所有 api 的返回值在客户端中 alert 出来,这种调试体验真的不是很好

不过因为是在 pc 端进行模拟,一些如扫码、定位、摇一摇等比较复杂的 sdk 功能无法进行模拟调试

2.2 再来唠唠移动调试的体验

微信 web 调试工具也带了真机调试功能,针对 Android 提供了 X5 Blink 调试和普通调试两种方式。

在开发中首先学习使用的是普通调试,简单来说就是借助 weinre 让你可以进行真机无线调试,下面是基本的调试界面:

在这里插入图片描述

最常用的功能有检查dom元素、查看network请求和console窗口,就是一个简陋版 chrome devtools,最大的劣势是不能进行断点调试,综合调试体验不如后面要介绍的 X5 Blink 调试

emmm… 这里要介绍的基于 X5 Blink 的真机调试不是微信 web 调试工具自带的那个。不知道为啥我在微信 web 调试工具中 X5 Blink 内核调试 的调试均以失败告终。只能使用另一种基于 X5 Blink 的真机调试方法。

3. x5 内核 + Chrome://inspect 进行微信环境 h5 真机调试

因为对底层原理不甚了解,所以此节着重介绍一些配置的步骤,也会贴出一些比较好的学习文章链接。

下面是谷歌官方对 Android 远程调试的介绍,可以自行学习:

Android 设备的远程调试入门

对 X5 内核的介绍:

X5 浏览器内核调研报告

3.1 打开微信 TBS 调试

微信进入下面的网址:http://debugx5.qq.com,或者扫下面的二维码

可能会有错误信息,先退出来,按照错误提示依次访问几个网址

  1. 进入 http://debugmm.qq.com/?forcex5=true

  2. 进入 http://debugtbs.qq.com 选择 “安装线下内核”

  3. 重新扫上面的码,可以进入下面的页面,选择 “打开TBS内核Inspector调试功能”

  4. 然后 USB 连接手机、电脑,打开开发者模式,打开 USB 调试,然后在 Chrome 中进入 chrome://inspect/#devices 页面,可以看到下面的页面

在这里插入图片描述

然后就可以选择对应页面 inspect,就可以开始真机调试,而且完美拥有 Chrome devtools 的功能

2019-06-28 10:44:03 xm_more 阅读数 429
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8009 人正在学习 去看看 秦子恒

本文介绍的是微信H5支付功能开发,也就是在微信之外的H5页面支付。

首先我们需要先看微信的官方文档https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1,这里面几乎介绍了全部流程了。等你了解大概流程之后,需要在微信公众平台和微信商户平台拿到或者配置一下参数。

appid:公众平台的appid

商户号:公众平台的商户号

商户密钥:key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

最后在商户平台后台产品中心-->开发配置 中添加H5支付回调域名,域名必须是通过备案的。(下图借用了某个兄弟的图,我懒得上后台截图了)

花了不少时间去填这些坑,填完了我们就可以吭哧吭哧开工搬砖了!

写完支付别忘了还有订单查询功能需要开发,主要为了查询出哪些王八蛋就只是来看看不买东西还占库存。不给钱的我们需要把库存要回来。

/**

* 保存订单并发起支付请求

* @param request

* @param response

* @throws IOException 

*/

@RequestMapping(value = "/save")

public void save(HttpServletRequest request, HttpServletResponse response) throws IOException{

//判断用户是否登录

String mobileNumber = (String)request.getSession().getAttribute("mobileNumber");

if(StringUtils.isEmpty(mobileNumber)){

return;

}

response.setContentType("text/xml;charset=utf-8");

PrintWriter out = response.getWriter();

ResponMsg msg = new ResponMsg();

msg.setSuccess(true);

String content = "提交成功";

try{

//获取用户选择的票务信息,邮寄信息

String ticketId = request.getParameter("ticketId");

String ticketCount = request.getParameter("ticketCount");

String userName = request.getParameter("userName");

String userAddress = request.getParameter("userAddress");

String userMobile = request.getParameter("userMobile");

 

//参数验证

if(StringUtils.isEmpty(ticketId) || StringUtils.isEmpty(ticketCount) || StringUtils.isEmpty(userAddress) 

|| StringUtils.isEmpty(userMobile) || StringUtils.isEmpty(userName)){

content = "请正确且完整填写收货信息!";

msg.setCode(-2);

return;

}

//判断是否有可售票 有则创建订单预留票并发起支付

ActTicket actTicket = showService.queryTicketById(Integer.valueOf(ticketId));

if(actTicket.getTicketStock() - Integer.valueOf(ticketCount) < 0){

content = "抱歉,已售完!感谢关注!";

msg.setCode(-1);

return;

}

//创建订单 

// 自己网站上的订单号

int randomNum  = (int) (Math.random() * 1999+5000);

//String out_trade_no = TimeUtils.getSysTime("yyyyMMddHHmmss") + randomNum;

String orderNO = TimeUtils.getSysTime("yyyyMMddHHmmss") + randomNum;

ActUserAddress actUserAddress = new ActUserAddress(mobileNumber, userName, userMobile,userAddress, orderNO);

ActOrder actOrder = new ActOrder();

actOrder.setOrderNumber(orderNO);

actOrder.setTicketId(actTicket.getId());

actOrder.setProductName(actTicket.getTicketLevel());

actOrder.setProductPrice(actTicket.getTicketPrice());

actOrder.setProductCount(Integer.valueOf(ticketCount));

actOrder.setTotalPay(actTicket.getTicketPrice() * Integer.valueOf(ticketCount));

actOrder.setPayType(1);

actOrder.setStatement(1);

actOrder.setUserAccount(mobileNumber);

actOrder.setActUserAddress(actUserAddress);

System.out.println(mobileNumber + " 创建订单:" +  actOrder.toString());

//缓存数据

request.getSession(true).setAttribute("actOrder", actOrder);

showService.createOrder(actOrder);

//发起支付 

content = "/show/wxPayH5";

msg.setCode(9);

}catch(Exception e){

msg.setCode(0);

msg.setSuccess(false);

msg.setMessage("当前人数过多,请稍后再来。");

e.printStackTrace();

}finally{

msg.setMessage(content);

out.print(JsonUtil.toJson(msg));

out.flush();

out.close();

}

}

 

 

 

/**

* 微信H5支付 

* 统一下单

* @param request

* @param response

* @param model

* @throws Exception

*/

@RequestMapping("/wxPayH5")

public void wxPayH5(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws Exception {

//System.out.println("pay ===== start===");

//System.out.println("pay mobile=== " + request.getSession().getAttribute("mobileNumber").toString());

ActOrder actOrder = (ActOrder)request.getSession(true).getAttribute("actOrder");

System.out.println("===wxPayH5===start===actOrder===" + actOrder.toString());

request.getSession().removeAttribute("actOrder");

Map<String, Object> result = new HashMap<String, Object>();

result.put("success", false);

try {

// 付款金额,必填

String total_fee = String.valueOf(actOrder.getTotalPay());  //"0.01"

 

// 账号信息

String appid = PayConfig.APP_ID; // appid

String mch_id = PayConfig.MCH_ID; // 商业号

String key = PayConfig.API_KEY; // key

 

String currTime = PayCommonUtil.getCurrTime();

String strTime = currTime.substring(8, currTime.length());

String strRandom = PayCommonUtil.buildRandom(4) + "";

String nonce_str = strTime + strRandom;

// 价格 注意:价格的单位是分

String order_price = new BigDecimal(total_fee).multiply(new BigDecimal(100)).toString().split("\\.")[0];

// 自己网站上的订单号

String out_trade_no = actOrder.getOrderNumber();

// 获取发起电脑 ip

String spbill_create_ip = HttpUtil.getRealIp(request);

 

// 回调接口

String notify_url = "http://wx.xxx.com/xx/xx/payNotifyMe";

// 页面跳转同步通知页面路径

String trade_type = "MWEB";

 

// 设置package订单参数

SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();

packageParams.put("appid", appid);

packageParams.put("mch_id", mch_id);

// 生成签名的时候需要你自己设置随机字符串

packageParams.put("nonce_str", nonce_str);

packageParams.put("out_trade_no", out_trade_no);

packageParams.put("total_fee", order_price);

packageParams.put("spbill_create_ip", spbill_create_ip);

packageParams.put("notify_url", notify_url);

packageParams.put("trade_type", trade_type);

packageParams.put("body", PayConfig.BODY);

packageParams.put("scene_info", "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"http://wx.xxxx.com\",\"wap_name\": \"测试\"}}");

String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);

System.out.println("订单号:" + out_trade_no + " 的签名:" + sign);

packageParams.put("sign", sign);

String requestXML = PayCommonUtil.getRequestXml(packageParams);

String resXml = HttpUtil.postData(PayConfig.UFDODER_URL, requestXML);

Map map = XMLUtil.doXMLParse(resXml);

//String urlCode = (String) map.get("code_url");

System.out.println("out_trade_no=" + map.get("out_trade_no"));

System.out.println("prepay_id=" + map.get("prepay_id"));

//确认支付过后跳的地址,需要经过urlencode处理

String urlString = URLEncoder.encode("http://wx.xxx.com/xx/xx/xx/list.html", "GBK");

String mweb_url = map.get("mweb_url")+"&redirect_url="+urlString;

 

//更新订单状态

actOrder.setPayOrderNO(map.get("prepay_id").toString());

actOrder.setStatement(2);

actOrder.setNote(map.get("sign").toString());

showService.updateOrderStatement(actOrder);

System.out.println("==========mweb_url==========" + mweb_url);

response.sendRedirect(mweb_url);

//result.put("sHtmlText", urlCode);

result.put("success", true);

} catch (Exception e) {

e.printStackTrace();

result.put("errormsg", e.getMessage());

}

}

 

 

/**

* 执行回调 确认支付后处理事件 例如添加金额到数据库等操作

* @param request

* @param response

* @throws Exception

*/

@RequestMapping("/payNotifyMe")

public void weixin_notify(HttpServletRequest request, HttpServletResponse response, ModelMap model)throws Exception {

System.out.println("进入支付h5回调=====================");

String xmlMsg = readData(request);

System.out.println("pay notice---------"+xmlMsg);

Map params = XMLUtil.doXMLParse(xmlMsg);

try {

// 过滤空 设置 TreeMap

SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();

Iterator it = params.keySet().iterator();

while (it.hasNext()) {

String parameter = (String) it.next();

String parameterValue = params.get(parameter)+"";

String v = "";

if (null != parameterValue) {

v = parameterValue.trim();

}

//System.out.println( parameter + " value==============="+v);

packageParams.put(parameter, v);

}

//订单号

String orderNO = packageParams.get("out_trade_no").toString().trim();

ActOrder actOrder = new ActOrder();

actOrder.setOrderNumber(orderNO);

actOrder.setPayOrderNO(packageParams.get("sign").toString().trim());

actOrder.setPayOrderNO(packageParams.get("transaction_id").toString());

String resXml = "";

// 处理业务开始

if ("SUCCESS".equals((String) packageParams.get("result_code"))) {

// 这里是支付成功 

model.put("msg", "付款成功");

// 执行自己的业务逻辑   更新订单状态

actOrder.setStatement(3);

// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.

resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";

} else {

model.put("msg", "付款失败");

actOrder.setStatement(0);

resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[充值失败]]></return_msg>" + "</xml> ";

}

 

//更新订单

showService.updateOrderStatement(actOrder);

 

BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());

out.write(resXml.getBytes());

out.flush();

out.close();

} catch (Exception e) {

e.printStackTrace();

}

}

 

public static String readData(HttpServletRequest request) {

BufferedReader br = null;

try {

StringBuilder result = new StringBuilder();

br = request.getReader();

for (String line; (line=br.readLine())!=null;) {

if (result.length() > 0) {

result.append("\n");

}

result.append(line);

}

 

return result.toString();

} catch (IOException e) {

throw new RuntimeException(e);

}

finally {

if (br != null)

try {br.close();} catch (IOException e) {e.printStackTrace();}

}

}

需要完整的代码可以留言哦!可有偿指导开发完整个流程!

 

2019-02-11 15:28:05 weixin_44436078 阅读数 600
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8009 人正在学习 去看看 秦子恒

先整理下需求:

  1. 首先确定的是,这是一个H5页面,是在微信端展示的一个H5页面
  2. 需要获取微信用户头像、性别、昵称需要获取微信用户头像、性别、昵称
  3. 测试结果需要生成图片,用户可直接长按保存图片
  4. 分享

具体流程:

  • 申请公众号(需要公众平台的账号密码)
  • 需要注册成为当前该公众号的开发者
  • 需要后台进行服务器的配置http使用80端口,https使用443端口
  • 需要知道appid(公众号的唯一授权)
  • 需要知道redirect_uri(授权成功后的回调地址)
  • 因为需求是要做一个在微信端的h5页面,还需要获取微信用户的信息,所以一定会进行微信网页授权。微信授权分为两种:
  • snsapi_base:获取用户进入页面的openID,是静默授权(也就是用户不会有感觉)
  • snsapi_userinfo:获取用户的基本信息,是非静默授权(需要用户手动进行授权)

需要在微信打开此地址(地址里的内容需要自行填写,图片是地址的参数)
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=scope&state=STATE#wechat_redirect
地址参数用户同意授权后,页面将跳转至 redirect_uri/?code=CODE&state=STATE
redirect_uri就是你填写的回调地址

  • 需要获取code(直接可以从地址栏获取)通过code换取网页的access_token(与之前的access_token不同),如果scope的值是snsapi_base(静默授权)就会同时获取到
//取地址栏参数
function GetQueryString(name) {
	var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
	var r = window.location.search.substr(1).match(reg);
	if (r != null) return unescape(r[2]);
	return null;
};
//调用方法
GetQueryString("code");
  • 请求方式get

  • 通过拼地址的方式向后台发送code请求用户数据

  • 我这里生成图片用的html2canvas,具体教程点击这里

  • html2canvas.js下载点击这里

  • 微信分享

  • 需要在调用接口的页面引入js点击这里

  • 需要提高服务器稳定性时,可点击这里

  • 需要后台生成签名,具体可看微信公众平台的附录1点击这里

  • 获取签名,就是普通的post请求,这里需要给后台传一个url就是上面回调函数中的url,也可以通过window.location.href.split('#')[0]方式来获取,后台需要返回生成签名的时间戳(timestamp),随机串(nonceStr)和签名(signature)

  • 注入权限验证配置(所有需要使用JS-SDK的页面必须先注入配置信息)

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名
    jsApiList: [] // 必填,需要使用的JS接口列表
});
  • 分享接口
//分享给朋友,分享到QQ好友
	wx.updateAppMessageShareData({
		title: '', // 分享标题
		desc: '', // 分享描述
		link: location.origin , // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
		imgUrl: '', // 分享图标
		success: function() {
			//成功后的回调函数
		}
	});
//分享到朋友圈,分享到QQ空间
wx.ready(function () {      //需在用户可能点击分享按钮前就先调用
    wx.updateTimelineShareData({ 
        title: '', // 分享标题
        link:  location.origin, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
        imgUrl: '', // 分享图标
        success: function () {
          // 设置成功
        }
    })
});

location.origin返回url中完整的协议和主机地址部分,包括端口

2018-01-23 18:10:09 qq_34664239 阅读数 1705
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8009 人正在学习 去看看 秦子恒

微信支付

h5微信支付-公众号支付

  • 微信H5支付接口开发步骤
  • 前端 传值:金额、trade_type
  • 后台下单,返回mweb_url
  • mweb_url为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付
  • mweb_url的有效期为5分钟。

完整代码

///app/video/pay/wechatReward.json是后台接口,前端传值(金额、tradetype等),后台下单,返回mweb_url
$('.btn').click(function(){
    var fzMoney = $('.money').val();
    gObj.parameterObj.tradetype = 'MWEB';
    gObj.parameterObj.type = 0;
    $.ajax({
        type:"post",
        url:"/app/video/pay/wechatReward.json?videoid=14079&payrmb="+ fzMoney +'&'+getNowTime(),
        async:true,
        dataType: 'json',
        data: gObj.parameterObj,
        success: function(data){
            alert(JSON.stringify(data))
            window.location.href = data.data.mweb_url;
        }
    });
})

微信H5开发(一)

阅读数 9859

SpringBoot对接微信H5

阅读数 1482

没有更多推荐了,返回首页