【小程序系列】微信支付JAVA-sdk

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

一.需求背景

1.小程序支付

在当前数字化时代,小程序支付已成为连接用户与服务的关键桥梁,它不仅为用户提供了便捷的支付方式,也为商家带来了更高效的收款和用户管理途径。如何更将快捷和方便对接小程序的支付呢,可以参考本文的 java-sdk
在这里插入图片描述

2.支付

api

image-20240901133802170

3.api 列表

具体的 api

image-20240901223423239

4.回调

回调查询

image-20240901223451632

二.代码实现

1.源码下载

微信支付-Java-sdk

2.config

public class MyWxPayConfig extends WXPayConfig {

    private byte[] certData;

    public MyWxPayConfig() throws Exception {
        String certPath = "/path/to/apiclient_cert.p12";
        File file = new File(certPath);
        InputStream certStream = Files.newInputStream(file.toPath());
        this.certData = new byte[(int) file.length()];
        certStream.read(this.certData);
        certStream.close();
    }

    /**
     * 小程序ID
     *
     * @return
     */
    public String getAppID() {
        return "wx12345e766d6ecf8a";
    }

    /**
     * 商户号
     *
     * @return
     */
    public String getMchID() {
        return "1684444405";
    }

    public String getKey() {
        return "88888888888888888888888888888888";
    }

    public InputStream getCertStream() {
        return new ByteArrayInputStream(this.certData);
    }

    public int getHttpConnectTimeoutMs() {
        return 8000;
    }

    public int getHttpReadTimeoutMs() {
        return 10000;
    }

    @Override
    protected IWXPayDomain getWXPayDomain() {
        return null;
    }
}

3.controller

@Api(tags = "微信支付管理", description = "微信支付管理")
@RestController
@RequestMapping("pay")
public class WxPayOrderController {

    @Resource
    private WxPayOrderService wxPayOrderService;


    @ApiOperation(value = "统一下单", nickname = "统一下单")
    @GetMapping("/unifiedOrder")
    public Result unifiedOrder(@RequestParam("outTradeNo") String outTradeNo,
                               @RequestParam("totalFee") Integer totalFee) {

        return Result.ok(wxPayOrderService.unifiedOrder(outTradeNo, totalFee));
    }

    @ApiOperation(value = "查询订单", nickname = "查询订单")
    @GetMapping("/orderQuery")
    public Result orderQuery(@RequestParam("outTradeNo") String outTradeNo) {
        return Result.ok(wxPayOrderService.orderQuery(outTradeNo));
    }

    @ApiOperation(value = "关闭订单", nickname = "关闭订单")
    @GetMapping("/closeOrder")
    public Result closeOrder(@RequestParam("outTradeNo") String outTradeNo) {
        return Result.ok(wxPayOrderService.closeOrder(outTradeNo));
    }

    @ApiOperation(value = "申请退款", nickname = "申请退款")
    @GetMapping("/refund")
    public Result refund(@RequestParam("outTradeNo") String outTradeNo, @RequestParam("outRefundNo") String outRefundNo,
                         @RequestParam("totalFee") Integer totalFee, @RequestParam("refundFee") Integer refundFee) {
        return Result.ok(wxPayOrderService.refund(outTradeNo, outRefundNo, totalFee, refundFee));
    }

    @ApiOperation(value = "退款查询", nickname = "退款查询")
    @GetMapping("/refundQuery")
    public Result refundQuery(@RequestParam("outTradeNo") String outTradeNo) {
        return Result.ok(wxPayOrderService.refundQuery(outTradeNo));
    }

    @ApiOperation(value = "支付结果通知", nickname = "支付结果通知")
    @GetMapping("/notify")
    public String notify(HttpServletRequest request, HttpServletResponse response) {
        return wxPayOrderService.notify(request,response);
    }
}

4.service

public interface WxPayOrderService {

    /**
     * 统一下单接口
     *
     * @return
     */
    Map<String, String> unifiedOrder(String outTradeNo, Integer totalFee);

    /**
     * 订单查询
     *
     * @return
     */
    Map<String, String> orderQuery(String outTradeNo);

    /**
     * 关闭订单
     * <p>
     * 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。
     * 订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。
     *
     * @param outTradeNo
     * @return
     */
    Map<String, String> closeOrder(String outTradeNo);

    /**
     * 申请退款
     *
     * @param outTradeNo  系统订单号
     * @param outRefundNo 退款订单号
     * @param totalFee    总金额
     * @param refundFee   退款金额
     * @return
     */
    Map<String, String> refund(String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee);

    /**
     * 退款查询
     *
     * @param outTradeNo
     * @return
     */
    Map<String, String> refundQuery(String outTradeNo);

    /**
     * 支付回调
     *
     * @return
     */
    String notify(HttpServletRequest request, HttpServletResponse response);
}

5.实现类

@Slf4j
@Service
public class WxPayOrderServiceImpl implements WxPayOrderService {
    @Autowired
    private OrderInfoService orderInfoService;

    @Override
    public Map<String, String> unifiedOrder(String outTradeNo, Integer totalFee) {
        try {
            Map<String, String> data = new HashMap<>();
            WXPayConfig config = new MyWxPayConfig();
            WXPay wxpay = new WXPay(config);
            data.put("body", "新空间小程序代办中心");// 产品描述
            data.put("out_trade_no", outTradeNo);// 商户订单号
            data.put("fee_type", "CNY");
            data.put("total_fee", String.valueOf(totalFee));// 订单总金额,单位为分
            data.put("spbill_create_ip", "ip");// 客户端ip
            data.put("notify_url", "https://xxxxxxxxxxx/notify");// 服务回调地址
            data.put("trade_type", "JSAPI");  // 此处指定为小程序支付
            Map<String, String> resp = wxpay.unifiedOrder(data);
            log.info("统一下单接口,返回信息={}", resp.toString());
            return resp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public Map<String, String> orderQuery(String outTradeNo) {
        try {
            WXPayConfig config = new MyWxPayConfig();
            WXPay wxpay = new WXPay(config);
            Map<String, String> data = new HashMap<>();
            data.put("out_trade_no", outTradeNo);
            Map<String, String> resp = wxpay.orderQuery(data);
            log.info("查询订单接口,返回信息={}", resp.toString());
            return resp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public Map<String, String> closeOrder(String outTradeNo) {
        try {
            WXPayConfig config = new MyWxPayConfig();
            WXPay wxpay = new WXPay(config);
            Map<String, String> data = new HashMap<>();
            data.put("out_trade_no", outTradeNo);
            Map<String, String> resp = wxpay.closeOrder(data);
            System.out.println(resp);
            log.info("关闭订单,返回信息={}", resp.toString());
            return resp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Map<String, String> refund(String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee) {
        try {
            WXPayConfig config = new MyWxPayConfig();
            WXPay wxpay = new WXPay(config);
            Map<String, String> data = new HashMap<>();
            data.put("out_trade_no", outTradeNo);
            data.put("out_refund_no", outRefundNo);
            data.put("total_fee", String.valueOf(totalFee));
            data.put("refund_fee", String.valueOf(refundFee));
            Map<String, String> resp = wxpay.refundQuery(data);
            System.out.println(resp);
            log.info("申请退款,返回信息={}", resp.toString());
            return resp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Map<String, String> refundQuery(String outTradeNo) {
        try {
            WXPayConfig config = new MyWxPayConfig();
            WXPay wxpay = new WXPay(config);
            Map<String, String> data = new HashMap<>();
            data.put("out_trade_no", outTradeNo);
            Map<String, String> resp = wxpay.refundQuery(data);
            System.out.println(resp);
            log.info("退款查询,返回信息={}", resp.toString());
            return resp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String notify(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> data = new HashMap<>();
        try {
            WXPayConfig config = new MyWxPayConfig();
            WXPay wxpay = new WXPay(config);
            String notifyData = WXPayUtil.requestToMap(request);
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);  // 转换成map
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                // 签名正确
                // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功
                log.info("支付成功");
                String transactionId = notifyMap.get("transaction_id");
                String outTradeNo = notifyMap.get("out_trade_no");
                final OrderInfo byId = orderInfoService.getById(Integer.valueOf(outTradeNo));
                byId.setTransactionId(transactionId);
                orderInfoService.updateById(byId);
            } else {
                // 签名错误,如果数据里没有sign字段,也认为是签名错误
                throw new ApplicationException("签名错误");
            }
            data.put("return_code", "SUCCESS");
            data.put("return_msg", "OK");
            WXPayUtil.mapToXml(data);
            return WXPayUtil.mapToXml(data);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("通知失败");
            throw new ApplicationException("通知失败");
        }
    }
}

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kwan的解忧杂货铺@新空间代码工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值