微信H5网页公众号支付教程附demo

微信H5网页公众号支付教程附demo

开发之前请详细阅读微信公众号支付开发文档,并配置好服务器信息。
微信支付开发文档

1.微信支付申请,开通微信商户平台。
微信H5网页公众号支付教程附demo_第1张图片

2.开发配置,填写服务器地址。
微信H5网页公众号支付教程附demo_第2张图片
微信H5网页公众号支付教程附demo_第3张图片

3.在开发电脑上安装证书,用于设置获取商户秘钥。
微信H5网页公众号支付教程附demo_第4张图片

4.设置获取秘钥。
微信H5网页公众号支付教程附demo_第5张图片

开始开发
1.用户点击下面页面自动跳转到微信授权链接。
index.html



  
  	
    
	
	
	    
	
	
  
  
  

  


2.微信回调处理函数。
MainServlet.java

package com.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import com.utils.CommonUtil;

public class MainServlet extends HttpServlet {

	//网页授权获取用户信息
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String appid = "";//公众号appid
		String appsecret = "";//公众号秘钥
		//微信返回的code
		String code = request.getParameter("code");
		
		//获取openId和access_token(获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder)
		String openId = "";
		String access_token = "";
		String URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+appsecret+"&code="+code+"&grant_type=authorization_code";
		JSONObject jsonObject = CommonUtil.httpsRequest(URL, "GET", null);
		if (null != jsonObject) {
			openId = jsonObject.getString("openid");
			access_token = jsonObject.getString("access_token");
		}
		request.getSession().setAttribute("openId", openId);
		
		//获取用户信息
		String nickname = "";
		String headimgurl = "";
		String userURL = "https://api.weixin.qq.com/sns/userinfo?access_token="+access_token+"&openid="+openId+"";
		JSONObject userJson = CommonUtil.httpsRequest(userURL, "GET", null);
		if (null != jsonObject) {
			nickname = userJson.getString("nickname");
			headimgurl = userJson.getString("headimgurl");
		}
		request.getSession().setAttribute("nickname", nickname);
		request.getSession().setAttribute("headimgurl", headimgurl);
		
		response.sendRedirect("shop/index.jsp");//跳转到支付页面
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

3.支付页面ajax请求接口获取微信网页调起微信支付的相关参数(详见文档),用户点击购买的时候,请求接口获取支付参数。
shop/index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<% String path=request.getContextPath(); String basePath=request.getScheme()+ "://"+request.getServerName()+ ":"+request.getServerPort()+path+ "/"; %>
    
        
      
        
        
        微信商城
        
        
        
        
        
        
        
        
        
        
        
        
      
      
      
        

第一期:上海迪士尼门票

已参与人次

总需人次

剩余人次

我要参与

人购买人次越多获得几率越大哦!

购买

商品介绍

夺宝记录

用户晒单

您需要知道的"香港迪士尼乐园"

  • 特色1  迪士尼全球的第十一个主题乐园
  • 特色2  根据加州迪士尼为蓝本的主题乐园
  • 特色3  欣赏百老汇式精彩表演
  • 特色4  畅玩乐趣无穷的动感机动游戏

香港迪士尼乐园简介

  • 香港迪士尼乐园度假区位于香港大屿山,于2005年9月开幕,为宾客提供奇妙迪士尼体验。
  • 香港迪士尼乐园分七大主题园区,他们是美国小镇大街、幻想世界、明日世界、探险世界、2011年11月开幕的反斗奇兵大本营、2012年7月开幕的灰熊山谷以及2013年5月开幕的迷离庄园。代表不同年代不同时空的迪士尼体验。

·香港迪士尼乐园10周年庆典多个全新精彩演出的体验

香港迪士尼乐园踏入10周年,整个乐园将化身成为耳目一新的华丽大舞台;全新的音乐剧“迪士尼魔法书房”、崭新的影像投影展现“星梦奇缘”烟花表演、全新座落于幻想世界的“童话园林”,以及多款精美礼品、美食和更多精彩活动,诚邀您和挚爱一起投入香港迪士尼乐园10周年庆典,缔造Happily Ever After的时光。

·全新百老汇式音乐剧迪士尼魔法书房

万众期待的全新音乐剧“迪士尼魔法书房”是特别为香港而创作、乐园历年最大型的娱乐表演制作,由米奇老鼠和高飞带领宾客穿梭7个迪士尼故事,透过华丽表演与崭新舞台技术,投入一个新层次的奇妙旅程。不论音乐、编舞、服饰及舞台设计等都融入了经典及现代元素。
“迪士尼魔法书房”长达28分钟,将于幻想世界的迪士尼故事剧场上演,故事发生于一间魔法书房内,米奇老鼠与高飞好奇打开魔法书,因而令人见人爱的雪人小白从故事书中跌了出来。为了在小白溶化之前带他回到自己的故事,米奇老鼠、高飞及小白踏上奇妙的历险旅程,穿梭于7个迪士尼故事,包括:《小泰山》、《小鱼仙》、《魔发奇缘》、《勇敢传说之幻险森林》、《阿拉丁》、《公主与青蛙》及《魔雪奇缘》。
而为庆祝乐园10周年特别创作的主题歌曲《Happily Ever After》更会压轴登场,为华丽的演出带来圆满的结局。

·全新百老汇式音乐剧迪士尼魔法书房

万众期待的全新音乐剧“迪士尼魔法书房”是特别为香港而创作、乐园历年最大型的娱乐表演制作,由米奇老鼠和高飞带领宾客穿梭7个迪士尼故事,透过华丽表演与崭新舞台技术,投入一个新层次的奇妙旅程。不论音乐、编舞、服饰及舞台设计等都融入了经典及现代元素。
“迪士尼魔法书房”长达28分钟,将于幻想世界的迪士尼故事剧场上演,故事发生于一间魔法书房内,米奇老鼠与高飞好奇打开魔法书,因而令人见人爱的雪人小白从故事书中跌了出来。为了在小白溶化之前带他回到自己的故事,米奇老鼠、高飞及小白踏上奇妙的历险旅程,穿梭于7个迪士尼故事,包括:《小泰山》、《小鱼仙》、《魔发奇缘》、《勇敢传说之幻险森林》、《阿拉丁》、《公主与青蛙》及《魔雪奇缘》。
而为庆祝乐园10周年特别创作的主题歌曲《Happily Ever After》更会压轴登场,为华丽的演出带来圆满的结局。

4.处理支付的接口
TopayServlet.java

package com.servlet;

import java.io.IOException;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import com.utils.GetWxOrderno;
import com.utils.RequestHandler;
import com.utils.Sha1Util;
import com.utils.TenpayUtil;

public class TopayServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		request.setCharacterEncoding("UTF-8");
		JSONObject json = new JSONObject();
		
		//网页授权后获取传递的参数
		String money = request.getParameter("money");//分为单位
		String openId = request.getParameter("openId");
		
		//金额转化为分为单位
//		float sessionmoney = Float.parseFloat(money);
//		String finalmoney = String.format("%.2f", sessionmoney);
//		finalmoney = finalmoney.replace(".", "");
		int intMoney = Integer.parseInt(money);
		
		//商户相关资料 
		String appid = "";//公众号appid
		String appsecret = "";//公众号秘钥
		String partner = "";//商户号
		String partnerkey = "";//商户API秘钥
	
		//用于获取随机数
		String currTime = TenpayUtil.getCurrTime();//获取当前时间
		String strTime = currTime.substring(8, currTime.length());//8位日期
		String strRandom = TenpayUtil.buildRandom(4) + "";//四位随机数
		String strReq = strTime + strRandom;//10位序列号,可以自行调整
		
		String orderNo=appid+Sha1Util.getTimeStamp();//随机生成了一个订单号
				
				//商户号
				String mch_id = partner;
				
				//子商户号  非必输
				//String sub_mch_id="";
				
				//设备号   非必输
				String device_info="WEB";
				
				//随机数 
				String nonce_str = strReq;
				
				//商品描述
				String body = "一元夺宝";
				
				//附加数据
				String attach = "xx科技有限公司";
				
				//商户订单号
				String out_trade_no = orderNo;
				
				//总金额以分为单位,不带小数点
				int total_fee = intMoney;
				
				//订单生成的机器 IP
				String spbill_create_ip = request.getRemoteAddr();
				
				//订 单 生 成 时 间   非必输
//				String time_start ="";
				
				//订单失效时间      非必输
//				String time_expire = "";
				
				//商品标记   非必输
//				String goods_tag = "";
				
				//支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等:http://*/weChatpay/notifyServlet
				String notify_url ="http://你的域名/weChatpay/notifyServlet";
				
				String trade_type = "JSAPI";
				
				String openid = openId;
				
				//非必输
//				String product_id = "";
				
				//获取sign(统一下单接口签名)
				//第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),
				//使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
				//第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,
				//再将得到的字符串所有字符转换为大写,得到sign值signValue。
				SortedMap packageParams = new TreeMap();
				packageParams.put("appid", appid);  
				packageParams.put("mch_id", mch_id);  
				packageParams.put("nonce_str", nonce_str);  
				packageParams.put("body", body);  
				packageParams.put("attach", attach);  
				packageParams.put("out_trade_no", out_trade_no);  
				packageParams.put("total_fee", money);  
				packageParams.put("spbill_create_ip", spbill_create_ip);  
				packageParams.put("notify_url", notify_url);  
				packageParams.put("trade_type", trade_type);  
				packageParams.put("openid", openid);  
				RequestHandler reqHandler = new RequestHandler(request, response);
				reqHandler.init(appid, appsecret, partnerkey);
				String sign = reqHandler.createSign(packageParams);
				
				//统一下单接口携带参数(xml格式),接口地址https://api.mch.weixin.qq.com/pay/unifiedorder
				String xml=""+
						""+appid+""+
						""+mch_id+""+
						""+nonce_str+""+
						""+sign+""+
						""+
						""+attach+""+
						""+out_trade_no+""+
						//金额,这里写的1 分到时修改,测试用
//						""+1+""+
						""+total_fee+""+
						""+spbill_create_ip+""+
						""+notify_url+""+
						""+trade_type+""+
						""+openid+""+
						"";
				System.out.println(xml);
				
				String allParameters = "";//没用
				try {
					allParameters =  reqHandler.genPackage(packageParams);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				//请求微信统一下单接口,成功后返回预支付交易会话标识prepay_id
				String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
				String prepay_id = "";
				try {
					prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
					if(prepay_id.equals("")){
						request.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");
						response.sendRedirect("error.jsp");
					}
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				
				//生成H5调起微信支付API相关参数(前端页面js的配置参数)
				SortedMap finalpackage = new TreeMap();
				String timestamp = Sha1Util.getTimeStamp();//当前时间的时间戳
				String packages = "prepay_id="+prepay_id;;//订单详情扩展字符串
				finalpackage.put("appId", appid);//公众号appid  
				finalpackage.put("timeStamp", timestamp);  
				finalpackage.put("nonceStr", strReq); //随机数 
				finalpackage.put("package", packages);  
				finalpackage.put("signType", "MD5");//签名方式
				String finalsign = reqHandler.createSign(finalpackage);//签名

				json.put("appId", appid);
				json.put("timeStamp", timestamp);
				json.put("nonceStr", strReq);
				json.put("packages", packages);
				json.put("sign", finalsign);
				response.getWriter().append(json.toString());
				
				//response.sendRedirect("shop/index.jsp?appid="+appid+"&timeStamp="+timestamp+"&nonceStr="+strReq+"&package="+packages+"&sign="+finalsign);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

开发前最好详细阅读微信支付开发文档,理解所用接口,以及相关签名、参数等。
代码中用的其他类以及完整demo见下面链接,demo中有需要修改参数的说明文档。
源码链接
链接:https://pan.baidu.com/s/1vqamVIALHecPr7fbZysMeQ
提取码:82ye

你可能感兴趣的:(微信网页支付,H5活动,微信支付源码,Java,微信开发)