huaweichenai头像

spring boot对接支付宝支付

一:参考文档

https://opendocs.alipay.com/openHome

二:依赖安装

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

三:支付宝配置

alipay:
  app-id: 你的沙箱appId
  app-private-key: 你的应用私钥
  alipay-public-key: 支付宝公钥
  notify-url: https://xx/notify #异步回调地址,公网POST
  return-url: http://xx/success #用户支付完页面跳转回前端
  gateway: https://openapi-sandbox.dl.alipaydev.com/gateway.do #沙箱网关,上线改正式网关

四:支付宝配置读取类

package com.example.demo.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {
    private String appId;
    private String appPrivateKey;
    private String alipayPublicKey;
    private String notifyUrl;
    private String returnUrl;
    private String gateway;
}

五:支付宝配置类

package com.example.demo.config;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.example.demo.properties.AlipayProperties;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AlipayConfig {
    @Resource
    private AlipayProperties alipayProperties;

    @Bean
    public AlipayClient alipayClient()
    {
        //构造client RSA2,UTF-8,JSON格式
        return new DefaultAlipayClient(
                alipayProperties.getGateway(),
                alipayProperties.getAppId(),
                alipayProperties.getAppPrivateKey(),
                "json",
                "UTF-8",
                alipayProperties.getAlipayPublicKey(),
                "RSA2");
    }
}

六:调用示例

package com.example.demo.controller;

import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.example.demo.properties.AlipayProperties;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/alipay")
public class AlipayController {
    @Resource
    private AlipayClient alipayClient;

    @Resource
    private AlipayProperties alipayProperties;

    /**
     * 发起支付,电脑网站支付,返回form表单,前端直接渲染自动跳转支付宝收银台
     */
    @GetMapping("/create")
    public String createPay() throws Exception {
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setReturnUrl(alipayProperties.getReturnUrl());
        request.setNotifyUrl(alipayProperties.getNotifyUrl());

        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        //商户订单号,必须唯一
        String outTradeNo = "ORDER_" + UUID.randomUUID().toString().replace("-","");
        model.setOutTradeNo(outTradeNo);
        model.setSubject("测试");
        model.setTotalAmount("0.01"); //金额,字符串,保留2位小数
        model.setProductCode("FAST_INSTANT_TRADE_PAY"); //电脑网站支付固定值

        request.setBizModel(model);
        //得到form表单html,前端直接输出
        String form = alipayClient.pageExecute(request).getBody();
        return form;
    }

    /**
     * 【核心】异步通知接口 POST,支付宝主动调用,**必须公网可访问**
     * 支付成功/退款等都会回调;验签成功后修改订单状态,返回 success
     */
    @PostMapping("/notify")
    public String notify(HttpServletRequest request, HttpServletResponse response) throws Exception{
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            params.put(entry.getKey(), entry.getValue()[0]);
        }

        // 1.验签,确认请求来自支付宝
        boolean signVerified = AlipaySignature.rsaCheckV1(
                params,
                alipayProperties.getAlipayPublicKey(),
                "UTF-8",
                "RSA2");

        if(!signVerified){
            //支付宝回调验签失败
            return "fail";
        }

        // 2.业务校验
        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");//金额

        if ("TRADE_SUCCESS".equals(tradeStatus)) {
            //========业务代码:更新订单状态为已支付,注意幂等!========
        }
        //支付宝收到 success 就不再重试;返回其他会重复回调
        return "success";
    }

    /**
     * 同步页面跳转 returnUrl GET请求
     * 支付宝会把参数拼在url后面,GET方式
     */
    @GetMapping("/success")
    public String returnUrl(HttpServletRequest request, Model model) throws Exception {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            params.put(entry.getKey(), entry.getValue()[0]);
        }

        // 同步回调同样需要验签!防止伪造链接
        boolean signVerified = AlipaySignature.rsaCheckV1(
                params,
                alipayProperties.getAlipayPublicKey(),
                "UTF-8",
                "RSA2");

        if (!signVerified) {
            //同步回调验签失败
            model.addAttribute("msg", "验签失败,非法请求");
            return "payFail";
        }

        // 获取参数
        String outTradeNo = params.get("out_trade_no"); //商户订单号
        String tradeNo = params.get("trade_no");        //支付宝交易号
        String totalAmount = params.get("total_amount");//金额
        String tradeStatus = params.get("trade_status");//状态

        // 【仅页面展示】不要在这里修改订单状态!
        // 建议:主动调用支付宝订单查询接口,实时确认订单状态,再展示页面
        AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();
        queryRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\"}");
        AlipayTradeQueryResponse resp = alipayClient.execute(queryRequest);

        if(resp.isSuccess() && "TRADE_SUCCESS".equals(resp.getTradeStatus())){
            model.addAttribute("outTradeNo", outTradeNo);
            model.addAttribute("tradeNo", tradeNo);
            model.addAttribute("amount", totalAmount);
            model.addAttribute("msg", "支付成功");
            return "paySuccess";
        }else{
            model.addAttribute("msg", "订单未支付成功");
            return "payFail";
        }
    }
}

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/huaweichenai/article/details/168228084

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--