【微信支付】Java实现微信APP支付流程

前言

微信登录网页授权与APP授权
微信JSAPI支付
微信APP支付
微信APP和JSAPI退款
支付宝手机网站支付
支付宝APP支付
支付宝退款
以上我都放到个人公众号,搜一搜:JAVA大贼船,文末有公众号二维码!觉得个人以后开发会用到的可以关注一下哦!少走点弯路…

官方文档

微信支付-APP支付文档

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

APP端开发步骤

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5

后端代码实现

引入依赖

  <!-- 微信支付 -->
   <dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>0.0.3</version>
   </dependency>

配置参数

application.yml

# 微信相关配置
wx:
  #商户 ID(微信支付平台-账户中心-个人信息)
  MCH_ID: 
  # APP_ID(微信开放平台查找)
  A_APP_ID: 
  # 秘钥(微信开放平台查找)
  A_APP_SECRET: 
  # 支付秘钥KEY(微信支付平台-账户中心-api安全-api秘钥)
  A_KEY: 
  # 支付商户证书所载目录(微信支付平台-账户中心-api安全-API证书)
  A_CERT_PATH: 
  #支付成功回调地址
  WX_CALLBACK_URL: 

YmlParament

@Component
@Data
public class YmlParament {
 /*微信相关字段*/
 @Value("${wx.A_APP_ID}")
 private String a_app_id;
 @Value("${wx.A_APP_SECRET}")
 private String a_app_secret;
 @Value("${wx.MCH_ID}")
 private String mch_id;
 @Value("${wx.A_KEY}")
 private String a_key;
 @Value("${wx.A_CERT_PATH}")
 private String a_cert_path;
 @Value("${wx.WX_CALLBACK_URL}")
 private String wx_callback_url;

微信统一下单

微信统一下单接口文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

  • 初始化微信支付配置

@Component
public class WxConfig {
   @Autowired
   private YmlParament ymlParament;
   
@Bean(autowire = Autowire.BY_NAME,value = WxParament.APP_WX_PAY)
 public WXPay setAppWXPay() throws Exception {
  return new WXPay(new WxPayConfig(
    ymlParament.getA_cert_path(),
    ymlParament.getA_app_id(),
    ymlParament.getMch_id(),
    ymlParament.getA_key()));
 }

WxPayConfig

public class WxPayConfig implements WXPayConfig {
 private byte[] certData;
 private String appID;
 private String mchID;
 private String key;

 public WxPayConfig(String certPath, String appID,String mchID,String key) throws Exception {
  File file = new File(certPath);
  InputStream certStream = new FileInputStream(file);
  this.certData = new byte[(int) file.length()];
  certStream.read(this.certData);
  certStream.close();
  this.appID = appID;
  this.mchID = mchID;
  this.key = key;
 }
}
  • 微信下单接口,关键代码(服务层)

@Resource(name = WxParament.APP_WX_PAY)
private WXPay wxAppPay;

/* 微信统一下单 */
   private Map<String, String> wxUnifiedOrder(String orderNo, String orderFee, String requestIp) throws RuntimeException {
      Map<String, String> data = new HashMap<String, String>();
      data.put("nonce_str", WXPayUtil.generateNonceStr());
      data.put("body", "我来下单啦");
      data.put("out_trade_no", orderNo);
      data.put("sign_type", "MD5");
      data.put("total_fee", orderFee);
      data.put("spbill_create_ip", requestIp);
      data.put("notify_url",ymlParament.getWx_callback_url());
      data.put("trade_type", "APP"); // 此处指定为APP支付
      Map<String, String> wxOrderResult = WxPay.unifiedorder(data,wxAppPay);
     if("FAIL".equals(wxOrderResult.get("return_code"))){
       throw new RuntimeException(wxOrderResult.get("return_msg"));
     }
        /* IsNull自定义,主要判断非空 */
      if (IsNull.isNull(wxOrderResult.get("prepay_id"))) {
         throw new RuntimeException("微信支付下单成功后,返回的prepay_id为空");
      }
      return wxOrderResult;

   }

@Override
public Map<String, String> insertWxAppPay(String orderNo,String orderFee, String requestIp, String openid) {
 try {
  /* 微信下单 */
  Map<String, String> wxOrderResult = wxUnifiedOrder(orderNo, orderFee, requestIp, openid);
  Map<String, String> chooseWXPay = new HashMap<>();
        /* 这里的key值都是小写的,而JSAPI是驼峰式写法 */
  chooseWXPay.put("appid", ymlParament.getA_app_id());
  chooseWXPay.put("partnerid", ymlParament.getMch_id());
  chooseWXPay.put("prepayid", wxOrderResult.get("prepay_id"));
  chooseWXPay.put("package", "Sign=WXPay");
  chooseWXPay.put("noncestr", wxOrderResult.get("nonce_str"));
  chooseWXPay.put("timestamp", WxUtils.create_timestamp());
  String signature = WXPayUtil.generateSignature(chooseWXPay, ymlParament.getA_key());
  chooseWXPay.put("sign", signature);
  return chooseWXPay;
 } catch (Exception e) {
  e.printStackTrace();
 }
}
  • controller层(略)

微信支付成功回调

  • 关键代码

   @Resource(name = WxParament.APP_WX_PAY)
   private WXPay wxAppPay;

   @ApiOperation("微信支付回调")
   @PostMapping("callback")
   public String callback(HttpServletRequest request) throws Exception {
    try {
     // 1、获取参数
     Map<String, String> params = getMapByRequest(request);
     log.info("微信回调回来啦!!!!" + params);
     // 2、校验
     checkCallbackWxPay(params);
     //业务逻辑
     return wxPaySuccess();
    } catch (Exception e) {
     e.printStackTrace();
     return wxPayFail(e.getMessage());
    }
   }
   
/**
    * 获取微信过来的请求参数
    * @param request
    * @return
    * @throws Exception
    */
   private static Map<String, String> getMapByRequest(HttpServletRequest request) throws Exception{
    InputStream inStream = request.getInputStream();
    ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len = 0;
    while ((len = inStream.read(buffer)) != -1) {
     outSteam.write(buffer, 0, len);
    }
    Map<String, String> ret= WXPayUtil.xmlToMap(new String(outSteam.toByteArray(), "utf-8"));
    outSteam.close();
    inStream.close();
    return ret;
   } 
   
   /*校验 */
   private void checkCallbackWxPay(Map<String, String> params)
     throws Exception {
    if ("FAIL".equals(params.get("result_code"))) {
     throw new Exception("微信支付失败");
    }
    if (!checkWxCallbackSing(params, wxAppPay)) {
     throw new Exception("微信支付回调签名认证失败");
    }
    //校验金额
       //判断订单是否重复
       //....业务逻辑
   }
   
/**
    * 检查微信回调签名 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
    * 
    * @param wp 传入:@Autowired WXPay
    */
   private static boolean checkWxCallbackSing(Map<String, String> notifyMap, WXPay wp) throws Exception {
    return wp.isPayResultNotifySignatureValid(notifyMap);
   }

   /**
    * 微信支付返回参数结果封装
    */
   private static String wxPaySuccess() throws Exception {
    Map<String, String> succResult = new HashMap<String, String>();
    succResult.put("return_code", "SUCCESS");
    succResult.put("return_msg", "OK");
    return WXPayUtil.mapToXml(succResult);
   }
   /**
    * @param mess 错误消息提示
    * @return 微信返回错我的提示
    * @throws Exception
    */
   private static String wxPayFail(String mess) throws Exception {
    Map<String, String> succResult = new HashMap<String, String>();
    succResult.put("return_code", "FAIL");
    succResult.put("return_msg", IsNull.isNull(mess)?"自定义异常错误!":mess);
    return WXPayUtil.mapToXml(succResult);
   }

补充

如果不想验证签名,还有一种方式判断是否支付成功,就是调用微信查询订单接口查看是否支付成功

  • 关键代码

 /*调用微信查询订单接口*/
      Map<String, String> orderqueryRes = orderquery(wXH5Pay,params.get("out_trade_no"));
      /*交易成功*/
      if (!"SUCCESS".equals(orderqueryRes.get("trade_state"))){
       throw new Exception("<===微信支付失败====>订单号为【"+ params.get("out_trade_no")+ "】的订单");
      }

   /**
    * 查询支付结果 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
    */
   private static Map<String, String> orderquery(WXPay wxpay, String outTradeNo) throws Exception {
       Map<String, String> parament = new HashMap<String, String>();
    parament.put("out_trade_no", outTradeNo);
    return wxpay.orderQuery(parament);
   }

 

                                                 

 

                                                   

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值