03.创建订单并生成支付链接接口
1..创建订单并生成支付链接接口#
1.1 goods/urls.py中注册路由#
urlpatterns = [
path('getpayurl/', views.PayUrlView.as_view()), # /goods/getpayurl/
]
1.2 goods/views.py 中写视图函数#
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from .models import Goods,Orders,GoodsCourse
from goods.utils import get_order_id, get_pay_url, alipay
# 创建订单并生成支付链接接口
class PayUrlView(APIView):
permission_classes = (IsAuthenticated,) # 用户权限
def post(self, request):
# 1. 获取课程id,获取购买途径(普通购买, 促销购买) 获取用户
goods_id = request.data.get('goods_id')
if not goods_id:
return Response({'msg': '参数不全'})
goods = Goods.objects.get(id=goods_id)
user = request.user
# 2.下订单 判断会员并打折
order_id = get_order_id()
if user.vip.vip_type == '1': # 普通会员
goods_price = goods.price * Decimal('0.80').quantize(Decimal('0.00'))
elif user.vip.vip_type == '2': # 高级会员
goods_price = goods.price * Decimal('0.60').quantize(Decimal('0.00'))
else:
goods_price = goods.price
goods_price = Decimal(goods_price).quantize(Decimal('0.00'))
order = Orders(user=user, goods=goods, order_id=order_id, pay_method=1, status=1, total_amount=goods_price)
order.save()
print(order.total_amount, type(order.total_amount))
# 3. 根据订单 生成支付链接
subject = "实验楼订单:%s, 价格:%s" % (order.order_id, order.total_amount)
pay_url = get_pay_url(order.order_id, order.total_amount, subject)
# 4. 返回链接
return Response({"code": 0, "msg": "下单成功", "data": {"pay_url": pay_url}})
注意啊:踩过的坑,涉及金融计算,涉及小数啊,要求特别精确的,我们用字符串存储。
如果是金融计算的话,我们用一个decimal来进行计算。
1.3 goods/utils.py中生成随机订单函数和生成支付URL函数#
# -*- coding: utf-8 -*-
import datetime
import os
import random
from alipay import AliPay
from django.conf import settings
# 获取文件路径
app_private_key_path = os.path.join(settings.BASE_DIR, "apps/goods/keys/app_private_key.pem")
alipay_public_key_path = os.path.join(settings.BASE_DIR, "apps/goods/keys/alipay_public_key.pem")
with open(app_private_key_path) as f:
app_private_key_string = f.read()
with open(alipay_public_key_path) as f:
alipay_public_key_string = f.read()
# 创建支付宝支付对象
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None, # 默认回调url
app_private_key_string=app_private_key_string,
alipay_public_key_string=alipay_public_key_string,
# app_private_key_path=app_private_key_path,
# alipay_public_key_path=alipay_public_key_path,
sign_type="RSA2",
debug=settings.ALIPAY_DEBUG
)
# 生成登录支付宝连接
def get_pay_url(out_trade_no, total_amount, subject):
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=out_trade_no,
total_amount=str(total_amount),
subject=subject,
return_url=settings.ALIPAY_RETURN_URL,
)
# 响应登录支付宝连接
# 真实环境电脑网站支付网关:https://openapi.alipay.com/gateway.do? + order_string
# 沙箱环境电脑网站支付网关:https://openapi.alipaydev.com/gateway.do? + order_string
alipay_url = settings.ALIPAY_URL + "?" + order_string
return alipay_url
#生成订单号:
def get_order_id():
"""
SYL202008241212121200005/24
生成订单号: 格式: SYL + 年月日时分秒 + 5位随机数
:return:
"""
d = datetime.datetime.now()
base = 'SYL'
time_str = '%04d%02d%02d%02d%02d%02d' % (d.year, d.month, d.day, d.hour, d.minute, d.second)
rand_num = str(random.randint(10000, 99999))
return base + time_str + rand_num
1.4 syl/setings.py中配置支付相关参数#
# 支付宝配置
ALIPAY_APPID = '2016102600762673' # 沙箱环境中alipay应用ID 自己的应用ID
ALIPAY_DEBUG = True
ALIPAY_URL = 'https://openapi.alipaydev.com/gateway.do' # alipay沙箱环 境支付宝网管
ALIPAY_RETURN_URL = 'http://127.0.0.1:8888/payment/callback/' # 支付完成后支 付宝回调我们应用的地址
2.测试#
- 请求地址
http://192.168.56.100:8888/goods/getpayurl/
- 携带参数
{
"goods_id":1
}
- 返回参数
{
"code":0,
"msg":"下单成功",
"data":{
"pay_url":"https://openapi.alipaydev.com/gateway.do?app_id=2016102600762673&biz_content=%7B%22subject%22%3A%22%5Cu5b9e%5Cu9a8c%5Cu697c%5Cu8ba2%5Cu5355%3ASYL2020101512171797508%2C+%5Cu4ef7%5Cu683c%3A532.80%22%2C%22out_trade_no%22%3A%22SYL2020101512171797508%22%2C%22total_amount%22%3A%22532.80%22%2C%22product_code%22%3A%22FAST_INSTANT_TRADE_PAY%22%7D&charset=utf-8&method=alipay.trade.page.pay&return_url=http%3A%2F%2F127.0.0.1%3A8888%2Fpayment%2Fcallback%2F&sign_type=RSA2×tamp=2020-10-15+12%3A17%3A17&version=1.0&sign=HFBOqgSdbqstvFFur9oBEwZuYT7eK30pE6zJ14CWjQPcvrkOylz2%2FOwLnPk7cUtwzU3R1O3hMq24H3VCzj2PIsVQazAlsbUrmm9Jaoliac%2FmpVXqZ7ERJYfzcse7UU4k0f%2FCgjj3lWqjHRuiE8tRdEdVdtl8aJKpRlkhrH4WbuTV8Ej3Hy%2Fkt9KTCS%2B6mkxcu57t9%2FgecPhcUweh%2FKWEFVv1A3owBjb%2BiqtemgAOVJ0NtxjfUbzr8poNVtKMjT%2Bw4aanvizwAIEoJsM9TNt1AtP%2BukAW8q7bTY6RFcl%2BhgJCtcUmeqyKTyUsnqjfkassA9sQj6P8K53CbFJLFoSyBA%3D%3D"
}
}
作者:就学45分钟
出处:https://www.cnblogs.com/tjw-bk/p/13823420.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了