购物车与商城订单的关系以及技术实现深入分析

来源:互联网 发布:詹姆斯生涯场均数据 编辑:程序博客网 时间:2024/06/08 20:31

接触商城开发已经有一段时间了,我们从B2C拼团项目做到了C2C视频电商系统。虽然项目都还不算成功,但还是积累了些业务经验,希望可以对大家有用。其实商城最主要的还是订单相关逻辑,例如购物车,下单,改价等。当然,电商还有一些比较麻烦的一些业务,例如sku,运费的合理计算,这不属于我们讨论的范围,今天我们主要分析购物车,商城,以及订单这三者的关系,以及相关数据库设计与伪代码实现。

- 透过现象看本质

首先我们从商城入手,来看看各家的购物车与订单的界面。

1、七乐康(比较传统的B2C医药电商网站)

             (1)购物车

           

             (2)生成订单

               

       

2、微店(微商的开店好帮手,C2C商城)

           (1)购物车

            

          (2)生成订单

            

3、有赞(移动零售服务商,C2C商城)

        (1)购物车

                    

        (2)生成订单

          

    

- 购物车与商城以及订单的关系

从一般的商城来看,可以分为B2C与C2C,也就是单商城系统和多商城系统。单商城的系统,基本上就是全部商品生成一个订单,而多商城系统里面的购物车则是可以根据店铺来分别支付生成订单(如微店)或者全部统一支付然后根据店铺拆分订单(如有赞,淘宝等)。

      总结如下:

          

      如上图所示:

     (1)根据每个店铺生成订单去支付,很好理解,例如我在店铺A,买了1,2,3这几个商品,我只需要生成一个订单号,然后去支付就可以了,后续的退款等各种处理,只需要根据该订单号进行处理即可。

     (2) 那么,最后一个,购物车里面有多个店铺的商品,又需要一起支付的时候怎么办呢?假定我们使用微信支付,微信支付每次下单只能使用唯一一个单号,那么我们只能把不同的店铺,例如店铺A和店铺B的所有商品,都统一放到一个订单号去微信下单支付。但是,这样子又违反了订单规则:不同的店铺存在着不同的订单业务,店铺和订单是一对多的关系,而且每个订单号必须是唯一的。怎么办?这个时候,我们可以把内部订单号和微信下单号做一个映射(也就是图所说的拆单),后续做各种处理例如退款等,就可以通过映射关系去进行处理,如下图:

      

      总结一下他们之间的关系:

      (1)购物车可以存在多个店铺多个商品,可以一次性给钱购买购物车所有商品

      (2)一个订单只能对应一个店铺,一个店铺可以拥有多个订单

      (3)微信下单号只有一个,一个微信下单号可以对应多个内部订单号,一个内部订单号只能对应一个微信下单号。


- C2C商城购物车数据库设计与技术实现

 由于B2C商城和C2C大同小异,这里暂且不讨论B2C的设计和实现,相信会C2C实现而不会B2C的同学是不存在的。且纵观目前的商城,大部分慢慢倾向于增加商家入住功能,所以建议预留多商铺功能,即先把商铺表加进去,与商品相关的带上商铺id,只不过目前商铺只有一个就是自己,就这样可以减少业务需求改动带来的大量数据库结构和代码的改动。

如果用户购物车内的商品都是一个店铺的,那么就不存在拆单、映射表这种说法,直接生成唯一订单号作为微信订单号支付就可以,但是谁都不知道需求是如何变化的,既然淘宝都是可以统一支付不同店铺的商品,那么设计的时候最好是支持购物车所有商品统一支付的,这样子就通杀了,不管你是B2C的购物车,还是微店的购物车,还是淘宝的购物车,都能满足需求。如果只能支持不同店铺做分别支付,类似微店这样,那么万一产品要改成支付宝这样子,就又得重新设计映射表,进行拆单了。本人所在公司的产品经理刚开始比较倾向于微店这种产品设计,而我设计系统时,也仅仅往产品的需求思考,而没考虑到淘宝的设计,现在换一个产品又要改为淘宝这种购物车,就感觉深深地掉进了坑里面。这里学到了一个道理,那就是永远不要相信产品经理(哭),当然也不要过度设计,这里其实不是过度设计,只是用多一点时间,就能减少以后的巨大时间,而且产品人员也很喜欢参考大公司的产品功能,毕竟一些基础功能都是经过大量的用户反馈的。

那么我们就以有赞这种做法来设计我们的购物车和订单吧。

      1、订单表

          

     2、购物车表

          

      最主要的是:商铺订单号in_trade_no和第三方支付下单号out_trade_no


- 下单核心实现(非完整代码)

       

一》购物车提交过来的下单最终是以不同店铺组成的数组
  如:             

 $data = arrray(           '店铺A' => array('商品1''商品2'),           '店铺B' => array('商品1''商品2'),);
二》只有一个数组时,让商铺订单号in_trade_no和第三方支付下单号out_trade_no一致,这样子的好处是,我们可以认为订单号和下单号一致时就是在一个店铺支付的,而不是多个,这样就可以复用微信下单接口返回的数据,从而对该待付款订单进行付款,而不是再调下单接口生成新的订单号去支付(既可以减少接口调用,也可以减少费单)
        如:            
1234 =1234 $unified_order = WeixinPay::unifiedOrder(         $this->conf['weixin']['pay_key'],         $this->openid,1234,$order['pay']*100,$this->appid,         $this->conf['weixin']['mch_id'],         $this->conf['weixin']['pay_notify_url'],         WeixinPay::getNonceStr(),$order['title']);$data = array(                                  'appId' => $this->appid,    'nonceStr' => $unified_order['nonce_str'],    'package' => "prepay_id={$unified_order['prepay_id']}",    'signType' => 'MD5',     'timeStamp' => strval($_SERVER['time']),);$data['paySign'] = WeixinPay::MakeSign($data, $this->conf['weixin']['pay_key']);$this->vshop_orderWeixinPrepay->setPrePay(1234,$data);$this->err_msg['ok']['data'] = $data;$this->_showJsonMsg('ok');
用户支付待付款订单时直接把之前存着的下单数据拿出来:
if(商铺订单号==第三方支付下单号){           //在一个店铺内购买东西         去微信检查1234这个下单号是否已经支付过了,支付过了则退出,而且如果订单不是未付款状态,例如网络超时等直接报错退出          通过执行下面代码          $data = $this->vshop_orderWeixinPrepay->getPrePay(1234);         $this->err_msg['ok']['data'] = $data;           $this->_showJsonMsg('ok');}else{          //不一致为什么这么做?请看《三》        重新生成商铺订单号和第三方支付下单号,让其一致    调用微信下单接口,根据该订单金额等,重新下单}
《三》多个数组时,每个店铺订单对应相同的第三方支付下单号,但是商铺订单号不能与下单号出现一致的情况,否则就会导致超额付款问题。

    如
      

       1234 => 1111       4567 => 1111       8910 => 1111       而不能是       1234 => 4567       4567 => 4567       8910 => 4567
为什么商铺订单号不能与下单号出现一致的情况,否则就会导致超额付款?
场景是用户把几个店铺的商品提交过来,假如3个店铺,我们内部会生成3个内部订单号和一个微信下单号,如果成功支付问题很好解决,假如没有成功支付,前端就会像有赞那样出现3个待付款的订单。
假如这么巧,用户就对        4567 => 4567  这个单进行付款操作,按照上面《二》的逻辑,就会进到getPrePay获取到微信下单号4567的下单数据,记住,微信下单号4567的金额是内部订单号1234,4567, 8910三者金额的和,用户本来想支付第二个内部订单4567的钱,最后却变成了支付三个订单的钱,这是万万不可的,因此要确保商铺订单号不能与下单号出现一致的情况,这很简单,例如加个字母前缀等即可      
       1234 => o_4567       4567 =>o_4567       8910 =>o_4567
这样子,用户单独支付订单时,永远走的是:《 重新生成商铺订单号和第三方支付下单号,让其一致; 调用微信下单接口,根据该订单金额等,重新下单》这个逻辑,请看《二》


四》订单的退款,成功付款,只需要结合内部订单号和第三方下单号处理就可以了

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 衣服发霉怎么洗掉霉斑 刲怎么读 刳剔 刳怎么读 刳胎杀夭 超神制卡师零下九十度 君主制洪荒之证道永生 秘制五花肉 进制转换 十六进制转换 制表位 浦项制铁 火制木 全自动制砖生产线 秘制小龙虾 制香竹签厂家 全自动制豆腐机 全自动制香 石料制沙设备 大明正德年制 工业废渣制砖 制香胶粉价格 秘制鸡腿饭 制香机械厂 秘制羊肉串 九制芒果干 咸鸭蛋制法 回合制卡牌手游 全自动制杯机 工业制刷厂 制刷机械厂 制砂机械厂家 制砖机械厂 中药制丸机价格 制香原料厂家 制沙生产线价格 制木炭机器 河卵石制沙 皮制文具盒