一、概述
本文介绍浦发银行支付的请求退款和查询退款结果两个接口,浦发银行的退款流水号是以5901开头。发起退款的时候,浦发银行返回浦发银行退款流水号给我们(这里的我们是指对接浦发银行支付的一方,于浦发银行而言,就是商户);我们在查询退款结果的时候,依据便是浦发银行退款流水号。
接口调用的先后顺序如下:
下面将详细介绍这两个接口的调用以及报文示例:
二、请求退款接口
退款接口是同步的,和微信退款不同,后者还需要额外对接退款回调逻辑。
- 接口名称:对公收款支付退货
- 接口URI:/api/corporateAccounts/payments/ordersReturn
- 请求方式:POST
- 必填的请求参数:
因为接口的入参数量比较多,就不一一贴出,而实际上发起退款,核心就是支付流水号和退款金额。
- frmrMrchOrdrNo:浦发银行支付流水号。在支付下单的时候返回,并保存至支付订单。
- bussLstNo:商户支付流水号。由支付系统生成的唯一单号。
- 返回参数
响应报文的参数数量多得吓人,其实我们也只需要两个值(tranOrdrNo和tranDate)。对于响应报文中的transNo(交易流水号),但是程序用不上,注意别混淆了二者。
- tranOrdrNo:浦发银行退款流水号
报文示例
- 请求报文
{
"mrchId": "310319982990001",
"bussLstNo": "062404171015030170B15",
"mrchOrdrNo": "R062B40417105220017504",
"mrchTm": "20240417105220",
"tranAmt": "0.01",
"frmrMrchOrdrNo": "1901041710141000674832060267",
"origTranDate": "20240417"
}
- 响应报文
同查询支付结果的返回报文一样,也不会返回平台退款流水号。
重要字段:{
“statusCode”: “0000”,
# 浦发银行退款流水号
“tranOrdrNo”: “5901041710511111585791059835”,
# 浦发银行交易日期
“tranDate”: “20240417”,
“tranAmt”: “0.01”,
“ordrSt”: “00”
}
{
"statusCode": "0000",
"transNo": "04972404176851052204509115",
"retGdsAmt": "",
"totalAmt": "",
"ordrAmt": "",
"transAmt": "0.01",
"cashRfndAmt": "",
"rfdAmt": "",
"vcherNum": "",
"byrOfAlipayAcctNO": "",
"fndChngFlg": "",
"wthdrwnUsAmtCnl": "",
"mrchStrNm": "",
"userId": "",
"ccy": "",
"mrchOrigOrdrNo": "",
"tranOrdrNo": "5901041710511111585791059835",
"tranDate": "20240417",
"tranAmt": "0.01",
"mrchId": "310319982990001",
"mrchOrdrNo": "062404171015030170B15",
"clrgDate": "",
"ordrSt": "00",
"dcnRfdDtl": "",
"rfndAcceptTime": "",
"thdPltfrmTm": "",
"byrRfndAmnt": "",
"dscntRfndAmnt": "",
"mdsctRfndAmnt": "",
"actRfndAmt": "",
"bussRetCd": "",
"returnInfo": "",
"bussRetInfo": "退货交易成功",
"errCode": "",
"errInfo": "",
"trdChnl": "",
"bussBranchId": "",
"tranTellerNo": "",
"rsrvFld1": "",
"rsrvFld2": "",
"rsrvFld3": "",
"rsrvFld4": "",
"rsrvFld5": "",
"rsrvFld6": "",
"rsrvFld7": "",
"remark": "",
"corpRcvPyRetInfo": [
]
}
三、查询退款结果
- 接口名称:对公收款交易查证
- 接口URI:/api/corporateAccounts/payments/status
- 请求方式:GET
请求参数
交易日期tranDate作为必填字段,无疑是画蛇添足了。本来支付服务只需要保存浦发银行退款流水号即可,现在可好,还需要额外保存它。
那你可不可以不保存它,采用平台退款订单的创建时间代替它呢?
这里会存在创建退款的时间和交易日期不在同一天,也即跨天的可能。
- tranOrdrNo:必填,浦发银行退款流水号,在请求退款接口中返回。
- mrchOrdrNo:非必填,平台退款流水号。既然是非必填,浦发银行方对该字段不作要求,更说明它是以浦发银行退款流水号为依据。
对tranDate字段的处理
- 1、请求退款,接口返回的tranDate,保存至退款订单中的refundOkDate。(refundOkDate原本是实际退款成功的时间。特别是像微信退款,发起退款的时候,refundOkDate还是空;待退款回调处理时,更新refundOkDate为实际退款时间)
这里会有个问题,实际退款的时间只能精确到年月日,不知道具体的时分秒。(可以从退款订单的创建时间大概推断出退款日期的时分秒) - 2、在查询退款结果的时候,查询退款订单中的refundOkDate;(如果它为空,意味着请求退款的时候出错,则取退款订单的创建时间)该接口会返回实际退款时间,而我们说了,请求退款接口是同步的,却未返回实际退款时间,只返回了交易日期yyyyMMdd。
- 3、处理退款订单,更新退款订单中的实际退款时间refundOkDate。
报文示例
- 请求报文
{
"mrchId": "310319982990001",
# 平台退款流水号
"mrchOrdrNo": "R062B40417105220017504",
# 浦发银行退款流水号
"tranOrdrNo": "5901041710511111585791059835",
# 浦发银行交易日期
"tranDate": "20240417"
}
- 响应报文
重要字段:{
“statusCode”: “0000”,
# 浦发银行退款流水号
“frmrMrchOrdrNo”: “5901041710511111585791059835”,
# 实际退款时间
“tranTimep”: “20240417105111”,
“tranAmt”: “0.01”,
“ordrSt”: “00”
}
{
"statusCode": "0000",
"transNo": "04972404176851201434413175",
"usrFlgId": "",
"isSbscrbFlg": "",
"usrChildFlg": "",
"isFlag": "",
"transAmt": "",
"busnPckt": "",
"clueDtl": "",
"totalAmt": "",
"ordrAmt": "",
"wthdrwnUsAmtCnl": "",
"retGdsAmt": "",
"rfdAmt": "",
"vcherNum": "",
"fundSource": "",
"inAcctName": "",
"rfndRlst": "",
"byrOfAlipayAcctNO": "",
"actRcvAmt": "",
"byrPayAmt": "",
"usPntsPayAmt": "",
"toUsEstbInvAmt": "",
"clientID": "",
"inrChlCnlNo": "",
"mrchStrNm": "",
"userId": "",
"addItInNal": "",
"infoDsc": "",
"fldData": "",
"bussRetCd": "",
"returnInfo": "",
"trdMerMechNo": "",
"weChatSubMechNo": "",
"errCode1": "",
"errInfo": "",
"terminalNo": "",
"tranType": "",
"ordrSt": "00",
"pyBnkInfo": "",
"cmdtyInfo": "",
"tranAmt": "0.01",
"ccy": "",
"thdPltfrmTm": "",
"thdPtySeq": "",
"tranOrdrNo": "",
"tranDate": "20240417",
"clrgDate": "",
"tranTimep": "20240417105111",
"mrchTm": "",
"bussLstNo": "",
"frmrMrchDate": "",
"frmrMrchOrdrNo": "5901041710511111585791059835",
"orgClrgDt": "",
"tranCode": "OORF",
"mrchId": "310319982990001",
"openBrNo": "",
"instId": "",
"mrchDvlpmBnkNo": "",
"mrchDvlpmBnkBrId": "",
"strNo": "",
"cshrNo": "",
"mrchlInfmAdr": "",
"channelNo": "",
"hvWthdrwnAmt": "0.00",
"rfndblAmt": "0.01",
"hvThdChrgAmt": "",
"reserveAmt": "",
"chrgAmt": "",
"charges": "",
"prjPrdTp": "",
"ordrPcsSt": "",
"trdRtCd": "00",
"feeRtId": "",
"cmdtyDsc": "",
"crdType": "",
"bussTrm": "",
"thdPtyObjNo": "",
"remark1": "",
"remark2": "11",
"dcnRfdDtl": "",
"crtTm": "",
"cashRfndAmt": "",
"pblcAcctId": "",
"bussRetInfo": "",
"trdStInfo": "",
"bussStatusDsc": "",
"weRfndStatus": "",
"aLTrnCrc": "",
"pymtMd": "",
"dscntAmnt": "",
"mdsctAmnt": "",
"byUserType": "",
"acceptEndTime": "",
"pftSt": "",
"errCode2": "",
"byrRfndAmnt": "",
"dscntRfndAmnt": "",
"mdsctRfndAmnt": "",
"trdChnl": "",
"rsrvFld1": "",
"rsrvFld2": "",
"rsrvFld3": "",
"rsrvFld4": "",
"rsrvFld5": "",
"rsrvFld6": "",
"rsrvFld7": "",
"remark3": "",
"tranVrfyInfo": [
]
}
退款账单
点击“查看退款详情”,可以看到浦发银行的支付流水号:
对于微信来说, 它的商户就是浦发银行,上面4200开头的交易单号是微信的支付流水号,下面1901开头的商户单号是浦发银行的支付流水号。
这里不会展示我们平台的支付流水号。(这是一个涉及三方的交互流程)
我们和浦发银行对账, 然后浦发银行和微信对账;前者的对账依据是1901开头的支付流水号,后者的对账依据是4200开头的支付流水号。
四、总结
当请求退款的时候,当返回报文是"errCode":“CBAS003”,“errInfo”:“无效交易”,可能浦发银行支付流水号存在,或者已全部退款(没有可退金额)。
所以,程序在解析响应报文的时候,先判断"statusCode"是否等于"0000",进一步判断errCode是否为空,报错提示信息包括errCode和errInfo。
奇怪的是,查询退款结果接口,却没有errCode,取而代之的是errCode1和errCode2,但是errInfo只有一个。
针对这个接口,我们改为判断errInfo是否为空。