一、概述
本文介绍浦发银行支付的请求退款和查询退款结果两个接口,浦发银行的退款流水号是以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是否为空。