springboot整合支付宝微信支付案例+代码

本文介绍了使用Spring Boot实现支付宝和微信支付的方法。包括下载官方demo、在蚂蚁金服官网配置个人信息、购买Natapp免费隧道进行内外网穿透,还展示了整合到Spring Boot的支付代码,最后总结提醒写博客要及时导出,并提供了完整代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot支付宝微信支付

每天多学一点点~
之前写好了一篇,不下心被覆盖的,我的锅。。。。下次写博客记得导出来!!!!
话不多说,这就开始吧…

1.下载官方的demo

重要的事情说三遍,官方demo很重要!!!
地址
在这里插入图片描述
官方demo对于每一种方法,每种回调都说的很清楚;
在这里插入图片描述

2.登陆蚂蚁金服官网,配置个人信息

蚂蚁金服开发者中心 https://openhome.alipay.com/platform/appDaily.htm

  1. 进入沙箱环境

在这里插入图片描述
2. 进入沙箱环境,配置AppkID等信息
在这里插入图片描述
密钥需要自己生成,appID和支付宝网关是已经给好的,网关有dev字样,表明是用于开发测试。点那个设置 可以下载生成公钥

  1. 配置密钥
    在这里插入图片描述
    注意:
    在这里插入图片描述
    点击上图的生成方法 下载 跟你系统对用的 程序,然后生成 相应的 密匙
    在这里插入图片描述
    如果没有设置过,此时显示文本是"设置应用公钥",我这里是已经设置过得

在这里插入图片描述
查看你的公钥把 公钥的字符串 复制过去 AlipayConfig.java 里面

在这里插入图片描述

3.Natapp购买免费隧道,用于内外网穿透

地址

在这里插入图片描述
配置隧道端口
在这里插入图片描述

4.代码

  1. 代码结构
    在这里插入图片描述
    在这里插入图片描述
    博主这里为了方便,就用了jsp页面

  2. 支付代码展示

package com.example.demo.controller;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.example.demo.config.AlipayConfig;
import com.example.demo.pojo.Orders;
import com.example.demo.pojo.Product;
import com.example.demo.service.OrdersService;
import com.example.demo.service.ProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Classname AlipayController
 * @Description TODO
 * @Date 2019/3/21 20:40
 * @Created by 爆裂无球
 */
@Controller
@RequestMapping("/alipay")
public class AlipayController {

    private static final Logger LOGGER = LoggerFactory.getLogger(AlipayController.class);


    @Autowired
    private ProductService productService;

    @Autowired
    private OrdersService ordersService;


    /**
     * 对应官方例子   alipay.trade.page.pay.jsp
     *
     * @Title: AlipayController.java
     * @Description: 前往支付宝第三方网关进行支付
     * Copyright: Copyright (c) 2019
     * Company:FURUIBOKE.SCIENCE.AND.TECHNOLOGY
     * @Classname AlipayController
     * @Description notify_url 和 return_url 需要外网可以访问,建议natapp 内网穿透
     * @Date 2019/3/21 20:40
     * @Created by 爆裂无球
     */
    @PostMapping("goAlipay")
    @ResponseBody
    public String goAlipay(String orderId, HttpServletRequest request, HttpServletRequest response) throws Exception {

        Orders order = ordersService.getOrderById(orderId);

        Product product = productService.getProductById(order.getProductId());

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号,商户网站订单系统中唯一订单号,必填
        String out_trade_no = orderId;
        //付款金额,必填
        String total_amount = order.getOrderAmount();
        //订单名称,必填
        String subject = product.getName();
        //商品描述,可空
        String body = "用户订购商品个数:" + order.getBuyCounts();

        // 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
        String timeout_express = "10m";

        //例子去官方api找
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"timeout_express\":\"" + timeout_express + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");


        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();

        return result;
    }


/*
 * 功能:支付宝服务器同步通知页面  return_url.jsp  return_url必须放在公网上
 * 日期:2017-03-30
 * 说明:
 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 * 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/

    /**
     * @Title: AlipayController.     对应官方例子return_url.jsp    return_url必须放在公网上  回跳页面
     * @Description: 支付宝同步通知页面
     * Copyright: Copyright (c) 2019
     * @Classname AlipayController
     * @Description TODO
     * @Date 2019/3/22 01:31
     * @Created by 爆裂无球
     */
    @RequestMapping("alipayReturnNotice")
    public String alipayReturnNotice(HttpServletRequest request, HttpServletRequest response, Map map) throws Exception {

        LOGGER.info("支付成功, 进入同步通知接口...");

        //获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名


        //——请在这里编写您的程序(以下代码仅作参考)——
        if (signVerified) {
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            // 修改叮当状态,改为 支付成功,已付款; 同时新增支付流水  这里放在 异步 业务 处理
//            ordersService.updateOrderStatus(out_trade_no, trade_no, total_amount);

            //页面  展示
            Orders order = ordersService.getOrderById(out_trade_no);
            Product product = productService.getProductById(order.getProductId());

            LOGGER.info("********************** 支付成功(支付宝同步通知) **********************");
            LOGGER.info("* 订单号: {}", out_trade_no);
            LOGGER.info("* 支付宝交易号: {}", trade_no);
            LOGGER.info("* 实付金额: {}", total_amount);
            LOGGER.info("* 购买产品: {}", product.getName());
            LOGGER.info("***************************************************************");

            map.put("out_trade_no", out_trade_no);
            map.put("trade_no", trade_no);
            map.put("total_amount", total_amount);
            map.put("productName", product.getName());


        } else {
            LOGGER.info("支付, 验签失败...");
        }

        //前后分离形式  直接返回页面 记得加上注解@Response  http://login.calidray.com你要返回的网址,再页面初始化时候让前端调用你其他接口,返回信息
//        String result = "<form action=\"http://login.calidray.com/?#/index/depreciation-scrap/depreciation\"  method=\"get\" name=\"form1\">\n" +
//                "</form>\n" +
//                "<script>document.forms[0].submit();</script>";
//
//        return result;
        //前后不分离的形式,直接返回jsp页面
        return "alipaySuccess";


    }


/* *
 * 功能:支付宝服务器异步通知页面   对应官方例子 notify_url.jsp     notify_url必须放入公网
 * 日期:2017-03-30
 * 说明:
 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 * 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 *************************页面功能说明*************************  制作业务处理
 * 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。
 * 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。
 * 如果没有收到该页面返回的 success
 * 建议该页面只做支付成功的业务逻辑处理,退款的处理请以调用退款查询接口的结果为准。
 */
    /**
     * @Title: AlipayController.java
     * @Description: 支付宝异步 通知  制作业务处理
     * Copyright: Copyright (c) 2017
     * Company:FURUIBOKE.SCIENCE.AND.TECHNOLOGY
     * @Description TODO
     * @Date 2019/3/22 01:45
     * @Created by 爆裂无球
     */
    @RequestMapping(value = "/alipayNotifyNotice")
    @ResponseBody
    public String alipayNotifyNotice(HttpServletRequest request, HttpServletRequest response) throws Exception {

        LOGGER.info("支付成功, 进入异步通知接口...");

        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用
//			valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        //——请在这里编写您的程序(以下代码仅作参考)——

		/* 实际验证过程建议商户务必添加以下校验:
        1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
		2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
		3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
		4、验证app_id是否为该商户本身。
		*/
        if (signVerified) {//验证成功
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

            //付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            if (trade_status.equals("TRADE_FINISHED")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                //如果有做过处理,不执行商户的业务程序

                //注意: 尚自习的订单没有退款功能, 这个条件判断是进不来的, 所以此处不必写代码
                //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                //如果有做过处理,不执行商户的业务程序

                //注意:
                //付款完成后,支付宝系统发送该交易状态通知

                // 修改叮当状态,改为 支付成功,已付款; 同时新增支付流水
                ordersService.updateOrderStatus(out_trade_no, trade_no, total_amount);

                //这里不用 查  只是为了 看日志 查的方法应该卸载 同步回调 页面 中
                Orders order = ordersService.getOrderById(out_trade_no);
                Product product = productService.getProductById(order.getProductId());

                LOGGER.info("********************** 支付成功(支付宝异步通知)查询 只是为了 看日志  **********************");
                LOGGER.info("* 订单号: {}", out_trade_no);
                LOGGER.info("* 支付宝交易号: {}", trade_no);
                LOGGER.info("* 实付金额: {}", total_amount);
                LOGGER.info("* 购买产品: {}", product.getName());
                LOGGER.info("***************************************************************");

            }
            LOGGER.info("支付成功...");

        } else {//验证失败
            LOGGER.info("支付, 验签失败...");
        }

        return "success";
    }


}

代码注释很详细了;
所有支付代码,官方demo中都有,只不过官方demo是写在jsp页面中的,博主将其整合到springboot中

  1. 效果展示
    多提一句,沙箱钱包现在只支持安卓环境。。。
    同步回调和异步回调,上文已经说过了,做个内网映射。

进入沙箱账户页面
在这里插入图片描述
用沙箱钱包登陆账号密码

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

异步回调,可用于 逻辑业务处理,同步回调,用于跳转页面。
博主这里前后不分离,同步回调后直接返回页面。若前后分离,可以用form表单形式返回页面,代码中都有注释。

5.总结

之前博客是写好的,不小心覆盖了,记住,以后写好博客后注意导出!!!
看到评论区有同学想要完整的例子,博主这次特意将代码整理好全部放入码云
支付宝微信支付例子

有需要的可以参考一下。

6.结语

世上无难事,只怕有心人,每天积累一点点,fighting!!!

评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值