开发之前请详细阅读微信公众号支付开发文档,并配置好服务器信息。
微信支付开发文档
开始开发
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