微信的H5支付区别与APP支付,主要在于预下单(返回的参数不一样),其它大体相同(基本没什么区别,区别在于有些人加密喜欢用MD5有些人喜欢用官方提供的加密方式加密,我用的是官方的),贴一下H5支付预下单的业务层以及控制层代码方便以后参考,其它代码可以参考微信APP支付

  • 业务层(预下单)
import com.aone.app.common.util.RandomNumUtil;
import com.aone.app.common.wx.*;
import com.aone.app.service.WxH5PayService;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map; @Service
public class WxH5PayServiceImpl implements WxH5PayService { private static final Logger logger = LoggerFactory.getLogger("WxH5PayServiceImpl");
@Autowired
private WxCfg wxCfg; /**
* /H5微信支付(预下单)
* @param type
* @param out_trade_no
* @param money
* @return
* @throws Exception
*/
@Override
public Map<String, String> dounifiedOrder(String type, String out_trade_no, String money, HttpServletRequest request) throws Exception {
//返回参数
Map<String, String> returnMap = new HashMap<>();
//微信配置
WXConfigUtil config = new WXConfigUtil();
WXPay wxpay = new WXPay(config);
//请求参数封装
Map<String, String> data = new HashMap<>();
data.put("appid", config.getAppID());
data.put("mch_id", config.getMchID());
data.put("nonce_str", WXPayUtil.generateNonceStr());
data.put("body", "H5订单支付");
data.put("out_trade_no", RandomNumUtil.getOrderIdByTime());//订单号
data.put("total_fee", "1");//支付金额
data.put("spbill_create_ip", IpAddr.getIpAddr(request)); //自己的服务器IP地址
data.put("notify_url", wxCfg.getH5NotifyUrl());//异步通知地址(请注意必须是外网)
data.put("trade_type", wxCfg.getH5Type());//交易类型
data.put("attach", type);//附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
String s = WXPayUtil.generateSignature(data, config.getKey()); //签名
data.put("sign", s);//签名
try {
logger.info("sign{}",data.get("sign"));
//使用官方API请求预付订单
Map<String, String> response = wxpay.unifiedOrder(data);
String returnCode = response.get("return_code");//获取返回码
logger.info("返回码{}",returnCode); //获取返回码
//若返回码为SUCCESS,则会返回一个result_code,再对该result_code进行判断
if (returnCode.equals("SUCCESS")) {
returnMap.put("ok", "200");
//拼接返回跳转地址
String url= UrlEnCode.urlEncode(wxCfg.getRedirect_url());
logger.info("url{}",url);
returnMap.put("url", response.get("mweb_url")+"&redirect_url="+url);
} else {
returnMap.put("ok", "201");
returnMap.put("url",null);
return returnMap;
}
} catch (Exception e) {
System.out.println(e);
//系统等其他错误的时候
}
return returnMap;
} }
  • 控制层下单接口以及回调接口
import com.aone.app.common.wx.XMLUtils;
import com.aone.app.service.WxH5PayService;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.util.HashMap;
import java.util.Map; @RestController
@RequestMapping("h5pay")
@Api("H5支付")
public class PayH5Controller { private static final Logger log = LoggerFactory.getLogger("PayH5Controller"); @Autowired
private WxH5PayService wxH5PayService; /**
* H5支付统一下单
* @param request
* @return
* @throws Exception
*/
@ResponseBody
@RequestMapping(value = "wxPay")
public Map<String, String> weixinPay(HttpServletRequest request) throws Exception{
String type= request.getParameter("type");
String orderNo= request.getParameter("orderNo");
String money= request.getParameter("money");
return wxH5PayService.dounifiedOrder(type,orderNo, money,request);
} /**
* H5微信支付异步结果通知
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value = "notify")
public void weixinPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
BufferedReader reader = request.getReader();
String line = "";
Map map = new HashMap();
String xml = "<xml><return_code><![CDATA[FAIL]]></xml>";;
StringBuffer inputString = new StringBuffer();
while ((line = reader.readLine()) != null) {
inputString.append(line);
}
request.getReader().close();
log.error("----接收到的报文---{}",inputString.toString());
if(inputString.toString().length()>0){
map = XMLUtils.parseXmlToList(inputString.toString());
}else{
log.error("接受微信报文为空");
}
log.error("map={}",map);
if(map!=null && "SUCCESS".equals(map.get("result_code"))){
//成功的业务。。。
xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
String type=map.get("attach").toString();
String orderNo=map.get("out_trade_no").toString();
log.error("订单号{}",map.get("out_trade_no"));log.error("其它必须参数{}",map.get("attach"));
if(StringUtils.isEmpty(type)||StringUtils.isEmpty(orderNo)){
log.error("当前参数类型异常");
}else{
//回调业务处理 }
}else{
//失败的业务。。。
}
//告诉微信端已经确认支付成功
response.getWriter().write(xml);
} }
  • H5回调接口中解析微信通知XML的工具类
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource; import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class XMLUtils { /**
* 解析微信通知xml
* @param xml
* @return
*/
@SuppressWarnings({ "unused", "rawtypes", "unchecked" })
public static Map parseXmlToList(String xml) {
Map retMap = new HashMap();
try {
StringReader read = new StringReader(xml);
// 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
InputSource source = new InputSource(read);
// 创建一个新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通过输入源构造一个Document
Document doc = (Document) sb.build(source);
Element root = doc.getRootElement();// 指向根节点
List<Element> es = root.getChildren();
if (es != null && es.size() != 0) {
for (Element element : es) {
retMap.put(element.getName(), element.getValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return retMap; }
}

微信支付过程中所需其它参数(应用AppID,商户密钥,商户号,以及商户证书的下载),参考微信官方开发文档。

微信H5支付(基于Java实现微信H5支付)的更多相关文章

  1. 微信APP支付(基于Java实现微信APP支付)

    步骤: 导入maven依赖 <!--微信支付--> <dependency> <groupId>com.github.wxpay</groupId> & ...

  2. 支付宝APP支付(基于Java实现支付宝APP支付)

    贴一下支付核心代码,以供后续参考: 业务层 import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; ...

  3. 带领技术小白入门——基于java的微信公众号开发(包括服务器配置、java web项目搭建、tomcat手动发布web项目、微信开发所需的url和token验证)

    微信公众号对于每个人来说都不陌生,但是许多人都不清楚是怎么开发的.身为技术小白的我,在闲暇之余研究了一下基于java的微信公众号开发.下面就是我的实现步骤,写的略显粗糙,希望大家多多提议! 一.申请服 ...

  4. 支付宝手机网站支付(基于Java实现支付宝手机网站支付)

    支付宝支付核心需要的参数是(APPID,PRIVATE_KEY,ALIPAY_PUBLIC_KEY) APPID:创建应用后就有的APPID. PRIVATE_KEY:应用私钥 ALIPAY_PUBL ...

  5. 微信开发 -- 搭建基于ngrok的微信本地调试环境

    第一步,安装ngrok客户端 (1)首先先到官网下载个客户端 http://natapp.cn/,选择适合的客户端类型,本人选择的是windows版 (2)下载后,解压,可以看到如下目录: 第二步,开 ...

  6. java实现微信H5支付

    前面做了app微信支付的回调处理,现在需要做微信公众号的支付,花了一天多时间,终于折腾出来了!鉴于坑爹的微信官方没有提供Java版的demo,所以全靠自己按照同样坑爹的文档敲敲敲,所以记录下来,以供自 ...

  7. java版微信公众号支付(H5调微信内置API)

    最近需要做微信公众号支付,网上找了大堆的代码,大多都只说了个原理,自己踩了太多坑,所有的坑,都会再下面的文章中标注,代码我也贴上最全的(叫我雷锋)!!! 第一步:配置支付授权目录 你需要有将你公司的微 ...

  8. .NET Core之微信支付之公众号、H5支付篇

    前言 本篇主要记录微信支付中公众号及H5支付全过程. 准备篇 公众号或者服务号(并开通微信支付功能).商户平台中开通JSAPI支付.H5支付. 配置篇 公众号或者服务号中 -------开发----- ...

  9. 前端:微信支付和支付宝支付在pc端和h5页面中的应用

    1:h5微信支付 使用的是https://pay.weixin.qq.com/wiki/doc/api/index.html  中的 (1):公司需要首先要配置公众号微信支付地址和测试白名单(支付的时 ...

随机推荐

  1. POJ 3903 Stock Exchange 最长上升子序列入门题

    题目链接:http://poj.org/problem?id=3903 最长上升子序列入门题. 算法时间复杂度 O(n*logn) . 代码: #include <iostream> #i ...

  2. Linq中demo,用力看看吧

    本文导读:LINQ to SQL全称基于关系数据的.NET语言集成查询,用于以对象形式管理关系数据,并提供了丰富的查询功能.Linq中where查询与SQL命令中的Where作用相似,都是起到范围限定 ...

  3. 【linux】查看TensorRT版本

    查看TensorRT版本: dpkg -l | grep TensorRT echo nvidia@tegra-ubuntu:~$ dpkg -l | grep TensorRT ii libnvin ...

  4. Visual Studio 2019 社区版本离线安装

    官方指导 :https://docs.microsoft.com/en-us/visualstudio/install/create-an-offline-installation-of-visual ...

  5. tcpreplay使用介绍

    安装 brew install tcpreplay yum install tcpreplay tcpreplay 回放 tcpreplay is a tool for replaying netwo ...

  6. CountDownLatch和CyclicBarrier使用上的区别

    一.CountDownLatchDemo package com.duchong.concurrent; import java.util.Map; import java.util.concurre ...

  7. c++ 编译 curl 报错 数组‘__curl_rule_01__’的大小为负 解决方法

    背景:在原有的项目GCC编译环境下(arm-linux 32位),增加x86-linux 64位的编译环境,编译curl库的时候发生错误. 其他:编译服务器为64位Centos 编译错误提示 /inc ...

  8. find_element_by_xpath()的几种方法

    Xpath (XML Path Language),是W3C定义的用来在XML文档中选择节点的语言一:从根目录/开始有点像Linux的文件查看,/代表根目录,一级一级的查找,直接子节点,相当于css_ ...

  9. golang之匿名函数结合defer

    defer语句中的函数会在return语句更新返回值变量后再执行,又因为在函数中定义的匿名函数可以访问该函数包括返回值变量在内的所有变量,所以,对匿名函数采用defer机制,可以使其观察函数的返回值. ...

  10. WUSTOJ 1318: 区间的连通性(Java)

    题目链接: