码迷,mamicode.com
首页 > 其他好文 > 详细

djangoB2C电商功能模块

时间:2019-01-19 21:11:40      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:llb   个数   请求   b2c   串行   pickle   inf   分布式文件   ===   

======B2C电商网站======
前后端分离,前端采用Vue框架,后端采用DRF框架,接口采用RESTAPI

---》 不分离:视图中调用模板,生成html字符串返回
  分离:视图中构造json数据返回。 优点:前后端耦合度较低,便于维护。

开发REST API接口时,在视图中做的最核心的事是:
    --将数据库数据序列化为前端需要的格式,并返回。
    --将前端发送的数据反序列化为模型类对象,保存到数据库中。
==1.用户:
1.Django认证系统,自定义Django认证后端类
2.JWT认证机制
3.云通讯发送短信验证码
4.celery异步任务队列
5.QQ第三方登录
6.邮箱激活
7.缓存
==2.商品:
1.FDFS文件存储系统
2.自定Django文件存储类
3.页面静态化
4.定时任务
5.Django Admin界面修改数据处理过程
6.ES搜索引擎&haystack全文检索框架
==3.购物车:
1.购物车记录存储(登录和未登录)
2.购物车记录合并
==4.订单:
1.订单保存(基本流程)
2.订单事务(Django事务)
3.订单支付(支付宝支付)

===1.用户部分===

==1.1 Django认证系统的功能及在项目中的使用
-
Django框架提供了一个用户认证系统,可以完成用户信息的存储,登录用户信息的校验,用户权限控制等功能,认证系统中提供了一个User模型类,在执行迁移时默认会依据此模型类生成对应的用户数据表。
User包含字段:username,password,email,is_staff,is_active,last_login等等 常用方法:set_password(),check_password()
在项目中,可以自定义User模型类来补充一些 默认User类 没有的字段。自定义User模型类需要在配置文件中指定AUTH_USER_MODEL= ‘users.User‘--》‘应用名.模型类名‘,这样执行迁移时会依据自定义User模型类生成 用户数据表。
在用户的注册和登录中,都用到了Django认证系统所提供的函数:create_user():创建新用户 authenticate():认证用户,检验账号和密码

-登录签发jwt:
JWT提供的登录视图obtain_jwt_token接收post请求,获取用户名,密码 ,
然后调用django.contrib.auth模块中的authenticate()方法,
authenticate()方法再调用配置中指定的认证后端类,其中定义了authenticate()方法,进行验证,
验证完成后,为用户签发jwt,把jwt作为属性赋给用户对象,服务器在响应时将jwt返回给客户端,客户端保存jwt,完成状态保持,登录成功。(obtain_jwt_token默认只返回jwt,可以修改该视图以增加返回值)
之后客户端在请求服务器的过程中,在每次需要进行用户的认证时,都要将jwt token数据通过请求头传递给服务器,服务器验证token值,并返回数据。
默认的认证后端是ModelBackend,默认实现是根据用户名查询对象,再验证密码
若需支持用户名和手机号都能登录,需:
1.自定义Django的认证后端类,重写authenticate()方法
  a.判断是否为手机号,如果是则按照mobile查询
  b.如果不是则按照username查询
  c.判断密码是否正确
  d.返回
2.配置,指定认证后端
-
==1.2 jwt toekn认证机制
-
jwt token认证机制是对session认证机制的替代
session认证机制存在的问题:
  1.session信息存储在服务器端,如果登录用户过多,会占用过多的服务器的空间;
  2.session依赖于cookie,session信息的标识保存在cookie中,如果cookie被截获,可能会造成CSRF(跨站请求伪造攻击);
  3.扩展性差:用户认证之后,服务器端做认证记录,如果认证的记录被保存在内存中,用户下次请求还必须请求在这台服务器上,才能拿到授权的资源。
        这样在分布式应用中,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。
jwt token使用:
  1.在用户登录时,服务器验证用户信息,验证通过后,服务器会生成一个jwt token字符串;
  2.服务器在响应时将jwt token数据返回给客户端,客户端保存jwt token数据;
  3.之后客户端在请求服务器过程中,在每次需要进行用户的认证时,都要将jwt token数据通过请求头传递给服务器,服务器验证token值,并返回数据。
  包含3部分内容,用 . 拼接:
  头部(header):包含token类型和加密算法信息,使用base64编码生成字符串。
  载荷(payload):保存有效的数据,通常包含token的有效期,使用base64编码生成字符串。由于base64可解密,不建议存放用户的敏感信息。
  签名(signature):防止jwt token被伪造,由服务器在生成jwt token时,将base64加密后的header和payload用 . 拼接,然后使用秘钥加密生成。
在Django中生成jwt_token:
1.在配置文件中配置jwt;
2.在创建用户系列化器中增加token属性;
3.用头部指定的加密方法,将需要加密的用户的非敏感信息加密生成payload,再生成token,保存并返回;
4.前端将返回的token保存在localstorege或sessionstorage中。
特点: 1.构成简单,字节占用很小,便于传输; 2.保存在客户端,不占用服务器的存储空间;
    3.适合于分布式站点的应用场景。 4.服务器端的密钥需要保存好,泄露密钥之后jwt token数据可以被随意伪造。
-
==1.3 发送短信验证码流程
-
-1.先判断账号和手机号是否注册过,若注册过,提示已注册;
-2.用户点击 ‘获取短信验证码’按钮,浏览器向后端API服务器发起跨域请求;
-3.后端API服务器进行业务处理,发出发送短信验证码的任务消息,然后直接给客户端返回应答,客户端进行倒计时操作;
-4.Celery的worker收到任务消息,调用发送短信的任务函数,使用云通讯给指定的手机号发送短信验证码。
-
==1.4 用celery发短信
-
说明:定义任务函数的文件tasks.py,文件名是固定的
实现步骤:
1.在项目目录下,新建包celery_tasks
2.新建config.py,指定代理人
3.新建main.py,创建celery对象,配置自动识别任务
4.新建包,如sms_code
5.创建tasks.py
6.定义方法,封装耗时代码,添加装饰器
7.在main.py中注册
8.启动工人,如果代码发生改变,需要重启任务
9.在视图函数中调用:任务方法.delay(参数)
在实际开发中,1、2、3做一次即可
如果发现耗时代码,则重复步骤4-9
-
==1.5 QQ登录
-
python标准模块urllib.parse:
  urlopen(url,data=None)-->发送http请求,可以通过read()获取bytes类型的响应体数据 data=None,GET请求;data不为None,POST请求
  urlencode(字典)-->生成查询字符串
  parse_qs(查询字符串)-->生成字典

第三方包itsdangerous: 将字典加密,解密,通过私钥保证安全性
  tjwss=TimedJSONWebSignatureSerializer(私钥,过期时间)
  tiwss.dumps(字典)-->加密字符串
  tjwss.loads(加密字符串)-->字典

-1.用户点击QQ登录按钮时,浏览器发起ajax请求,django服务器生成授权网址,返回给浏览器,
  浏览器在ajax的回调函数中打开授权网址,请求QQ服务器,QQ服务器返回授权页面

-2.用户填写账号密码,点击授权并登录,QQ服务器验证通过后,将用户的浏览器重定向到设置好的回调网址,同时在回调网址后携带code.

-3.浏览器运行js,发起ajax请求,后端API进行业务处理,根据code请求QQ服务器获取access token,再根据token请求QQ服务器获取openID,
  然后根据openID进行处理,如果openID已经绑定过网站用户,直接签发jwt token数据并进行返回;

-4.若openID未绑定过网站用户,说明是第一次用QQ登录,将openid加密并返回给客户端,展示绑定页面

-5.用户填写手机号,密码,短信验证码等,点击‘绑定‘,提交数据

-6.根据手机号查询用户对象,若用户存在,判断密码是否正确,若正确,新建QQ授权对象,保存绑定信息,登录成功,若错误,提示绑定失败

-7.若用户不存在,新建用户对象,新建QQ授权对象,然后签发jwt token数据并返回。
-
==1.6 邮箱激活
-
-设置邮箱: 修改当前登录用户的邮箱属性
1.用户输入邮箱,点击进行设置,浏览器请求后端API接口;
2.后端进行业务处理:
  a.接收参数email并进行校验
  b.设置用户邮箱,并发出 发送验证激活邮件 的任务消息(celery的worker收到任务消息,调用 发送邮件任务函数 进行激活验证邮件的发送)
  c.返回应答
-发激活邮件:
  1.定义任务。发邮件:用Django的django.core.mail模块的send_mail()方法
  2.在修改邮箱序列化器中 调用任务
-激活邮箱:
  当用户点击邮箱里的链接时,进入到success_verify_email.html页面。在该页面中,请求 网址中用于验证的token 发送给后端接口,
  判断token的有效性,若token有效,修改邮箱的验证状态,并将处理结果返回给前端展示给用户。

修改邮箱用户的is_active属性:
a.接受密文,
b.解密,
c.查询对象,
d.修改属性。
-
==1.7 缓存(省市区)
-
-作用:缓存是对网站进行优化的一种方式,可以将经常被用户访问的数据从数据库中获取之后存放到缓存中,当用户来访问时直接从缓存中返回数据,
    只有在缓存中获取不到时再去查询数据库,以此来减少数据库的查询,从而减轻数据库压力,提升网站性能。
-使用:
1.需安装drf-extensions包
2.让视图继承CacheResponseMixin,因为省市区查询时只用到ReadOnlyModelViewSet(ListModelMixin(查省)和RetrieveModelMixin(查市县)),
ListCacheResponseMixin:
用于缓存返回列表数据的视图,与ListModelMixin扩展类配合使用,实际是为list方法添加了cache_response装饰器
RetrieveCacheResponseMixin:
用于缓存返回单一数据的视图,与RetrieveModelMixin扩展类配合使用,实际是为retrieve方法添加了cache_response装饰器
CacheResponseMixin:
为视图集同时补充List和Retrieve两种缓存,与ListModelMixin和RetrieveModelMixin一起配合使用。
3.在配置文件中设置有效期和存储地址(可以存Redis)
-

===2.商品部分===

==2.1 FDFS(分布式文件存储系统)
-
fastDFS是用c语言编写的一款开源的分布式文件存储系统。
充分考虑了冗余备份,负载均衡,现行扩容等机制,并注重高可用,高性能等指标,可以搭建一套高性能的文件服务器集群提供上传,下载等服务。

fastDFS架构包括Tracker server 和Storage server:
    Tracker(追踪/调度 服务器):负载均衡和调度。管理集群,收集storage集群的状态。tracker也可以实现集群。每个tracker节点地位平等。
  Storage(存储服务器):文件存储。分为多个组,每个组之间保存的文件是不同的。在组内,每个组成员的地位一致、内部保存的内容一样,没有主从的概念。
  Storage server没有实现自己的文件系统而是利用操作系统的文件系统来管理文件。
上传文件的流程:
  client 发送上传,下载请求到tracker,tracker去查询storage存储节点是否有位置,查询到之后给client一个准确地、具体地storage节点的ip和路径
  client直接上传文件到该路径,storage返回一个文件ID给client,需要进行保存。
-
==2.2 Docker
-
容器与管理程序虚拟化不同,容器是直接运行在操作系统内核之上的用户空间,直接调用硬件资源。管理程序虚拟化是通过中间层将一台或者多台独立 的机器虚拟运行与物理硬件之上。
容器启动完成后,就可以在容器中安装自己需要的软件或服务,容器中可以运行多个进程。镜像是docker生命周期中的构建或者打包阶段,而容器则是启动或者执行阶段。
作用:
  在开发阶段,会使用多种软件,在服务器部署时,同样需要这些软件。可以将需要的软件安装在docker中,并完成配置,直接将docker拷贝到服务器,在服务器中运行。

镜像(image):Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image是二进制文件。
        image文件在各台电脑上是通用的。开发中,从网上的image仓库(Docker Hub)中下载image文件,再加上自己的个性化设置。
容器(container):运行镜像,生成容器。docker根据image文件生成容器的实例,同一个image文件,可以生成多个同时运行的容器实例。
安装:
  添加私钥:sudo apt-key add gpg
  安装:sudo dpkg -i docker-ce_17.03.2~ce-0~ubuntu-xenial_amd64.deb
  增加管理员权限:sudo usermod -a -G docker $USER
docker服务命令:
  sudo service docker start/stop/restart
镜像命令:
  查看:docker image ls
  下载:docker image pull 镜像名称
  删除:docker rm 名称或ID
容器命令:
  查看正在运行的容器:docker container ls
  查看所有:docker container ls -a
  删除:docker container rm 容器名或容器id
  docker container start/stop/kill 名称或id 若无法重新运行storage,可以删除/var/fdfs/storage/data目录下的fdfs_storaged.pid 文件,重新运行。
使用:
1.将容器保存为镜像:
  docker commit 容器名 镜像名
2.将镜像打包成文件:
  docker save -o 保存的文件名 镜像名
3.将镜像加载到本地:
  docker load -i 保存的文件名
4.创建容器(运行镜像):
  docker run 参数 镜像名称 向启动容器中传入的命令
用docker安装fastDFS:
1.拷贝fastdfs_docker.tar文件到Ubuntu桌面
2.进入桌面,执行命令:docker load -i fastdfs_docker.tar docker image ls -a
3.创建目录:进入/var/,mkdir fdfs 进入fdfs,创建tracker,storage
4.创建容器(运行镜像),启动Tracker:
docker run -dti --network=host --name 新建容器名称 -v 本地目录:容器目录 镜像名 tracker

  参数: t---在最后指定命令 d---后台运行(守护式容器。在容器内部exit退出时,容器也不会停止。) i---交互
      tracker-----前面指定了t,在容器运行后执行此命令。当前为tracker,表示容器启动后,运行tracker命令,即启动软件tracker
5.启动storage:
docker run -dti --network=host --name 容器名称 -e TRACKER_SERVER=本机IP:端口 -v 本地目录:容器目录 镜像名 storage

  参数: -e TRACKER_SERVER=本机ip:端口---指定环境变量,fastdfs不允许本机IP写为127.0.0.1。当前是指定tracker服务器的IP和端口。
自定义文件存储:
  1.定义类,继承自Storage
  2.重写save()方法,调用fastdfs_client中的类,完成上传
  3.重写url()方法,返回完整的url(服务器域名+文件名)用于读取文件
  4.配置,指定django上传文件使用的类型

-
==2.3 CKEditor富文本编辑器
后台运营人员编辑商品信息时,商品详情信息可能包含html语法格式的字符串。为了能在页面中编辑带格式的文本,引入富文本编辑器。富文本即具备丰富样式格式的文本。
1.安装:pip install django-ckeditor
2.添加应用
3.添加设置
4.添加路由
5.为模型类添加字段:RichTextField 不支持富文本字段 RichTextUploadingField 支持富文本字段
6.迁移
-
==2.4 页面静态化
-
作用: 网站优化
将页面用到的数据从数据库中查询出来,生成一个html文件,放到静态文件服务器中,用户访问时,直接访问处理好的html静态文件。
登录时,在用户请求完html页面后,通过ajax向后端发送请求,获取用户的数据。

首页:定时更新:在配置文件中配置定时任务
1.提前准备一个模板文件
2.在配置中配置生成静态页面的路径
3.定义任务函数,生成静态首页
3.1从数据库中查询所需数据
3.2生成html字符串
3.3写文件,给模板文件传递数据,进行模板渲染(将模板文件中变量进行替换)
详情页:
定义celery任务。管理员通过Admin界面修改数据时才会更新对应商品的详情页。
在admin.py中,定义管理类,管理类中包括save_model()、delete_model()
当添加、修改对象时,会执行save_model()方法
当删除对象时,会执行delete_model()方法
定时任务:
1.安装包
2.注册应用
3.配置:指定任务,支持中文
4.命令:python manage.py crontab add/show/remove
-
==2.5 Python脚本
将python文件做成可执行脚本
作用:在后台批量导入数据,生成详情页静态文件。
实现:制作python可执行文件
  1.分权限:chmod +x 文件名.py
  2.在第一行指定Python解释器:#!/usr/bin/env python
  3.执行:./文件名.py
-
==2.6 es搜索引擎+haystack全文检索框架
优点:1.查询速度快;2.支持中文分词。
es搜索引擎:
Elasticsearch(简称es)是java语言实现的一个开源的搜索引擎,是目前全文检索的首选。
通过搜索引擎进行数据查询时,搜索引擎并不是直接在数据库中进行查询,而是会对数据库中的数据进行一遍预处理,单独建立起一份索引结构数据。
在通过搜索引擎搜索时,搜索引擎将关键字在索引数据中进行快速对比查找,进而找到数据的真实存储位置。
搜索引擎在对数据构建索引时,需要进行分词处理。Elasticsearch 不支持中文分词,需要配合扩展elasticsearch-analysis-ik来实现中文分词。
使用Docker安装Elasticsearch及其扩展:
获取镜像:docker image pull delron/elasticsearch-ik:2.4.6-1.0
配置:修改ip地址
创建docker容器运行:docker run -dti --network=host --name=elasticsearch -v /home/python/elasticsearch-2.4.6/config:/usr/share/elasticsearch/config delron/elasticsearch-ik:2.4.6-1.0
haystack全文检索框架:
  python中的全文检索框架,支持多种搜索引擎。在django中可以通过使用haystack来调用Elasticsearch搜索引擎。
  Haystack为Django提供了模块化的搜索。它的特点是统一的,熟悉的API,可以让你在不修改代码的情况下使用不同的搜索后端。
作用: 1.帮助开发者利用搜索引擎建立数据表的索引数据。
    2.帮助开发者利用搜索引擎进行关键词搜索,获取对应的索引数据。
    3.利用索引数据查找到对应数据表的数据。
开发:
1.安装
2.注册
3.配置,可以修改ip、库名称
4.建立索引类:可修改模型类、查询集
5.建立模板:search/indexes/应用名称/模型类小写_text.txt
6.定义可搜索的属性:{{object.属性名称}}
7.生成初始索引数据:python manage.py rebuild_index
8.定义序列化器:指定object使用的序列化器,object表示查询到的对象,当前为SKU对象
9.定义视图:指定模型类
10.调用查询
-

===3.购物车===

-
==3.1 购物车记录
-
身份验证:
  当类继承自APIView,进行请求时,perform_authentication()方法会进行身份验证
根据请求报文获取身份信息:
  若没有身份信息,则是匿名用户
  有身份信息,则调用配置中的类,进行身份认证,正确则返回用户对象
解决身份认证问题:重写方法
def perform_authentication(self, request):
  ‘‘‘
  在视图方法执行前,不再进行身份认证
  ‘‘‘
  pass
登录用户购物车记录:
  保存在Redis中,每个用户的购物车数据采用两条数据保存。
  hash:{user_id:{sku_id:count}}
  set:{user_id:{sku_id,sku_id,...}}
未登录用户购物车记录:
  保存在cookie。
  在cookie中只能保存字符串数据。可以用pickle将Python数据序列化为bytes类型,并使用base64编码,再用decode()转为字符串。
pickle+base64:
  1.转换效率高 2.数据加密,安全
pickle模块是Python标准模块,可以将Python数据转换为bytes类型,序列化速度比json模块高。
pickle.dumps(字典)---->bytes
pickle.loads(bytes)----->字典
python标准库中提供了base64模块
base64.b64encode(bytes)---->base64编码
base64.b64decode(编码后bytes)---->解码
-
==3.2 合并购物车
-
当用户登录时,把cookie中的购物车数据合并到登录用户的Redis购物车记录中。
在登录的API接口执行合并过程即可。
-

===4.订单===

==4.1 订单保存
-
流程:
1.获取当前下单用户
2.生成订单编号
3.保存订单基本信息orderinfo
4.从Redis中获取购物车结算商品数据
5.遍历结算商品
判断商品库存是否充足
减少商品库存,增加商品销量
保存订单商品数据
6.在Redis购物车中删除已结算商品数据
订单事务:
逻辑:选中多个商品统一下单时,如果发现某个商品库存不足,则下单失败
在订单信息保存的过程中,涉及到数据库的操作,都放在同一个事务中,下单过程中任何一个地方出错,订单相关表中都不应该添加数据。
-
==4.2 数据库事务
-
事务:ACID 原子性,一致性,隔离性,持久性
对于数据库的操作,要么一次性提交成功,要么全部放弃。
使用:from django.db import transaction
方法1.装饰器:@transaction.atomic
方法2.with transaction.atomic():
   sid=transaction.savepoint()===》开启事务=======》begin
   transaction.savepoint_commit(sid)===》提交事务===》commit
   transaction.savepoint_rollback(sid)===》回滚事务===》rollback

事务隔离级别:在处理同一个数据的多个事务中,一个事务何时能看到其他事务修改后的数据的结果。

低级别的隔离级一般支持更高的并发处理,且系统开销低。

MySQL事务隔离级别:
串行化(Serializable):事务挨个执行。级别最高。 在每条数据上加上共享锁,可能导致大量的超时现象和锁竞争。
可重复读(Repeatable read):MySQL默认隔离级别。本事务中看到的数据值始终不受其他事务影响。会导致 幻读。
              InnoDB存储引擎通过多版本并发控制机制解决幻读。
读取已提交(Read committed):大多数数据库默认隔离级别。本事务能读取到其他事务提交的修改后的数据值。支持 不可重复读。
读取未提交(Read uncommitted)(脏读):本事务能看到其他事务修改但未提交的数据值。
幻读:在一个事务的两次查询中 数据行 不一致。可能是两次查询过程中其他事务在该被查询范围内插入了新的数据行。
不可重复读:在一个事务的两次查询中 数据 不一致。可能是两次查询过程中其他事务更新了被查询的数据。
脏读:A事务已更新一份数据,B事务在此时读取了同一份数据,若A事务Rollback了操作,则B事务所读取的数据就会是不正确的。

InnoDB 是MySQL的数据库存储引擎之一,是一套放在 MySQL后台的完整数据库系统。最大特色是支持了ACID兼容的事务功能。
-
==4.3 并发
-
解决办法:
1.悲观锁:当查询到某条数据时,让数据库为该记录加锁,使别人无法操作。类似于在多线程中的互斥锁,容易出现死锁。
2.乐观锁:虚拟的锁。在更新数据的时候先判断数据是否是之前查询出的数据,若未被修改,更新数据;若被修改,不再执行数据更新。
# 根据原始库存条件更新,返回更新的条目数,乐观锁
ret = SKU.objects.filter(id=sku.id, stock=origin_stock).update(stock=new_stock, sales=new_sales)
  if ret == 0:
    continue
MySQL事务隔离级别默认为:可重复读(Repeatable read)。使用乐观锁时,应修改为:读取已提交(Read committed)

3.将下单的逻辑放到任务队列中(如celery),将并行转为串行,所有人排队下单。比如开启只有一个进程的celery,挨个处理订单。
-
==4.4 支付宝
-
流程:
1.用户点击 去支付 按钮,请求后端API,后端API进行业务处理,返回支付宝支付网址及参数(回调页面);
2.客户端访问支付宝支付网址,支付宝平台进行处理,调用下单支付接口,返回登录支付页面;
3.用户登录支付宝,选择支付方式,输入支付密码,点击确认付款;
4.付款成功后,支付宝返回回调页面和流水号;
5.客户端访问回调页面,在页面加载时请求后端API接口并携带流水号;
6.后端API根据流水号向支付宝获取支付状态,支付成功则修改订单状态。

实现:

1.新建应用,配置

2.成为开发者,进入沙箱环境,设置应用公钥:

1.选用支付宝提供的生成应用公钥的工具:openssl

2.在桌面上创建目录alipay,进入此目录

3.进入openssl命令:openssl

3.生成私钥genrsa -out app_private_key.pem 2048

4.生成公钥rsa -in app_private_key.pem -pubout -out app_public_key.pem

5.在alipay目录中会生成文件,复制需要的两个文件到项目的apps/payments/keys中,根据要求条件只把公钥文件中的 公钥部分 剪切到支付宝上,再把支付宝生成的支付宝公钥复制到项目的公钥文件中

6.配置
ALIPAY_APPID = "2016095200590063"

ALIPAY_URL = "https://openapi.alipaydev.com/gateway.do?"

ALIPAY_DEBUG = True # 调试,使用沙箱必须设置成True

ALIPAY_KEY_PATH = os.path.join(BASE_DIR, ‘apps/payments/keys‘)

ALIPAY_RETURN_URL = ‘http://www.meiduo.site:8080/pay_success.html‘


7.python对接支付宝SDK:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md

安装包:pip install python-alipay-sdk --upgrade


1.获取支付地址
1.创建alipay对象
2.调用方法生成支付参数
3.拼接支付地址
2.验证支付流水号
1.接收支付宝返回的数据,转字典
2.弹出sign
3.创建alipay对象
4.调用verify方法,进行验证
5.判断是否支付成功
6.如果支付成功则修改订单状态,保存流水号,返回流水号

 

djangoB2C电商功能模块

标签:llb   个数   请求   b2c   串行   pickle   inf   分布式文件   ===   

原文地址:https://www.cnblogs.com/x-z2/p/10293003.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!