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<String,String> getWxpayUrl(Map<String, String> sourceMap);

  //订单查询
  public String orderQuery(String out_trade_no);
}
@Service
public class WeChatPayServiceImpl implements WeChatPayServcie {

  /**
   * 微信支付请求
   * @param sourceMap
   * @return
   */
  public Map<String,String> getWxpayUrl(Map<String, String> sourceMap) {
    SortedMap<String, Object> signParams = new TreeMap<String, Object>();
    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<String, Object> 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<String,String> 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<String, Object> 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<String, Object> 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<String ,String> toWxpay(HttpServletRequest httpRequest,String payId, String totalFee, String body){
    System.out.println("开始微信支付...");
    Map<String, String> map = new HashMap<>();
    String nonce_str = UUID.randomUUID().toString().trim().replaceAll("-", "");

    //生成一笔支付记录

    //拼接支付参数
    Map<String, String> 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<String, String> 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<String> 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<String ,Object> 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<String ,Object> 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 = "<xml><return_code><![CDATA[" + content + "]]></return_code></xml>";
      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<String, Object> packageParams, String KEY) {
    StringBuffer sb = new StringBuffer();
    Set<Entry<String, Object>> es = packageParams.entrySet();
    Iterator it = es.iterator();

    while(it.hasNext()) {
      Entry<String, Object> 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<String, Object> map) {
    String xmlResult = "";
    StringBuffer sb = new StringBuffer();
    sb.append("<xml>");
    Iterator var3 = map.keySet().iterator();

    while(var3.hasNext()) {
      String key = (String)var3.next();
      String value = "<![CDATA[" + map.get(key) + "]]>";
      sb.append("<" + key + ">" + value + "</" + key + ">");
      System.out.println();
    }

    sb.append("</xml>");
    xmlResult = sb.toString();
    return xmlResult;
  }

  //将xml转为map
  public static Map<String, Object> parseXmlMap(String xml) throws DocumentException {
    Document document = DocumentHelper.parseText(xml);
    Element root = document.getRootElement();
    List<Element> elementList = root.elements();
    Map<String, Object> 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支付

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

(0)

相关推荐

  • 微信支付H5调用支付详解(java版)

    最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一.配置公众号微信支付  需要我们配置微信公众号支付地址和测试白名单. 比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/ 那此处配置www.xxx.com/shop/pay/ 二.开发流程 借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/d

  • java实现微信App支付服务端

    微信App支付服务端的实现方法,供大家参考,具体内容如下 引言 主要实现app支付统一下单.异步通知.调起支付接口.支付订单查询.申请退款.查询退款功能:封装了https对发起退款的证书校验.签名.xml解析等. 支付流程 具体支付流程参考"微信APP"文档,文档地址 APP支付:APP端点击下单--服务端生成订单,并调起"统一下单",返回app支付所需参数-–APP端"调起支付接口",发起支付--微信服务器端调用服务端回调地址-–服务端按照&q

  • java实现微信支付(服务端)

    废话不多说,直接看代码. RequestHandler requestHandler = new RequestHandler(super.getRequest(),super.getResponse()); //获取token //两小时内有效,两小时后重新获取 Token = requestHandler.GetToken(); //更新token 到应用中 requestHandler.getTokenReal(); System.out.println("微信支付获取token=====

  • java服务端微信APP支付接口详解

    一.微信APP支付接入商户服务中心 [申请流程指引] (https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317780&token=84f23b4e9746c5963128711f225476cfd49ccf8c&lang=zh_CN) 二.开始开发 1.配置相关的配置信息 1.1.配置appid(Androi

  • 微信APP支付Java代码

    本文实例为大家分享了java微信APP支付代码,供大家参考,具体内容如下 import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Random; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.htt

  • 微信支付java版本之查询订单

    本文实例为大家分享了微信支付订单的查询接口,供大家参考,具体内容如下 1.接口简介 2.代码实现 package com.zhrd.bussinss.platform.controller.shop; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import java.text.SimpleDateFormat; import java.util.Date; import

  • java开发微信公众号支付

    最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时间,也只是达到了实现功能的水平,并没有太多考虑到性能问题,所以这篇文章比较适合初学者. 微信公众号支付的总体其实很简单,大致就分为三步.第一步需要获取用户授权:第二步调用统一下单接口获取预支付id:第三步H5调起微信支付的内置的js.下面介绍具体每一步的开发流程. 一    首先要明确微信公众号支付属于网页版支付,所以相较于app的直接调取微信支付要多一步微信授权.也就是需要获取用户的openid.微信公众号使用的交易类型是JSAPI,

  • java微信公众号支付开发之现金红包

    我们先来看看公众号发放现金红包的效果: 需要调用商户平台的接口,接口发放规则如下: 1.发送频率限制--默认1800/min 2.发送个数上限--按照默认1800/min算 3.金额上限--根据传入场景id不同默认上限不同,可以在商户平台产品设置进行设置和申请,最大不大于4999元/个 4.其他的"量"上的限制还有哪些?--用户当天的领取上限次数,默认是10 5.如果量上满足不了我们的需求,如何提高各个上限?--金额上限和用户当天领取次数上限可以在商户平台进行设置 注意-红包金额大于2

  • Java微信支付-微信红包

    微信红包的使用已经很广泛,本篇文章介绍了微信发红包的实例,需要有认证的公众号,且开通了微信支付,商户平台且开通了现金红包的权限即可. https://pay.weixin.qq.com商户登陆地址.选择查看营销中心的现金红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1 现金红包的官网文档说明 先看几个图 简单的测试.前提需要你去商户平台先充值.不支持预支付.本文只是总结微信现金红包接口的调用与

  • 详解JAVA后端实现统一扫码支付:微信篇

    最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用来判断支付平台,是微信还是支付宝,判断过后就好办了,直接照搬微信支付和支付宝的官方文档.不过微信的文档感觉有点坑,得多花点心思. 现在讲讲怎么实现微信支付网页支付,也就是公众号支付: 1.判断支付平台,在判断是微信平台时,必须使用window.location打开网页,使用其他方法在IOS版微信无法打开网页

  • Java编程调用微信支付功能的方法详解

    本文实例讲述了Java编程调用微信支付功能的方法.分享给大家供大家参考,具体如下: 微信开发文档地址:https://mp.weixin.qq.com/wiki/home/ 从调用处开始 我的流程: 1.点击"支付"按钮,去后台 --> 2.后台生成支付所需数据返回页面 --> 3.页面点击"确认支付"调用微信支付js.完成支付功能. 支付按钮 <div class="button" id="pay" onc

  • java实现微信H5支付方法详解

    前面做了app微信支付的回调处理,现在需要做微信公众号的支付,花了一天多时间,终于折腾出来了!鉴于坑爹的微信官方没有提供Java版的demo,所以全靠自己按照同样坑爹的文档敲敲敲,所以记录下来,以供自己及后来人参考,不足之处,还请指正. 首先,我们贴出调用支付接口的H5页面,当然,在这个页面之前,还需要做很多其他的操作,我们一步一步的来. 坑爹的官方文档给了两个不同的支付接口,在微信公众平台开发中文档的"微信JS-SDK说明文档"中,给出的支付方式是下面被屏蔽的那一部分,而在商户平台的

随机推荐