首页 > 其他分享 >SpringBoot 集成支付宝的各种应用场景

SpringBoot 集成支付宝的各种应用场景

时间:2023-03-31 16:05:52浏览次数:54  
标签:集成 支付宝 SpringBoot alipay request params 支付 String

SpringBoot 集成支付宝的各种应用场景_SpringBoot

Spring Boot是一个非常流行的Java框架,它提供了一种快速、简便的方式来开发基于Java的Web应用程序。支付宝是中国最大的第三方支付平台,它提供了丰富的API,支持多种支付方式。在本篇博客中,我将介绍如何使用Spring Boot集成支付宝支付,包括以下几个场景:

  • 手机网站支付
  • 电脑网站支付
  • 移动支付
  • 扫码支付
  • APP支付

在开始之前,您需要先在 支付宝开放平台 注册一个支付宝账号,并且完成开发者认证,获取到支付宝开放平台的APPID、商户私钥、支付宝公钥等信息。

一. 手机网站支付

手机网站支付是指在手机浏览器中完成支付的一种方式。下面是集成步骤:

1.引入支付宝SDK依赖

在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.22.22.ALL</version>
</dependency>

2.配置支付宝信息

在SpringBoot的配置文件(application.yml或application.properties)中,添加支付宝的配置参数,例如:

alipay:
  alipayPublicKey: ALIPAY_PUBLIC_KEY
  appId: YOUR_APP_ID
  gateway: https://openapi.alipay.com/gateway.do
  appPrivateKey: YOUR_PRIVATE_KEY

alipay.alipayPublicKey=ALIPAY_PUBLIC_KEY
alipay.appId=YOUR_APP_ID
alipay.gateway=https://openapi.alipay.com/gateway.do
alipay.appPrivateKey=YOUR_PRIVATE_KEY

3.编写支付请求接口

@RestController
public class PayController {

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

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

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

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

    @RequestMapping("/pay")
    public String pay(HttpServletRequest request) throws AlipayApiException {
        // 实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, appPrivateKey, "json", "utf-8", alipayPublicKey, "RSA2");
        // 实例化请求对象
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        // 设置回调地址
        alipayRequest.setReturnUrl(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/return_url");
        alipayRequest.setNotifyUrl(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/notify_url");
        // 设置订单信息
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo("20150320010101001");
        model.setSubject("Iphone6 16G");
        model.setTotalAmount("0.01");
        model.setBody("Iphone6 16G");
        model.setTimeoutExpress("30m");
        model.setProductCode("QUICK_WAP_WAY");
        alipayRequest.setBizModel(model);
        // 调用SDK生成表单
        String form = alipayClient.pageExecute(alipayRequest).getBody();
        return form;
    }

    @RequestMapping("/return_url")
    public String returnUrl(HttpServletRequest request) throws AlipayApiException {
        // 获取支付宝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 = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 解码
            params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
        }
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
        if (signVerified) {
            return "success";
        } else {
            return "fail";
        }
    }

    @RequestMapping("/notify_url")
    public String notifyUrl(HttpServletRequest request) throws AlipayApiException {
        // 获取支付宝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 = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 解码
            params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
        }
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
        if (signVerified) {
            // 商户订单号
            String outTradeNo = params.get("out_trade_no");
            // 支付宝交易号
            String tradeNo = params.get("trade_no");
            // 交易状态
            String tradeStatus = params.get("trade_status");
            if (tradeStatus.equals("TRADE_SUCCESS")) {
                // TODO: 处理业务逻辑
                return "success";
            }
        }
        return "fail";
    }
}

二. 电脑网站支付

电脑网站支付是指在电脑浏览器中完成支付的一种方式。下面是集成步骤:

1.引入支付宝SDK依赖

在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.22.22.ALL</version>
</dependency>

2.配置支付宝信息

在SpringBoot的配置文件(application.yml或application.properties)中,添加支付宝的配置参数,例如:

alipay:
  alipayPublicKey: ALIPAY_PUBLIC_KEY
  appId: YOUR_APP_ID
  gateway: https://openapi.alipay.com/gateway.do
  appPrivateKey: YOUR_PRIVATE_KEY

alipay.alipayPublicKey=ALIPAY_PUBLIC_KEY
alipay.appId=YOUR_APP_ID
alipay.gateway=https://openapi.alipay.com/gateway.do
alipay.appPrivateKey=YOUR_PRIVATE_KEY

3.编写支付请求接口

@RestController
public class PayController {

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

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

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

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

    @RequestMapping("/pay")
    public String pay(HttpServletRequest request) throws AlipayApiException {
        // 实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, appPrivateKey, "json", "utf-8", alipayPublicKey, "RSA2");
        // 实例化请求
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        // 设置异步通知地址
        alipayRequest.setNotifyUrl("http://localhost:8080/notify_url");
        // 设置同步通知地址
        alipayRequest.setReturnUrl("http://localhost:8080/return_url");
        // 设置订单号
        String outTradeNo = "20220326112000001";
        // 设置订单总金额
        String totalAmount = "100.00";
        // 设置订单标题
        String subject = "测试电脑网站支付";
        // 组装请求参数
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(outTradeNo);
        model.setTotalAmount(totalAmount);
        model.setSubject(subject);
        model.setBody("测试电脑网站支付");
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizModel(model);
        // 请求支付宝进行支付
        String form = alipayClient.pageExecute(alipayRequest).getBody();
        return form;
    }

    @RequestMapping("/return_url")
    public String returnUrl(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
        // 获取支付宝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 = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 解码
            params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
        }
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
        if (signVerified) {
            // 获取订单号
            String outTradeNo = params.get("out_trade_no");
            // 获取支付宝交易号
            String tradeNo = params.get("trade_no");
            // 获取交易状态
            String tradeStatus = params.get("trade_status");
            if (tradeStatus.equals("TRADE_SUCCESS")) {
                // TODO: 处理业务逻辑
                return "success";
            }
        }
        return "fail";
    }

    @RequestMapping("/notify_url")
    public String notifyUrl(HttpServletRequest request) throws AlipayApiException {
        // 获取支付宝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 = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 解码
            params.put(name, URLDecoder.decode(valueStr, "UTF-8"));
        }
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
        if (signVerified) {
            // 获取订单号
            String outTradeNo = params.get("out_trade_no");
            // 获取支付宝交易号
            String tradeNo = params.get("trade_no");
            // 获取交易状态
            String tradeStatus = params.get("trade_status");
            if (tradeStatus.equals("TRADE_SUCCESS")) {
                // TODO: 处理业务逻辑
                return "success";
            }
        }
        return "fail";
    }
}

在上面的代码中,我们首先定义了一个AlipayClient对象,用来创建支付宝请求对象和发送请求。然后,我们定义了一个方法,用于生成电脑网站支付的表单,该方法接收订单号、订单总金额和订单标题等参数,并返回生成的表单字符串。在该方法中,我们首先创建了一个AlipayTradePagePayRequest对象,设置了异步通知地址和同步通知地址等参数,然后使用AlipayTradePagePayModel对象组装了请求参数,最后使用alipayClient.pageExecute()方法发起支付宝支付请求,并将返回的表单字符串返回给调用方。

returnUrl方法中,我们首先获取支付宝返回的参数,并验证签名是否正确。如果签名验证通过,我们再从返回参数中获取订单号、支付宝交易号和交易状态等信息,根据交易状态进行业务逻辑处理。如果交易状态为TRADE_SUCCESS,表示交易成功,我们可以在这里处理相关业务逻辑,例如更新订单状态等操作。

notifyUrl方法中,与returnUrl方法类似,我们也是首先获取支付宝返回的参数,并验证签名是否正确。如果签名验证通过,我们再从返回参数中获取订单号、支付宝交易号和交易状态等信息,根据交易状态进行业务逻辑处理。与returnUrl方法不同的是,该方法是异步通知接口,支付宝服务器会向该接口发送POST请求,通知支付结果,我们需要在该方法中及时处理通知,并返回success字符串表示已成功接收到通知。

三. 移动支付

除了电脑网站支付,支付宝还提供了移动支付的功能,让用户可以在手机端完成支付。

1.注册支付宝开发者账号并创建应用

在使用支付宝移动支付之前,我们需要注册一个支付宝开发者账号,并在开发者中心创建一个应用。具体步骤如下:

1.1. 打开支付宝开发者中心网址: https://openhome.alipay.com/platform/appManage.htm

1.2. 登录支付宝开发者账号,如果还没有账号,可以先注册一个。

1.3. 点击“创建应用”按钮,进入创建应用页面。

1.4. 填写应用名称和应用类型,选择移动应用,并提交创建。

1.5. 创建成功后,会自动生成AppID、私钥等信息。我们需要将这些信息保存下来,后面会用到。

2.引入支付宝SDK依赖

在项目的pom.xml文件中添加支付宝SDK依赖,具体代码如下:

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.22.22.ALL</version>
</dependency>

3.配置支付宝参数

在SpringBoot的配置文件(application.yml或application.properties)中,添加支付宝的配置参数,例如:

ali:
  pay:
    app-id: YOUR_APP_ID
    notify-url: http://www.example.com/notify
    private-key: YOUR_PRIVATE_KEY
    public-key: ALIPAY_PUBLIC_KEY

ali.pay.app-id=YOUR_APP_ID
ali.pay.private-key=YOUR_PRIVATE_KEY
ali.pay.public-key=ALIPAY_PUBLIC_KEY
ali.pay.notify-url=http://www.example.com/notify

其中,ali.pay.app-id是在支付宝开发者中心创建应用时生成的AppID;ali.pay.private-key是我们自己生成的私钥,需要在支付宝开发者中心上传,同时也需要保存在本地;ali.pay.public-key是支付宝公钥,也需要在支付宝开发者中心获取;ali.pay.notify-url是支付成功后,支付宝服务器将支付结果通知给商户服务器的回调接口地址。

4.编写支付接口

在SpringBoot中,我们可以使用@Controller和@ResponseBody注解来定义一个接口,用于处理支付请求。具体代码如下:

@Controller
public class PayController {

    @Autowired
    private AliPayConfig aliPayConfig;

    @PostMapping("/pay")
    @ResponseBody
    public String pay(@RequestParam("outTradeNo") String outTradeNo,
                      @RequestParam("totalAmount") String totalAmount,
                      @RequestParam("subject") String subject) throws AlipayApiException {
        // 创建 AlipayClient 对象,用于调用支付宝接口
        AlipayClient alipayClient = new DefaultAlipayClient(
                aliPayConfig.getServerUrl(),
                aliPayConfig.getAppId(),
                aliPayConfig.getPrivateKey(),
                "json",
                "utf-8",
                aliPayConfig.getPublicKey(),
                "RSA2");
        // 创建 AlipayTradeAppPayRequest 对象,用于设置支付参数
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        // 设置异步回调地址
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
	    // 设置订单信息
	    AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
	    model.setOutTradeNo(outTradeNo);
	    model.setTotalAmount(totalAmount);
	    model.setSubject(subject);
	    model.setProductCode("QUICK_MSECURITY_PAY");
	    request.setBizModel(model);
	    // 调用支付接口,获取支付参数
	    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
	    // 返回客户端支付参数
	    return response.getBody();
	}
}

在代码中,我们通过AlipayClientAlipayTradeAppPayRequest对象来设置支付参数,然后调用支付宝的接口获取支付参数。最后将支付参数返回给客户端,客户端就可以使用支付宝SDK调起支付宝APP进行支付了。

5. 处理支付结果回调

当客户端支付成功后,支付宝服务器会将支付结果通知给商户服务器的回调接口地址,我们需要编写一个接口来处理支付结果回调。具体代码如下:

@Controller
public class NotifyController {

    @PostMapping("/notify")
    @ResponseBody
    public String notify(HttpServletRequest request) throws AlipayApiException {
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<>();
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String paramName = parameterNames.nextElement();
            String paramValue = request.getParameter(paramName);
            params.put(paramName, paramValue);
        }
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params,
                aliPayConfig.getPublicKey(),
                "utf-8",
                "RSA2");
        if (signVerified) {
            // 处理支付结果
            String tradeStatus = params.get("trade_status");
            String outTradeNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            String totalAmount = params.get("total_amount");
            // TODO: 处理支付结果
            return "success";
        } else {
            return "failure";
        }
    }
}

在代码中,我们首先获取支付宝POST过来的反馈信息,然后通过AlipaySignature.rsaCheckV1()方法验证签名,确保支付结果是合法的。最后,我们可以根据支付结果进行相应的业务处理,例如更新订单状态、发送邮件通知等。

6.发起支付请求

客户端在发起支付请求时,需要调用我们编写的支付接口,并将支付参数传递给支付宝SDK。具体代码如下:

public class PayActivity extends AppCompatActivity {

    private static final String TAG = "PayActivity";

    private static final String SERVER_URL = "http://www.example.com/pay";

    private static final int SDK_PAY_FLAG = 1;

    private Button mBtnPay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pay);
        mBtnPay = findViewById(R.id.btn_pay);
        mBtnPay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pay();
            }
        });
    }

    private void pay() {
        String outTradeNo = UUID.randomUUID().toString();
        String totalAmount = "0.01";
        String subject = "测试商品";
        OkHttpClient client = new OkHttpClient();
        RequestBody requestBody = new FormBody.Builder()
                .add("out_trade_no", outTradeNo)
                .add("total_amount", totalAmount)
                .add("subject", subject)
                .build();
        Request request = new Request.Builder()
                .url(SERVER_URL)
                .post(requestBody)
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "请求支付接口失败", e);
                showToast("请求支付接口失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    // 获取支付参数成功,打印日志,并将支付参数传递给支付宝SDK
                    String body = response.body().string();
                    Log.d(TAG, "获取支付参数成功: " + body);
                    PayTask task = new PayTask(PayActivity.this);
                    Map<String, String> result = task.payV2(body, true);
                    // 将支付结果通过 Handler 对象传递回主线程
                    Message msg = new Message();
                    msg.what = SDK_PAY_FLAG;
                    msg.obj = result;
                    mHandler.sendMessage(msg);
                } else {
                    // 获取支付参数失败,打印日志,并提示用户
                    Log.e(TAG, "获取支付参数失败: " + response.code());
                    showToast("获取支付参数失败");
                }
            }
        });
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG:
                    Map<String, String> result = (Map<String, String>) msg.obj;
                    String resultStatus = result.get("resultStatus");
                    if (TextUtils.equals(resultStatus, "9000")) {
                        showToast("支付成功");
                    } else if (TextUtils.equals(resultStatus, "6001")) {
                        showToast("支付取消");
                    } else {
                        showToast("支付失败");
                    }
                    break;
            }
        }
    };

    private void showToast(String message) {
        runOnUiThread(() -> Toast.makeText(PayActivity.this, message, Toast.LENGTH_SHORT).show());
    }
}

在代码中,我们首先调用我们编写的支付接口获取支付参数,然后将支付参数传递给支付宝SDK,让SDK调起支付宝APP进行支付。支付结果会通过SDK_PAY_FLAG标志和Handler对象返回到主线程,我们可以在Handler对象中根据支付结果进行相应的提示。

至此,我们已经成功集成了支付宝移动支付。在实际开发中,还需要考虑异常处理、订单状态同步、订单查询等问题。

四. 扫码支付

除了电脑网站支付和移动支付,支付宝还提供了扫码支付的功能,让用户可以在商户店铺扫描二维码完成支付。

1.注册支付宝开发者账号

首先,我们需要注册一个支付宝开发者账号。在注册完成后,我们需要进入开发者中心,在“应用管理”中创建一个新的应用,选择“PC网站支付”作为接口类型。

在创建完应用后,我们需要获取一些必要的配置信息,包括应用ID、商户私钥、支付宝公钥、异步通知地址、同步跳转地址等。这些配置信息将在后面的代码中使用。

2.引入支付宝SDK依赖

在我们的Spring Boot项目中,我们需要引入支付宝SDK。支付宝SDK提供了一系列用于调用支付宝接口的Java类和方法。我们可以使用Maven或Gradle来管理我们的项目依赖。下面是一个Maven的依赖配置示例:

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.22.22.ALL</version>
</dependency>

3.配置支付宝信息

在我们的Spring Boot项目中,我们需要在配置文件中添加支付宝信息。下面是一个示例配置文件:

# 支付宝网关
alipay.gatewayUrl=https://openapi.alipay.com/gateway.do
# 应用ID
alipay.appId=xxxxxxxxxxxx
# 商户私钥
alipay.privateKey=xxxxxxxxxxxx
# 支付宝公钥
alipay.alipayPublicKey=xxxxxxxxxxxx
# 异步通知地址
alipay.notifyUrl=http://localhost:8080/notify
# 同步跳转地址
alipay.returnUrl=http://localhost:8080/return

alipay:
  alipayPublicKey: xxxxxxxxxxxx
  appId: xxxxxxxxxxxx
  gatewayUrl: https://openapi.alipay.com/gateway.do
  notifyUrl: http://localhost:8080/notify
  privateKey: xxxxxxxxxxxx
  returnUrl: http://localhost:8080/return

4.实现支付接口

在我们的Spring Boot项目中,我们需要实现一个支付接口,用于生成支付二维码并返回给前端。下面是一个示例代码:

@RestController
public class AlipayController {

    @Resource
    private AlipayConfig alipayConfig;

    /**
     * 支付宝扫码支付
     */
    @GetMapping("/scan/pay")
    public String scanPay(String orderNo, String amount, String subject) throws AlipayApiException {
        // 创建AlipayClient对象
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getServerUrl(), alipayConfig.getAppId(), alipayConfig.getPrivateKey(), "json", "UTF-8", alipayConfig.getAlipayPublicKey(), "RSA2");
        // 创建AlipayTradePrecreateRequest对象
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        // 设置异步通知地址
        request.setNotifyUrl("异步通知地址");
        // 设置订单信息
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setOutTradeNo(orderNo);
        model.setTotalAmount(amount);
        model.setSubject(subject);
        request.setBizModel(model);
        // 发起支付请求
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            // 返回二维码链接给前端
            return response.getQrCode();
        } else {
            // 处理支付失败的情况
            throw new AlipayApiException(response.getMsg());
        }
    }

    /**
     * 处理支付结果
     */
    @PostMapping("/notify")
    public String notify(HttpServletRequest request) throws AlipayApiException {
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<>();
        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, alipayConfig.getAlipayPublicKey(), "UTF-8", "RSA2");
        if (verifyResult) {
            // 处理支付成功的情况
            String orderNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            String amount = params.get("total_amount");
            // TODO: 处理订单状态
            return "success";
        } else {
            // 处理验签失败的情况
            return "failure";
        }
    }
}

在上面的代码中,我们定义了一个AlipayController,其中包含了两个接口:scanPaynotify

scanPay接口中,我们首先创建了一个AlipayClient对象,然后创建了一个AlipayTradePrecreateRequest对象,并设置了异步通知地址和订单信息。最后,我们通过AlipayClient对象的execute方法发送支付请求,获取二维码链接,并将其返回给前端。

notify接口中,我们首先从request中获取支付结果参数,并使用AlipaySignature.rsaCheckV1方法验证签名。如果验签成功,则处理支付成功的情况,否则处理验签失败的情况。在处理支付成功的情况时,我们可以根据订单号、交易号和金额等参数来更新订单状态。

5. 测试支付接口

最后,我们可以使用Postman等工具来测试我们的支付接口。在测试时,我们需要传入订单号、订单金额和订单标题等参数,然后可以获取到支付宝生成的二维码,并使用支付宝App或支付宝扫码枪扫描二维码来完成支付。

至此,我们已经完成了在Spring Boot中集成支付宝扫码支付的过程。如果您在实际使用中遇到了问题,可以查看支付宝SDK文档或咨询支付宝开发者支持。

五. APP支付

除了移动支付和扫码支付,支付宝还提供了APP支付的功能,让开发者可以在APP中集成支付宝支付。

1.引入支付宝SDK依赖

在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.22.22.ALL</version>
</dependency>

2.配置支付宝信息

在application.properties文件中添加支付宝相关配置信息,包括应用ID、私钥、公钥等:

# 支付宝配置信息
alipay.app-id=应用ID
alipay.private-key=应用私钥
alipay.public-key=支付宝公钥
alipay.server-url=https://openapi.alipay.com/gateway.do

alipay:
  app-id: 应用ID
  private-key: 应用私钥
  public-key: 支付宝公钥
  server-url: https://openapi.alipay.com/gateway.do

其中,应用ID可以在支付宝开放平台中创建应用后获得,私钥和公钥需要在创建应用时生成。

3.创建支付接口

在Spring Boot应用程序中创建一个控制器类,命名为AlipayController,用于处理支付相关的请求:

@RestController
@RequestMapping("/alipay")
public class AlipayController {

    @Autowired
    private AlipayConfig alipayConfig;

    /**
     * 处理支付请求
     */
    @PostMapping("/app-pay")
    public String appPay(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
        // 实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getServerUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getPrivateKey(),
                "json",
                "UTF-8",
                alipayConfig.getAlipayPublicKey(),
                "RSA2");
        // 实例化请求对象
        AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
        // 设置异步通知地址
        alipayRequest.setNotifyUrl("http://localhost:8080/alipay/notify");
        // 设置订单信息
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setOutTradeNo("订单号");
        model.setSubject("订单标题");
        model.setBody("订单描述");
        model.setTotalAmount("订单金额");
        alipayRequest.setBizModel(model);
        // 请求支付宝生成支付结果
        String form = alipayClient.sdkExecute(alipayRequest).getBody();
        // 将支付结果返回给客户端
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write(form);
        response.getWriter().flush();
        response.getWriter().close();
        return null;
    }

    /**
     * 处理支付结果
     */
    @PostMapping("/notify")
    public String notify(HttpServletRequest request) throws AlipayApiException {
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<>();
        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, alipayConfig.getAlipayPublicKey(), "UTF-8", "RSA2");
        if (verifyResult) {
            // 处理支付结果
            String tradeStatus = params.get("trade_status");
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                String outTradeNo = params.get("out_trade_no");
                String tradeNo = params.get("trade_no");
                // TODO: 处理支付结果
            }
            return "success";
        } else {
            return "failure";
        }
    }
}

在支付请求处理方法appPay()中,我们创建了一个AlipayTradeAppPayRequest对象,设置了异步通知地址、订单信息等参数,然后通过AlipayClient对象调用sdkExecute()方法向支付宝发起支付请求,并将支付结果以HTML形式返回给客户端。

在支付结果处理方法notify()中,我们获取支付宝POST过来的反馈信息,使用AlipaySignature类的rsaCheckV1()方法验证签名,然后根据支付结果处理业务逻辑,最后返回一个success字符串表示处理成功,或者返回failure字符串表示处理失败。

4.调用支付接口

在客户端调用支付接口时,需要向服务端发送支付请求,并获取服务端返回的支付结果。具体代码如下:

public class AlipayClient {
    
    private static final String APP_PAY_URL = "http://localhost:8080/alipay/app-pay";

    /**
     * 调用支付接口
     */
    public String pay() {
        OkHttpClient client = new OkHttpClient();
        RequestBody formBody = new FormBody.Builder()
                .build();
        Request request = new Request.Builder()
                .url(APP_PAY_URL)
                .post(formBody)
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

在客户端的AlipayClient类中,我们通过OkHttpClient对象向服务端发送一个POST请求,获取服务端返回的支付结果,最后将支付结果返回给调用方。

以上就是集成支付宝APP支付的基本步骤。需要注意的是,在使用支付宝SDK进行支付开发时,需要遵守支付宝的相关规定和安全要求,确保支付过程的安全和正确性。在实际开发中,还需要根据业务需求进行相关的调整和优化。例如,可以根据不同的支付场景选择不同的支付方式,或者对支付结果进行定时查询和处理等等。总之,只有不断地实践和优化,才能在实际项目中使用支付宝SDK进行高效、安全、稳定的支付开发。

总结

在本篇博客中,我们介绍了在SpringBoot项目中集成支付宝支付的五种场景;需要注意保护支付宝API密钥和支付宝公钥等敏感信息,确保支付过程的安全性。

在实际的开发过程中,我们可以根据具体的业务场景和需求,进行支付宝支付功能的扩展和定制化开发。同时,我们也需要考虑支付宝支付过程中的异常情况和处理方法,例如订单重复支付、支付超时、支付金额不正确等问题。

希望这篇博客能够帮助您掌握SpringBoot集成支付宝支付的方法,并能够在实际项目中得到应用。如果您有任何问题或建议,欢迎在评论区留言,谢谢!

标签:集成,支付宝,SpringBoot,alipay,request,params,支付,String
From: https://blog.51cto.com/loveddz/6150371

相关文章

  • SpringBoot 集成微信支付的各种支付产品
    SpringBoot是一款非常流行的Java开发框架,而微信支付则是众多移动支付产品中的佼佼者,整合两者可以让我们更方便地开发各种支付产品。在本篇博客中,我将介绍如何在SpringBoot中整合微信支付的各种支付产品。准备工作微信支付官网注册一个微信支付商户账号创建一个微信支付应用......
  • spring MongoDB 集成crud操作(简单封装)
    这两天一直在学习mongodb,由于我的博客网站想把mysql替换成mongodb,为什么会有这样的冲动,我通过收集一些资料,关于mongodb跟mysql的对比...发现性能上mongodb比上mysql是高出很多倍...无论是增,删,修,查的操作.....都比mysql效率好...但是,我也看到,mongodb是文档型数据库...做......
  • 1-SpringBoot快速入门
    SpringBoot快速入门1.什么是SpringBoot回顾什么是Spring?Spring是一个开源框架,2003年兴起的一个轻量级的Java开发框架,作者:RodJohnson。Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。Spring是如何简化Java开发的?为了降低Java开发的复杂性,Spring采用......
  • 使用SpringBoot异步方法优化报销单查询接口,提高接口响应速度
    合理使用异步方法可以提高接口性能。异步方法适用于逻辑与逻辑之间可以相互分割互不影响的业务中。SpringBoot支持异步方法调用。具体用法:在启动类添加@EnableAsync注解,声明开启异步方法在异步方法添加@Async注解,被@Async注解修改的方法由SpringBoot默认线程池(SimpleAsyncTas......
  • 【AGC】集成AGC认证服务facebook登录报错问题
    ​【关键字】认证服务、facebook、AGC 【问题描述】开发者反馈应用集成了AGC认证服务的facebook登录功能,在登录时遇到了一些问题。提示SERVER_ERROR:[code]1675030[message]:执行查询时出错,具体如下所述:开发接入集成认证服务中的fb登陆,目前我们有自己的google包,接入了f......
  • SpringBoot中如何动态加载类到容器
    任何业务脱离场景无任何实际意义。场景:1,实现了多种存储方式,redis和本地内存或者其它,但是你希望根据注解配置只加载一种类到容器。2,经典场景:mybatis将接口的代理类动态加载到容器。分类:静态加载:1,springboot中会扫描同包路径下的(@configuration@Service@Component)标记了上述......
  • SpringBoot2.7集成Swagger3
    1、引入pom坐标<!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version></dependency><dependency><groupId&......
  • springboot注册Servlet、Filter、Listener的方式
    方式一:注解@WebServlet@WebFilter@WebListener在实现类上使用该注解即可一键注册方式二:配置类在@Configuration标识的配置类中通过RegistrationBean进行注册@Beanp......
  • Spring-Boot整合微信登陆、微信支付、邮箱发送、支付宝支付和阿里云短信
    Spring-Boot整合1.发送邮件2.支付宝支付3.阿里云短信4.微信登陆5.微信支付6.Swargger2前后端API接口信息文档7.ehcache缓存缓存8.Spring-Boot注解详解9.自定义配......
  • SpringBoot 项目使用 Sa-Token 完成登录认证
    一、设计思路对于一些登录之后才能访问的接口(例如:查询我的账号资料),我们通常的做法是增加一层接口校验:如果校验通过,则:正常返回数据。如果校验未通过,则:抛出异常,告知其需......