Java调用支付宝接口

一、环境准备

准备:内网穿透工具以及支付宝沙箱环境

1、内网穿透,申请免费域名(用于支付宝异步通知回调,要求外网可访问)

申请地址:https://www.ngrok.cc/

 

 

下载Ngrok客户端

 

解压,点击bat文件启动

 

输入刚才申请的隧道id,回车

 

端口映射完成

项目启动可使用http://donleo.free.idcfengye.com 访问

2、登录支付宝电脑端

网站地址:https://open.alipay.com/platform/home.htm

沙箱文档地址:https://opendocs.alipay.com/open/200/105311

首页-->支付宝扫码登录-->进入管理中心-->开发服务-->研发服务

设置秘钥

下载开发助手:https://opendocs.alipay.com/open/291/introduce

下载解压-->安装-->打开工具-->生成密匙(安装路径不要有空格)

将刚才通过工具生成的应用公钥复制到沙箱应用中,自动生成对应的支付宝公钥

 

 

沙箱账号,提供了卖家和买家两个测试账号,用于开发时方便测试

二、搭建项目

以电脑网站支付为例

支付宝接口文档:https://opendocs.alipay.com/open/270/105900

接口英文名

接口中文名

alipay.trade.page.pay

统一收单下单并支付页面接口

alipay.trade.refund

统一收单交易退款接口

alipay.trade.fastpay.refund.query

统一收单交易退款查询接口

alipay.trade.query

统一收单线下交易查询接口

alipay.trade.close

统一收单交易关闭接口

alipay.data.dataservice.bill.downloadurl.query

查询对账单下载地址

alipay.trade.refund.depositback.completed

收单退款冲退完成通知

 

参考官方demohttps://opendocs.alipay.com/open/270/106291

下载demo参考

1、新建SpringBoot项目,向pom文件添加alipay-sdk-java依赖

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.11.54.ALL</version>
</dependency>

2、在官方给的demo例子,拷贝AlipayConfig配置文件到项目中

import java.io.FileWriter;
import java.io.IOException;

/**
 * 类名:AlipayConfig
 * 功能:基础配置类
 * 详细:设置帐户有关信息及返回路径
 * 修改日期:2017-04-05
 * 说明:
 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 * 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 */
public class AlipayConfig {

//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    public static String app_id = "";

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "";

    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "";

    // 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String notify_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";

    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String return_url = "http://工程公网访问地址/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.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();
                }
            }
        }
    }
}

应用id(自己的应用id):

商户私钥(刚才支付宝开发助手生成的):

支付宝公钥:

更改支付宝网关地址为开发环境地址:https://openapi.alipaydev.com/gateway.do

notify_url异步通知接口地址,例如:http://donleo.free.idcfengye.com/alipay/notifyPay

return_url页面跳转同步通知路径

三、测试接口

1、支付接口测试

接口文档地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay/

调用流程

公共请求参数,每次请求都会包含的参数

查看支付请求参数,这四个参数必选

创建支付记录和退款记录两个实体类,用于将交易信息保存到本地数据库

Base:基础类

class Base implements Serializable {
    /**
     * id 主键,自增
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    /**
     * 更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updateTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

PayLog:交易记录

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class PayLog extends Base {

    /**
     * 商户订单号
     */
    private String outTradeNo;
    /**
     * 支付宝交易号
     */
    private String tradeNo;
    /**
     * 支付金额
     */
    private Double totalAmount;
    /**
     * 支付订单名称
     */
    private String subject;
    /**
     * 支付订单详情
     */
    private String subjectInfo;
    /**
     * 支付时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date payTime;
    /**
     * 支付状态
     */
    private Integer status;
    /**
     * 退款总金额
     */
    private Double refundTotalAmount;
}

RefundLog:退款记录

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class RefundLog extends Base {
    /**
     * 商户订单号
     */
    private String outTradeNo;
    /**
     * 退款编号
     */
    private String refundNo;
    /**
     * 退款金额
     */
    private Double refundAmount;
    /**
     * 退款原因
     */
    private String refundInfo;
    /**
     * 退款时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date refundTime;

这些只是部分部分,具体参数可参考支付宝接口文档

交易支付状态常量类

public class Constant {
    //待支付
    public static final int PAY_STATUS_WAITING=0;
    //已支付
    public static final int PAY_STATUS_PAID=1;
    //已关闭
    public static final int ABLE_PRAISE_CLOSED=2;
    //已部分退款
    public static final int PAY_STATUS_REFUNDED=3;
    //已全额退款
    public static final int PAY_STATUS_ALL_REFUNDED=4;
}

支付代码请求示例:

   @Override
    public void pay(String price, String name, HttpServletResponse response) {
        try {
            //获得初始化的AlipayClient
            DefaultAlipayClient client = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key,
       "json",AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //电脑网页支付 AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); //手机网页支付 // AlipayTradeWapPayRequest request=new AlipayTradeWapPayRequest(); Map<Object, Object> map = new HashMap<>(); //商户订单号,商户网站订单系统中唯一订单号,必填 String outTradeNo = UUIDUtil.getUUID(); map.put("out_trade_no", outTradeNo); //销售产品码,目前仅支持FAST_INSTANT_TRADE_PAY,必填 map.put("product_code", "FAST_INSTANT_TRADE_PAY"); //付款金额,必填 map.put("total_amount", price); //订单名称,必填 map.put("subject", name); String string = JSONObject.toJSONString(map); log.info("--------" + string); request.setBizContent(string); //创建订单 createPayLog(outTradeNo, name, price); //异步通知 request.setNotifyUrl(AlipayConfig.notify_url); //页面跳转 request.setReturnUrl(AlipayConfig.return_url); String body = client.pageExecute(request).getBody(); response.setContentType("text/html;charset=utf-8"); response.getWriter().write(body); response.getWriter().flush(); response.getWriter().close(); } catch (Exception e) { log.error(e.getMessage()); } } /** * 创建订单,保存到本地数据库 * * @param outTradeNo 商户订单号 * @param name 订单名称 * @param price 付款金额 */ private void createPayLog(String outTradeNo, String name, String price) { PayLog payLog = new PayLog(); payLog.setOutTradeNo(outTradeNo); payLog.setSubject(name); payLog.setTotalAmount(parseDouble(price)); payLog.setStatus(Constant.PAY_STATUS_WAITING); payLog.setCreateTime(new Date()); payLogDao.insert(payLog); }

异步通知回调,post请求

    @Override
    public String notifyPay(HttpServletRequest request) {
        try {
            log.info("进入异步通知接口");
            //获取支付宝POST过来反馈信息
            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] + ",";
                }
                params.put(name, valueStr);
            }
            //调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);

            /* 实际验证过程建议商户务必添加以下校验:
               1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
               2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
               3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
               4、验证app_id是否为该商户本身。
           */
            if (signVerified) {//验证成功
                //商户订单号
                String out_trade_no = request.getParameter("out_trade_no");
                //支付宝交易号
                String trade_no = request.getParameter("trade_no");
                //交易状态
                String trade_status = request.getParameter("trade_status");
                //支付金额
                String total_amount = request.getParameter("total_amount");

                if (StringUtils.isEmpty(out_trade_no)) {
                    log.error("商户订单号为空");
                    return "fail";
                }
                if (StringUtils.isEmpty(trade_no)) {
                    log.error("支付宝交易号为空");
                    return "fail";
                }
                if (StringUtils.isEmpty(total_amount)) {
                    log.error("支付金额为空");
                    return "fail";
                }
                if (StringUtils.isEmpty(trade_status)) {
                    log.error("交易状态为空");
                    return "fail";
                }

                //比对金额和交易号是否一致
                PayLog payLog = new LambdaQueryChainWrapper<>(payLogDao).eq(PayLog::getOutTradeNo, out_trade_no).one();
                if (payLog == null) {
                    log.error("订单编号不存在!【" + out_trade_no + "】");
                    return "fail";
                } else {
                    if (payLog.getTotalAmount().compareTo(new Double(total_amount)) != 0) {
                        log.error("支付金额不同!【" + total_amount + "】" + "【" + payLog.getTotalAmount() + "】");
                        return "fail";
                    }
                }
                //参数验证合法,将交易号与状态更新到本地数据库
                payLog.setTradeNo(trade_no);
                payLog.setStatus(Constant.PAY_STATUS_PAID);
                payLog.setPayTime(new Date());
                payLogDao.updateById(payLog);
                return "success";

            } else {//验证失败
                //调试用,写文本函数记录程序运行情况是否正常
//                String sWord = AlipaySignature.getSignCheckContentV1(params);
//                AlipayConfig.logResult(sWord);
                return "fail";
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return "fail";
    }

请求示例:

http://donleo.free.idcfengye.com/alipay/pay?price=9000&name=华为Pro40

可以下载支付宝App沙箱版扫码支付,也可以输入账号密码支付

方便测试,直接输入账号密码

 

输入密码可支付成功后会进入异步通知接口,是否真正支付成功是以异步通知为准,可在异步通知接口中进行一系列的逻辑验证

2、交易查询测试

接口文档地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.query

代码示例:

@Override
public String queryPayLog(HttpServletRequest request) {
    try {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key,
     "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //设置请求参数 AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest(); //商户订单号,商户网站订单系统中唯一订单号 String out_trade_no = request.getParameter("out_trade_no"); //支付宝交易号 String trade_no = request.getParameter("trade_no"); //请二选一设置,两者都存在优先取trade_no Map<String, Object> map = new HashMap<>(); map.put("out_trade_no", out_trade_no); map.put("trade_no", trade_no); alipayRequest.setBizContent(JSONObject.toJSONString(map)); //请求 String result = alipayClient.execute(alipayRequest).getBody(); log.info("交易查询:【" + result + "】"); return result; } catch (Exception e) { log.error(e.getMessage()); return e.getMessage(); }

返回结果示例:

{
    "alipay_trade_query_response": {
        "code": "10000",
        "msg": "Success",
        "buyer_logon_id": "stb***@sandbox.com",
        "buyer_pay_amount": "0.00",
        "buyer_user_id": "2088622955538298",
        "buyer_user_type": "PRIVATE",
        "invoice_amount": "0.00",
        "out_trade_no": "39d1a795c14d4078bbb26665a6f9fe69",
        "point_amount": "0.00",
        "receipt_amount": "0.00",
        "send_pay_date": "2021-03-08 16:36:35",
        "total_amount": "99.90",
        "trade_no": "2021030822001438290501186947",
        "trade_status": "TRADE_SUCCESS"
    },
    "sign": "ceDc9LR7Co8kh/oJbWpzdCQhylR6JEG6pxQnh89WQLUal0+t5Sds493XHET8QdZONb2tbRNAxwhbgbgLRiQjMCNQLRg+Hxu8uGjH2dpwEIlCWwc3LfFOZo5bCmofKV03sl+ABa4HhMVhVYIwEjCUlEofMoeC2n/PNA8HeQ8h7uPHAv/A9yIxMnzXraoBTYcXiXGtV/IdTWLepq9vmrmMRDVxjFqAzRH/p1dtq+D5fTb45jSUFUYU1UC1MDsVqkS6iM9oVGtqRS8JrZun9HVUFiMPm9Bi17HDnCfQBjo63olPk2620N9W5HwV3W9xUD2Yp6ncndCB99rhOuDf8BwQ=="
}

3、交易关闭测试

接口文档地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.close

请求流程

 

代码示例:

    @Override
    public String closePayLog(HttpServletRequest request) {
        try {
            //获得初始化的AlipayClient
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key,
       "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //设置请求参数 AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest(); //商户订单号,商户网站订单系统中唯一订单号 String out_trade_no = request.getParameter("out_trade_no"); //支付宝交易号 // String trade_no = request.getParameter("trade_no"); //请二选一设置 alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"}"); //请求 String result = alipayClient.execute(alipayRequest).getBody(); log.info("返回数据------>" + result); JSONObject jsonObject = JSONObject.parseObject(result).getJSONObject("alipay_trade_close_response"); Long code = Long.valueOf(jsonObject.get("code").toString()); //关闭成功,同步数据状态 if (code.compareTo(10000L) == 0) { PayLog payLog = new LambdaQueryChainWrapper<>(payLogDao).eq(PayLog::getOutTradeNo, out_trade_no).one(); payLog.setStatus(Constant.ABLE_PRAISE_CLOSED); payLog.setUpdateTime(new Date()); payLogDao.updateById(payLog); } return result; } catch (Exception e) { log.error(e.getMessage()); return e.getMessage(); } }

4、退款接口测试

接口文档地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.refund

调用流程

 

如果可以多次退款,out_request_no必传,且保证唯一

代码示例(支持一个订单多次退款)

@Override
    public String refundPay(HttpServletRequest request) {
        try {
            //获得初始化的AlipayClient
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key,
       "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //设置请求参数 AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest(); //商户订单号,商户网站订单系统中唯一订单号 String out_trade_no = request.getParameter("out_trade_no"); //支付宝交易号 // String trade_no = request.getParameter("trade_no"); //请二选一设置 //需要退款的金额,该金额不能大于订单金额,必填 String refund_amount = request.getParameter("refund_amount"); //退款的原因说明 String refund_reason = request.getParameter("refund_reason"); //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传 String out_request_no = UUIDUtil.getUUID(); //判断是否可以退款 int payCode = refundAliPay(out_trade_no, refund_amount); if (payCode == 1) { return "退款金额不能大于可退款金额"; } else if (payCode == 2) { return "订单已关闭,不能退款"; } else if (payCode == 3) { return "订单未支付,不能退款"; } else if (payCode == 4) { return "订单已全部退款"; } else { alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"refund_amount\":\"" + refund_amount + "\"," + "\"refund_reason\":\"" + refund_reason + "\"," + "\"out_request_no\":\"" + out_request_no + "\"}"); //请求 String result = alipayClient.execute(alipayRequest).getBody(); log.info("退款信息------>" + result); JSONObject jsonObject = JSONObject.parseObject(result).getJSONObject("alipay_trade_refund_response"); Long code = Long.valueOf(jsonObject.get("code").toString()); //退款成功,更新数据库并保存退款记录 if (code.compareTo(10000L) == 0) { //查询退款记录 List<RefundLog> refundLogList = new LambdaQueryChainWrapper<>(refundLogDao).eq(RefundLog::getOutTradeNo, out_trade_no).list(); double refundTotalAmount = 0.00; BigDecimal d1 = new BigDecimal(refundTotalAmount); if (refundLogList.size() > 0) { for (RefundLog aRefundLogList : refundLogList) { BigDecimal d2 = new BigDecimal(aRefundLogList.getRefundAmount()); refundTotalAmount += d1.add(d2).doubleValue(); } } //插入退款记录 RefundLog refundLog = new RefundLog(); refundLog.setOutTradeNo(out_trade_no); refundLog.setRefundNo(out_request_no); refundLog.setRefundAmount(parseDouble(refund_amount)); refundLog.setRefundInfo(refund_reason); refundLog.setRefundTime(new Date()); refundLogDao.insert(refundLog); //更新支付记录 refundTotalAmount += parseDouble(refund_amount); PayLog payLog = new LambdaQueryChainWrapper<>(payLogDao).eq(PayLog::getOutTradeNo, out_trade_no).one(); payLog.setUpdateTime(new Date()); if (refundTotalAmount == payLog.getTotalAmount()) { payLog.setStatus(Constant.PAY_STATUS_ALL_REFUNDED); } else { payLog.setStatus(Constant.PAY_STATUS_REFUNDED); } payLog.setRefundTotalAmount(refundTotalAmount); payLogDao.updateById(payLog); } return result; } } catch (Exception e) { log.error(e.getMessage()); return e.getMessage(); } } /** * 判断是否可以退款 * * @param out_trade_no 订单号 * @param refund_amount 退款金额 * @return int */ private int refundAliPay(String out_trade_no, String refund_amount) { List<RefundLog> refundLogList = new LambdaQueryChainWrapper<>(refundLogDao).eq(RefundLog::getOutTradeNo, out_trade_no).list(); double refundTotalAmount = 0.00; BigDecimal d1 = new BigDecimal(refundTotalAmount); if (refundLogList.size() > 0) { for (RefundLog aRefundLogList : refundLogList) { BigDecimal d2 = new BigDecimal(aRefundLogList.getRefundAmount()); refundTotalAmount += d1.add(d2).doubleValue(); } } //查询支付记录 PayLog payLog = new LambdaQueryChainWrapper<>(payLogDao).eq(PayLog::getOutTradeNo, out_trade_no).one(); //退款金额 double refundAmount = parseDouble(refund_amount); //支付总金额 double totalAmount = payLog.getTotalAmount(); //可退款金额 BigDecimal b1 = new BigDecimal(totalAmount); BigDecimal b2 = new BigDecimal(refundTotalAmount); double enableAmount = b1.subtract(b2).doubleValue(); if (payLog.getStatus().equals(Constant.ABLE_PRAISE_CLOSED)) { //订单已关闭,不能退款 return 2; } else if (payLog.getStatus().equals(Constant.PAY_STATUS_WAITING)) { //订单未支付,不能退款 return 3; } else if (payLog.getStatus().equals(Constant.PAY_STATUS_ALL_REFUNDED)) { //订单已全部退款 return 4; } else { //表示可以退款 if (refundAmount > enableAmount) { //退款金额不能大于可退款金额 return 1; } return 0; } }

请求示例:

  http://donleo.free.idcfengye.com/alipay/refundPay?out_trade_no=15baf0eb282844c9a7bbcf491a3ab214&refund_amount=100&refund_reason=好评返现

响应示例:

{
    "alipay_trade_refund_response": {
        "code": "10000",
        "msg": "Success",
        "buyer_logon_id": "stb***@sandbox.com",
        "buyer_user_id": "2088622955538298",
        "fund_change": "Y",
        "gmt_refund_pay": "2021-03-09 10:36:00",
        "out_trade_no": "15baf0eb282844c9a7bbcf491a3ab214",
        "refund_fee": "322.20",
        "send_back_fee": "0.00",
        "trade_no": "2021030622001438290501185818"
    },
    "sign": "h6k02XohrwCg4HhEFjHXdER+AkOc4jbt5c06nuEYAI/RjCfnX9Km3LO0+Z2Xz+0RJTGgAtWJcp94Te4/Uomdnug9m+LA3bX1O1HSi/wlThUXT7QGwN/EyYxxZV5uAJzd5Q49bZZIsh8n39NXnShzRcZ2FP8sSp02kECCyiKjYVDrMLyOPoR4gcJiGUmwE2jKNIHZ2dxJ6D75XBtQkg9YsaOfbX47bDqAEEIxAcySBVfF0WkNha0rpTXWtriqZHrLzJZsNSwwqdM2W+EezLnxmpfzIdSE35fCJHXehVXm5veJ9czgkiDpuToaD+o0qUo6ex+1pnxu8nqmSMFraaTA=="
}

查看本地数据库中的退款记录

5、退款查询测试

接口文档地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.fastpay.refund.query

代码示例:

@Override
public String refundQuery(HttpServletRequest request) {
    try {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();
        //商户订单号,商户网站订单系统中唯一订单号
        String out_trade_no = request.getParameter("out_trade_no");
        //请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号,必填
        //此处为退款记录编号
        String out_request_no = request.getParameter("refund_no");

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"out_request_no\":\"" + out_request_no + "\"}");
        //请求
        String result = alipayClient.execute(alipayRequest).getBody();
        log.info("退款记录------>" + result);
        return result;
    } catch (Exception e) {
        log.error(e.getMessage());
        return e.getMessage();
    }
}

请求示例:

  http://localhost:9000/alipay/refundQuery?out_trade_no=15baf0eb282844c9a7bbcf491a3ab214&refund_no=65bdc5dc0afa457688be38b7d5042e4b

响应示例:

{
    "alipay_trade_fastpay_refund_query_response": {
        "code": "10000",
        "msg": "Success",
        "out_request_no": "65bdc5dc0afa457688be38b7d5042e4b",
        "out_trade_no": "15baf0eb282844c9a7bbcf491a3ab214",
        "refund_amount": "100.00",
        "total_amount": "9000.00",
        "trade_no": "2021030622001438290501185818"
    },
    "sign": "TOIvyxk+FGQPuTgX9s6rWyxRSEaEA0AgqlJj7dmwU6IPfjgLIBDMw6NXsax0nQQTaYFOfLaZ56c0ap7+I/t31WQbF5/6DczWKoxK7ijenXvtQ9IcYx17e272xdUDrwLMe/w3q5b30py0WBqTLfBRUkV9tqystI7yeF9QAx90wMp9oe8spxeYXKcfuJ3fVpjEpCA0RbL6SvO69Vawh400adcVu2PIG5W1/gkKTOCgE6cXsJ1MGL7GvYnXgfFwMFwnhZP+JZFmktdfTNsIV8eakp+oyVNJJvobIKjjcr5Bfvrzt3BIqN2M6XOAxfkaZ9nxE0hcmRY/LTZ5FFvo2b2A=="
}

6、账单下载测试

接口文档地址:https://opendocs.alipay.com/apis/api_15/alipay.data.dataservice.bill.downloadurl.query

调用流程

 

代码示例:

@Override
public String downloadPayLog(HttpServletRequest request) {
    try {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        AlipayDataDataserviceBillDownloadurlQueryRequest alipayRequest = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        //账单类型 trade:商户基于支付宝交易收单的业务账单;signcustomer:基于商户支付宝余额收入及支出等资金变动的帐务账单。
        String bill_type = request.getParameter("bill_type");
        //账单时间,必填
        String bill_date = request.getParameter("bill_date");
        alipayRequest.setBizContent("{\"bill_type\":\"" + bill_type + "\","
                + "\"bill_date\":\"" + bill_date + "\"}");
        //请求
        String result = alipayClient.execute(alipayRequest).getBody();
        log.info("账单记录------>" + result);
        return result;
    } catch (Exception e) {
        log.error(e.getMessage());
        return e.getMessage();
    }
}

请求示例:

http://localhost:9000/alipay/downloadPayLog?bill_type=trade&bill_date=2020-03-08

响应示例:

{
    "alipay_data_dataservice_bill_downloadurl_query_response": {
        "code": "10000",
        "msg": "Success",
        "bill_download_url": "http://dwbillcenter-2-1-2.daily.alipay.net/downloadBillFile.resource?bizType=trade&userId=20886219553637780156&fileType=csv.zip&bizDates=20200308&downloadFileName=2088621955363770156_20200308.csv.zip&fileId=%2Ftrade%2F20886219553637780156%2F20200308.csv.zip&timestamp=1615257961&token=515b244e8b28fe10e0b0fcd3923c6b6"
    },
    "sign": "q1vX2Pt+Sm4iThIiGeMb9JwAOlew1zCcPUhotuE3iPsyE4c6m35TgpiqyYNZwTMse59fovogCUfiw1XwbG/7d5p7z6LWfgWws88Mh1v1nWYb7HNyNfh0KMd5CWf3KLJ0tE2hWeUpWAoOVruDQ8NVyWM1it/iDQa+Mh9Nr7KwWpMxOhNK2vH7MzRt5lKECQOLPXc5ko6IgYI4ddF62nMtLdKkJQeLyP7ByWGpWcBpLLca5pYTVvnMwo1dfobgNi05jYE5id+n6J2/q81gTPbJaP9UMv99qmURX37SJKwdekICRXMdfHRaEnTztM6BqCw0EvrnUMf/0BAt4RhvKw=="
}

 

 

 

 

 

posted @ 2021-03-19 22:37  donleo123  阅读(852)  评论(0编辑  收藏  举报