代码改变世界

在线支付平台设计之Order.do (上)

2009-01-07 21:13  Kevin Zhou  阅读(2970)  评论(5编辑  收藏  举报

     假如在线支付平台让我们来设计,就是说我们作为bank方,我们该怎样设计系统。首先,我想很简单的是,设计的支付平台至少包含两个:

Order.do(支付功能)

Query.do(历史交易查询功能)

     这节我们只谈Order.do,下面我们开始正文;

一:Order.do工作流程

    谈到支付接口,就要先看一下,支付接口Order.do的整体工作流程

    这里我们假设bank位最终的接口(不是支付网关),可以直接进行划款。为了说明bank和支付网关的不同,这里我也将支付网关的工作流程简要的用图形描述一下:

二:参数约定

    谈到参数设计,我们一定要考虑可从重用、多用性,使得我们设计的Order.do不会因为增加商户而要去重构接口,所以在参数设计上一定要周密。

这里谈一下设计思想:

(1) 为了能够供多个商家使用接口,参数应含有partner_no

(2) 为了能够区分每一笔交易,那么应该对每笔交易有order_no

(3) 当然支付接口不可以少money

(4) 还有交易日期order_date

(5) 为了交易时数据不被篡改,应该有一个加密之后的validate_key

(6) 附加说明:partner_no + order_no + order_date 必须唯一(或者前两项唯一)

当然还有一些其他的附加参数,这里我们\设计如下:

参数 长度 参数名称 是否为空 说明
partner_no 6 商户代码 not 例如:000010
order_no 50 订单号 not 例如:0001020020090101
money 16 金额 not 例如:50
date 14 订单日期 not 例如:20090105002300
currency_type 3 币种 not 例如:RMB
lang 6 语言 not 例如:GB
return_url 255 交易成功跳转的url not 例如:http://...
signtype 6 加密类型 not 例如:MD5
signkey 50 加密串 not 例如:加密后的key

三:附加功能(Notify)

     这里我主要谈谈Notify(通知),做过接口或者支付,都应该或多或少接触过支付接口的Notify。那么什么是Notify呢?这里用图展示一下:

    从图中可以看出,商家得到客户是否支付成功,就是通过客户在bank支付成功之后,然后通过bank把支付成功后的参数加密后传递给商家,商家再进行下一步处理。那么试想一下,客户在bank端支付成功后,客户的电脑突然断电了,那么bank跳转到商家的Return路子就断了。这个时候,当然也可以处理,因为支付接口还有Query.do,商家可以根据order_no + order_date 去查询客户是否已经支付,但是这个过程还需要手工去操作,十分麻烦。

    现在我们引入Notify,简单来讲,商家先给bank一个页面A,其功能就是得到客户支付后的信息,并在成功处理后Response.write(“Y”),否则Response.write(“N”)。就是客户在bank支付成功后,

    然后,bank在web前端就response.redirect到商家的return_url,然后后台也通过httpwebrequest去Notify商家的页面A,然后得到商家的页面A的“Y”之后,整个支付过程就结束;反之则间隔某个时间(比如1Min)继续Notify,直到Notify得到“Y”或者在进行某(比如50)次都得到“N”后,也结束,因为这个过程不可能死循环下去~~。

四:安全附加

    因为我们在设计支付接口,直接和RMB打交道,又是WEB的,能上网的地方都可以看到。所以安全性必须得很高。那么我们大概看一下,至少应该有以下几个限制:

(1) SQL注入攻击防范

(2) 参数合法性(是否含有html标签)

(3) Partner_no是否存在

(4) Validate_key是否正确

(5) 其他约定的限制(比如单次充值金额最大值限制)

五:代码范例

    (1)接受参数内容

        string partnerNo = SafeRequset(Request["partner_no"]);
        //...
        //public string SafeRequset(object obj) {}  
        //SafeRequset: when obj is null return String.Empty

 

   (2)判断商户是否存在

if(true == IsLeagalPartner(partnerNo))
{
    //IsLeagalPartner : judge the partnerNo is leagal...
    //
    //进行下一步的操作
}

   (3)判断加密串是否合法

string bankPrivate = bankEncrypt(partnerNo, /*...*/);  //加密Request内容
if(String.Compare(validateKey, bankPrivate, true) == 0)
{
    //进行下一步的操作
}

   这次先谈到这里,一次看的太多,太累,也不好理解。这也是我的学习习惯!

   欢迎大家pk……