代码改变世界

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

  Kevin Zhou  阅读(2989)  评论(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……

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示