0
# Refund Management
1
2
Comprehensive refund processing with support for full and partial refunds, refund querying, and notification handling for both API versions.
3
4
## Capabilities
5
6
### Create Refund (API v2)
7
8
Process refunds using WeChat Pay API v2 with XML-based communication.
9
10
```java { .api }
11
/**
12
* Create a refund using WeChat Pay API v2
13
* @param request Refund request with transaction and refund details
14
* @return Refund result with refund ID and status
15
* @throws WxPayException if refund processing fails
16
*/
17
WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException;
18
19
/**
20
* Create a refund using WeChat Pay API v2 (alternative method)
21
* @param request Refund request with transaction and refund details
22
* @return Refund result with refund ID and status
23
* @throws WxPayException if refund processing fails
24
*/
25
WxPayRefundResult refundV2(WxPayRefundRequest request) throws WxPayException;
26
```
27
28
**Usage Example:**
29
30
```java
31
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
32
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
33
34
// Create refund request
35
WxPayRefundRequest refundRequest = WxPayRefundRequest.newBuilder()
36
.transactionId("1234567890123456789") // WeChat transaction ID
37
.outRefundNo("REFUND_20230101_001") // Merchant refund number
38
.totalFee(100) // Original payment amount in cents
39
.refundFee(50) // Refund amount in cents (partial refund)
40
.refundDesc("Product defect") // Refund reason
41
.notifyUrl("https://your-domain.com/refund/notify")
42
.build();
43
44
// Alternatively, use merchant order number instead of transaction ID
45
WxPayRefundRequest refundRequest2 = WxPayRefundRequest.newBuilder()
46
.outTradeNo("ORDER_20230101_001") // Merchant order number
47
.outRefundNo("REFUND_20230101_002")
48
.totalFee(100)
49
.refundFee(100) // Full refund
50
.refundDesc("Customer cancellation")
51
.build();
52
53
// Process refund
54
WxPayRefundResult result = wxPayService.refund(refundRequest);
55
56
if ("SUCCESS".equals(result.getResultCode())) {
57
System.out.println("Refund successful");
58
System.out.println("Refund ID: " + result.getRefundId());
59
System.out.println("Refund Fee: " + result.getRefundFee());
60
}
61
```
62
63
### Create Refund (API v3)
64
65
Process refunds using WeChat Pay API v3 with JSON-based communication and enhanced security.
66
67
```java { .api }
68
/**
69
* Create a refund using WeChat Pay API v3
70
* @param request V3 refund request with transaction and refund details
71
* @return V3 refund result with detailed refund information
72
* @throws WxPayException if refund processing fails
73
*/
74
WxPayRefundV3Result refundV3(WxPayRefundV3Request request) throws WxPayException;
75
```
76
77
**Usage Example:**
78
79
```java
80
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
81
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
82
83
// Create V3 refund request
84
WxPayRefundV3Request refundRequest = new WxPayRefundV3Request();
85
refundRequest.setOutRefundNo("REFUND_20230101_003");
86
refundRequest.setReason("Quality issue");
87
refundRequest.setNotifyUrl("https://your-domain.com/refund/notify/v3");
88
89
// Set amount details
90
WxPayRefundV3Request.Amount amount = new WxPayRefundV3Request.Amount();
91
amount.setRefund(50); // Refund amount in cents
92
amount.setTotal(100); // Original payment amount in cents
93
amount.setCurrency("CNY");
94
refundRequest.setAmount(amount);
95
96
// Set transaction reference (use either transactionId or outTradeNo)
97
refundRequest.setTransactionId("1234567890123456789");
98
// OR
99
// refundRequest.setOutTradeNo("ORDER_20230101_001");
100
101
// Process V3 refund
102
WxPayRefundV3Result result = wxPayService.refundV3(refundRequest);
103
104
System.out.println("Refund ID: " + result.getRefundId());
105
System.out.println("Status: " + result.getStatus());
106
System.out.println("Success Time: " + result.getSuccessTime());
107
```
108
109
### Query Refund Status (API v2)
110
111
Query refund status and details using various identifiers.
112
113
```java { .api }
114
/**
115
* Query refund status using transaction or refund identifiers
116
* @param transactionId WeChat transaction ID (optional)
117
* @param outTradeNo Merchant order number (optional)
118
* @param outRefundNo Merchant refund number (optional)
119
* @param refundId WeChat refund ID (optional)
120
* @return Refund query result with status and details
121
* @throws WxPayException if query fails
122
*/
123
WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo,
124
String outRefundNo, String refundId) throws WxPayException;
125
126
/**
127
* Query refund status using request object
128
* @param request Refund query request
129
* @return Refund query result with status and details
130
* @throws WxPayException if query fails
131
*/
132
WxPayRefundQueryResult refundQuery(WxPayRefundQueryRequest request) throws WxPayException;
133
134
/**
135
* Query refund status using WeChat Pay API v2 (alternative method)
136
* @param request Refund query request
137
* @return Refund query result with status and details
138
* @throws WxPayException if query fails
139
*/
140
WxPayRefundQueryResult refundQueryV2(WxPayRefundQueryRequest request) throws WxPayException;
141
```
142
143
**Usage Example:**
144
145
```java
146
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
147
148
// Query refund by merchant refund number
149
WxPayRefundQueryResult result = wxPayService.refundQuery(
150
null, null, "REFUND_20230101_001", null);
151
152
// Check refund status
153
System.out.println("Refund Status: " + result.getRefundStatus());
154
System.out.println("Refund Count: " + result.getRefundCount());
155
156
// Process each refund in the result
157
for (int i = 0; i < result.getRefundCount(); i++) {
158
System.out.println("Refund " + i + ":");
159
System.out.println(" Refund ID: " + result.getRefundId(i));
160
System.out.println(" Refund Fee: " + result.getRefundFee(i));
161
System.out.println(" Status: " + result.getRefundStatus(i));
162
System.out.println(" Success Time: " + result.getRefundSuccessTime(i));
163
}
164
```
165
166
### Query Refund Status (API v3)
167
168
Query refund status using WeChat Pay API v3.
169
170
```java { .api }
171
/**
172
* Query refund status using merchant refund number (API v3)
173
* @param outRefundNo Merchant refund number
174
* @return V3 refund query result with detailed information
175
* @throws WxPayException if query fails
176
*/
177
WxPayRefundQueryV3Result refundQueryV3(String outRefundNo) throws WxPayException;
178
179
/**
180
* Query refund status using request object (API v3)
181
* @param request V3 refund query request
182
* @return V3 refund query result with detailed information
183
* @throws WxPayException if query fails
184
*/
185
WxPayRefundQueryV3Result refundQueryV3(WxPayRefundQueryV3Request request) throws WxPayException;
186
187
/**
188
* Query partner refund status (API v3)
189
* @param request Partner refund query request
190
* @return V3 refund query result with detailed information
191
* @throws WxPayException if query fails
192
*/
193
WxPayRefundQueryV3Result refundPartnerQueryV3(WxPayRefundQueryV3Request request) throws WxPayException;
194
```
195
196
**Usage Example:**
197
198
```java
199
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryV3Result;
200
201
// Query V3 refund by merchant refund number
202
WxPayRefundQueryV3Result result = wxPayService.refundQueryV3("REFUND_20230101_003");
203
204
System.out.println("Refund ID: " + result.getRefundId());
205
System.out.println("Status: " + result.getStatus());
206
System.out.println("Create Time: " + result.getCreateTime());
207
System.out.println("Success Time: " + result.getSuccessTime());
208
209
// Check amount details
210
WxPayRefundQueryV3Result.Amount amount = result.getAmount();
211
System.out.println("Refund Amount: " + amount.getRefund());
212
System.out.println("Total Amount: " + amount.getTotal());
213
```
214
215
## Request Types
216
217
### WxPayRefundRequest (API v2)
218
219
```java { .api }
220
class WxPayRefundRequest extends BaseWxPayRequest {
221
// Transaction reference (provide one)
222
String transactionId; // WeChat transaction ID
223
String outTradeNo; // Merchant order number
224
225
// Required fields
226
String outRefundNo; // Merchant refund number (unique)
227
Integer totalFee; // Original payment amount in cents
228
Integer refundFee; // Refund amount in cents
229
230
// Optional fields
231
String refundFeeType; // Refund currency (default: CNY)
232
String refundDesc; // Refund reason/description
233
String refundAccount; // Refund account source
234
String notifyUrl; // Refund notification URL
235
236
// Builder pattern
237
static WxPayRefundRequestBuilder newBuilder();
238
}
239
```
240
241
### WxPayRefundV3Request (API v3)
242
243
```java { .api }
244
class WxPayRefundV3Request {
245
// Transaction reference (provide one)
246
String transactionId; // WeChat transaction ID
247
String outTradeNo; // Merchant order number
248
249
// Required fields
250
String outRefundNo; // Merchant refund number (unique)
251
String reason; // Refund reason
252
Amount amount; // Amount details
253
String notifyUrl; // Refund notification URL
254
255
// Amount details
256
static class Amount {
257
Integer refund; // Refund amount in cents
258
Integer total; // Original payment amount in cents
259
String currency; // Currency code (CNY)
260
}
261
}
262
```
263
264
### WxPayRefundQueryRequest
265
266
```java { .api }
267
class WxPayRefundQueryRequest extends BaseWxPayRequest {
268
// Search criteria (provide at least one)
269
String transactionId; // WeChat transaction ID
270
String outTradeNo; // Merchant order number
271
String outRefundNo; // Merchant refund number
272
String refundId; // WeChat refund ID
273
Integer offset; // Query offset (for pagination)
274
}
275
```
276
277
## Result Types
278
279
### WxPayRefundResult (API v2)
280
281
```java { .api }
282
class WxPayRefundResult extends BaseWxPayResult {
283
String transactionId; // WeChat transaction ID
284
String outTradeNo; // Merchant order number
285
String outRefundNo; // Merchant refund number
286
String refundId; // WeChat refund ID
287
Integer refundFee; // Refund amount in cents
288
Integer settlementRefundFee; // Settlement refund amount
289
Integer totalFee; // Original payment amount in cents
290
Integer settlementTotalFee; // Settlement total amount
291
String feeType; // Currency type
292
Integer cashFee; // Cash payment amount
293
String cashFeeType; // Cash currency type
294
Integer cashRefundFee; // Cash refund amount
295
Integer couponRefundFee; // Coupon refund amount
296
Integer couponRefundCount; // Coupon refund count
297
}
298
```
299
300
### WxPayRefundV3Result (API v3)
301
302
```java { .api }
303
class WxPayRefundV3Result {
304
String refundId; // WeChat refund ID
305
String outRefundNo; // Merchant refund number
306
String transactionId; // WeChat transaction ID
307
String outTradeNo; // Merchant order number
308
String channel; // Refund channel
309
String userReceivedAccount; // User refund account
310
String status; // Refund status
311
String createTime; // Refund creation time
312
String successTime; // Refund success time
313
Amount amount; // Amount details
314
315
static class Amount {
316
Integer total; // Original payment amount
317
Integer refund; // Refund amount
318
Integer payerTotal; // Payer amount
319
Integer payerRefund; // Payer refund amount
320
Integer settlementRefund; // Settlement refund amount
321
Integer settlementTotal; // Settlement total amount
322
Integer discountRefund; // Discount refund amount
323
String currency; // Currency code
324
}
325
}
326
```
327
328
### WxPayRefundQueryResult (API v2)
329
330
```java { .api }
331
class WxPayRefundQueryResult extends BaseWxPayResult {
332
String transactionId; // WeChat transaction ID
333
String outTradeNo; // Merchant order number
334
Integer totalFee; // Original payment amount
335
Integer settlementTotalFee; // Settlement total amount
336
String feeType; // Currency type
337
Integer cashFee; // Cash payment amount
338
Integer refundCount; // Number of refunds
339
340
// Methods to access refund details by index
341
String getOutRefundNo(int index);
342
String getRefundId(int index);
343
String getRefundChannel(int index);
344
Integer getRefundFee(int index);
345
Integer getSettlementRefundFee(int index);
346
Integer getCouponRefundFee(int index);
347
Integer getCouponRefundCount(int index);
348
String getRefundStatus(int index);
349
String getRefundAccount(int index);
350
String getRefundRecvAccount(int index);
351
String getRefundSuccessTime(int index);
352
}
353
```
354
355
## Refund Status Values
356
357
### API v2 Status Values
358
- **SUCCESS**: Refund successful
359
- **REFUNDCLOSE**: Refund closed
360
- **PROCESSING**: Refund processing
361
- **CHANGE**: Refund abnormal
362
363
### API v3 Status Values
364
- **SUCCESS**: Refund successful
365
- **CLOSED**: Refund closed
366
- **PROCESSING**: Refund processing
367
- **ABNORMAL**: Refund abnormal
368
369
## Important Notes
370
371
### Certificate Requirements
372
Refund operations require merchant certificates for authentication:
373
- **API v2**: Requires .p12 certificate file configured in `WxPayConfig.setKeyPath()`
374
- **API v3**: Requires private key and certificate serial number
375
376
### Refund Limitations
377
- Partial refunds are supported (refund amount can be less than total payment)
378
- Multiple partial refunds are allowed for the same order
379
- Refund amount cannot exceed the original payment amount
380
- Refunds typically process within 1-7 business days depending on the original payment method
381
382
### Notification Handling
383
Configure notification URLs to receive refund status updates:
384
- **API v2**: XML-based notifications
385
- **API v3**: JSON-based notifications with enhanced security
386
387
### Error Handling
388
Common refund errors include:
389
- **ORDERNOTEXIST**: Original order not found
390
- **NOTENOUGH**: Insufficient refundable amount
391
- **FREQ_LIMIT**: Refund frequency limit exceeded