目录
关于银联支付
目前B2C购物支付场景下,支付宝和微信的在线支付已经成为我们经常遇到的支付方式。另外,银联支付也是我们日常的一种支付方式,本文所指的银联支付即指中国银联网关支付产品,主要适用于持卡人在商户网站B2C购物支付场景,持卡人通过点击银联在线支付图标(可选择支付类型),并在银联在线支付网关完成支付信息录入,最终完成支付。银联在线支付支持输入卡号付款、用户登录支付、网银支付、迷你付(IC卡支付)等多种付款方式,用户通过统一入口,访问支付首页,按照提示和所列功能即可完成支付。
一些准备
做为软件开发商,实现银联在线支付,需要协助(但不必要)目标商户签署支付协议,开通商户平台。以2007版支付为例,开通过商户平台需要提交许多资料,包括企业及个人信息(如管理员用户名、名称、手机号等)备案。本文将不重点介绍如何实现在线支付,仅就支付反馈中遇到的一些问题进行分析。
在分析前,我们简单讲述一下要 POST 的一些参数和数据,参见下表:
以下是示例代码,提供了一个服务器 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” 的即为失败交易,我们要根据实际的返回保存到数据库并给予对应的提示。
详细的交易状态码见下表:
在银联支付20070129版本的实际应用中,回调获取的交易状态码基本正常,但出现了一些问题就是在回调获取成功交易状态码 “1001” 后,银联继续推送了一些状态码回调,因此在开发中需要进行判断 ,一味的接收并更新状态码,可能无法达到预期的效果,尤其当状态码已经为“1001”的情况下。在实际应用中,除正常状态码反馈,我们遇到了 “2006” 和 “2148” 错误。
从 “2148” 错误可以理解,是用户的重复交易(包括当日和隔日重复交易),因此我们需要在更新数据库前对两次交易码进行比对,如果之前为 “1001” 的可以无视 “2148” 的存在。
另外我们遇到的是 “2006” 错误,从代码表中仅查询出说明为 “出错” ,这个问题我们曾致电银联客服求解,未得到任何有效答案,包括可能出现的情况。关键是,状态码会在获得“1001” 后不定期的时间内(非正常回调周期)推送到回调地址,这就比较难以判断真实发生的情况。
因此对于非“1001”的特殊情况,建立日志表跟踪非常关键,目前来看,对于“2006”的拦截很有必要,实际应用中错误更新的情况明显减少。
小结
更多的详情请参考如下链接(中国银联开放平台):
https://open.unionpay.com/tjweb/index
在实际与银联客服的沟通中,我们尽量使用官方提供的联系邮件进行沟通,这样效率可以高一些。也便于留档查询,而且如果修改资料(包括更换联系人、修改企业信息等)手续比较繁琐,不是太友好,需要一定的时间,因此在应用上线功能时需要做好准备工作。
以上是本人的一些体会与实践,仅代表个人的一些观点,再次感谢您的阅读,欢迎讨论、指教!