热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Java开发微信Navicat支付完整版

这篇文章主要介绍了Java开发微信Navicat支付完整版,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一:准备工作

1:先去微信公众平台注册一个公众号,选择服务号

2:去微信商户平台注册一个商户号,用于收款

3:在商户号中配置对应的公众号的APPID

4:支付结果异步通知(需要重点注意)

注意:请先详细查看官方文档按步骤开发,一切以官方文档为主 微信Navicat支付官方文档

5:测试的时候一定要使用内网穿透软件,否则回调时会报错

 二:开发代码

WeChatPayConfig:

 

public class WeChatPayConfig {
  //公众号APPID
  private String APPID = "";
 
  //商户号KEY
  private String KEY = "";
 
  //商户号ID
  private String MCHID = "";
 
  //支付完成后微信回调地址,需要外网能访问要是域名,不能是127.0.0.1跟localhost
  private String NOTIFY_URL = "";
}

WeChatPayServcie:

public interface WeChatPayServcie {
 
  //微信支付下单
  public Map getWxpayUrl(Map sourceMap);
 
  //订单查询
  public String orderQuery(String out_trade_no);
}
@Service
public class WeChatPayServiceImpl implements WeChatPayServcie {
  
  /**
   * 微信支付请求
   * @param sourceMap
   * @return
   */
  public Map getWxpayUrl(Map sourceMap) {
    SortedMap signParams = new TreeMap();
    String nonce_str = UUID.randomUUID().toString().trim().replaceAll("-", "");
    signParams.put("appid", PayConfig.APPID);
    signParams.put("mch_id",PayConfig.MCHID);
    signParams.put("nonce_str",sourceMap.get("nonce_str"));
    signParams.put("product_id",sourceMap.get("prod_id"));
    signParams.put("body",sourceMap.get("body"));
    signParams.put("out_trade_no",sourceMap.get("out_trade_no"));
    signParams.put("total_fee",sourceMap.get("total_fee"));
    signParams.put("spbill_create_ip", WxUtil.getIp());
    signParams.put("notify_url",PayConfig.NOTYFLY_URL);
    signParams.put("trade_type","NATIVE");
    String sign = WxUtil.createSign(signParams,PayConfig.KEY);
    signParams.put("sign",sign);
    String xmlPackage = WxUtil.parseMapXML(signParams);
    Map resultMap = new HashMap();
    try {
      String result = HttpUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder",xmlPackage);
      resultMap = WxUtil.parseXmlMap(result);
    } catch (Exception e) {
      e.printStackTrace();
    }
    String returnCode = (String) resultMap.get("return_code");
    String returnMsg = (String) resultMap.get("return_msg");
    if (returnCode.equalsIgnoreCase("FAIL")) {
      throw new RuntimeException(returnMsg);
    }
    String result_code = (String) resultMap.get("result_code");
    if (result_code.equalsIgnoreCase("FAIL")) {
      throw new RuntimeException(resultMap.get("err_code_des"));
    }
    String code_url = (String) resultMap.get("code_url");
    Map map = new HashMap<>();
    map.put("code_url",code_url);
    map.put("out_trade_no",sourceMap.get("out_trade_no"));
    return map;
  }
 
 
  /**
   * 微信支付订单查询
   * @param out_trade_no
   * @return
   */
  public String orderQuery(String out_trade_no) {
    String nonce_str = UUID.randomUUID().toString().trim().replaceAll("-", "");
    SortedMap signParams = new TreeMap<>();
    signParams.put("appid", payConfig.getWeChatPorpetties().getAppId());
    signParams.put("mch_id",payConfig.getWeChatPorpetties().getMchId());
    signParams.put("out_trade_no",out_trade_no);
    signParams.put("nonce_str",nonce_str);
    String sign = WxUtil.createSign(signParams,payConfig.getWeChatPorpetties().getApiKey());
    signParams.put("sign",sign);
    String xmlPackage = WxUtil.parseMapXML(signParams);
    Map resultMap = new HashMap();
    try {
      String result = HttpUtil.post("https://api.mch.weixin.qq.com/pay/orderquery",xmlPackage);
      resultMap = WxUtil.parseXmlMap(result);
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException("渠道网络异常");
    }
    String returnCode = (String) resultMap.get("return_code");
    String returnMsg = (String) resultMap.get("return_msg");
    if (returnCode.equalsIgnoreCase(PayContants.FAIL)) {
      throw new RuntimeException(returnMsg);
    }
    String result_code = (String) resultMap.get("result_code");
    if (result_code.equalsIgnoreCase(PayContants.FAIL)) {
      throw new RuntimeException(resultMap.get("err_code_des"));
    }
    String trade_state = (String) resultMap.get("trade_state");
    return trade_state;
  }
}

WeChatPayController:

/**
 * 微信支付接口
 */
@Controller
public class WxPayController {
 
  @Autowired
  WeChatPayServcie weChatPayServcie;
 
  /**
  * 微信支付下单
  * payID可以不用传自己生成32位以内的随机数就好,要保证不重复
  * totalFee金额一定要做判断,判断这笔支付金额与数据库是否一致
  */
  @RequestMapping("pay")
  @ResponseBody
  public Map toWxpay(HttpServletRequest httpRequest,String payId, String totalFee, String body){
    System.out.println("开始微信支付...");
    Map map = new HashMap<>();
    String nonce_str = UUID.randomUUID().toString().trim().replaceAll("-", "");
 
    //生成一笔支付记录
 
 
    //拼接支付参数
    Map paramMap = new HashMap<>();
    paramMap.put("nonce_str", nonce_str);
    paramMap.put("prod_id", payId);
    paramMap.put("body", body);
    paramMap.put("total_fee", totalFee);
    paramMap.put("out_trade_no", payId);
 
    //发送支付请求并获取返回参数与二维码,用于支付与调用查询接口
    Map returnMap = weChatPayServcie.getWxpayUrl(paramMap);
    httpRequest.setAttribute("out_trade_no", payId);
    httpRequest.setAttribute("total_fee", totalFee);
    
    //code_url就是二维码URL,可以把这个URL放到草料二维码中生成微信二维码
    httpRequest.setAttribute("code_url", returnMap.get("code_url"));
 
    map.put("out_trade_no", payId);
    map.put("total_fee", String.valueOf(bigDecimal));
    map.put("code_url", returnMap.get("code_url"));
    return map;
  }
 
  /**
  * 查询微信订单
  * ot_trade_no是支付
  */
  @RequestMapping("query")
  @ResponseBody
  public Root orderQuery(String out_trade_no){
    return weixinPayServcie.orderQuery(queryCallbackForm.getOut_trade_no());
  }
 
  /**
  * 微信支付回调,这个地址就是Config中的NOTYFLY_URL
  */
  @RequestMapping("callback")
  public void notify_url(HttpServletRequest request, HttpServletResponse response) throws DocumentException, ServletException, IOException,Throwable {
    System.out.print("微信支付回调获取数据开始...");
    String inputLine;
    String notityXml = "";
    try {
      while ((inputLine = request.getReader().readLine()) != null) {
        notityXml += inputLine;
      }
      request.getReader().close();
    } catch (Exception e) {
      WxUtil.sendXmlMessage(request,response, PayContants.FAIL);
      throw new RuntimeException("回调数据xml获取失败!");
    }
    if(StringUtils.isEmpty(notityXml)){
      WxUtil.sendXmlMessage(request,response, PayContants.FAIL);
      throw new RuntimeException("回调数据xml为空!");
    }
    Map resultMap = XMLParse.parseXmlMap(notityXml);
    String returnCode = (String) resultMap.get("return_code");
    String returnMsg = (String) resultMap.get("return_msg");
    if (returnCode.equalsIgnoreCase(PayContants.FAIL)) {
      WxUtil.sendXmlMessage(request,response, PayContants.FAIL);
      throw new RuntimeException(returnMsg);
    }
    String resultCode = (String) resultMap.get("result_code");
    if (resultCode.equalsIgnoreCase(PayContants.FAIL)) {
      WxUtil.sendXmlMessage(request,response, PayContants.FAIL);
      throw new RuntimeException(resultMap.get("err_code_des"));
    }
 
    SortedMap paramMap = new TreeMap<>();
    paramMap.put("appid",resultMap.get("appid"));
    paramMap.put("mch_id",resultMap.get("mch_id"));
    paramMap.put("nonce_str",resultMap.get("nonce_str"));
    paramMap.put("body",resultMap.get("body"));
    paramMap.put("openid", resultMap.get("openid"));
    paramMap.put("is_subscribe",resultMap.get("is_subscribe"));
    paramMap.put("trade_type",resultMap.get("trade_type"));
    paramMap.put("bank_type",resultMap.get("bank_type"));
    paramMap.put("total_fee",resultMap.get("total_fee"));
    paramMap.put("fee_type",resultMap.get("fee_type"));
    paramMap.put("cash_fee",resultMap.get("cash_fee"));
    paramMap.put("transaction_id",resultMap.get("transaction_id"));
    paramMap.put("out_trade_no",resultMap.get("out_trade_no"));
    paramMap.put("time_end",resultMap.get("time_end"));
    paramMap.put("return_code",resultMap.get("return_code"));
    paramMap.put("return_msg",resultMap.get("return_msg"));
    paramMap.put("result_code",resultMap.get("result_code"));
 
    String out_trade_no = (String) resultMap.get("out_trade_no");
    String sign = SignUtil.createSign(paramMap,WxPayConfig.KEY);
    String mySign =(String) resultMap.get("sign");
 
    //回调一定要验证签名以防数据被篡改
    if(sign.equals(mySign)){
      System.out.println("回调签名验证成功!");
      
        //修改业务逻辑,将那笔支付状态改为已支付
      }
      WxUtil.sendXmlMessage(request,response, PayContants.SUCCESS);
    }else{
      WxUtil.sendXmlMessage(request,response, PayContants.FAIL);
      throw new RuntimeException("签名不一致!");
    }
  }
 
}

 WxUtil:

package com.ys.commons.utils.pay;
 
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
//微信工具类
public class WxUtil {
 
  //获取当前IP
  public static String getIp() {
    try {
      String spbill_create_ip = InetAddress.getLocalHost().getHostAddress();
      return spbill_create_ip;
    } catch (UnknownHostException var2) {
      var2.printStackTrace();
      return "获取IP失败...";
    }
  }
 
  //输出xml格式
  public static void sendXmlMessage(HttpServletRequest request, HttpServletResponse response, String content) {
    try {
      String cOntentXml= "";
      OutputStream os = response.getOutputStream();
      BufferedWriter resBr = new BufferedWriter(new OutputStreamWriter(os));
      resBr.write(contentXml);
      resBr.flush();
      resBr.close();
    } catch (IOException var6) {
      var6.printStackTrace();
    }
 
  }
  
  //生成sign签名
  public static String createSign(SortedMap packageParams, String KEY) {
    StringBuffer sb = new StringBuffer();
    Set> es = packageParams.entrySet();
    Iterator it = es.iterator();
 
    while(it.hasNext()) {
      Entry entry = (Entry)it.next();
      String k = (String)entry.getKey();
      String v = (String)entry.getValue();
      if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
        sb.append(k + "=" + v + "&");
      }
    }
 
    sb.append("key=" + KEY);
    String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
    return sign;
  }
 
  //将map转为xml
  public static String parseMapXML(SortedMap map) {
    String xmlResult = "";
    StringBuffer sb = new StringBuffer();
    sb.append("");
    Iterator var3 = map.keySet().iterator();
 
    while(var3.hasNext()) {
      String key = (String)var3.next();
      String value = "";
      sb.append("<" + key + ">" + value + "");
      System.out.println();
    }
 
    sb.append("");
    xmlResult = sb.toString();
    return xmlResult;
  }
 
  //将xml转为map
  public static Map parseXmlMap(String xml) throws DocumentException {
    Document document = DocumentHelper.parseText(xml);
    Element root = document.getRootElement();
    List elementList = root.elements();
    Map map = new HashMap();
    Iterator var5 = elementList.iterator();
 
    while(var5.hasNext()) {
      Element e = (Element)var5.next();
      map.put(e.getName(), e.getText());
    }
 
    return map;
  }
}

发送请求需要推荐一个非常好用的工具,里面各种常用的工具都封装好了hutool,如果想直接使用也需要引入此工具的maven库

注意:此工具只支持JDK 1.7以上至此代码已经完成,有意见建议的都可以留言,后续会更新最完整最新版的PayPal支付,同时有需要的也可以看看博主的支付宝PC支付

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 微信小程序支付官方参数小程序中代码后端发起支付代码支付回调官方参数文档地址:https:developers.weixin.qq.comminiprogramdeva ... [详细]
  • 深入理解SAP Fiori及其核心概念
    本文详细介绍了SAP Fiori的基本概念、发展历程、核心特性、应用类型、运行环境以及开发工具等,旨在帮助读者全面了解SAP Fiori的技术框架和应用场景。 ... [详细]
  • Python安全实践:Web安全与SQL注入防御
    本文旨在介绍Web安全的基础知识,特别是如何使用Python和相关工具来识别和防止SQL注入攻击。通过实际案例分析,帮助读者理解SQL注入的危害,并掌握有效的防御策略。 ... [详细]
  • 本文详细介绍了如何利用go-zero框架从需求分析到最终部署至Kubernetes的全过程,特别聚焦于微服务架构中的网关设计与实现。项目采用了go-zero及其生态组件,涵盖了从API设计到RPC调用,再到生产环境下的监控与维护等多方面内容。 ... [详细]
  • Android开发经验分享:优化用户体验的关键因素
    随着Android市场的不断扩展,用户对于移动应用的期望也在不断提高。本文探讨了在Android开发中如何优化用户体验,以及为何用户体验的重要性超过了技术本身。 ... [详细]
  • 本文详细解析了LeetCode第300题——最长递增子序列的解题方法,特别是如何使用动态规划来高效解决问题。文章不仅提供了详细的代码实现,还探讨了常见的错误理解和正确的解题思路。 ... [详细]
  • Spring Boot 初学者指南(第一部分)
    本文介绍了Spring Boot框架的基础知识,包括其设计理念、主要优势以及如何简化传统的J2EE开发流程。 ... [详细]
  • 本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ... [详细]
  • BeautifulSoup4 是一个功能强大的HTML和XML解析库,它能够帮助开发者轻松地从网页中提取信息。本文将介绍BeautifulSoup4的基本功能、安装方法、与其他解析工具的对比以及简单的使用示例。 ... [详细]
  • 择要:Fundebug的JavaScript毛病监控插件同步支撑Vue.js异步毛病监控。Vue.js从降生至今已5年,尤大在本年2月份宣布了严重更新,即Vue2.6。更新包含新增 ... [详细]
  • 构建高性能Feed流系统的设计指南
    随着移动互联网的发展,Feed流系统成为了众多社交应用的核心组成部分。本文将深入探讨如何设计一个高效、稳定的Feed流系统,涵盖从基础架构到高级特性的各个方面。 ... [详细]
  • 详解MyBatis二级缓存的启用与配置
    本文深入探讨了MyBatis二级缓存的启用方法及其配置细节,通过具体的代码实例进行说明,有助于开发者更好地理解和应用这一特性,提升应用程序的性能。 ... [详细]
  • 本文总结了在使用React Native开发过程中遇到的一些常见问题及其解决方法,包括配置错误、依赖问题和特定组件的使用技巧。 ... [详细]
  • 题目大意:给你一棵树,根节点为1有2种操作,第一种是给u节点所在的子树的所有节点的权值x第二种是询问,假设v是子树u中的节点 ... [详细]
  • Python脚本实现批量删除多种类型文件的扩展名
    本文介绍了一个Python脚本,用于批量处理并移除指定目录下不同格式文件(如png、jpg、xml、json、txt、gt等)的文件扩展名。该方法通过递归遍历文件夹中的所有文件,并对每个文件执行重命名操作。 ... [详细]
author-avatar
涩味122_508
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有