前提:注册支付宝开放平台 开放平台

并且登录到沙箱控制台 登录 - 支付宝

1.准备工作做完,加pom依赖

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.22.110.ALL</version>
</dependency>
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-easysdk</artifactId>
    <version>2.2.0</version>
</dependency>

  2.配置 将以下配置写入nacos

alipay:
  #APPID
  appId: 支付宝账号ID
  gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do
  #应用私钥
  appPrivateKey: 这里写账号里的私钥
  #支付宝公钥
  alipayPublicKey: 支付宝公钥
  #回调接口 (使用内网穿透:https://natapp.cn/)
  returnUrl: https://www.baidu.com/s?ie=UTF-8&wd=%E5%8C%97%E4%BA%AC%E6%97%B6%E9%97%B4
  # 支付通知的回调地址,支付宝会在支付完成后通知这个地址
  notifyUrl: http://j97sy7.natappfree.cc/priceSum/notify
  # 参数返回格式,只支持JSON
  format: JSON
  # 请求使用的编码格式
  charset: UTF-8
  # 生成签名字符串所使用的签名算法类型
  signType: RSA2

注:支付宝公钥 分为两种,一种 支付宝公钥 一种应用公钥,这里一定要用支付宝公钥,不要写错了!!!

如图所示:

3.配置工具类

package com.shopgoods.order.config;

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

@Component
@Data
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {
    /**
     * 支付宝网关
     */
    private String gatewayUrl;
    /**
     * 应用ID
     */
    private String appId;
    /**
     * 应用私钥
     */
    private String appPrivateKey;
    /**
     * 支付宝公钥
     */
    private String alipayPublicKey;
    /**
     * 用户确认支付后,支付宝调用的页面返回路径
     * 开发环境为:http://localhost:8060/#/pages/money/paySuccess
     */
    private String returnUrl;
    /**
     * 支付成功后,支付宝服务器主动通知商户服务器里的异步通知回调(需要公网能访问)
     * 开发环境为:http://localhost:8085/alipay/notify
     */
    private String notifyUrl;
    /**
     * 参数返回格式,只支持JSON
     */
    private String format;
    /**
     * 请求使用的编码格式
     */
    private String charset;
    /**
     * 生成签名字符串所使用的签名算法类型
     */
    private String signType;
}

4.当Spring容器启动时,它会自动调用alipayClient方法,并将结果作为bean存储在Spring的IoC(控制反转)容器中,这样在整个应用程序中都可以方便地注入和使用这个AlipayClient实例来进行支付宝相关的操作

package com.shopgoods.order.config;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AlipayClientConfig {

    @Bean
    public AlipayClient alipayClient(AlipayConfig config){
        return new DefaultAlipayClient(config.getGatewayUrl(),config.getAppId(),config.getAppPrivateKey(), config.getFormat(),config.getCharset(),config.getAlipayPublicKey(),config.getSignType());
    }
}

创建Service

package com.shopgoods.order.service;

import com.shopgoods.order.config.AlipayConfig;
import com.shopgoods.order.domain.AliPayParam;
import com.shopgoods.order.domain.PricesSum;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @ClassName: PriceSumService
 * @Description: TODO
 * @Author: qh
 * @Date: 2024/11/22 18:34
 */

public interface PriceSumService {
    String webPay(AliPayParam aliPayParam);
/**
     * 支付宝异步回调处理
     */
    String notify(Map<String, String> params);
}

创建ServiceImpl

package com.shopgoods.order.service.impl;

import com.alibaba.csp.sentinel.util.StringUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.shopgoods.order.config.AlipayConfig;
import com.shopgoods.order.domain.AliPayParam;
import com.shopgoods.order.mapper.OrderMapper;
import com.shopgoods.order.service.IOrderService;
import com.shopgoods.order.service.PriceSumService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

import static org.bouncycastle.asn1.x500.style.RFC4519Style.cn;

/**
 * @ClassName: PriceSumServiceImpl
 * @Description: TODO
 * @Author: qh
 * @Date: 2024/11/22 18:35
 */
@Service
@Log4j2
public class PriceSumServiceImpl implements PriceSumService {

    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private AlipayConfig alipayConfig;
    @Override
    public String webPay(AliPayParam aliPayParam) {
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest ();
        if(StrUtil.isNotEmpty(alipayConfig.getNotifyUrl())){
            //异步接收地址,公网可访问
            request.setNotifyUrl(alipayConfig.getNotifyUrl());
        }
        if(StrUtil.isNotEmpty(alipayConfig.getReturnUrl())){
            //同步跳转地址
            request.setReturnUrl(alipayConfig.getReturnUrl());
        }
        //******必传参数******
        JSONObject bizContent = new JSONObject();
        //商户订单号,商家自定义,保持唯一性
        bizContent.put("out_trade_no", aliPayParam.getOutTradeNo());
        //支付金额,最小值0.01元
        bizContent.put("total_amount", aliPayParam.getTotalAmount());
        //订单标题,不可使用特殊符号
        bizContent.put("subject", aliPayParam.getSubject());
        //手机网站支付默认传值FAST_INSTANT_TRADE_PAY
        bizContent.put("product_code", "QUICK_WAP_WAY");
        request.setBizContent(bizContent.toString());
        String formHtml = null;
        try {
            formHtml = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return formHtml;
    }

     @Override
    public String notify(Map<String, String> params) {
        String result = "failure";
        boolean signVerified = false;
        try {
            //调用SDK验证签名
            signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());
        } catch (AlipayApiException e) {
            log.error("支付回调签名校验异常!",e);
            e.printStackTrace();
        }
        if (signVerified) {
            String tradeStatus = params.get("trade_status");
            if("TRADE_SUCCESS".equals(tradeStatus)){
                result = "success";
                log.info("notify方法被调用了,tradeStatus:{}",tradeStatus);
                String outTradeNo = params.get("out_trade_no");
//                portalOrderService.paySuccessByOrderSn(outTradeNo,1);
               //支付成功修改状态
                orderService.updatePaySuccessByOrderSn(outTradeNo,3);
            }else{
                log.warn("订单未支付成功,trade_status:{}",tradeStatus);
            }
        } else {
            log.warn("支付回调签名校验失败!");
        }
        return result;
    }

6.回调之前必须提前配置好内网穿透

先下载natapp

内网穿透链接:NATAPP -

购买一个免费隧道就可以了

将nacos回调地址更改为以上的地址

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐