支付宝退款调用指南(Java)
本文介绍了使用Java调用支付宝SDK实现退款功能的实现方法。代码示例展示了如何初始化AlipayClient、构建退款请求参数(包括订单信息、退款金额、商品明细和分账信息),并执行退款操作。重点解析了核心参数配置,包括商户订单号(outTradeNo)、支付宝交易号(tradeNo)、退款金额(refundAmount)等必填字段,以及商品明细(RefundGoodsDetail)和分账信息(O
关于调用支付宝完成退款(java)
package com.java.sdk.demo;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.domain.RefundGoodsDetail;
import com.alipay.api.domain.OpenApiRoyaltyDetailInfoPojo;
import com.alipay.api.FileItem;
import java.util.Base64;
import java.util.ArrayList;
import java.util.List;
public class AlipayTradeRefund {
public static void main(String[] args) throws AlipayApiException {
// 初始化SDK
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
// 构造请求参数以调用接口
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
// 设置商户订单号
model.setOutTradeNo("20150320010101001");
// 设置支付宝交易号
model.setTradeNo("2014112611001004680073956707");
// 设置退款金额
model.setRefundAmount("200.12");
// 设置退款原因说明
model.setRefundReason("正常退款");
// 设置退款请求号
model.setOutRequestNo("HZ01RF001");
// 设置退款包含的商品列表信息
List<RefundGoodsDetail> refundGoodsDetail = new ArrayList<RefundGoodsDetail>();
RefundGoodsDetail refundGoodsDetail0 = new RefundGoodsDetail();
refundGoodsDetail0.setOutSkuId("outSku_01");
refundGoodsDetail0.setOutItemId("outItem_01");
refundGoodsDetail0.setGoodsId("apple-01");
refundGoodsDetail0.setRefundAmount("19.50");
List<String> outCertificateNoList = new ArrayList<String>();
outCertificateNoList.add("202407013232143241231243243423");
refundGoodsDetail0.setOutCertificateNoList(outCertificateNoList);
refundGoodsDetail.add(refundGoodsDetail0);
model.setRefundGoodsDetail(refundGoodsDetail);
// 设置退分账明细信息
List<OpenApiRoyaltyDetailInfoPojo> refundRoyaltyParameters = new ArrayList<OpenApiRoyaltyDetailInfoPojo>();
OpenApiRoyaltyDetailInfoPojo refundRoyaltyParameters0 = new OpenApiRoyaltyDetailInfoPojo();
refundRoyaltyParameters0.setAmount("0.1");
refundRoyaltyParameters0.setTransIn("2088101126708402");
refundRoyaltyParameters0.setRoyaltyType("transfer");
refundRoyaltyParameters0.setTransOut("2088101126765726");
refundRoyaltyParameters0.setTransOutType("userId");
refundRoyaltyParameters0.setRoyaltyScene("达人佣金");
refundRoyaltyParameters0.setTransInType("userId");
refundRoyaltyParameters0.setTransInName("张三");
refundRoyaltyParameters0.setDesc("分账给2088101126708402");
refundRoyaltyParameters.add(refundRoyaltyParameters0);
model.setRefundRoyaltyParameters(refundRoyaltyParameters);
// 设置查询选项
List<String> queryOptions = new ArrayList<String>();
queryOptions.add("refund_detail_item_list");
model.setQueryOptions(queryOptions);
// 设置针对账期交易
model.setRelatedSettleConfirmNo("2024041122001495000530302869");
request.setBizModel(model);
// 第三方代调用模式下请设置app_auth_token
// request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
AlipayTradeRefundResponse 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);
}
}
private static AlipayConfig getAlipayConfig() {
String privateKey = "<-- 请填写您的应用私钥,例如:MIIEvQIBADANB ... ... -->";
String alipayPublicKey = "<-- 请填写您的支付宝公钥,例如:MIIBIjANBg... -->";
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId("<-- 请填写您的AppId,例如:2019091767145019 -->");
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(alipayPublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
return alipayConfig;
}
}
上述代码是支付宝沙盒样例代码可供观看,接下里我们来说具体的参数如何理解和使用
1.首先先导入支付宝依赖在pom.xml中
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.1.0</version>
</dependency>
然后上述代码是写在后端控制层可供直接调用,来具体解析:
// 初始化SDK
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
2.这一步是用来初始化SDK:即支付宝沙盒提供的信息:
AlipayClient alipayClient = new DefaultAlipayClient(
AlipayConfig.gatewayUrl, // 1️⃣ 支付宝网关地址(沙箱环境或正式环境)
"https://openapi-sandbox.dl.alipaydev.com/gateway.do";
AlipayConfig.app_id, // 2️⃣ 支付宝分配给你的应用ID
AlipayConfig.merchant_private_key,// 3️⃣ 应用私钥(用于签名请求)
"json", // 4️⃣ 数据格式,支付宝支持 "json"(一般使用JSON)
AlipayConfig.charset, // 5️⃣ 字符集编码,通常是 "utf-8"
AlipayConfig.alipay_public_key, // 6️⃣ 支付宝公钥(用于验签支付宝返回的数据)
AlipayConfig.sign_type // 7️⃣ 签名方式,推荐 "RSA2"
);
这一步的公钥,私钥都是从支付沙盒直接复制过来的,这里可以单独写一个配置类,来写这些参数(因为有一部分参数很长),然后像上述代码一样直接调用即可(或者直接在配置类里写入参数,然后再写一个上述方法,直接
@Bean注入,然后在这个调用退款的控制层直接来利用调用@Autowired)即可。
3.参数
1️⃣ 核心对象
对象 | 用途 |
---|---|
AlipayTradeRefundRequest request |
支付宝退款请求对象,封装通知 URL 和业务参数(model ) |
AlipayTradeRefundModel model |
退款业务参数模型,封装订单号、退款金额、商品明细、分账信息等 |
RefundGoodsDetail |
退款商品明细对象,可拆分商品或房型退款金额和凭证 |
OpenApiRoyaltyDetailInfoPojo |
分账信息对象,退款涉及分账时使用 |
AlipayTradeRefundResponse response |
调用接口后的响应对象,返回退款结果信息 |
2️⃣ AlipayTradeRefundModel
核心字段
字段 | 类型 | 是否必填 | 用途 | 适用场景 |
---|---|---|---|---|
outTradeNo |
String | ✅ 必填 | 商户订单号,用于标识退款订单 | 必须传,任何退款都需要 |
tradeNo |
String | ❌ 可选 | 支付宝交易号,对应支付宝系统的订单 | 可选,如果你有支付宝交易号,可以传,否则只用 outTradeNo |
refundAmount |
String | ✅ 必填 | 本次退款金额 | 必传,支持部分退款和全额退款 |
refundReason |
String | ✅ 必填 | 退款原因说明 | 必传,用户或系统生成退款原因 |
outRequestNo |
String | ✅ 部分退款必填 | 退款请求号,用于标识这次退款唯一性 | 部分退款必须传,全额退款可不传但推荐传 |
refundGoodsDetail |
List | ❌ 可选 | 商品明细列表,拆分退款金额和凭证 | 需要按房型/商品退款或返回明细时传 |
refundRoyaltyParameters |
List | ❌ 可选 | 分账信息 | 退款涉及分账时传,不分账可不传 |
queryOptions |
List | ❌ 可选 | 查询选项,控制返回哪些额外信息 | 想要返回退款明细列表或资金变化时传,如 refund_detail_item_list |
relatedSettleConfirmNo |
String | ❌ 可选 | 针对账期交易,指定结算确认单号 | 仅账期交易需要传,普通实时支付不用传 |
3️⃣ RefundGoodsDetail
核心字段
字段 | 类型 | 是否必填 | 用途 |
---|---|---|---|
outSkuId |
String | ❌ 可选 | 商家商品 SKU 编号 |
outItemId |
String | ❌ 可选 | 商家商品 ID |
goodsId |
String | ❌ 可选 | 支付宝侧商品编号 |
refundAmount |
String | ✅ 必填 | 本商品退款金额 |
outCertificateNoList |
List | ❌ 可选 | 退货凭证编号列表,用于核对退款凭证 |
💡 注意:
RefundGoodsDetail
主要是 按商品/房型拆分退款,不拆分可不传。
4️⃣ OpenApiRoyaltyDetailInfoPojo
核心字段
字段 | 类型 | 是否必填 | 用途 |
---|---|---|---|
amount |
String | ✅ 必填 | 分账金额 |
transIn |
String | ✅ 必填 | 收款方账户(支付宝账号或userId) |
transOut |
String | ✅ 必填 | 支付方账户 |
royaltyType |
String | ✅ 必填 | 分账类型,例如 transfer |
transInType |
String | ❌ 可选 | 收款方类型,例如 userId |
transOutType |
String | ❌ 可选 | 支付方类型 |
royaltyScene |
String | ❌ 可选 | 分账场景说明 |
transInName |
String | ❌ 可选 | 收款方姓名 |
desc |
String | ❌ 可选 | 分账描述 |
💡 注意:只有 涉及分账 才需要设置,否则可以不传。
5️⃣ 调用流程总结
-
构建退款模型
AlipayTradeRefundModel
,设置必填参数 + 可选参数 -
构建请求对象
AlipayTradeRefundRequest
-
可设置同步/异步通知 URL
-
-
绑定业务模型:
request.setBizModel(model)
-
调用退款接口:
AlipayTradeRefundResponse response = alipayClient.execute(request)
-
处理返回结果:
-
response.isSuccess()
→ 判断退款是否成功 -
response.getBody()
→ 获取支付宝返回的 JSON 数据
6️⃣ 调用流程
-
构建退款模型
AlipayTradeRefundModel
,设置必填参数 + 可选参数。 -
构建请求对象
AlipayTradeRefundRequest
,可设置同步/异步通知 URL。 -
绑定业务模型:
request.setBizModel(model)
。 -
调用退款接口:
AlipayTradeRefundResponse response = alipayClient.execute(request)
。 -
处理返回结果:
-
response.isSuccess()
→ 判断退款请求是否提交成功。 -
response.getBody()
→ 获取支付宝返回 JSON 数据。
-
7️⃣ 同步调用与异步回调说明
同步调用
-
立即返回接口调用结果,确认支付宝是否成功接收退款请求。
-
仅表示请求被支付宝接收,不代表资金已到账。
异步回调
-
配置退款异步通知 URL,支付宝在资金实际到账后回调。
-
用于更新系统退款状态,确认资金已退回用户账户。
-
异步回调数据包含退款状态、金额、交易号等。
-
4、最终
因为是要在项目里调用这个方法,所有你需要将上述代码理清楚后,将需要的参数封装然后传入方法进行匹配调用
更多推荐
所有评论(0)