一、创建支付二维码
开发思路:使用Google的zxing来生成二维码,将图片生成base64,输出到前台显示!
1.1、用到的jar包
<!-- 生成微信二维码 -->
<dependency>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.2</version>
</dependency>
1.2、Action方法
/**
* 创建微信二维码
* 2017-09-06
* @param request
* @param response
*/
@RequestMapping(value = "/createPayCode")
public void createPayCode(HttpServletRequest request,HttpServletResponse response){
HttpSession session=request.getSession();
String userId = session.getAttribute("userId").toString();
String money = request.getParameter("money");
String orderId = request.getParameter("orderId");
try {
//预充值订单存redis
boolean flag = createRechargeOrder(userId,money,Long.valueOf(orderId));
if(flag){
SortedMap<Object,Object> paras = new TreeMap<Object,Object>();
paras.put("appid", PayConfigUtil.APPID);
paras.put("mch_id", PayConfigUtil.MCH_ID);
paras.put("time_stamp", Long.toString(new Date().getTime()));
paras.put("nonce_str", PayCommonUtil.CreateNoncestr());
paras.put("product_id", orderId);
String sign = PayCommonUtil.createSign("UTF-8", paras);
paras.put("sign", sign);
String url = "weixin://wxpay/bizpayurl?sign=SIGN&appid=APPID&mch_id=MCHID&product_id=PRODUCTID&time_stamp=TIMESTAMP&nonce_str=NOCESTR";
String result = url.replace("SIGN", sign).
replace("APPID", PayConfigUtil.APPID).
replace("MCHID", PayConfigUtil.MCH_ID).
replace("PRODUCTID", String.valueOf(paras.get("product_id"))).
replace("TIMESTAMP", String.valueOf(paras.get("time_stamp"))).
replace("NOCESTR", String.valueOf(paras.get("nonce_str")));
String res=PayCommonUtil.createCodeStream(result);
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain");
response.getWriter().println(res);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建预充值订单
* 2017-09-06
* @param userId
* @param money
* @param orderId
* @return
*/
private boolean createRechargeOrder(String userId, String money, Long orderId) {
JSONObject json=new JSONObject();
OrderRecharge recharge=new OrderRecharge();
boolean flag = false;
User user =null;
Long num=0L;
try {
user = userService.getUserById(Integer.valueOf(userId));
if(user !=null){
recharge.setOrderId(orderId);
recharge.setFriendpoolsId(user.getFriendpoolsId());
recharge.setOrderCreateTime(new Date());
recharge.setOrderMoney(Double.valueOf(money));
recharge.setOrderStatus(1); //预缓存
recharge.setOrderSystemPercentage(Const.SYSTEMPERCENTAGE);
recharge.setUserId(Integer.valueOf(userId));
json = (JSONObject) JSON.toJSON(recharge);
num = PayConfigUtil.WXPAYHash.hSet(orderId.toString(), json.toJSONString());
if(num == 0L){
FileUtils.addDebugLog("订单入redis失败,请检查redis的状态");
}else{
flag =true;
}
}
} catch (Exception e) {
System.out.println("充值订单入Redis报错:"+e.getMessage());
e.printStackTrace();
}
return flag;
}
二、微信支付回调
2.1 个人思路:用户前台扫描支付二维码后,将扫描到的数据提交到微信系统,微信系统根据商户预设的后台回调地址,将订单productid回传,后台接收到以后,根据productid去redis中查询预存的订单。然后调用微信统一下单接口,下单完成后向商户系统数据库中插入一条充值订单!
微信下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder
/**
* 微信支付回调
* 2017-09-06
* @param request
* @param response
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/wxPayCallBack",method=RequestMethod.POST)
public void wxPayCallBack(HttpServletRequest request,HttpServletResponse response)throws Exception{
InputStream stream = request.getInputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len = 0;
while((len = stream.read(buff)) !=-1){
outStream.write(buff, 0, len);
}
outStream.close();
stream.close();
String result = new String(outStream.toByteArray(),"utf-8");
Map<Object, Object> map=null;
JSONObject object=new JSONObject();
try {
map = PayXmlUtil.doXMLParse(result);
for(Object keyVal :map.entrySet()){
System.out.println(keyVal+"="+map.get(keyVal));
}
String orderId = map.get("product_id").toString();
if(PayConfigUtil.WXPAYHash.hExists(orderId)){
String value = PayConfigUtil.WXPAYHash.hGet(orderId);
OrderRecharge recharge=new OrderRecharge();
recharge = JSON.parseObject(value,OrderRecharge.class);
recharge.setOrderStat