支付宝沙箱

1.注册并登录

地址:开放平台

2.进入该界面
2.1自定义秘钥

文档地址:小程序文档 - 支付宝文档中心

使用工具生成密钥

 

一定要保存好对应的秘钥

2.2配置自定义秘钥


那么到这一步就基本配置完成了

文档地址:小程序文档 - 支付宝文档中心

api接口

文档地址:小程序文档 - 支付宝文档中心

应用私钥

打开工具就能找到对应目录。

3.主要代码

#支付宝
#appId:  沙箱中的应用id
#appPrivateKey:  应用私钥
#alipayPublicKey: 支付宝公钥
#notifyUrl: 调用支付宝支付接口后产生的回调,需要内网穿透,后面详细讲,先不配置
#returnUrl: 支付成功后的页面跳转,设置成你项目中的成功支付界面(可不填)
alipay:
  appId: 9021
  appPrivateKey: 
  alipayPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjDKi0mY9zSsGe9O+Og9FZmOP8qgEMMaiQMejG4wzxT4tcyCPUvsmjrkGnk9rgCJ/d4mf+Ms2IyXp6usQ+
  notifyUrl: http://hzkv99.natappfree.cc/pay-api/pay/notify
  returnUrl: http://localhost:8080/#/success
  gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do
  format: JSON 
  charset: utf-8
  signType: RSA2

 

支付controller及配置类

package com.chen.controller;
​
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.easysdk.factory.Factory;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chen.entity.Order;
import com.chen.mapper.OrderMapper;
import com.chen.pay.AliPayConfig;
import com.chen.vo.Result;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
​
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
​
@RestController
@RequestMapping("/pay")
@Slf4j
public class PayController {
​
    @Resource
    AliPayConfig aliPayConfig;
    @Resource
    OrderMapper orderMapper;
​
​
    /**
     * 支付接口
     *
     * @param order
     * @param httpResponse
     * @throws Exception
     */
    @GetMapping("/payOrder")
    public void pay(Order order, HttpServletResponse httpResponse) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(), aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), aliPayConfig.getFormat(), aliPayConfig.getCharset(),
                aliPayConfig.getAlipayPublicKey(), aliPayConfig.getSignType());
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        request.setReturnUrl(aliPayConfig.getReturnUrl());
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", order.getOrderSno());
        bizContent.put("total_amount", order.getOrderPrice());
        bizContent.put("subject", "商品" + order.getOrderSno());
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        request.setBizContent(bizContent.toString());
        String form = "";
        try {
            // 调用SDK生成表单
            form = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + aliPayConfig.getCharset());
        // 直接将完整的表单html输出到页面
        httpResponse.getWriter().write(form);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
​
​
    /**
     * 支付宝回调
     *
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/notify")
    public Result payNotify(HttpServletRequest request) throws Exception {
        log.info("---------------进入支付回调---------------");
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            log.info("=========支付宝异步回调========");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }
            System.out.println(params);
            // 支付宝验签
            if (Factory.Payment.Common().verifyNotify(params)) {
                // 验签通过
                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"));
                // 更新订单状态
                String out_trade_no = params.get("out_trade_no");
                String trade_no = params.get("trade_no");
                Integer i = orderMapper.updateByOrder(out_trade_no, trade_no);
                return Result.success();
            }
        }
        return Result.error("回调错误~");
    }
​
​
    /**
     * 退款接口
     *
     * @param orderSno
     * @return
     */
    @PostMapping("/refund")
    public Result refund(@RequestParam("orderSno") String orderSno) {
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(), aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), aliPayConfig.getFormat(), aliPayConfig.getCharset(),
                aliPayConfig.getAlipayPublicKey(), aliPayConfig.getSignType());
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        // 获取获取对应订单信息
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderSno, orderSno));
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", order.getOutTradeNo());
        bizContent.put("refund_amount", order.getOrderPrice());
        bizContent.put("out_request_no", "HZ01RF002"); //退款标识,用于查询状态是操作
        request.setBizContent(bizContent.toString());
        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            log.info("结果:{}", response);
            if (response.isSuccess()) {
                log.info("退款成功~");
                order.setOrderStatus(3);
                orderMapper.updateById(order);
                return Result.success();
            } else {
                log.info("退款失败~");
                return Result.error("退款失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("退款失败");
        }
    }
​
​
    /**
     * 查看支付订单状态
     *
     * @param orderSno
     * @return
     */
    @SneakyThrows
    @GetMapping("/selectPayList")
    public Result selectPayList(@RequestParam("orderSno") String orderSno) {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(), aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), aliPayConfig.getFormat(), aliPayConfig.getCharset(),
                aliPayConfig.getAlipayPublicKey(), aliPayConfig.getSignType());
        // 构造请求参数以调用接口
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
//        更具自己的业务查询
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderSno, orderSno));
        if (Objects.isNull(order)) {
            return Result.error("订单号不存在");
        }
        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(order.getOutTradeNo());
        // 设置查询选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("trade_settle_info");//交易结算信息
        queryOptions.add("fund_bill_list");//交易支付资金渠道
        model.setQueryOptions(queryOptions);
        // 设置支付宝交易号
        model.setTradeNo(order.getTradeNo());
        request.setBizModel(model);
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
//            这里做演示就直接丢给前端了
            return Result.success("成功", response.getBody());
        } else {
            return Result.error("第三方调用失败~");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }
​
​

}
配置类

package com.chen.pay;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
import javax.annotation.PostConstruct;
​
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
@Slf4j
public class AliPayConfig {
   private String appId;
   private String appPrivateKey;
   private String alipayPublicKey;
   private String notifyUrl;
   private String returnUrl;
   private String gatewayUrl;
   private String format;
   private String charset;
   private String signType;
​
   @PostConstruct
   public void init() {
     log.info("-------配置初始化-----------");
      Config config = new Config();
      config.protocol = "https";
      config.gatewayHost = "openapi.alipaydev.com";
      config.signType = "RSA2";
      config.appId = this.appId;
      config.merchantPrivateKey = this.appPrivateKey;
      config.alipayPublicKey = this.alipayPublicKey;
      config.notifyUrl = this.notifyUrl;
      Factory.setOptions(config);
   }
}

演示视频

springboot调用支付宝沙箱案例:支付,退款,支付查询,退款查询等

 需要源码的私信下免费提供,后面会持续更新小程序版本的案例。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐