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

举报
初九之潜龙勿用 发表于 2024/12/05 14:41:29 2024/12/05
【摘要】 在银联支付20070129版本的实际应用中,回调获取的交易状态码基本正常,但出现了一些问题就是在回调获取成功交易状态码 “1001” 后,银联继续推送了一些状态码回调,因此在开发中需要进行判断 ,一味的接收并更新状态码,可能无法达到预期的效果

关于银联支付

目前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 和一些隐藏字段域 准备提交时使用

<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 (如测试环境或生产环境),示例代码如下:

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 ATM\POS终端找不到
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

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

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







【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。