• Java集成支付宝沙箱支付,详细教程(SpringBoot完整版)


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    一、开发前准备?

    easy支付官方文档:https://opendocs.alipay.com/open/009ys9

    通用版文档:https://opendocs.alipay.com/open/02np94

    支付宝沙箱的配置:
    注册支付宝开发者账户,进入开发者控制台

    沙箱快捷入口:
    https://open.alipay.com/develop/sandbox/app

    在这里插入图片描述
    沙箱的界面:

    在这里插入图片描述

    二、使用步骤

    1、引入库

    <dependency>
        <groupId>com.alipay.sdkgroupId>
        <artifactId>alipay-easysdkartifactId>
        <version>2.2.2version>
    dependency>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、配置在 application.yml 里面进行配置:

    #阿里沙箱支付配置
    alipay:
      #签名算法
      signType: 
      #应用ID
      appId: 
      #应用私钥
      appPrivateKey:
      #支付宝公钥
      publicKey: 
      #回调地址
      notifyUrl: 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3、alipay的java配置:AplipayConfig.java

    /**
     * @author :Mr.ZJW
     * @date :Created 2023/9/20 17:40
     * @description:alipay沙箱环境配置
     */
    @Slf4j
    @Data
    @Component
    @ConfigurationProperties(prefix = "alipay")
    public class AlipayConfig {
    
        /**
         * appId
         */
        private String appId;
    
        /**
         * 私钥
         */
        private String appPrivateKey;
    
        /**
         * 公钥
         */
        private String publicKey;
    
        /**
         * 回调地址
         */
        private String notifyUrl;
    
        /**
         * 支付宝配置初始化,公钥模式
         */
        @PostConstruct
        public void init() {
            Config config = new Config();
            //#基础配置
            config.protocol = "https";  //协议
            config.gatewayHost = "openapi.alipaydev.com";    //支付宝网关
            config.signType = "RSA2";   //签名方式
            //#业务配置
            config.appId = this.appId;  //应用id
            config.merchantPrivateKey = this.appPrivateKey;    应用私钥
            config.alipayPublicKey = this.publicKey;    //支付宝公钥
            config.notifyUrl = this.notifyUrl;  //回调地址
            Factory.setOptions(config);
            log.info("支付宝配置初始化完成");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    4、支付接口

    import com.alipay.easysdk.factory.Factory;
    import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
    import com.google.common.collect.Maps;
    import com.jowell.common.exception.base.BaseException;
    import com.jowell.common.response.Result;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Controller;
    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.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.Map;
    
    /**
     * @author :Mr.ZJW
     * @date :Created 2023/9/20 17:53
     * @description:支付controller
     */
    @Slf4j
    @RequestMapping("/alipay")
    @Controller
    @ResponseBody
    public class TestAlipayController {
    
        /**
         * 支付接口
         *
         * @param subject     名称
         * @param outTradeNo  订单号
         * @param totalAmount 金额
         * @return /
         */
        @GetMapping("/pay")
        public String pay(String subject, String outTradeNo, String totalAmount) {
            AlipayTradePagePayResponse response;
            try {
                response = Factory.Payment.Page().pay(subject, outTradeNo, totalAmount, "");
            } catch (Exception e) {
                log.error("支付宝付款调用失败,原因:" + e.getMessage());
                throw new BaseException("网络异常,请刷新后重试");
            }
            return response.getBody();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    接口测试:
    访问URL进行测试,测试的url格式:http://localhost:10000/alipay/pay?subject=支付测试&outTradeNo=D239211000000&totalAmount=1

    效果:
    在这里插入图片描述
    进行用买家账号密码登录:
    在这里插入图片描述
    输入支付密码进行支付:
    在这里插入图片描述

    支付成功:
    在这里插入图片描述

    4、回调接口

    回调接口要有一个外网域名,这里可以使用花生壳以及我分享过的一遍文章:
    文章链接:https://blog.csdn.net/javaeEEse/article/details/117983797?spm=1001.2014.3001.5502

    在这里插入图片描述
    把这个域名复制到配置文件里的回调地址上。

    回调完整代码:

        /**
         * 支付宝回调
         */
        @PostMapping("/notify")
        public Result<String> notify(HttpServletRequest request) {
            log.info("支付宝回调成功");
            //校验是否成功
            if ("TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {
                //#解析回调数据
                Map<String, String> params = Maps.newHashMap();
                Map<String, String[]> requestParams = request.getParameterMap();
                for (String name : requestParams.keySet()) {
                    params.put(name, request.getParameter(name));
                }
                //订单号
                String tradeNo = params.get("out_trade_no");
                //支付金额
                String gmtPayment = params.get("gmt_payment");
                //支付宝交易凭证号
                String alipayTradeNo = params.get("trade_no");
                //#支付宝验签,防止不法分子伪造请求
                try {
                    Boolean flag = Factory.Payment.Common().verifyNotify(params);
                    if (Boolean.TRUE.equals(flag)) {
                        log.info("交易名称: " + params.get("subject"));
                        log.info("交易状态: " + params.get("trade_status"));
                        log.info("支付宝交易凭证号: " + params.get("trade_no"));
                        log.info("商户订单号: " + params.get("out_trade_no"));
                        log.info("交易金额: " + params.get("total_amount"));
                        log.info("买家在支付宝唯一id: " + params.get("buyer_id"));
                        log.info("买家付款时间: " + params.get("gmt_payment"));
                        log.info("买家付款金额: " + params.get("buyer_pay_amount"));
                    } else {
                        log.error("异步通知验签失败");
                        return Result.error("fail");
                    }
    
                } catch (Exception e) {
                    log.error("异步发生异常{}", e.getMessage());
                    return Result.error("fail");
                }
                //#进行一些业务逻辑,如更新订单等操作
            }
            return Result.success();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 相关阅读:
    基于 arm64 Linux nanosleep 系统调用流程分析
    C/C++开发,libiec61850库学习及运用
    VR赋能红色教育,让爱国主义精神永放光彩
    A*算法例子
    zabbix监控Linux
    [含毕业设计论文+PPT+源码等]ssm校友录网站+Java后台管理系统|前后分离VUE
    Type Script 在流程设计器的落地实践
    聚观早报 | 微博个人主页将展示评论;京东PLUS会员突破 3000 万
    Java Hash 碰撞
    R语言缺失时间序列的填充:补齐时间序列数据中所有缺失的时间索引对象(补齐缺失的日期时间点或者序列)
  • 原文地址:https://blog.csdn.net/javaeEEse/article/details/133134302