关于银联支付交易状态码的一些分析

2024-08-05 10:05:22 浏览数 (3)

关于银联支付

目前B2C购物支付场景下,支付宝和微信的在线支付已经成为我们经常遇到的支付方式。另外,银联支付也是我们日常的一种支付方式,本文所指的银联支付即指中国银联网关支付产品,主要适用于持卡人在商户网站B2C购物支付场景,持卡人通过点击银联在线支付图标(可选择支付类型),并在银联在线支付网关完成支付信息录入,最终完成支付。银联在线支付支持输入卡号付款、用户登录支付、网银支付、迷你付(IC卡支付)等多种付款方式,用户通过统一入口,访问支付首页,按照提示和所列功能即可完成支付。

一些准备

做为软件开发商,实现银联在线支付,需要协助(但不必要)目标商户签署支付协议,开通商户平台。以2007版支付为例,开通过商户平台需要提交许多资料,包括企业及个人信息(如管理员用户名、名称、手机号等)备案。本文将不重点介绍如何实现在线支付,仅就支付反馈中遇到的一些问题进行分析。

在分析前,我们简单讲述一下要 POST 的一些参数和数据,参见下表:

序号

字段名

类型

说明

1

MerId

数字串

必填,为银联统一分配给商户的商户号,15位长度

2

OrdId

数字串

必填,商户提交给银联的交易订单号,16位长度,请注意生成的订单号当天支付如果不成功,则再次使用相同的订单号提交后会提示重复交易,但次日该订单号仍可以做为交易失败后的“新”订单号继续在线支付。从另一个角度来说,使用固定订单号有助于商户端更新支付状态失败造成用户的重复交易。

3

TransAmt

数字串

必填,订单交易金额,12位长度,左补0,单位为分。如 000000007890,表示七十八元九角零分,即 78.90 元。

4

CuryId

数字串

必填,订单交易币种,3位长度,固定为人民币156

5

TransDate

数字串

必填,订单交易日期,8位长度

6

TransType

数字串

必填,交易类型,4位长度,0001 表示消费,0002 表示退款

7

Version

数字串

必填,支付接入版本号,如 20070129

8

BgRetUrl

数字串

必填,后台交易接收的回调 URL,URL地址的长度不超过80个字节

9

PageRetUrl

数字串

必填,前台交易页面接收的回调 URL(显示给用户方的页面,交易情况显示详情页面),URL地址的长度不超过80个字节

10

GateId

数字串

非必填,支付网关号

11

Priv1

数字串

非必填,商户私有域,长度不超过60个字节,属于商户的备注内容

12

ChkValue

数字串

必填,256字节长的ASCII码,是本次交易的关键数字签名

以下是示例代码,提供了一个服务器 Form 和一些隐藏字段域 准备提交时使用

代码语言:javascript复制
<form id="payform" runat="server">

<input type="hidden" name="MerId" value="" id="MerId" runat="server"/>
<input type="hidden" name="OrdId" value="" id="OrdId" runat="server"/>
<input type="hidden" name="TransAmt" value="" id="TransAmt" runat="server"/>
<input type="hidden" name="CuryId" value="156" id="CuryId" runat="server"/> 
<input type="hidden" name="TransDate" value="" id="TransDate" runat="server"/>
<input type="hidden" name="TransType" value="0001" id="TransType" runat="server"/> 
<input type="hidden" name="Version" value="" id="Version" runat="server"/> 
<input type="hidden" name="BgRetUrl" value="https://x.x.com/BR.aspx" id="BgRetUrl" runat="server"/>
<input type="hidden" name="PageRetUrl" value="https://x.x.com/PR.aspx" id="PageRetUrl" runat="server"/>
<input type="hidden" name="GateId" value="" id="GateId" runat="server"/>
<input type="hidden" name="Priv1" value="" id="Priv1" runat="server"/>
<input type="hidden" name="ChkValue" value="" id="ChkValue" runat="server"/>

</form>

假设我们可以动态的设置 Form 的 Action (如测试环境或生产环境),示例代码如下:

代码语言:javascript复制
protected void b_insbtn_Click(object sender, EventArgs e)
{
    if (ViewState["RunType"].ToString() == "1")
    {
        payform.Action = "https://payment.chinapay.com/pay/TransGet";  //生产环境
        payform.Method = "post";
    }
    else if (ViewState["RunType"].ToString() == "0")
    {
        payform.Action = "http://payment-test.chinapay.com/pay/TransGet"; //测试环境
        payform.Method = "post";
    }

    //后续参数配置代码....
}

​代码中 https://payment.chinapay.com/pay/TransGet ,即为正式提交在线支付的入口页。

交易状态码的一些分析

当引导用户到银联支付页面,并完成支付操作后(包括未成功的交易),通过 PageRetUrl 和 BgRetUrl 回调地址我们会获取银联的交易状态码,状态码为4位数字,交易状态码为非 “1001” 的即为失败交易,我们要根据实际的返回保存到数据库并给予对应的提示。

详细的交易状态码见下表:

交易状态码

说明

交易状态码

说明

1001

消费交易成功

2063

违反安全保密规定

1003

退款交易成功

2064

原始金额不正确

1005

退款撤销成功

2065

超出取款次数限制

1111

未支付

2066

受卡方呼受理方安全保密部门

2000

银行无应答

2067

捕捉

2001

查发卡放

2068

收到的回答太迟

2002

查发卡放特殊条件

2075

允许输入PIN的次数超限

2003

无效商户

2090

日期切换正在处理

2004

没收卡

2091

发卡方与交换中心不能操作

2005

不予承兑

2092

金融机构或中间网络设施找不到或无法到达

2006

出错

2093

交易违法、不能完成

2007

特殊条件下没收卡

2094

重复交易

2009

请求正在处理中

2095

调节控制错

2010

卡bin未参与CPUSecure服务

2096

系统异常、失效

2012

无效交易

2097

ATMPOS终端找不到

2013

无效金额

2098

交换中心收不到收卡方应答

2014

无效卡号

2099

PIN格式错误

2015

无此发卡方

20A0

MAC鉴别失败

2019

重新送入交易

2101

网关出错

2020

无效应答

2102

密码加密出错

2021

不作任何处理

2111

消息时间太新,请调整浏览器时间与实际时间一致

2022

怀疑操作有误

2112

消息时间太旧,请调整浏览器时间与实际时间一致

2023

不可接受的交易费

2113

信息不符

2030

格式错误

2114

商户号验证出错

2031

交换中心不支持的银行

2115

商户信息格式出错

2033

过期的卡

2116

撤销交易信息出错

2034

有作弊嫌疑

2117

查新个数为零

2035

受卡方与安全保密部门联系

2118

查询个数大于100

2036

受限制的卡

2141

系统出错

2037

受卡方呼受理方安全部门

2142

撤销交易出错

2038

超过允许的PIN试输入

2143

撤销交易已处理

2039

无此信用卡账户

2144

交易已被冲正

2040

请求的功能不支持

2145

撤销交易出错

2041

挂失卡

2146

交换中心无应答

2042

无此账户

2147

网管未收到该交易

2043

被窃卡

2148

重复交易

2044

无此投资账户

2150

通讯线路故障

2051

无足够的存款

2157

不允许持卡人进行交易

2052

无此支票账户

2158

该银行卡网上支付功能因系统升级而暂停

2053

无此储蓄卡账户

2199

系统出错

2054

过期的卡

2257

基于风险控制阻止的交易

2055

不正确的PIN

2997

交易提交银行错误

2056

无此卡记录

4001

HSBC交易中止

2057

不允许持卡人进行的交易

4055

HSBC安全认证错误

2058

不允许此终端进行的交易

4097

HSBC交易无应答

2059

有作弊嫌疑

5501

工行网关无应答

2060

受卡方与安全保密部门联系

5511

工行网关处理失败

2061

超出取款金额限制

5522

工行网关未收到后台应答

2062

受限制的卡

交易状态码

说明

交易状态码

说明

8001

HSBC交易失败

9000

电话支付订单已成功发给银行

8002

HSBC交易失败

9001

电话支付订单发送银行失败(订单电话域非法)

8003

HSBC交易失败

9002

电话支付订单发送银行失败(秘密数域非法)

8004

HSBC交易失败

9003

电话支付订单发送银行失败(商户扩展域非法)

8005

HSBC交易失败

9004

电话支付订单发送银行失败(CP保留域非法)

8006

HSBC交易失败

9100

电话支付订单撤销成功

8007

HSBC交易失败

9101

电话支付订单撤销失败(订单号不匹配)

8008

HSBC交易失败

9102

电话支付订单撤销失败(金额不匹配)

8009

HSBC交易失败

9103

电话支付订单撤销失败(交易日期不对)

在银联支付20070129版本的实际应用中,回调获取的交易状态码基本正常,但出现了一些问题就是在回调获取成功交易状态码 “1001” 后,银联继续推送了一些状态码回调,因此在开发中需要进行判断 ,一味的接收并更新状态码,可能无法达到预期的效果,尤其当状态码已经为“1001”的情况下。在实际应用中,除正常状态码反馈,我们遇到了 “2006” 和 “2148” 错误。

从 “2148” 错误可以理解,是用户的重复交易(包括当日和隔日重复交易),因此我们需要在更新数据库前对两次交易码进行比对,如果之前为 “1001” 的可以无视 “2148” 的存在。

另外我们遇到的是 “2006” 错误,从代码表中仅查询出说明为 “出错” ,这个问题我们曾致电银联客服求解,未得到任何有效答案,包括可能出现的情况。关键是,状态码会在获得“1001” 后不定期的时间内(非正常回调周期)推送到回调地址,这就比较难以判断真实发生的情况。

因此对于非“1001”的特殊情况,建立日志表跟踪非常关键,目前来看,对于“2006”的拦截很有必要,实际应用中错误更新的情况明显减少。

小结

更多的详情请参考如下链接(中国银联开放平台):

https://open.unionpay.com/tjweb/index

在实际与银联客服的沟通中,我们尽量使用官方提供的联系邮件进行沟通,这样效率可以高一些。也便于留档查询,而且如果修改资料(包括更换联系人、修改企业信息等)手续比较繁琐,不是太友好,需要一定的时间,因此在应用上线功能时需要做好准备工作。

以上是本人的一些体会与实践,仅代表个人的一些观点,再次感谢您的阅读,欢迎讨论、指教!

1 人点赞