SpringBoot 集成第三方聚合支付 微信、支付宝

在这篇博客中,我将介绍如何使用Spring Boot集成第三方支付聚合支付。聚合支付是一种将多种支付方式整合到一起的方式,使用户可以选择他们喜欢的支付方式进行支付。在本文中,我们将使用支付宝和微信支付作为示例。
在这里插入图片描述

1. 创建Spring Boot项目

首先,我们需要创建一个Spring Boot项目。我们可以使用Spring Initializr来创建项目。打开https://start.spring.io/,选择使用Gradle构建工具和Java语言,输入项目名称和组名,然后单击生成。

2. 添加依赖

我们需要添加以下依赖:

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.8.96.ALL</version>
</dependency>
<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>3.0.9</version>
</dependency>

3. 配置支付宝、微信

我们需要在application.properties文件中添加以下配置:

# 支付宝支付配置
alipay:
  appId: xxxxxxxxxx
  notifyUrl: http://xxxxx.com/notify/alipay
  privateKey: xxxxxxxxxx
  publicKey: xxxxxxxxxx
# 微信支付配置
wxpay:
  appId: xxxxxxxxxx
  certPath: /path/to/cert
  key: xxxxxxxxxx
  mchId: xxxxxxxxxx
  notifyUrl: http://xxxxx.com/notify/wxpay

4. 实现支付接口

我们需要创建一个PaymentController类,实现支付接口。在这个类中,我们需要实现以下方法:

@RequestMapping("/pay")
public String pay(@RequestParam("type") String type, @RequestParam("amount") BigDecimal amount) {
    if ("alipay".equals(type)) {
        return alipayService.pay(amount);
    } else if ("wxpay".equals(type)) {
        return wxpayService.pay(amount);
    }
    return "Unknown payment type";
}

5. 实现支付服务

我们需要创建一个AlipayService类和一个WxpayService类,实现支付服务。在这些类中,我们需要实现以下方法:

AlipayService:

/**
 * 支付宝支付
 */
public class AlipayService {
    @Value("${alipay.appId}")
    private String appId;

    @Value("${alipay.appId}")
    private String privateKey;

    @Value("${alipay.appId}")
    private String publicKey;

    @Value("${alipay.appId}")
    private String notifyUrl;

    public String pay(BigDecimal amount) {
        // 构造请求参数
        AlipayClient client = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                appId, privateKey, "json", "utf-8", publicKey, "RSA2");
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        // 跳转地址
        request.setReturnUrl("http://xxxxx.com/return/alipay");
        // 异步通知
        request.setNotifyUrl(notifyUrl);
        request.setBizContent("{\"out_trade_no\":\"" + UUID.randomUUID().toString() + "\",\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                "\"total_amount\":\"" + amount + "\",\"subject\":\"xxxxx\"}");
        // 发起支付请求
        try {
            return client.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }
}

WxpayService:

/**
 * 微信支付
 */
public class WxpayService {
    @Value("${wxpay.appId}")
    private String appId;

    @Value("${wxpay.mchId}")
    private String mchId;

    @Value("${wxpay.key}")
    private String key;

    @Value("${wxpay.certPath}")
    private String certPath;

    @Value("${wxpay.notifyUrl}")
    private String notifyUrl;

    public String pay(BigDecimal amount) {
        try {
            WXPay wxpay = new WXPay(new WXPayConfig() {
                @Override
                public String getAppID() {
                    return appId;
                }

                @Override
                public String getMchID() {
                    return mchId;
                }

                @Override
                public String getKey() {
                    return key;
                }

                @Override
                public InputStream getCertStream() {
                    try {
                        return new FileInputStream(certPath);
                    } catch (FileNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public int getHttpConnectTimeoutMs() {
                    return 0;
                }

                @Override
                public int getHttpReadTimeoutMs() {
                    return 0;
                }

            }, WXPayConstants.SignType.MD5);
            Map<String, String> data = new HashMap<String, String>();
            data.put("body", "xxxxx");
            data.put("out_trade_no", UUID.randomUUID().toString());
            data.put("fee_type", "CNY");
            data.put("total_fee", String.valueOf(amount.multiply(new BigDecimal(100)).intValue()));
            data.put("spbill_create_ip", "127.0.0.1");
            data.put("notify_url", notifyUrl);
            data.put("trade_type", "NATIVE");
            data.put("product_id", UUID.randomUUID().toString());
            // 发起支付请求
            Map<String, String> resp = wxpay.unifiedOrder(data);
            if ("SUCCESS".equals(resp.get("return_code")) && "SUCCESS".equals(resp.get("result_code"))) {
                return resp.get("code_url");
            } else {
                throw new RuntimeException("wxpay error");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

6. 实现支付回调接口

我们需要创建一个NotifyController类,实现支付回调接口。在这个类中,我们需要实现以下方法:

/**
 * 回调处理
 */
public class NotifyController {

    @Value("${alipay.publicKey}")
    private String publicKey;

    @RequestMapping("/notify/alipay")
    public String alipayNotify(HttpServletRequest request) throws AlipayApiException {
        // 解析支付宝回调请求参数
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            StringBuilder valueStr = new StringBuilder();
            for (int i = 0; i < values.length; i++) {
                valueStr.append((i == values.length - 1) ? values[i] : values[i] + ",");
            }
            params.put(name, valueStr.toString());
        }
        // 验证支付宝回调请求签名
        boolean verifyResult = AlipaySignature.rsaCheckV1(params, publicKey, "utf-8", "RSA2");
        if (verifyResult) {
            // 处理支付宝回调请求
            String outTradeNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            String totalAmount = params.get("total_amount");
            // ...
            return "success";
        } else {
            return "fail";
        }
    }


    @Value("${wxpay.appId}")
    private String appId;
    @Value("${wxpay.mchId}")
    private String mchId;
    @Value("${wxpay.key}")
    private String key;
    @Value("${wxpay.certPath}")
    private String certPath;
    @Value("${wxpay.notifyUrl}")
    private String notifyUrl;

    @RequestMapping("/notify/wxpay")
    public String wxpayNotify(HttpServletRequest request) {
        try {
            // 解析微信支付回调请求参数
            InputStream inputStream = request.getInputStream();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
            String xml = outputStream.toString("utf-8");
            Map<String, String> params = WXPayUtil.xmlToMap(xml);
            // 验证微信支付
            WXPay wxpay = new WXPay(new WXPayConfig() {
                @Override
                public String getAppID() {
                    return appId;
                }

                @Override
                public String getMchID() {
                    return mchId;
                }

                @Override
                public String getKey() {
                    return key;
                }

                @Override
                public InputStream getCertStream() {
                    try {
                        return new FileInputStream(certPath);
                    } catch (FileNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public int getHttpConnectTimeoutMs() {
                    return 0;
                }

                @Override
                public int getHttpReadTimeoutMs() {
                    return 0;
                }

            }, WXPayConstants.SignType.MD5);
            boolean verifyResult = wxpay.isPayResultNotifySignatureValid(params);
            if (verifyResult) {
                // 处理微信支付回调请求
                String outTradeNo = params.get("out_trade_no");
                String transactionId = params.get("transaction_id");
                String totalFee = params.get("total_fee");
                // ...
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            } else {
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>";
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

7. 测试支付

在实现了支付和回调接口之后,我们可以编写一个简单的测试用例,测试支付是否能够正常工作。

@RunWith(SpringRunner.class)
@SpringBootTest
public class PayTest {
	@Autowired
	private AlipayService alipayService;
	@Autowired
	private WxpayService wxpayService;
	
	@Test
	public void testAlipay() {
	    String payUrl = alipayService.pay(new BigDecimal("0.01"));
	    System.out.println("payUrl: " + payUrl);
	    // 手动调用支付宝回调接口,模拟支付宝异步通知
	    String notifyUrl = "http://localhost:8080/notify/alipay";
	    String outTradeNo = "xxxxxxxxxxxx";
	    String tradeNo = "xxxxxxxxxxxx";
	    String totalAmount = "0.01";
	    String sign = AlipaySignature.rsaSign(AlipayUtil.getParamsString(outTradeNo, tradeNo, totalAmount), privateKey, "utf-8", "RSA2");
	    String notifyResponse = HttpUtil.post(notifyUrl, AlipayUtil.getNotifyString(outTradeNo, tradeNo, totalAmount, sign));
	    System.out.println("notifyResponse: " + notifyResponse);
	}
	
	@Test
	public void testWxpay() {
	    String codeUrl = wxpayService.pay(new BigDecimal("0.01"));
	    System.out.println("codeUrl: " + codeUrl);
	    // 手动调用微信支付回调接口,模拟微信异步通知
	    String notifyUrl = "http://localhost:8080/notify/wxpay";
	    String outTradeNo = "xxxxxxxxxxxx";
	    String transactionId = "xxxxxxxxxxxx";
	    String totalFee = "1";
	    String sign = WXPayUtil.generateSignature(WXPayUtil.getPayParams(outTradeNo, transactionId, totalFee), key);
	    String notifyResponse = HttpUtil.post(notifyUrl, WXPayUtil.getNotifyString(outTradeNo, transactionId, totalFee, sign));
	    System.out.println("notifyResponse: " + notifyResponse);
	}
}

这就是整合第三方支付的Spring Boot应用的基本步骤。当然,不同的支付方式可能会有不同的实现细节,但整体流程是类似的。

8. 总结

本文介绍了如何使用Spring Boot框架将支付宝和微信支付集成到Web应用程序中。我们首先介绍了支付宝和微信支付的基本概念和流程,然后介绍了如何在Spring Boot中集成支付宝和微信支付,包括如何进行支付和回调处理。最后,我们还编写了简单的测试用例来测试我们的支付系统是否正常工作。

通过本文的学习,读者应该可以了解如何将第三方支付集成到Spring Boot应用程序中,也可以了解一些支付相关的技术和概念。

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
支付宝微信是中国最知名的移动支付平台,它们在用户量和影响力上都具有很大的优势。支付宝主要由蚂蚁金服运营,而微信支付则是腾讯公司旗下的支付平台。这两个平台通过技术和市场的整合,逐渐形成了移动支付市场的垄断局面。 支付宝微信支付都具备了快捷、安全、便利的特点,用户可以通过手机APP进行线上和线下的支付。无论是购买商品、转账还是缴纳各类费用,支付宝微信支付都能提供便捷的支付方式。用户只需扫描二维码或输入相关信息即可完成支付,节省了线下排队等待的时间。 而CSDN是中国领先的专业技术社区,提供了软件开发、IT技术、互联网等领域的最新资讯和技术交流平台。CSDN提供了丰富的学习资源、技术分享和在线交流社区,为广大的软件开发人员、技术爱好者和IT从业人员提供了良好的学习和交流环境。 将支付宝微信支付与CSDN聚合在一起,可以为用户提供更便捷的支付和技术交流方式。比如,在CSDN平台上购买技术书籍或参加技术培训,用户可以直接通过支付宝微信支付完成交易;同时,在技术论坛上,用户也可以使用支付宝微信支付打赏优秀的技术分享者,激励他们分享更多有价值的技术内容。 总之,支付宝微信支付作为中国领先的移动支付平台,与CSDN的聚合,将为用户提供更加便捷和全面的支付和技术交流服务,促进移动支付和技术发展的融合。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LOVE_DDZ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值