Przeglądaj źródła

feat:完成对支付宝沙箱的调用完整流程.

yang yi 10 miesięcy temu
commit
3d53dd47fc

+ 28 - 0
.gitignore

@@ -0,0 +1,28 @@
+# created by virtualenv automatically
+
+
+**/.idea
+**/node_modules
+**/.gradle
+**/.mvn
+**/*.iml
+**/*.log
+**/*.rar
+**/*.png
+**/*.jpg
+**/*.xls
+**/*.xlsx
+**/*.zip
+**/*.o
+**/*.exe
+**/out/**
+**/target/**
+**/build/**
+/*
+
+!/**/**.java
+!/**/**.yaml
+!/**/**.xml
+
+!/src
+!.gitignore

+ 28 - 0
pom.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>space.anyi</groupId>
+    <artifactId>aliPayDemo</artifactId>
+    <version>1.0.0</version>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <version>2.7.17</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.40.576.ALL</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 256 - 0
src/main/java/space/anyi/alipay/AlipayTradePrecreate.java

@@ -0,0 +1,256 @@
+package space.anyi.alipay;
+
+/**
+ * @ProjectName: aliPayDemo
+ * @FileName: AlipayTradePrecreate
+ * @Author: 杨逸
+ * @Data:2025/12/10 20:24
+ * @Description:
+ */
+
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.AlipayConfig;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.domain.*;
+import com.alipay.api.request.AlipayTradePagePayRequest;
+import com.alipay.api.request.AlipayTradePrecreateRequest;
+import com.alipay.api.response.AlipayTradePagePayResponse;
+import com.alipay.api.response.AlipayTradePrecreateResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+public class AlipayTradePrecreate {
+    Logger log = LoggerFactory.getLogger(AlipayTradePrecreate.class);
+
+    public String testAlipayTradePrecreateRequest() throws AlipayApiException {
+        // 初始化SDK
+        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+
+        // 构造请求参数以调用接口
+        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
+        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
+
+        // 设置商户订单号
+        model.setOutTradeNo("20150320010101001");
+
+        // 设置订单总金额
+        model.setTotalAmount("88.88");
+
+        // 设置订单标题
+        model.setSubject("Iphone6 16G");
+
+        // 设置产品码
+        model.setProductCode("QR_CODE_OFFLINE");
+
+        // 设置卖家支付宝用户ID
+        model.setSellerId("2088721052139981");
+
+        // 设置订单附加信息
+        model.setBody("Iphone6 16G");
+
+        // 设置订单包含的商品列表信息
+        List<GoodsDetail> goodsDetail = new ArrayList<GoodsDetail>();
+        GoodsDetail goodsDetail0 = new GoodsDetail();
+        goodsDetail0.setGoodsName("ipad");
+        goodsDetail0.setQuantity(1L);
+        goodsDetail0.setPrice("2000");
+        goodsDetail0.setGoodsId("apple-01");
+        goodsDetail0.setGoodsCategory("34543238");
+        goodsDetail0.setCategoriesTree("124868003|126232002|126252004");
+        goodsDetail0.setShowUrl("http://www.alipay.com/xxx.jpg");
+        goodsDetail.add(goodsDetail0);
+        model.setGoodsDetail(goodsDetail);
+
+        // 设置业务扩展参数
+        ExtendParams extendParams = new ExtendParams();
+        extendParams.setSysServiceProviderId("2088511833207846");
+        model.setExtendParams(extendParams);
+
+        // 设置商户传入业务信息
+        BusinessParams businessParams = new BusinessParams();
+        businessParams.setMcCreateTradeIp("127.0.0.1");
+        model.setBusinessParams(businessParams);
+
+        // 设置可打折金额
+        model.setDiscountableAmount("80.00");
+
+        // 设置商户门店编号
+        model.setStoreId("NJ_001");
+
+        // 设置商户操作员编号
+        model.setOperatorId("yx_001");
+
+        // 设置商户机具终端编号
+        model.setTerminalId("NJ_T_001");
+
+        // 设置商户的原始订单号
+        model.setMerchantOrderNo("20161008001");
+
+        request.setBizModel(model);
+        // 第三方代调用模式下请设置app_auth_token
+        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
+
+        AlipayTradePrecreateResponse response = alipayClient.execute(request);
+        System.out.println(response.getBody());
+
+        if (response.isSuccess()) {
+            System.out.println("调用成功");
+        } else {
+            System.out.println("调用失败");
+            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
+            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
+            // System.out.println(diagnosisUrl);
+        }
+        return response.getBody();
+    }
+
+    public String testAlipayTradePagePayRequest() throws AlipayApiException {
+        // 初始化SDK
+        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+
+        // 构造请求参数以调用接口
+        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
+        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
+
+        // 设置商户订单号
+        model.setOutTradeNo("20150320010101001"+(int)(Math.random()*100));
+
+        // 设置订单总金额
+        model.setTotalAmount("88.88");
+
+        // 设置订单标题
+        model.setSubject("Iphone6 16G");
+
+        // 设置产品码
+        model.setProductCode("FAST_INSTANT_TRADE_PAY");
+
+        // 设置PC扫码支付的方式
+        model.setQrPayMode("1");
+
+        // 设置商户自定义二维码宽度
+        model.setQrcodeWidth(100L);
+
+        // 设置订单包含的商品列表信息
+        List<GoodsDetail> goodsDetail = new ArrayList<GoodsDetail>();
+        GoodsDetail goodsDetail0 = new GoodsDetail();
+        goodsDetail0.setGoodsName("ipad");
+        goodsDetail0.setAlipayGoodsId("20010001");
+        goodsDetail0.setQuantity(1L);
+        goodsDetail0.setPrice("2000");
+        goodsDetail0.setGoodsId("apple-01");
+        goodsDetail0.setGoodsCategory("34543238");
+        goodsDetail0.setCategoriesTree("124868003|126232002|126252004");
+        goodsDetail0.setShowUrl("http://www.alipay.com/xxx.jpg");
+        goodsDetail.add(goodsDetail0);
+        model.setGoodsDetail(goodsDetail);
+
+        // 设置订单绝对超时时间
+        //model.setTimeExpire("2025-12-11 10:05:01");
+
+        // 设置二级商户信息
+        //SubMerchant subMerchant = new SubMerchant();
+        //subMerchant.setMerchantId("2088000603999128");
+        //subMerchant.setMerchantType("alipay");
+        //model.setSubMerchant(subMerchant);
+
+        // 设置业务扩展参数
+        //ExtendParams extendParams = new ExtendParams();
+        //extendParams.setSysServiceProviderId("2088511833207846");
+        //extendParams.setHbFqSellerPercent("100");
+        //extendParams.setHbFqNum("3");
+        //extendParams.setIndustryRefluxInfo("{\"scene_code\":\"metro_tradeorder\",\"channel\":\"xxxx\",\"scene_data\":{\"asset_name\":\"ALIPAY\"}}");
+        //extendParams.setRoyaltyFreeze("true");
+        //extendParams.setCardType("S0JP0000");
+        //model.setExtendParams(extendParams);
+
+        // 设置商户传入业务信息
+        //model.setBusinessParams("{\"mc_create_trade_ip\":\"127.0.0.1\"}");
+
+        // 设置优惠参数
+        //model.setPromoParams("{\"storeIdType\":\"1\"}");
+
+        // 设置请求后页面的集成方式
+        //model.setIntegrationType("PCWEB");
+
+        // 设置请求来源地址
+        //model.setRequestFromUrl("https://");
+
+        // 设置商户门店编号
+        //model.setStoreId("NJ_001");
+
+        // 设置商户的原始订单号
+        //model.setMerchantOrderNo("20161008001");
+
+        // 设置外部指定买家
+        //ExtUserInfo extUserInfo = new ExtUserInfo();
+        //extUserInfo.setCertType("IDENTITY_CARD");
+        //extUserInfo.setCertNo("362334768769238881");
+        //extUserInfo.setMobile("16587658765");
+        //extUserInfo.setName("李明");
+        //extUserInfo.setMinAge("18");
+        //extUserInfo.setNeedCheckInfo("F");
+        //extUserInfo.setIdentityHash("27bfcd1dee4f22c8fe8a2374af9b660419d1361b1c207e9b41a754a113f38fcc");
+        //model.setExtUserInfo(extUserInfo);
+
+        // 设置开票信息
+        //InvoiceInfo invoiceInfo = new InvoiceInfo();
+        //InvoiceKeyInfo keyInfo = new InvoiceKeyInfo();
+        //keyInfo.setTaxNum("1464888883494");
+        //keyInfo.setIsSupportInvoice(true);
+        //keyInfo.setInvoiceMerchantName("ABC|003");
+        //invoiceInfo.setKeyInfo(keyInfo);
+        //invoiceInfo.setDetails("[{\"code\":\"100294400\",\"name\":\"服饰\",\"num\":\"2\",\"sumPrice\":\"200.00\",\"taxRate\":\"6%\"}]");
+        //model.setInvoiceInfo(invoiceInfo);
+
+        //回调地址
+        request.setNotifyUrl("http://anyi.space:10002/notify");
+        //成功返回地址
+        request.setReturnUrl("http://anyi.space:10002/hello");
+        //时间戳参数
+        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+        log.info("timestamp:{}",timestamp);
+        request.putOtherTextParam("timestamp",timestamp);
+        //业务参数
+        request.setBizModel(model);
+        log.info("request:{}",request);
+        // 第三方代调用模式下请设置app_auth_token
+        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
+
+        AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");
+        // 如果需要返回GET请求,请使用
+        // AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "GET");
+        String pageRedirectionData = response.getBody();
+        System.out.println(pageRedirectionData);
+
+        if (response.isSuccess()) {
+            System.out.println("调用成功");
+        } else {
+            System.out.println("调用失败");
+            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
+            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
+            // System.out.println(diagnosisUrl);
+        }
+        return pageRedirectionData;
+    }
+
+    private static AlipayConfig getAlipayConfig() {
+        String privateKey  = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCElgGegoE2Wo/FceL8NvpH2cTRclHyQ9S8MB8vO9hTCCnnhuxG6vV9fefI62tcg13G1DOi1Ft8mnEq/NREzkGlD4+J7RCd7L8d/CMoO3Lhr4g/OMVlwNGj5qYr8I4QKGY9EkQiRct/MTrXXppjkxrZqduWAob26t++AzkwCQx6nwGCXfnw56X7OSGVctWLesR8iaMkPQx/L5taiDtcaRDDq2pxmIslZJ5ag524B5vAVieAZx1QoKqeyLRaqI9o0fPRUntMsCMYlSGsy5/HeP47nFvZc6EEd/pvhEIOV/HxPeHNSoHjjHgTxF1a+pyFnKhceOjVns3X4O7AGSZ+WgyFAgMBAAECggEATtdQsSxTn7msgrGdU3Nx0uYJJq7/UbvKNfm7oX/JvF4/ZOETgXxYbL5A5XYwinvHeONYrTvwByFjqDdeFmg8GuYs6cyhs/dDEpaLZXIsd03FDCs7Hq3RO9B9AeXy5GLRoQFKqMKuJr1kiwtDbXDdZ4+c9xAbp5q1X61VBV5sIEGv2DQC35riOStCSNMjyyMdaxKNNfZN2Z6cWBJtTLlUpI0LhokVA7hqnM8kyMbL26felXhZHXes7pxSMLuF5YXBCjIdnrPIr3HLj/Zi0KzOCmWt4SwUKMjkvZZ+bxSE5WmyhL9pkyyaPuSMa7F0IW8LBvqaaWFBQ5Q1uoZ1Cu4fhQKBgQDCp7zZ8xCsxLYLQW+VafDhNCytTD7CfYGU0QhJq0MvcPd7NVQTM+x1kUC/uiL1lUSjQbihWcFrT7toQ7fL9tkSOVgDQmv3hT2qNqybE4qxMvBA3IfeGhu95b7ps2lHlZE36DMYdTr4s8ku1TLv9UUti/HheTXZCNLjrjgP+Z0lDwKBgQCuXq/LAtcgLgjvFaF8nc4EiJ1VpHgoffmig2Kz/ryYut6NuLgw1dMBmBgL7eF3LWOZ39G8dAuk+1C+CO/x3IKkb80rniGshfUdoCMB2E5LnsaGKXcsPlZ/kKCaykiTScvd5g0M6NJ9cL1xv31GXu9q2g4O7AeqVKo5t8wpeVv9KwKBgDkmGAsBEs82fZ/2WTVLwj3MHKXQcciWIno3mLBQSMxf5TjWIlX086Jcv97KXkMtzNYFkJhGisPfx8zHvOl0Eq0ICvACC0LDaqRTov9wkFKP+vuAA5/QmH57Oj7QvsMWhWkdkgrHOEYWOqW2UFsk7md948jn1khfD9Nqrej6xwk/AoGABHsCYWENThJgwGP55k3XwV4RTOYRAFlcVMSzgJSHHBWRKmsYsIiOB3h1BblzFbDg4k9SAFmrAu5CQN/R6pET+k21I+3IR7qZdc1rmNyKBn9p8oCWQ1jGuDhrKA8SllZLGsSSiUZiQj7nX0jgWzKNTF2WBuQhvkq2pQ0H/fjUWEkCgYA1+hGhnOPHqe7MLKhGVSdS+mrPwC8y/ppsjhM6LYjNwPgIjAHR843k+o1XT5jlXFnQKj0I6amiN2Y9PHr/Ikk4GlcJ/1kB1QLf9t5iP1msCEgXfzVGYkHh8rJPoWxnejLZtPSK9PLDYDPiXTf52ZZ8zynhqF+QvG5y3FiXj22ulw==";
+        String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlDYk9buY1lSzVAlUL2Dr0JvwBbXjIkZMCoYFiApF8ynTgOMFQ1GM7JnoYkPbpHnOB1UzXKZUFSkwvNl35lsWKZm1Iz0RhlIcBMcNiBvsYp3zrQyMCBFPkv4jZNhOEyhVXHhghHnuknd0NzbWwMjSq3pjs2CbpGngDCu3unr6HXrzNjtAZ82ExPBZMfeEMQrpWqQpxEMVRXTreMVqCCWFxIR+bNQ5yiBG/ZcepCj8y7m5XBwnR2YtIIIZBziHYEm5T/6t+OkQ4pj9ML5ETL6iVKT8lAjLvTO26nR5sGlTNeXUf9maTwmAFWyDWRgZ8xZL+KR8X6/zLPmfQQgEjD1zuQIDAQAB";
+        AlipayConfig alipayConfig = new AlipayConfig();
+        alipayConfig.setServerUrl("https://openapi-sandbox.dl.alipaydev.com/gateway.do");
+        //<-- 请填写您的AppId,例如:2019091767145019 -->
+        alipayConfig.setAppId("9021000142656859");
+        alipayConfig.setPrivateKey(privateKey);
+        alipayConfig.setFormat("json");
+        alipayConfig.setAlipayPublicKey(alipayPublicKey);
+        alipayConfig.setCharset("UTF-8");
+        alipayConfig.setSignType("RSA2");
+        return alipayConfig;
+    }
+}

+ 18 - 0
src/main/java/space/anyi/alipay/Application.java

@@ -0,0 +1,18 @@
+package space.anyi.alipay;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @ProjectName: aliPayDemo
+ * @FileName: Application
+ * @Author: 杨逸
+ * @Data:2025/12/10 20:09
+ * @Description:
+ */
+@SpringBootApplication
+public class Application {
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}

+ 99 - 0
src/main/java/space/anyi/alipay/controller/HelloController.java

@@ -0,0 +1,99 @@
+package space.anyi.alipay.controller;
+
+import com.alipay.api.AlipayApiException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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.ResponseBody;
+import space.anyi.alipay.AlipayTradePrecreate;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @ProjectName: aliPayDemo
+ * @FileName: HelloController
+ * @Author: 杨逸
+ * @Data:2025/12/10 20:10
+ * @Description:
+ */
+@Controller
+public class HelloController {
+    Logger log = LoggerFactory.getLogger(HelloController.class);
+    @GetMapping("/hello")
+    @ResponseBody
+    public String hello(){
+        return "hello";
+    }
+    @ResponseBody
+    @GetMapping("/pay")
+    public String pay(){
+        String result = "";
+        try {
+            result = new AlipayTradePrecreate().testAlipayTradePagePayRequest();
+        } catch (AlipayApiException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+    /**
+     * 给支付宝的回调接口
+     */
+    @PostMapping("/notify")
+    public void notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
+        Map<String, String> params = new HashMap<>();
+        //获取支付宝POST过来反馈信息,将异步通知中收到的待验证所有参数都存放到map中
+        Map<String, String[]> parameterMap = request.getParameterMap();
+        log.info("支付宝回调参数:{}", parameterMap);
+        for (String name : parameterMap.keySet()) {
+            String[] values = parameterMap.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);
+        }
+        log.info("支付宝回调参数:{}", params);
+        //验签
+        //Boolean signResult = Factory.Payment.Common().verifyNotify(params);
+        Boolean signResult = true;
+        if (signResult) {
+            log.info("收到支付宝发送的支付结果通知");
+            String out_trade_no = request.getParameter("out_trade_no");
+            log.info("交易流水号:{}", out_trade_no);
+            //交易状态
+            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
+            //交易成功
+            switch (trade_status) {
+                case "TRADE_SUCCESS":
+                    //支付成功的业务逻辑,比如落库,开vip权限等
+                    log.info("订单:{} 交易成功", out_trade_no);
+                    break;
+                case "TRADE_FINISHED":
+                    log.info("交易结束,不可退款");
+                    //其余业务逻辑
+                    break;
+                case "TRADE_CLOSED":
+                    log.info("超时未支付,交易已关闭,或支付完成后全额退款");
+                    //其余业务逻辑
+                    break;
+                case "WAIT_BUYER_PAY":
+                    log.info("交易创建,等待买家付款");
+                    //其余业务逻辑
+                    break;
+            }
+            response.getWriter().write("success");   //返回success给支付宝,表示消息我已收到,不用重调
+
+        } else {
+            response.getWriter().write("fail");   ///返回fail给支付宝,表示消息我没收到,请重试
+        }
+    }
+
+}

+ 2 - 0
src/main/resources/application.yaml

@@ -0,0 +1,2 @@
+server:
+  port: 10200