Java实现微信H5支付详细步骤与问题解析
"Java微信H5支付实例,配置教程参考自https://blog.csdn.net/leigelg/article/details/80456758,支付时遇到网络环境安全验证失败的问题,解决方法是检查并确认正确的IP地址。代码示例包含SpringMVC Controller中的支付处理逻辑。" 在Java开发中,微信H5支付是一种常见的在线支付方式,它允许用户在微信内置的浏览器中完成商品购买。以下是对这个实例中涉及的关键知识点的详细说明: 1. **微信H5支付**:微信H5支付是微信支付提供的一种服务,使得商家可以在自己的H5页面内集成支付功能,用户可以通过点击支付按钮,跳转到微信支付界面进行支付操作。支付流程包括预下单、调起支付、支付结果通知等步骤。 2. **URL配置问题**:在描述中提到的错误信息“网络环境未能通过安全验证,请稍后重试”,通常是因为服务器的IP地址未在微信商户后台进行配置或未被微信认可。解决方案是将服务器的公网IP地址添加到微信商户平台的安全域名或IP白名单中。 3. **Spring MVC Controller**:`@SecurityMapping` 和 `@RequestMapping` 是Spring MVC框架中的注解,用于处理HTTP请求。`@SecurityMapping` 是一个自定义的安全注解,可能用于实现特定的权限控制,而 `@RequestMapping` 指定控制器处理的请求路径及返回的数据类型。 4. **支付逻辑处理**:`paymentSubmit` 方法是处理支付提交的入口,接收订单ID (`order_id`) 和支付类型 (`payType`) 参数。方法内部首先获取订单对象,然后根据支付类型(可能是平台支付或商家支付)查询可用的支付方式(如微信支付、支付宝等),这些信息通常存储在数据库中。 5. **支付服务层(PaymentService)**:`paymentService` 被用来查询支付方式,这表明有一个服务层负责与数据库交互,获取和处理支付相关的数据。使用 `query` 方法执行SQL查询,返回支付对象列表。 6. **条件判断**:通过 `if` 语句检查订单状态是否为10(表示订单已创建但未支付),以及根据配置的支付类型来决定查询哪种类型的支付方式。这确保了只有有效的订单才能进行支付操作。 7. **参数映射**:`params` 是一个HashMap,用于存放查询支付方式时的条件,例如支付标记(`mark`)和类型(`type`)。这允许在SQL查询中动态传入参数,提高代码的灵活性。 8. **配置服务(configService)**:`configService` 用于获取系统配置,比如支付类型(1表示平台支付)。这显示了系统可能有一个全局配置中心,用于存储和管理各种系统级的配置信息。 9. **支付对象(Payment)**:支付对象包含了支付方式的相关信息,如支付标记和类型,这些信息在支付过程中是必要的。 10. **数据库操作**:在示例中,使用了类似MyBatis的SQL查询语法,通过 `query` 方法执行动态SQL,这表明项目可能使用了MyBatis或者类似的持久层框架来与数据库交互。 这个Java微信H5支付实例展示了如何在Spring MVC环境中实现支付接口调用,包括订单状态检查、支付方式选择和数据库查询等关键步骤。同时,也体现了对安全验证、支付配置和权限控制的理解。
@SecurityMapping(display = false, rsequence = 0, title = "wap订单支付", value = "/wxwap_submit.htm*", rtype = "buyer", rname = "购物流程3", rcode = "goods_cart", rgroup = "在线购物")
@RequestMapping(value = "/pay_submit.htm",produces="text/html; charset=UTF-8")
public String paymentSubmit(HttpServletRequest request,
HttpServletResponse response, String payType, String order_id) {
OrderForm of = this.orderFormService.getObjById(CommUtil.null2Long(order_id));
if (of != null && of.getOrder_status() == 10) {
List payments = new ArrayList();
Map params = new HashMap();
// 1为平台支付:
if (this.configService.getSysConfig().getConfig_payment_type() == 1) {
params.put("mark", payType);
params.put("type", "admin");
payments = this.paymentService.query("select obj from Payment obj where obj.mark=:mark and obj.type=:type", params, -1, -1);
} else {
params.put("store_id", of.getStore().getId());
params.put("mark", payType);
payments = this.paymentService.query("select obj from Payment obj where obj.mark=:mark and obj.store.id=:store_id", params, -1, -1);
}
// 支付方式已经配置:wap支持支付宝wap支付以及微信公众号支付
if (payments.size() > 0) {
of.setPayment((Payment) payments.get(0));
this.orderFormService.update(of);
// 微信公众号支付weixin_wap
if (payType.equals("weixin_wap")) {
//以下代码才是重点
Map<String, Object> result = new HashMap<String, Object>();
result.put("success", false);
try {
// 付款金额,必填
String total_fee = request.getParameter("WIDtotal_fee");
// ip地址获取 这个地方不知道是不是因为写了转发分流的原因导致不能使用request.getServerName()。
//也不能写域名,不知道是不是腾讯直接用IP。
String basePath = "服务器IP地址:" + request.getServerPort();
// 账号信息
String appid = of.getPayment().getWeixin_appId(); // appid
String mch_id = of.getPayment().getWeixin_partnerId(); // 商业号
String key = Payment.getWeixin_partnerKey(); // key
//订单号
order_id = request.getParameter("order_id");
String order_id1 = request.getParameter("order_id1");
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 = order_id1;
// 获取发起电脑 ip ,这个IP地址如果获取不到 就直接写127.0.0.1
String spbill_create_ip = HttpUtil.getRealIp(request);
// 回调接口
String userName = request.getParameter("shopuername");
剩余7页未读,继续阅读
- 粉丝: 0
- 资源: 1
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C++多态实现机制详解:虚函数与早期绑定
- Java多线程与异常处理详解
- 校园导游系统:无向图实现最短路径探索
- SQL2005彻底删除指南:避免重装失败
- GTD时间管理法:提升效率与组织生活的关键
- Python进制转换全攻略:从10进制到16进制
- 商丘物流业区位优势探究:发展战略与机遇
- C语言实训:简单计算器程序设计
- Oracle SQL命令大全:用户管理、权限操作与查询
- Struts2配置详解与示例
- C#编程规范与最佳实践
- C语言面试常见问题解析
- 超声波测距技术详解:电路与程序设计
- 反激开关电源设计:UC3844与TL431优化稳压
- Cisco路由器配置全攻略
- SQLServer 2005 CTE递归教程:创建员工层级结构