对接支付-Alipay 沙箱支付

1.注册支付宝开放平台账号
访问 支付宝|开放平台 地址:https://open.alipay.com/develop/manage,注册开发者账号并创建应用。

2.获取沙箱环境信息
在开放平台控制台进入「沙箱环境」,获取:

3.添加支付宝 SDK 依赖(Maven)

<!-- 支付宝沙箱支付对接文档:https://opendocs.alipay.com/common/02kkv7 -->
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.38.157.ALL</version>
</dependency>

4.创建配置类存储支付宝相关参数
https://opendocs.alipay.com/open/00dn74

@Data
@ConfigurationProperties(prefix = "alipay", ignoreInvalidFields = true)
public class AliPayConfigProperties {
    //获取地址;https://open.alipay.com/develop/sandbox/app
    private String app_id="";
    //「沙箱环境」商户私钥,你的PKCS8格式RSA2私钥
    private String app_private_key="";
    // 「沙箱环境」支付宝公钥
    private String alipay_public_key="";
    // 「沙箱环境」服务器异步通知页面路径
    private String notify_url;
    // 「沙箱环境」页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    private String return_url;
    // 「沙箱环境」支付宝网关(固定)https://openapi-sandbox.dl.alipaydev.com/gateway.do
    private String serverUrl;
    // 签名方式
    private String sign_type = "RSA2";
    // 字符编码格式
    private String charset = "utf-8";
    // 传输格式
    private String format = "json";
}

5.创建AlipayClient实例

@Configuration
@EnableConfigurationProperties(AliPayConfigProperties.class)
public class AliPayConfig {

    @Bean("alipayClient")
    public AlipayClient alipayClient(AliPayConfigProperties properties){
        return new DefaultAlipayClient(
                properties.getServerUrl(),
                properties.getApp_id(),
                properties.getApp_private_key(),
                properties.getFormat(),
                properties.getCharset(),
                properties.getAlipay_public_key(),
                properties.getSign_type()
        );
    }
}

6.统一下单接口实现

private PayOrder doPrepayOrder(String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException {
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(notifyUrl);
        request.setReturnUrl(returnUrl);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderId);//设置商户订单号
        bizContent.put("total_amount", totalAmount.toString());//设置订单总金额
        bizContent.put("subject", productName);//设置订单标题
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");//设置产品码 FAST_INSTANT_TRADE_PAY	电脑网站支付(PC 端支付页面)
        request.setBizContent(bizContent.toString());

       String form = alipayClient.pageExecute(request).getBody();
       log.info("测试结果\r\n\n把我复制到 index.html ->:{}", form);
       PayOrder payOrder = new PayOrder();
       payOrder.setOrderId(orderId);
       payOrder.setPayUrl(form);
       payOrder.setStatus(Constants.OrderStatusEnum.PAY_WAIT.getCode());

       orderDao.updateOrderPayInfo(payOrder);

       return payOrder;
    }

7.异步通知处理

@RequestMapping(value = "alipay_notify_url", method = RequestMethod.POST)
    public String payNotify(HttpServletRequest request) throws AlipayApiException {
        log.info("支付回调,消息接收 {}", request.getParameter("trade_status"));
        if (!request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            return "false";
        }

        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            log.info("参数:{}——{}",name,request.getParameter(name));
            params.put(name, request.getParameter(name));
        }

        String sign = params.get("sign");  // 从参数中获取签名
        String content = AlipaySignature.getSignCheckContentV1(params);  // 生成待签名字符串

        log.info("待验签内容:{} ",content);
        log.info("签名:{} ", sign);

        boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayPublicKey, "UTF-8");  // 验证签名

        // 支付宝验签
        if (!checkSignature) {
            return "false";
        }

        // 验签通过
        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"));
        log.info("支付回调,支付回调,更新订单 {}", params.get("out_trade_no"));

        return "success";

    }

8.查询订单是否已支付(处理调单补偿)

List<String> orderIds = orderService.queryNoPayNotifyOrder();
  if (null == orderIds || orderIds.isEmpty()) {return;}
  for (String orderId : orderIds) {
      AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
      AlipayTradeQueryModel bizModel = new AlipayTradeQueryModel();
      bizModel.setOutTradeNo(orderId);
      request.setBizModel(bizModel);

      AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.execute(request);
      String trade_status = alipayTradeQueryResponse.getTradeStatus();
      // 判断状态码
      if ("TRADE_SUCCESS".equals(trade_status)) {
          orderService.changeOrderPaySuccess(orderId);
      }
  }

posted @ 2025-05-12 16:14  必行之码  阅读(109)  评论(0)    收藏  举报