1.Django中创建模型类
from django.db import models
from userapp.models import *
# Create your models here.
class Order(models.Model):
'''订单模块'''
out_trade_num = models.UUIDField()
trade_no = models.CharField(max_length=120)
order_num = models.CharField(max_length=50)
status = models.CharField(max_length=20, default='待支付')
payway = models.CharField(max_length=20, default='alipay')
address = models.ForeignKey(Address, on_delete=models.CASCADE)
user = models.ForeignKey(UserInfo, on_delete=models.CASCADE)
class OrderItem(models.Model):
'''订单项'''
goodsid = models.PositiveIntegerField()
colorid = models.PositiveIntegerField()
sizeid = models.PositiveIntegerField()
count = models.PositiveIntegerField()
order = models.ForeignKey(Order, on_delete=models.CASCADE)
迁移数据库
python .\manage.py makemigrations
python .\manage.py migrate
2.支付宝沙箱支付功能
后端
from django.shortcuts import render
from django.shortcuts import render,redirect,HttpResponse
import jsonpickle
from utils.cartmanager import DBCartManger
from utils.alipay_p3 import AliPay
import uuid
from orderapp.models import *
from datetime import datetime
from userapp.models import *
from goodsapp.models import *
from django.db.models import F
# Create your views here.
# 跳转结算视图
def toOrder(request):
# 获取购物车页面传递的参数
cartitems = request.GET.get('cartitems','')
totalPrice = request.GET.get('totalPrice',0)
# 判断用户是否登录
# 从session对象中获取用户信息
if not request.session.get('user',''):
# 如果没有登录,跳转登录页面,进行登录
return render(request, 'userapp/login.html',{'reflag':'orderapp', 'cartitems':cartitems, 'totalPrice':totalPrice})
# 获取登录用户默认地址信息
user = jsonpickle.loads(request.session.get('user'))
# 根据user对象获取默认地址
addrObj = user.address_set.get(isdefault=True)
# 获取订单中的商品信息
cartitemsList = jsonpickle.loads(cartitems)
# cartitemList ["{\"goodsid\":\"4\",\"sizeid\":\"9\",\"colorid\":\"9\"}","{\"goodsid\":\"4\",\"sizeid\":\"6\",\"colorid\":\"10\"}"]
# 循环遍历cartitemList生成CartItem对象的列表
# 创建DBCartManager实例对象——调用工具类的获取数据方法
dbCartObj = DBCartManger(user)
print(cartitemsList,'-----------------------------------+++++')
cartitemObjList = [dbCartObj.get_cartitems(**eval(item)) for item in cartitemsList]
return render(request, 'orderApp/toOrder.html',{'addrObj':addrObj, 'cartitemObjList':cartitemObjList,'totalPrice':totalPrice})
# 创建AliPay实例对象
alipay = AliPay(appid = '2021000121697847',
app_notify_url = 'http://127.0.0.1:8000/orderapp/checkPay/',
app_private_key_path='keys/my_private_key.txt',
alipay_public_key_path='keys/alipay_public_key.txt',
return_url = 'http://127.0.0.1:8000/orderapp/checkPay/',
debug=True)
def toPay(request):
# 获取支付金额
totalPrice = request.GET.get('totalPrice',0)
# 获取请求参数
# 保存订单
orderObj = Order.objects.create(out_trade_num=uuid.uuid4().hex,
order_num = datetime.strftime(datetime.now(),'%Y%m%d%H%M%S'),
payway=request.GET.get('payway',''),
address = Address.objects.get(id=request.GET.get('address','')),
user = jsonpickle.loads(request.session.get('user')))
# 保存订单项
cartitems = jsonpickle.loads(request.GET.get('cartitems',''))
orderItemList = [OrderItem.objects.create(order=orderObj,**ci) for ci in cartitems if ci]
# 调用支付界面
params = alipay.direct_pay(subject='淘宝商城', out_trade_no=orderObj.out_trade_num, total_amount=totalPrice)
return redirect(alipay.gateway+"?"+params)
def checkPay(request):
# 获取所有的请求参数
params = request.GET.dict()
# 获取sign的值
sign = params.pop('sign')
# 判断是否支付成功
if alipay.verify(params, sign):
# 1. 修改订单状态,以及trade_no设置值
# 获取订单
orderObj = Order.objects.get(out_trade_num=params.get('out_trade_no',''))
orderObj.status = '待发货'
orderObj.trade_no = params.get('trade_no')
# 2.修改库存
# 根据订单获取订单项
orderitems = orderObj.orderitem_set.all()
[Inventory.objects.filter(goods_id=oi.goodsid, color_id=oi.colorid, size_id=oi.sizeid).update(count=F('count')-oi.count) for oi in orderitems]
# 3.更新购物车表中的数据
# 获取当前用户
user = jsonpickle.loads(request.session.get('user'))
[user.cartitem_set.filter(goodsid=oi.goodsid, colorid=oi.colorid, sizeid=oi.sizeid, count=oi.count).delete() for oi in orderitems]
return HttpResponse('支付成功')
else:
return HttpResponse('支付失败')
前端
{% extends 'base.html' %}
{% block title %}结算页面{% endblock %}
{% load static %}
{% block headercss %}
<link rel="stylesheet" type="text/css" href="{% static 'css/public.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/proList.css' %}">
{% endblock %}
{% block main %}
<div class="order cart mt">
<!-----------------site------------------->
<div class="site">
<p class="wrapper clearfix">
<span class="fl">订单确认</span>
</p>
</div>
<!-----------------orderCon------------------->
<div class="orderCon wrapper clearfix">
<div class="orderL fl">
<!--------h3---------------->
<h3>收件信息</h3>
<!--------addres---------------->
<div class="addres clearfix">
<div class="addre fl on">
<div class="tit clearfix">
<p class="fl"><span id="name_address">{{addrObj.aname}}</span>
<span class="default">[默认地址]</span>
</p>
</div>
<div class="addCon">
<p id="address_address">{{addrObj.addr}}</p>
<p id="phone_address">{{addrObj.phone}}</p>
</div>
</div>
</div>
<h3>支付方式</h3>
<!--------way---------------->
<div class="way clearfix">
<img class="on" src="{% static 'images/way01.jpg' %}" name="alipay">
<img src="{% static 'images/way02.jpg' %}" name="wechat">
<img src="{% static 'images/way03.jpg' %}" name="union">
</div>
<!--------dis---------------->
</div>
<div class="orderR fr">
<div class="msg">
<h3>订单内容</h3>
<!--------ul---------------->
{% for cartitem in cartitemObjList %}
<ul class="clearfix" goodsid="{{cartitem.goodsid}}" sizeid="{{cartitem.sizeid}}" colorid="{{cartitem.colorid}}" count="{{cartitem.count}}">
<li class="fl">
<img src="{{ cartitem.getColor.colorurl }}" width="87px" height="87px">
</li>
<li class="fl">
<p>{{cartitem.getGoods.gname}}</p>
<p>{{cartitem.getColor.colorname}}</p>
<p>数量:{{cartitem.count}}</p>
</li>
<li class="fr">¥{{totalPrice}}</li>
</ul>
{% endfor %}
</div>
<!--------tips---------------->
<div class="tips">
<p><span class="fl">商品金额:</span><span class="fr">¥{{totalPrice}}</span></p>
<p><span class="fl">优惠金额:</span><span class="fr">¥0.00</span></p>
<p><span class="fl">运费:</span><span class="fr">免运费</span></p>
</div>
<!--------tips count---------------->
<div class="count tips">
<p><span class="fl">合计:</span><span class="fr">¥{{totalPrice}}</span></p>
</div>
<!--<input type="button" name="" value="去支付"> -->
<a href="http://127.0.0.1:8000/order/order.html" id="pay" class="pay" onclick="javascript:void(0);">去支付</a>
</div>
</div>
</div>
{% endblock %}
{% block footerjs %}
<script src="{% static 'js/public.js' %}" type="text/javascript" charset="utf-8"></script>
<script src="{% static 'js/pro.js' %}" type="text/javascript" charset="utf-8"></script>
<script src="{% static 'js/user.js' %}" type="text/javascript" charset="utf-8"></script>
<script>
$("#pay").click(function(){
var cartitems = []
$.each($('.msg ul'),function(index,item){
cartitems.push({"goodsid":$(item).attr('goodsid'),
"sizeid":$(item).attr('sizeid'),
"colorid":$(item).attr('colorid'),
"count":$(item).attr('count')
})
})
//拼接请求参数
var params = 'address={{addrObj.id}}&payway='+$('.way .on').attr('name')+'&cartitems='+JSON.stringify(cartitems)+"&totalPrice={{totalPrice}}"
//拼接请求地址
var url = '/orderapp/toPay/?'+params
$(this).attr('href',url)
})
</script>
{% endblock %}
效果展示
若想了解具体支付功能可以查看本专栏上一节的demo