Java对接第三方支付渠道之微信支付APIV3版本


一、接入指引

1.获取商户号

2.获取AppID

3.申请商户证书

步骤:登录商户平台 => 选择 账户中心 => 安全中心 => API安全 => 申请API证书 包括商户证书和商户私钥

可以预先下载,也可以通过编程的方式获取 我这里是直接下载在本地的

步骤:登录商户平台 => 选择 账户中心 => 安全中心 => API安全 => 设置APIv3密钥


二、导入依赖


三、书写配置类

这里导入支付秘钥的时候,我直接选择的是导入秘钥字符串,没有选择导入秘钥文件


四、书写工具类

1.订单状态枚举类

@AllArgsConstructor
@Getter
public enum OrderStatus {
          
   

    /**
     * 未支付
     */
    NOTPAY("未支付"),

    /**
     * 支付成功
     */
    SUCCESS("支付成功"),

    /**
     * 已关闭
     */
    CLOSED("超时已关闭"),

    /**
     * 已取消
     */
    CANCEL("用户已取消"),
    
    /**
     * 类型
     */
    private final String type;
}

2.支付类型枚举类

package com.ruiya.commons.enums.wxpay;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum WxApiType {
          
   

	/**
	 * Native下单
	 */
	NATIVE_PAY("/v3/pay/transactions/native"),

	/**
	 * 查询订单
	 */
	ORDER_QUERY_BY_NO("/v3/pay/transactions/out-trade-no/%s"),

	/**
	 * 关闭订单
	 */
	CLOSE_ORDER_BY_NO("/v3/pay/transactions/out-trade-no/%s/close"),

	/**
	 * 类型
	 */
	private final String type;

}

五、调用相关支付接口

1.流程图

2.发起支付

/**
     * 统一下单 - 生成支付二维码
     * @param orderNo 订单编号
     * @param uid 用户id
     * @return
     */
    @Override
    public String nativePay(String orderNo, String uid) throws Exception{
          
   

        //根据orderNo获取orderInfo
        OrderInfo orderInfo = orderInfoService.getOne(new LambdaQueryWrapper<OrderInfo>()
                .eq(OrderInfo::getOrderNo, orderNo)
                .eq(OrderInfo::getUid, uid));

        if (Objects.isNull(orderInfo)){
          
   
            throw new ServiceErrorException(ResultCode.ERROR, "发起支付请求失败 - 订单不存在");
        }

        String codeUrl = orderInfo.getCodeUrl();
        String orderStatus = orderInfo.getOrderStatus();
        //支付二维码不为空 &&订单的支付状态为支付中
        if(!StringUtils.isEmpty(codeUrl) && OrderStatus.NOTPAY.getType().equals(orderStatus)){
          
   
            log.info("订单已存在,二维码已保存");
            //返回二维码
            return codeUrl;
        }

        //更新订单的支付类型
        orderInfoService.updatePayTypeByOrderNo(orderInfo.getOrderNo(), PayType.WXPAY);

        //调用统一下单API
        HttpPost httpPost=new HttpPost(wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType()));

        // 请求body参数
        Gson gson = new Gson();
        Map paramsMap = new HashMap();
        paramsMap.put("appid", wxPayConfig.getAppid());
        paramsMap.put("mchid", wxPayConfig.getMchId());
        paramsMap.put("description", orderInfo.getTitle());
        paramsMap.put("out_trade_no", orderInfo.getOrderNo());
        paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType()));

        Map amountMap = new HashMap();

        BigDecimal payMoney = orderInfo.getTotalFee();
        BigDecimal total = payMoney.multiply(new BigDecimal("100"));
        total = total.setScale(0,BigDecimal.ROUND_UP);

        //支付金额单位:分
        amountMap.put("total", total.intValue());
        amountMap.put("currency", "CNY");

        paramsMap.put("amount", amountMap);

        //将参数转换成json字符串
        String jsonParams = gson.toJson(paramsMap);
        log.info("请求参数:" + jsonParams);

        StringEntity entity = new StringEntity(jsonParams,"utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        httpPost.setHeader("Accept", "application/json");

        //完成签名并执行请求
        CloseableHttpResponse response = (CloseableHttpResponse) httpClientWithSign.execute(httpPost);

        try {
          
   
            String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
            int statusCode = response.getStatusLine().getStatusCode();//响应状态码

            if (statusCode == 200) {
          
    //处理成功
                log.info("成功, 返回结果 = " + bodyAsString);
            } else if (statusCode == 204) {
          
    //处理成功,无返回Body
                log.info("成功");
            } else {
          
   
                log.info("Native下单失败,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
                throw new ServiceErrorException(ResultCode.ERROR, "发起支付请求失败 - Native下单失败:" + bodyAsString);
            }

            //响应结果
            Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
            //获取二维码
            codeUrl = resultMap.get("code_url");
            //保存支付二维码
            orderInfoService.saveCodeUrl(orderNo, codeUrl);

            return codeUrl;
        }finally {
          
   
            response.close();
        }
    }

3.支付通知

4.查询订单

5.取消支付

总结

经验分享 程序员 微信小程序 职场和发展