Documentation Index
Fetch the complete documentation index at: https://sdk.qfapi.com/llms.txt
Use this file to discover all available pages before exploring further.
Only transactions with the return code 0000 (transaction successful) can be refunded.
For credit card payments, QFPay performs automatic capture. If a refund is submitted on the same day, it will be treated as a void and handled by this same refund API.
API Endpoint
Endpoint : /trade/v1/refund
Method : POST
Content-Type: application/x-www-form-urlencoded
X-QF-APPCODE: <your-app-code>
X-QF-SIGN: <signature>
Request Parameters
| Parameter | Mandatory | Type | Description |
|---|
syssn | Yes | String(128) | QFPay transaction number of the original transaction to be refunded |
out_trade_no | Yes | String(128) | Unique refund transaction ID (must not repeat across refund requests) |
txamt | Yes | Int(11) | Refund amount in cents (e.g. 100 = $1). Suggest > 200 to avoid risk control. |
txdtm | Yes | String(20) | Refund request time. Format: YYYY-MM-DD hh:mm:ss |
mchid | Conditional | String(16) | Merchant ID. Required only if one is issued. |
udid | No | String(40) | Unique transaction device ID |
Response Parameters
| Parameter | Type | Description |
|---|
syssn | String(40) | New refund transaction ID |
orig_syssn | String(128) | Original transaction ID |
txamt | Int(11) | Refunded amount in cents |
sysdtm | String(20) | Refund system time (YYYY-MM-DD hh:mm:ss) |
respcd | String(4) | 0000 = success, 1143/1145 = processing, other = failed |
resperr | String(128) | Response message |
cash_fee | String | Actual amount paid by user (after discounts) |
cash_fee_type | String | Payment currency (e.g. CNY) |
cash_refund_fee | String | Actual refunded amount |
cash_refund_fee_type | String | Refund currency (e.g. CNY) |
Sample HTTP Body
txamt=10&syssn=20191227000200020061752831&out_trade_no=12345678&txdtm=2019-12-27 10:39:39&mchid=ZaMVg*****
SDK Code Examples
import urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse, hashlib
import requests
from hashids import Hashids
import datetime
import string
import random
# Enter Client Credentials
environment = 'https://test-openapi-hk.qfapi.com'
app_code = 'D5589D2A1F2E42A9A60C37**********'
client_key = '0E32A59A8B454940A2FF39**********'
# Create parameter values for data payload
current_time = datetime.datetime.now().replace(microsecond=0)
random_string = ''.join(random.choices(string.ascii_uppercase + string.digits, k=32))
# Create signature
def make_req_sign(data, key):
keys = list(data.keys())
keys.sort()
p = []
for k in keys:
v = data[k]
p.append('%s=%s'%(k,v))
unsign_str = ('&'.join(p) + key).encode("utf-8")
s = hashlib.md5(unsign_str).hexdigest()
return s.upper()
# Body payload
txamt = '10' # Partial or full refund amount
syssn = '20191227000200020061752831' # Original transaction number
out_trade_no = random_string
txdtm = current_time
key = client_key
mchid = 'ZaMVg*****'
data = {'mchid': mchid, 'txamt': txamt, 'syssn': syssn, 'out_trade_no': out_trade_no, 'txdtm': txdtm}
r = requests.post(
environment + "/trade/v1/refund",
data=data,
headers={'X-QF-APPCODE': app_code, 'X-QF-SIGN': make_req_sign(data, key)}
)
print(r.json())
Sample JSON Response
{
"orig_syssn": "20191227000200020061752831",
"sysdtm": "2019-12-27 11:11:23",
"paydtm": "2019-12-27 11:11:26",
"txdtm": "2019-12-27 11:10:38",
"udid": "qiantai2",
"txcurrcd": "EUR",
"txamt": "10",
"resperr": "success",
"respmsg": "",
"out_trade_no": "RGNOEIVU9JZLNP9GGYXWXCW7OEMI720F",
"syssn": "20191227000300020061652643",
"respcd": "0000",
"chnlsn": "2019122722001411461404119764",
"cardcd": ""
}
Notes
- Ensure refund amount does not exceed the original transaction value.
- Some wallets may not support partial refunds.
- Refund time limits vary by channel. Contact QFPay support for details.
- For failed refunds (
respcd not 0000), retry logic or query via Transaction Enquiry is advised.