• Spring Boot集成支付宝电脑网站支付功能


    接入准备

    登录

    访问支付宝开放平台:https://open.alipay.com/ 登录后补充开发者信息,然后在开发接入项,点击网页/移动应用开发项跳转创建应用。
    在这里插入图片描述

    创建应用

    填写应用基础信息
    在这里插入图片描述

    添加能力

    创建应用后,配置应用的能力,在添加能力项加入需要的能力,如电脑网站支付能力
    在这里插入图片描述

    生成私钥与公钥

    访问https://opendocs.alipay.com/common/02khjo下载密匙生成工具,然后生成公钥与私钥
    在这里插入图片描述

    开发设置

    在这里插入图片描述
    设置自己生成的公钥
    在这里插入图片描述
    将自己生成的公钥告诉支付宝,支付宝返回一个支付宝公钥
    在这里插入图片描述
    最终得到3个密匙:1.应用公钥 2.应用私钥 3.支付宝公钥

    沙箱环境

    沙箱地址:https://open.alipay.com/develop/sandbox/app

    参考上述生成私钥与公钥开发设置,在接口加签方式处进行设置。最终得到3个密匙:1.应用公钥 2.应用私钥 3.支付宝公钥
    在这里插入图片描述
    沙箱账号用于支付测试
    在这里插入图片描述

    示例Demo的使用与学习

    下载Demo

    在文档中心:https://openhome.alipay.com/docCenter/docCenter.htm找到需要接入应用类型的对应文档
    在这里插入图片描述
    或者直接搜索,如电脑网站支付
    在这里插入图片描述
    找到需要文档后,查看文档中的SDK&Demo项,下载对应语言Demo,用于学习
    在这里插入图片描述

    启动项目

    在这里插入图片描述

    参数配置

    在Demo项目中的AlipayConfig类中配置:应用ID,商户私钥(应用私钥)、支付宝公钥、异步通知、同步通知地址等参数。

    注意:如果这里使用沙箱环境测试,一定要修改支付宝网关,否则调试错误
    在这里插入图片描述

    沙箱环境网关为: https://openapi.alipaydev.com/gateway.do 
    
    正式环境网关为:https://openapi.alipay.com/gateway.do 
    
    • 1
    • 2
    • 3
    /* *
     *类名:AlipayConfig
     *功能:基础配置类
     *详细:设置帐户有关信息及返回路径
     *修改日期:2017-04-05
     *说明:
     *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
     *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
     */
    
    public class AlipayConfig {
    
    //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    
    	// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    	public static String app_id = "20166660581647";
    
    	// 商户私钥,您的PKCS8格式RSA2私钥
        public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCKNOWSnUMsaeEZZMDy+DvbdUMVTuJ/jQ4Ks8lQEatRjXS7ZWX+NMszQir3HyRWe1q8+8n6ZvJSiMGpS2Ku7ZeTHyZvOB9BTG3vgapDKKJAQ0NYaB3561FaU3ZRnCay5ls50WVCZ82pO//NZ5xRYND53+ZjSvOZi58FV1uKnCEAx8tPZKeGi5c2hQ6epjjzcjsdD/1fZEF5B667AM8nLe3zZWftvBxJe8Z1yoRP/w4aWW451myFViQWaKiWsERz7KAHCJEu+wAyvgqB18MOoNk76svqr71Z0whjrTF/1eEHaoictzMdao8hWYNhveaPA4Ic46rWoBTyHOHdt9p+hF1NAgMBAAECggEAQP39E4RWyXUFAO8LeXbYlyw+nq+Y/ch0WP4Q5lFY0iIGSfW2D+P9xp4QHGQNr4mUsxho9BMjU0KyZ41/j5LfpqO0s+abeQgAvwP3WXm9EkgcDP1UulCG74YQmXa7e+ORT3+3Vmt6lC/rY3SurFLl2HNkH1dBHhO2+XpYV/WGDDRFJ/WxI3gFdWF31sqT9n75HsozFtA5vp90ZOq3SxqtQKBgQDZDqfj6Aw5jCI+rPapmp4NISDLUHtcIKKfRx/2yjmCPZ/WCnIW4R7jxyf3rvd4beNMqVHfAhdwISfug5C3n2nZJV4aMY/o52DEH38d2dYqkJX78V+Jaw0vy8DvuxGtVCB/5r3tK4zbza9g2uFPUb9/8QBo3h8KKbjs6haOxBLFqwKBgQCjAKqhTsrZwI0AR1NQ76U558CkR5NbR15pROgzXvzLwnr5L2pOhrf+IEsGOZklXgv727jc907Gp/VlBQrsFU5rPKMc091HdLV7fmsVY/CIb9P+oSGj7nZ5X6O2n3wY2nJzlnWT4+wZSLQDiThuUA+awDe1TZZ4jVX4Y9kDOLwA5wKBgHWhsLEdp8pkPIbU+9SMu80HwBsPYdtawGcrh5IapDIGLaI1BQGLPU9aNjnP88OrYfzA4mLGYmddQKPNX1d0KEwLKUVuyLwC8Pk4zI4j6SImO3JPrGPvxTS66rPBIOJbbkWCijmHWY4hmUMXO/Xdqreup3ctsYqzc8nJTzJN5pKDAoGAQxOuI81BypPjMj8nuQG1E3wcGT5fFEvtPRKfHyyyiMMSSeLKM2Ba7NerJ/eh3u+xrMYBb+TRZQyO/jAyC27FI3oDgYRp5dLQL+6Y8Gd8/xhNu9Xg+w3RcSb7Ptaoga27NXewENjVOp5hfacFMtf9Y+g/xHsWNauruhiUoC/DpfcCgYEA2KjZndyY4iKQg2ia3PrRREZukoTAiYVE36i66YVYhwnrqjP3VRwrrK8kpG/HMhcPYFEuO1d7pKLShoxn10UdDlAX1R7mkFSGS/t8KNp7LqNHaDxL0lWeUq7/WEHn7vxvlHtB3dIB+cuq5iC/VuTvnQhXPOGU/6hgJu1ImuDz5uQ=";
    
    	// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
        public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1j83H1RmHZeuLbYyxhWAn80GTK/963/SnGHfZAujXsB4/EWn+BqHK6zOmBwXAZAsvjrG+oFakMagANwBl34fFVEpwIHF7o9DdX6skYlyO2HRfc/XZMKBg1snAXA/OBjUjTcKTeFJx75zezxgTwrHl3MSrXEr4WnGPAxu+jC9cFrsFdTTGz1gp4K25OBbsSNFdEnqaVbWmJT/U0wAAE8eOcHSk5TYgQfmvqFLuSpjOwDWF0m6/Ymr7EKagsBvtb/Y+IUyQKWi62nqJrDbuduaRiC43hUp6nU3E2VNDuxdexkuQF/cjz5l3/GEeRtFgb00RmkmjtnC+FwIDAQAB";
    
    	// 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    	public static String notify_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
    
    	// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    	public static String return_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
    
    	// 签名方式
    	public static String sign_type = "RSA2";
    
    	// 字符编码格式
    	public static String charset = "utf-8";
    
    	// 支付宝网关
    //	public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";
    	public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
    
    	// 支付宝网关
    	public static String log_path = "C:\\";
    
    
    //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    
        /**
         * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
         * @param sWord 要写入日志里的文本内容
         */
        public static void logResult(String sWord) {
            FileWriter writer = null;
            try {
                writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
                writer.write(sWord);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    try {
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    • 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
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    执行测试

    发起一个付款操作
    在这里插入图片描述
    跳到转支付页面,输入沙箱环境中的测试账号进行登录
    在这里插入图片描述

    选择支付方式,输入支付密码
    在这里插入图片描述
    支付成功,最终会跳转到配置的回调地址
    在这里插入图片描述
    至此,支付宝Demo的支付功能就测试通过,具体实现就可以参考源码进行学习。

    Spring Boot集成支付宝支付功能

    获取SDK

    在开发工具包(SDK)下载页面:https://opendocs.alipay.com/open/02nk0x找到依赖坐标
    在这里插入图片描述

    <dependency>
      <groupId>com.alipay.sdk</groupId>
      <artifactId>alipay-sdk-java</artifactId>
      <version>4.33.39.ALL</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    添加依赖

            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
                
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.bootgroupId>
                        <artifactId>spring-boot-starter-tomcatartifactId>
                    exclusion>
                exclusions>
            dependency>
            
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-jettyartifactId>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-devtoolsartifactId>
                <optional>trueoptional>
            dependency>
            
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <optional>trueoptional>
            dependency>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
            dependency>
            
            <dependency>
                <groupId>com.alipay.sdkgroupId>
                <artifactId>alipay-sdk-javaartifactId>
                <version>4.9.28.ALLversion>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-thymeleafartifactId>
            dependency>
    
    • 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

    配置application.properties

    在application.properties文件中配置支付相关配置

    #--------------------支付宝相关的配置--------------------
    # 应用ID
    alipay.app_id=2016077300581647
    # 商户私钥
    alipay.merchant_private_key=MIIEvQIqqANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCKNOWSnUMsaeEZZMDy+DvbdUMVTuJ/jQ4Ks8lQEatRjXS7ZWX+NMszQir3HyRWe1q8+8n6ZvJSiMGpS2Ku7ZeTHyZvOB9BTG3vgapDKKJAQ0NYaB3561FaU3ZRnCay5ls50WVCZ82pO//NZ5xRYND53+ZjSvOZi58FV1uKnCEAx8tPZKeGi5c2hQ6epjjzcjsdD/1fZEF5B667AM8nLe3zZWftvBxJe8Z1yoRP/w4aWW451myFViQWaKiWsERz7KAHCJEu+wAyvgqB18MOoNk76svqr71Z0whjrTF/1eEHaoictzMdao8hWYNhveaPA4Ic46rWoBTyHOHdt9p+hF1NAgMBAAECggEAQP39E4RWyXUFAO8LeXbYlyw+nq+Y/ch0WP4Q5lFY0iIGSfW2D+P9xp4QHGQNr4mUsxho9BMjU0KyZ41m28IpLGtSpKysrgVmEWJVkf1yx2uaKOHVbuiFOkfTdS9MV4bSUY8x4hd0dGgdtBdMQEyaGVd8PSdLBOLOpjFdgAJJ1tZrAENG1VqbSgRdAs0cIFSPPUpjK+EC61zIG4Cb/j5LfpqO0s+abeQgAvwP3WXm9EkgcDP1UulCG74YQmXa7e+ORT3+3Vmt6lC/rY3SurFLl2HNkH1dBHhO2+XpYV/WGDDRFJ/WxI3gFdWF31sqT9n75HsozFtA5vp90ZOq3SxqtQKBgQDZDqfj6Aw5jCI+rPapmp4NISDLUHeeeKfRx/2yjmCPZ/WCnIW4R7jxyf3rvd4beNMqVHfAhdwISfug5C3n2nZJV4aMY/o52DEH38d2dYqkJX78V+Jaw0vy8DvuxGtVCB/5r3tK4zbza9g2uFPUb9/8QBo3h8KKbjs6haOxBLFqwKBgQCjAKqhTsrZwI0AR1NQ76U558CkR5NbR15pROgzXvzLwnr5L2pOhrf+IEsGOZklXgv727jc907Gp/VlBQrsFU5rPKMc091HdLV7fmsVY/CIb9P+oSGj7nZ5X6O2n3wY2nJzlnWT4+wZSLQDiThuUA+awDe1TZZ4jVX4Y9kDOLwA5wKBgHWhsLEdp8pkPIbU+9SMu80HwBsPYdtawGcrh5IapDIGLaI1BQGLPU9aNjnP88OrYfzA4mLGYmddQKPNX1d0KEwLKUVuyLwC8Pk4zI4j6SImO3JPrGPvxTS66rPBIOJbbkWCijmHWY4hmUMXO/Xdqreup3ctsYqzc8nJTzJN5pKDAoGAQxOuI81BypPjMj8nuQG1E3wcGT5fFEvtPRKfHyyyiMMSSeLKM2Ba7NerJ/eh3u+xrMYBb+TRZQyO/jAyC27FI3oDgYRp5dLQL+6Y8Gd8/xhNu9Xg+w3RcSb7Ptaoga27NXewENjVOp5hfacFMtf9Y+g/xHsWNauruhiUoC/DpfcCgYEA2KjZndyY4iKQg2ia3PrRREZukoTAiYVE36i66YVYhwnrqjP3VRwrrK8kpG/HMhcPYFEuO1d7pKLShoxn10UdDlAX1R7mkFSGS/t8KNp7LqNHaDxL0lWeUq7/WEHn7vxvlHtB3dIB+cuq5iC/VuTvnQhXPOGU/6hgJu1ImuDz5uQ=
    # 支付宝公钥
    alipay.alipay_public_key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1j83H1RmHZeuLbYyxhWAn80GTK/963/SnGHfZAujXsB4/EWn+BqHK6zOmBwXAZAsvjrG+oFakMagANwBl34fFVEpwIHF7o9DdX6skYlSYv1eeq2HRfc/XZMKBg1snAXA/OBjUjTcKTeFJx75zezxgTwrHl3MSrXEr4WnGPAxu+jC9cFreeep4K25OBbsSNFdEnqaVbWmJT/U0wAAE8eOcHSk5TYgQfmvqFLuSpjOwDWF0m6/YmqagsBvtb/Y+IUyQKWi62nqJrDbuduaRiC43hUp6nU3E2VNDuxdexkuQF/cjz5l3/GEeRtFgb00RmkmjtnC+FwIDAQAB
    # 服务器异步通知页面路径
    alipay.notify_url=http://jackchen.imwork.net:27687/pay/asyncNotify
    # 页面跳转同步通知页面路径
    alipay.return_url=http://jackchen.imwork.net:27687/pay/syncNotify
    # 签名方式
    alipay.sign_type=RSA2
    # 字符编码格式
    alipay.charset=utf-8
    # 支付宝网关
    #alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
    # 支付宝沙箱网关
    alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
    
    # 异步通知 对时间字段格式化,否则异步通知失败
    spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    创建AlipayUtil

    支付信息VO

    @Data
    public class PayVo {
        /**
         * 商户订单号,必填
         */
        private String out_trade_no;
        /**
         * 订单名称,必填
         */
        private String subject;
        /**
         * 付款金额,必填
         */
        private String total_amount;
        /**
         * 商品描述,可为空
         */
        private String body;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    AlipayUtil 工具类

    @ConfigurationProperties(prefix = "alipay")
    @Component
    @Data
    public class AlipayUtil {
        /**
         * 应用ID
         */
        public String app_id;
        /**
         * 商户私钥
         */
        public String merchant_private_key;
        /**
         * 支付宝公钥
         */
        public String alipay_public_key;
        /**
         * 服务器[异步通知]页面路径 必须外网可以正常访问 支付宝会告诉支付成功的信息
         */
        public String notify_url;
        /**
         * 页面跳转[同步通知]页面路径 必须外网可以正常访问 支付成功跳转到成功页
         */
        public String return_url;
        /**
         * 签名方式
         */
        private String sign_type;
        /**
         * 字符编码格式
         */
        private String charset;
        /**
         * 订单超时时间
         */
        private String timeout = "1m";
        /**
         * 支付网关
         */
        public String gatewayUrl;
    
        /**
         * 发起支付请求
         * @param vo 支付信息
         * @return
         * @throws AlipayApiException
         */
        public String pay(PayVo vo) throws AlipayApiException {
            // 根据支付宝的配置生成一个支付客户端
            AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);
    
            // 创建一个支付请求
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            // 设置请求参数
            alipayRequest.setReturnUrl(return_url);
            alipayRequest.setNotifyUrl(notify_url);
    
            // 商户订单号,商户网站订单系统中唯一订单号
            String out_trade_no = vo.getOut_trade_no();
            // 付款金额
            String total_amount = vo.getTotal_amount();
            // 订单名称
            String subject = vo.getSubject();
            // 商品描述
            String body = vo.getBody();
    
            alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                    + "\"total_amount\":\"" + total_amount + "\","
                    + "\"subject\":\"" + subject + "\","
                    + "\"body\":\"" + body + "\","
                    + "\"timeout_express\":\"" + timeout + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
    
            String result = alipayClient.pageExecute(alipayRequest).getBody();
    
            // 收到支付宝的响应,响应一个页面,浏览器显示这个页面,就会自动到支付宝的收银台页面
            System.out.println("支付宝响应:" + result);
    
            return result;
    
        }
    }
    
    • 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
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    创建支付成功返回页面

    paySuccess.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h2>您已支付成功</h2>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    异步/同步通知参数封装对象

    @ToString
    @Data
    public class PayAsyncVo {
        /**
         * 交易创建时间。格式为 yyyy-MM-dd HH:mm:ss
         */
        private String gmt_create;
        /**
         * 编码格式。如 utf-8、gbk、gb312等。
         */
        private String charset;
        /**
         * 交易付款时间。格式为 yyyy-MM-dd HH:mm:ss
         */
        private String gmt_payment;
        /**
         * 通知的发送时间。格式为 yyyy-MM-dd HH:mm:ss
         */
        private Date notify_time;
        /**
         * 订单标题/商品标题/交易标题/订单关键字等,是请求时对应参数,会在通知中原样传回
         */
        private String subject;
        /**
         * 签名。详情可查看 异步返回结果的验签
         */
        private String sign;
        /**
         * 买家支付宝账号 ID。以 2088 开头的纯 16 位数字
         */
        private String buyer_id;
        /**
         * 商品描述。该订单的备注、描述、明细等。对应请求时的 body 参数,会在通知中原样传回
         */
        private String body;
        /**
         * 开票金额。用户在交易中支付的可开发票的金额,单位为人民币(元),精确到小数点后 2 位
         */
        private String invoice_amount;
        /**
         * 调用的接口版本。固定为1.0
         */
        private String version;
        /**
         * 通知校验 ID
         */
        private String notify_id;
        /**
         * 支付金额信息。支付成功的各个渠道金额信息。详情可查看下文 资金明细信息说明
         */
        private String fund_bill_list;
        /**
         * 通知类型
         */
        private String notify_type;
        /**
         * 商家订单号。原支付请求的商家订单号
         */
        private String out_trade_no;
        /**
         * 订单金额。本次交易支付订单金额,单位为人民币(元),精确到小数点后 2 位
         */
        private String total_amount;
        /**
         * 交易状态。交易目前所处状态,详情可查看下表 交易状态说明
         */
        private String trade_status;
        /**
         * 支付宝交易号,支付宝交易凭证号
         */
        private String trade_no;
        /**
         * 授权方的APPID。由于本接口暂不开放第三方应用授权,因此 auth_app_id=app_id
         */
        private String auth_app_id;
        /**
         * 实收金额。商家在交易中实际收到的款项,单位为人民币(元),精确到小数点后 2 位
         */
        private String receipt_amount;
        /**
         * 使用集分宝支付金额,单位为人民币(元),精确到小数点后 2 位
         */
        private String point_amount;
        /**
         * 支付宝应用的APPID。支付宝分配给开发者的应用 ID
         */
        private String app_id;
        /**
         * 用户在交易中支付的金额,单位为人民币(元),精确到小数点后 2 位
         */
        private String buyer_pay_amount;
        /**
         * 签名类型。签名算法类型,目前支持RSA2和RSA,推荐使用 RSA2
         */
        private String sign_type;
        /**
         * 卖家支付宝账号 ID。以 2088 开头的纯 16 位数字
         */
        private String seller_id;
    }
    
    • 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
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    API接口

    @Controller
    public class TestController {
    
        @Autowired
        private AlipayUtil alipayUtil;
    
        @ResponseBody
        @RequestMapping("/test")
        public String index() {
            return "Hello World";
        }
    
        /**
         * 用户下单:支付宝支付
         * 1、让支付页让浏览器展示
         * 2、支付成功以后,跳转到用户的订单列表页
         *
         * @param orderCode 订单编码
         * @return
         * @throws AlipayApiException
         */
        @ResponseBody
        @GetMapping(value = "/payOrder", produces = "text/html")
        public String aliPayOrder(@RequestParam String orderCode) throws AlipayApiException {
            // 通过订单编码查询支付信息
            // PayVo payVo = orderService.getOrderPay(orderCode);
    
            System.out.println("订单编码:" + orderCode);
            // 构造一份订单支付信息
            PayVo payVo = new PayVo();
            payVo.setOut_trade_no(UUID.randomUUID().toString());
            payVo.setSubject("话费充值100元");
            payVo.setTotal_amount("99.8");
            payVo.setBody("话费充值100元,急速充值。");
    
            String pay = alipayUtil.pay(payVo);
            return pay;
        }
    
        @GetMapping(value = "/pay/syncNotify")
        public String paySyncNotify(PayAsyncVo payasyncVo, HttpServletRequest request) {
            System.out.println("同步通知内容:" + payasyncVo);
            return "paySuccess";
        }
    
        /**
         * 支付宝的异步通知,只要返回 success 支付宝便不再通知
         */
        @PostMapping(value = "/pay/asyncNotify")
        @ResponseBody
        public String payAsyncNotify(PayAsyncVo asyncVo, HttpServletRequest request) throws AlipayApiException {
            // 获取支付宝反馈信息
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                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] + ",";
                }
                // 出现乱码时使用
                // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }
    
            // 调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayUtil.getAlipay_public_key(), alipayUtil.getCharset(), alipayUtil.getSign_type());
    
            if (signVerified) {
                System.out.println("签名验证成功...");
                // 业务处理,如修改订单状态
                System.out.println(asyncVo.toString());
    
                return "success";
            } else {
                System.out.println("签名验证失败...");
                return "error";
            }
        }
    }
    
    • 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
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    支付测试

    在这里插入图片描述

    请求http://localhost:8080/payOrder/?orderCode=123378904789支付地址,生成如下表单脚本

    订单编码:123378904789
    支付宝响应:<form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=SxbAuMfBTS3KPP1qWTjr29mmfDhWUtnu4YEaadJ6PCoqvL3kkQlJqFcZWZnprR3xs5iGrJdcPfzuq4Oga9ga8wMRhxfdjF4FaygFq4EJTaWMcePphfdhNpv4k8wPjNbHblYt7YK5oeDf0Ssj33EPfCHdMjR0OVu%2F8grmR4kq2%2FaBtmeYwdaHwmIGvOgAwnp%2Be12OZXgNksiuH0ex1YeFKxbYveaa6Yi2SGLd8voPSria7MsFhS%2B%2F6NQ5VZ79XwUY4NseJY2%2BGBEm8Vv2dO9EbngKBP4sGj%2FDg8opgsMmW%2FlrZTxifQ6fzyk7rsrwSp6zSB5YzL%2B82u7mZvSsC0egXw%3D%3D&return_url=http%3A%2F%2Fjackchen.imwork.net%3A27687%2Fpay%2FsyncNotify¬ify_url=http%3A%2F%2Fjackchen.imwork.net%3A27687%2Fpay%2FasyncNotify&version=1.0&app_id=2016092300581647&sign_type=RSA2×tamp=2022-09-11+21%3A09%3A42&alipay_sdk=alipay-sdk-java-dynamicVersionNo&format=json">
    <input type="hidden" name="biz_content" value="{"out_trade_no":"aec33d19-eda4-4f17-8cb5-5aa0e6129b4b","total_amount":"99.8","subject":"话费充值100元","body":"话费充值100元,急速充值。","timeout_express":"1m","product_code":"FAST_INSTANT_TRADE_PAY"}">
    <input type="submit" value="立即支付" style="display:none" >
    </form>
    <script>document.forms[0].submit();</script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    上述脚本返回游览器,自动执行,生成如下页面。
    在这里插入图片描述
    登录沙箱环境账号进行支付
    在这里插入图片描述
    支付成功异步回调执行
    在这里插入图片描述

    签名验证成功...
    PayAsyncVo(gmt_create=2022-09-11 21:09:56, charset=utf-8, gmt_payment=2022-09-11 21:10:18, notify_time=Sun Sep 11 21:10:19 CST 2022, subject=话费充值100, sign=Yty7oT1xpLQ5UwC5DKVFwMO+k2XtOBOza37itFL/R8rIjtFxDoMtP3Qxdi8r76hmLyDjBShz8IQxag6zcqvfhN3OvoyN/gYzYpKz/sqKIYgDqQJqgM4SYA1/4W7kRhG4A0yw2M9ANpm8MYq+i21lvDerQ6R2w71urn/HR7GteZLOFvniisbUu6/Dcykdb6tDgM9tsl1iqGSE/xf6kahcboTXlSdAasFAKPHmiPhjrvs7lpwoFiZZeHlDMYFUkg0hhmJVz/VT8tkVNSEfN/jXZDU+2nvJwK6tR0EkG4gpiQEa7cRP26Jjmbl/pAZ1qKqkhzxRsCa+0U2xYUMy5/r+AQ==, buyer_id=2088102177032991, body=话费充值100,急速充值。, invoice_amount=99.80, version=1.0, notify_id=2022091100222211018032990521528764, fund_bill_list=[{"amount":"99.80","fundChannel":"ALIPAYACCOUNT"}], notify_type=trade_status_sync, out_trade_no=aec33d19-eda4-4f17-8cb5-5aa0e6129b4b, total_amount=99.80, trade_status=TRADE_SUCCESS, trade_no=2022091122001432990501977422, auth_app_id=2016092300581647, receipt_amount=99.80, point_amount=0.00, app_id=2016092300581647, buyer_pay_amount=99.80, sign_type=RSA2, seller_id=2088102176985780)
    
    • 1
    • 2

    等待几秒后,返回同步通知配置地址

    同步通知内容:PayAsyncVo(gmt_create=null, charset=utf-8, gmt_payment=null, notify_time=null, subject=null, sign=JuFKKdvhaFPJ6LAJ2BIwVLNS7xb1gZzLtg4kvs2XpuC4i/ElwxKgouyDa/OnJkxCjiO1+YkOhFkPGSNnaWbsic9vgskER5OwChbs5CXgPIZKzG1nFPHTitYHpOeC6XP7O1gzhj9Rq/W3lzYhvnhQBcea3SiF5We21icEMWvahJHp25hlbpOJVxWJOXSB1DjRlnbd30zp09aAV5o+VVDdqByPuBS3ff8owPYh0duhP0f1LEh/BHmJUpBXbeUbwgruay1Tmqzf37SXY/YQymHIIbnz0BpCJ60xj+SuXMlnTwy3LnK0xni9JK+QeHcdY5XpqdtJNl1Vy75zl6PTIgei5A==, buyer_id=null, body=null, invoice_amount=null, version=1.0, notify_id=null, fund_bill_list=null, notify_type=null, out_trade_no=aec33d19-eda4-4f17-8cb5-5aa0e6129b4b, total_amount=99.80, trade_status=null, trade_no=2022091122001432990501977422, auth_app_id=2016092300581647, receipt_amount=null, point_amount=null, app_id=2016092300581647, buyer_pay_amount=null, sign_type=RSA2, seller_id=2088102176985780)
    
    • 1

    在这里插入图片描述

    支付查询测试

    AlipayUtil添加订单查询方法

        public String payQuery(String outTradeNo) throws AlipayApiException {
            // 根据支付宝的配置生成一个支付客户端
            AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);
    
            // 创建一个支付请求
            AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
    
            JSONObject bizContent = new JSONObject();
            // 订单支付时传入的商户订单号,和支付宝交易号不能同时为空。trade_no,out_trade_no如果同时存在优先取trade_no
            bizContent.put("out_trade_no", outTradeNo);
            // 支付宝交易号,和商户订单号不能同时为空
            //bizContent.put("trade_no", "2014112611001004680073956707");
            alipayRequest.setBizContent(bizContent.toString());
            AlipayTradeQueryResponse response = alipayClient.execute(alipayRequest);
            if (response.isSuccess()) {
                System.out.println("调用成功");
                return response.getBody();
            } else {
                System.out.println("调用失败");
                return "查询失败。";
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    订单查询接口

        /**
         * 通过商户订单号进行查询支付信息
         * @param outTradeNo 商户订单号
         * @return
         * @throws AlipayApiException
         */
        @GetMapping(value = "/pay/payQuery")
        @ResponseBody
        public String payQuery(String outTradeNo) throws AlipayApiException {
            String pay = alipayUtil.payQuery(outTradeNo);
            return pay;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    发起一份订单支付,得到商户ID:a83cf764-f177-4f27-81f7-615bfb418d43,进入付款页面暂定付款
    在这里插入图片描述
    访问http://localhost:8080/pay/payQuery?outTradeNo=a83cf764-f177-4f27-81f7-615bfb418d43查询订单状态

    交易状态:

    WAIT_BUYER_PAY(交易创建,等待买家付款)
    
    TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
    
    TRADE_SUCCESS(交易支付成功)
    
    TRADE_FINISHED(交易结束,不可退款)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    订单查询接口响应信息如下:

    {"alipay_trade_query_response":{"code":"10000","msg":"Success","buyer_logon_id":"cvj***@sandbox.com","buyer_pay_amount":"0.00","buyer_user_id":"2088102177032991","buyer_user_type":"PRIVATE","invoice_amount":"0.00","out_trade_no":"a83cf764-f177-4f27-81f7-615bfb418d43","point_amount":"0.00","receipt_amount":"0.00","total_amount":"99.80","trade_no":"2022091222001432990501977609","trade_status":"WAIT_BUYER_PAY"},"sign":"Ab5EVgiN1y+4z78gIfepK9V4ZDb03gX4IjE3Ao/O3LfIRclFVoTFbvl9MbkVvJ7jfELt/cQ3HQYs9ihxQC3n+2xz/tS0MwYVlvPIdBfu+9uP9nzjYp6Qzd1ccTag0BTCue/bASUdV3Ze4/l86Zec/FC7x30HIu2dPVY9PPK7QabXUypFLb24DUkTPUlb4xr7TSz6S6Zum1vOHabFPvSR1IgQ/ZqC5dnfmB60KclcyWAchfoBvTHJCfytnXZac8iAAfd+E2PKE2SOqpFQFquvC75/JleBsXdt0AuXMXXKDKJTq0g6qPVEOSgZQW+hnsbOaIB2A2OTxlNrvtdOBSVQ8A=="}
    
    • 1

    订单关闭测试

    AlipayUtil添加订单关闭方法

        public String payClose(String outTradeNo) throws AlipayApiException {
            // 根据支付宝的配置生成一个支付客户端
            AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);
    
            // 创建一个支付请求
            AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
    
            JSONObject bizContent = new JSONObject();
            // 该交易在支付宝系统中的交易流水号。最短 16 位,最长 64 位。和out_trade_no不能同时为空,如果同时传了 out_trade_no和 trade_no,则以 trade_no为准。
    //        bizContent.put("trade_no", "2013112611001004680073956707");
            // 	订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 trade_no,out_trade_no如果同时存在优先取trade_no
            bizContent.put("out_trade_no", outTradeNo);
            alipayRequest.setBizContent(bizContent.toString());
            AlipayTradeCloseResponse response = alipayClient.execute(alipayRequest);
            if(response.isSuccess()){
                System.out.println("调用成功");
                return response.getBody();
            } else {
                System.out.println("调用失败");
                return "订单关闭失败。";
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    订单关闭接口

        /**
         * 未支付订单关闭
         * @param outTradeNo 商户订单号
         * @return
         * @throws AlipayApiException
         */
        @GetMapping(value = "/pay/payClose")
        @ResponseBody
        public String payClose(String outTradeNo) throws AlipayApiException {
            String pay = alipayUtil.payClose(outTradeNo);
            return pay;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    访问:http://localhost:8080/pay/payClose?outTradeNo=a83cf764-f177-4f27-81f7-615bfb418d43接口关闭订单

    订单关闭接口响应信息如下:

    {"alipay_trade_close_response":{"code":"10000","msg":"Success","out_trade_no":"a83cf764-f177-4f27-81f7-615bfb418d43","trade_no":"2022091222001432990501977609"},"sign":"Jem6c7OOfcRHbats0Cx7nGJivIqzrnGwzAYElyay3jEVRKcd/gCYkMwpAM7axDg6PAKLRPS7yXW9GyFeuQm/vweKrEeQxZPq9GbBFLZmwJ272nj0Qxo5lkqwI7nneU1srje/HfVOF8uTiPQIr1kO8FZw0z4QD2E28PFNUG7xouVweN5+U847ha2crWoWJR/VtJRr5oR925/BMlPjOt8ih25P3Wt0SxiXnU7/iKPV7OK7NJV4zGIZ81AO1kFD+rNEWkDbbRnESPEqvTTSqbWLrAP8n1nKvCoaQRRCsyJvuCv9m6gs7AG62qZxYLca9QbiIUjHtGqMOR8g8V5Vfz8bHA=="}
    
    • 1

    再次访问http://localhost:8080/pay/payQuery?outTradeNo=a83cf764-f177-4f27-81f7-615bfb418d43查询订单状态

    交易状态:

    WAIT_BUYER_PAY(交易创建,等待买家付款)
    
    TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
    
    TRADE_SUCCESS(交易支付成功)
    
    TRADE_FINISHED(交易结束,不可退款)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    订单查询接口响应信息如下:

    {"alipay_trade_query_response":{"code":"10000","msg":"Success","buyer_logon_id":"cvj***@sandbox.com","buyer_pay_amount":"0.00","buyer_user_id":"2088102177032991","buyer_user_type":"PRIVATE","invoice_amount":"0.00","out_trade_no":"a83cf764-f177-4f27-81f7-615bfb418d43","point_amount":"0.00","receipt_amount":"0.00","total_amount":"99.80","trade_no":"2022091222001432990501977609","trade_status":"TRADE_CLOSED"},"sign":"Ab5EVgiN1y+4z78gIfepK9V4ZDb03gX4IjE3Ao/O3LfIRclFVoTFbvl9MbkVvJ7jfELt/cQ3HQYs9ihxQC3n+2xz/tS0MwYVlvPIdBfu+9uP9nzjYp6Qzd1ccTag0BTCue/bASUdV3Ze4/l86Zec/FC7x30HIu2dPVY9PPK7QabXUypFLb24DUkTPUlb4xr7TSz6S6Zum1vOHabFPvSR1IgQ/ZqC5dnfmB60KclcyWAchfoBvTHJCfytnXZac8iAAfd+E2PKE2SOqpFQFquvC75/JleBsXdt0AuXMXXKDKJTq0g6qPVEOSgZQW+hnsbOaIB2A2OTxlNrvtdOBSVQ8A=="}
    
    • 1
  • 相关阅读:
    暴雨服务器:科技创新构建高效、高质、可持续的新质生产力
    Vue2中10种组件通信方式和实践技巧
    Topology零部件拆解3D可视化解决方案
    Cesium 展示——一键控制所有 label 的显隐
    数据持久化技术(Python)的使用
    【问题思考】二重积分积分限上的x和积分内部的x有什么区别?【几何直观】
    Java实现更新excel文件内容
    Web攻防01-ASP应用相关漏洞-HTTP.SYS&IIS短文件&文件解析&ACCESS注入
    Vue中的路由嵌套
    rabbitmq-exporter部署方式
  • 原文地址:https://blog.csdn.net/qq_38628046/article/details/123017946