ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

基于Django的订单支付系统设计:从回调验签到并发扣款实战解析

基于Django的订单支付系统设计:从回调验签到并发扣款实战解析 简介这是一套面向计算机相关专业本科生的毕业设计级实战项目基于Django框架完整实现电商场景下的订单支付系统深度集成支付宝与微信双通道支付接口解决课程设计、毕设立项及Web开发进阶中支付模块落地难的问题。资源包共34个文件含19个核心Python后端逻辑文件如支付回调、订单管理、签名验签、4个前端HTML模板订单确认、购物车结算、订单列表等、3个PEM密钥文件支撑安全通信另有README说明、requirements依赖清单及LICENSE协议文件整体仅34KB轻量易部署。已有104人学习下载项目代码经实测可直接运行配套详细使用说明文档涵盖环境配置、密钥替换、沙箱调试及常见报错解决方案目录结构清晰分层前后端分离雏形、日志记录模块、可扩展支付适配器设计适合从零理解支付流程或在此基础上二次开发。 毕业设计选基于Django的订单支付系统这个题目的同学我猜你多半是看中了它既有技术深度、又有现实场景这个组合。订单、支付、异步回调、并发扣款这几个词放在一起几乎覆盖了后端开发最核心的链路。再加上支付宝和微信双通道接入简历上写出来也确实好看。但这恰恰也是坑最多的地方。我见过太多人选了这个题目结果卡在支付宝回调验签、微信支付二维码生成、数据库乐观锁这些细节上一拖就是两三个星期。网上的教程要么只讲了支付宝不讲了微信要么代码能跑但一问原理就懵。所以这篇就把我从需求分析、表结构设计、支付流程、回调处理、踩坑记录到答辩准备的完整思路整理出来给正在做类似项目的你一个可以直接参考的坐标。1. 项目整体设计与技术选型思路1.1 为什么这个题目适合当毕业设计先说结论这个题目的性价比非常高。原因有三点。第一它的业务闭环完整。一个用户从注册登录、浏览商品加购物车、生成订单、发起支付、等待回调、修改订单状态这一整条链路做完你基本就掌握了一个电商系统的最小可用闭环。这个闭环本身就是一个完整项目而不是某个零散的增删改查模块。第二它的技术覆盖面恰到好处。Django框架的使用ORM、视图、路由、模板、第三方支付SDK的对接支付宝openapi、微信支付v3、异步回调的处理验签、幂等、并发安全、数据库事务与锁的使用这些都踩中了Web后端开发的高频考点。第三它的答辩亮点非常直观。支付系统天然具备高价值业务场景你可以直接演示沙箱环境里的真实支付流程也可以在答辩时讲清楚用户取消订单但回调却到了这种极端情况的处理方案这些都是评委老师容易追问的点。1.2 Django做支付系统的优势我明确建议你使用Django而不是Flask或FastAPI来做这个项目。不是说其他框架不行而是Django在这个场景下的基础设施最齐全。Django自带的Admin后台可以直接管理订单和支付记录这对演示和调试极有帮助。你不需要额外写一套后台管理页面就可以在后台看到每笔订单的状态流转。Django的ORM在处理订单和支付这种强关系数据时也非常顺手模型之间的ForeignKey、OneToOne关系写起来非常直观。还有一个隐藏优势是Django的CSRF、XSS防护机制是默认开启的这在涉及资金操作的场景能在答辩时作为安全性设计的加分项。另外Django的中间件机制可以用来做统一的签名校验、请求日志记录这些对支付系统的安全性和可追溯性非常重要。Django自身的信号Signal机制还可以用于订单超时自动关闭这类逻辑虽然这个也可以靠定时任务实现但信号提供了另一种更优雅的出路。1.3 整体功能模块划分我建议把系统拆成这样的模块每个模块之间保持低耦合用户模块注册、登录、个人信息维护。如果是演示项目可以直接用Django默认的User模型加一个Profile扩展。商品模块商品列表、商品详情、库存管理。如果不想花时间做前端可以直接渲染Django模板也可以提供DRF接口给小程序或APP调用。订单模块创建订单、订单详情、订单列表、取消订单、订单超时处理。支付模块支付发起、支付回调处理、退款处理、对账。消息通知模块支付成功后的站内信或邮件提醒这个可以简化。这里我特别建议你把支付单独拆成一个app不要和订单模块混在一起。支付的业务逻辑非常独立而且它有自己单独的数据表支付记录表单独拆开后面排查问题会省很多力气。1.4 技术栈和版本选型我当时用的版本组合是Python 3.10 Django 4.2 MySQL 5.7 Redis用于缓存和分布式锁限制。Django 4.2是LTS版本稳定且资料多不建议用Django 5.x做毕设因为部分第三方库可能还没有完全适配。支付SDK方面支付宝使用官方推荐的python-alipay-sdk微信支付使用wechatpayv3库配合微信支付v3版本的API。这里特别提一句微信支付v2的API已经在2023年停止了新商户入驻新的项目直接用v3。v3和v2最大的区别是使用了Apache HttpClient风格的请求签名方式通过商户私钥对请求进行SHA256-RSA2048签名并且回调数据是AES-256-GCM加密的所以需要额外做解密。这个细节后文我会专门讲。数据库我建议直接用MySQL别用SQLite。原因一是生产环境支付系统不可能用SQLite答辩时老师可能会问二是MySQL对事务、行锁的支持更成熟你在做并发扣库存实验时才能真正体会到行锁的效果。Redis的用处主要是缓存商品信息、实现分布式锁以及存储支付二维码ticket。2. 数据库设计与核心表结构2.1 订单表和支付记录表的职责划分这是整个项目最关键的数据设计一定要把订单和支付记录分开。订单表order_order负责业务侧的数据哪个用户下的单、买了什么商品、数量多少、订单总金额、订单状态待支付、已支付、已发货、已完成、已取消。支付记录表payment_paymentrecord负责资金侧的数据哪笔订单发起了支付、使用哪个支付渠道支付宝还是微信、第三方支付流水号支付宝的trade_no或微信的transaction_id、支付金额、支付状态待支付、成功、失败、已退款。为什么要分开因为一笔订单可以发起多次支付。比如用户下了一笔100元的订单第一次支付超时了订单还在待支付状态用户又发起了一次支付第二次支付成功。在这个过程中订单其实只有一条记录但支付记录有两条。如果你把支付信息直接冗余在订单表里第二次支付发起时你是覆盖还是保留无论怎么选都会丢数据。拆分成两张表这种问题就自然解决了。订单表核心字段order_no订单编号一定要自己生成不要用数据库自增ID。推荐格式日期随机数或直接使用UUID去掉横线。用户会拿这个编号找客服自增ID会暴露你的销量。user_id下单用户外键。total_amount总金额单位用分存储不用Decimal这样可以避免浮点数精度问题。虽然Django的DecimalField能处理十进制精度但AES加密、签名这些环节用整数分更方便。status订单状态用SmallIntegerField加choices不要直接存字符串。created_at和updated_at创建时间和更新时间。支付记录表核心字段payment_no支付记录编号同样自己生成。order_no关联的订单编号。channel支付渠道1代表支付宝2代表微信。trade_no第三方支付平台的交易流水号支付成功后回调里会带。amount支付金额单位分。status支付记录状态。notify_count接收回调的次数。这个字段放在表里会非常方便排查回调风暴问题。2.2 商品表和库存扣减的并发处理商品表没什么稀奇的但库存扣减务必使用乐观锁或悲观锁。我用的是乐观锁版本号方案商品表加一个version字段每次扣库存时执行类似这样的更新语句affected_rows Product.objects.filter( idproduct_id, versioncurrent_version, stock__gtequantity ).update( stockF(stock) - quantity, versionF(version) 1 ) if affected_rows 0: # 说明版本号不匹配或库存不足重试或提示用户 raise InventoryShortageError(库存不足或商品信息已变更)这样比select_for_update()的行锁更轻量而且在高并发场景下更容易扩展。如果答辩时老师问你怎么保证不超卖这就是一个非常标准的答案。2.3 为什么金额一律用整数分存储这条经验是我踩坑换来的。Django的DecimalField虽然能存精确小数但你一旦和支付宝、微信的接口对接就会发现他们传回来的金额单位是分而且是整数字符串。如果你数据库里存的是元回调处理时就得做转换转换过程中如果精度控制不好就会出现99.99元变成99.99000000000001这种问题。所以最稳的做法是数据库金额字段全部用BigIntegerField或IntegerField单位分。展示给用户时再除以100需要计算时直接用整数计算。整个系统内部所有业务逻辑都基于分来计算只在模板渲染层做一次转换。这样既不会丢精度也天然和第三方支付接口对齐。3. 支付流程的核心机制拆解3.1 支付宝电脑网站支付的完整流程支付宝的接入流程是所有支付渠道里最标准的建议你先把这个跑通再去做微信支付。用户在订单详情页点击支付宝支付你重定向到支付宝的网关地址URL上带上你的参数app_id、method、sign、biz_content等。用户在那个页面上完成扫码或登录支付。支付宝处理完以后会做两件事第一同步跳转回你的return_url告诉你用户已经支付了第二异步POST到你的notify_url告诉你这笔交易的结果。这里有个非常重要的认知同步跳转return_url是不可靠的。用户可能付完钱直接关闭了浏览器根本不触发这个跳转也有可能支付宝返回了支付成功但因为网络原因回跳你的页面时数据丢了。所以核心一定要以异步通知notify_url为准。同步跳转只能用来给用户展示支付完成的页面绝不能在里面改订单状态。还有一个更隐蔽的坑是用户在支付宝页面付完款但点返回商家时支付宝只是GET跳转到你的return_url。这时候如果你想在页面里查一次订单状态给用户看可以但不要直接改库。我见过有同学直接把return_url里支付成功参数当作可信数据结果被人用一条URL就模拟了支付成功订单状态直接被改了这是非常严重的安全漏洞。3.2 微信支付Native扫码支付流程微信支付v3的Native模式也就是扫码支付流程稍微绕一点。你要先调用微信支付的/v3/pay/transactions/native接口传入你的商户号、AppID、商品描述、订单号、金额、回调地址微信会返回一个形如weixin://pay.weixin.qq.com/bizpay?......的code_url。这个code_url是用于生成二维码的用户扫码后手机会拉起微信支付。这个接口的请求签名方式比支付宝复杂。你需要用商户私钥对请求中的method、path、timestamp、nonce_str和请求体拼接成的字符串做SHA256-RSA2048签名然后把签名放进HTTP头部的Authorization字段里。这一步如果用第三方SDK实现还好如果要自己实现建议用wechatpayv3这个库它把证书加载、请求签名、响应验签都封装好了。我做完才发现一个容易出问题的地方微信支付v3的证书是商户API证书和AppID对应的开放平台证书是两回事。初始化SDK的时候要传四个东西apiclient_key.pem商户私钥、apiclient_cert.pem商户证书、wechatpay_platform_cert.pem微信支付平台证书、serial_no证书序列号。其中商户私钥是你自己生成的千万别提交到Git仓库。微信支付平台证书是用来验签微信返回的响应和回调的不能搞混。如果用了旧版证书会导致回调验签一直失败日志里报verification failed。3.3 前端交互设计前端这块我推荐一个低成本高效果的做法。支付宝不需要你真的在页面上跳转你可以直接用前端JS把请求发给后端后端返回一个payment_url支付宝的网关地址或code_url微信的二维码内容然后前端根据不同的渠道做不同的处理。支付宝的payment_url就是一个URL直接window.location.href跳转。微信的code_url需要渲染成二维码建议用前端qrcode.js的库不要在后端生成二维码图片那样反而增加复杂度。用户扫码后前端进入一个轮询等待的状态每隔3秒不要短于3秒否则可能被支付平台限流调用一次后端的查询订单状态接口。轮询的同时后端还开着两个后台通道一个就是微信/支付宝的异步回调这是最终的订单状态官方认定来源另一个是主动调用微信/支付宝的查询订单接口兜底。这三者之间的关系是异步回调来了以它为准更新订单异步回调没来或延迟了轮询查到订单已支付也可以主动确认。4. 支付宝和微信回调处理的细节4.1 回调验签和数据解密这是整个项目里最容易出Bug的地方也是你能在答辩时讲出彩的地方。支付宝的回调通知是直接POST明文参数过来的带一个sign字段。验签的逻辑是除去sign和sign_type字段把剩下的所有参数按照ASCII码排序拼接成keyvaluekeyvalue的字符串然后用支付宝公钥做RSA2验签。注意用的是支付宝公钥不是你的应用私钥。微信支付v3的回调就复杂一些。请求体本身是加密的格式大致如下{ resource: { algorithm: AEAD_AES_256_GCM, ciphertext: 加密串, nonce: 随机串, associated_data: 附加数据 } }你需要用APIv3密钥自己在商户平台设置的32字节字符串做AES-256-GCM解密。解密时associated_data就是回调报文里的resource节点下的associated_data字段nonce就是nonce字段解密成功后的明文是JSON格式里面包含out_trade_no你的订单号和transaction_id微信交易号。解密之后再用微信支付平台证书对请求头里的Wechatpay-Signature做验签验签通过才真正可信。解密和验签的先后顺序业界有两种做法我建议先验签再解密。验签保证了数据的完整性和来源可信解密只是解开内容。先验签后解密更安全因为如果数据在传输中被篡改验签就会失败你也就不用费劲去解一个不可信的数据了。4.2 回调处理的幂等性和最终态保护支付回调由于网络原因被支付平台重试是常态不是异常。支付宝和微信都会以一定的频率微信支付v3的重试策略是首次通知失败后15秒、15秒、30秒、3分钟、10分钟、20分钟、30分钟、30分钟、30分钟、60分钟、3小时、3小时、3小时、6小时、6小时逐次拉长重复通知。所以你的回调处理函数必须天然支持幂等。我当初写这个处理逻辑时的核心代码是# 依据 order_no 和 channel 查已有的支付记录 record PaymentRecord.objects.filter( order_nodata[out_trade_no], channeldata[channel] ).first() # 关键保护如果这条支付记录已经是成功状态直接返回成功不重复处理 if record and record.status PAYMENT_SUCCESS: return HttpResponse(success) # 加锁并检查订单当前状态是否已经是终态已支付/已取消 with transaction.atomic(): order Order.objects.select_for_update().get(order_nodata[out_trade_no]) if order.status in (ORDER_PAID, ORDER_CANCELLED): # 如果订单已经取消说明有退款或关闭流程需要额外的业务处理 pass else: order.status ORDER_PAID order.paid_at now() order.save() record.status PAYMENT_SUCCESS record.trade_no data[trade_no] record.save()核心思想就是在更新前先查询一遍当前状态如果已经是终态就直接返回success告诉支付平台不用再重试了不要再做任何修改。这样可以避免并发回调或重复通知带来的状态错乱。4.3 回调签名验证失败的排查思路签名验证失败是最让人头疼的问题。我的排查经验是先打印出收到的原始参数和我自己拼接的待签名字符串这两样东西逐个字符对比看有没有\n、\r、空格、URL转义之类的差异。支付宝最常见的问题是回调参数里有个别字段是空值空值要不要参与签名答案是空值也要拼进去形式是key。另一个常见问题是把验签的请求体直接原样用来验签了但支付宝回调的body其实是URL解码后的。微信支付v3最常见的验签失败问题是获取微信支付平台证书的方式不对或者平台证书被更新了还在用旧证书。一个小技巧是在验签失败时不要直接返回failure给支付平台可以先打印日志记录signature、timestamp、nonce然后返回failure。这样支付平台会再重试你就有机会去日志里分析。如果直接不返回网络层可能直接断开或超时支付平台也会重试但已经失去了第一手的调试信息。5. 订单超时关闭与支付结果主动查询5.1 订单超时关闭的三种实现方案用户下单后不支付订单一直占着库存这是必须处理的问题。毕业设计里有三种常见的方案我建议你按下面的排序来选择第一种是使用Celery的定时任务。这个方案最标准用Celery Beat每隔一段时间扫描一次超时订单把超过15分钟未支付的订单关闭。优点是思路简单缺点是Celery的部署稍微麻烦如果只是做毕设会引入额外复杂度。第二种是Django自带的management command配合cron或Windows计划任务。写一个自定义命令close_expired_orders每分钟执行一次扫描所有超时未支付订单改为关闭状态。这个方案不需要引入Celery代码量很少演示时手动执行一次也能看到效果。第三种方案也叫懒关闭。用户在下单后再次查询订单或进入订单详情时先检查一下这个订单是否已超时如果超时了就先把它关闭再正常展示。这种方案的响应时间稍快但依赖用户主动触发对于僵尸订单处理不及时。我实际采用的是方案二加方案三的组合。定时任务关闭大部分超时订单懒关闭兜底确保用户在任何入口看到订单时状态都是正确的。答辩时讲这种定时懒关闭的组合方案也是一个加分点。5.2 主动查询支付结果兜底支付平台的异步回调虽然有重试机制但极端情况下比如你的服务器正好在维护、回调地址被防火墙拦住或者你和支付平台之间的网络链路故障回调可能一直不来。这时候如果没有主动查询机制用户的订单就会一直是待支付状态但钱已经扣了。所以当用户在前端轮询订单状态时如果发现订单还是待支付且距离下单时间已经过去30秒这个时间可以调后端可以主动调用查询接口支付宝的alipay.trade.query或微信支付的/v3/pay/transactions/out-trade-no/{out_trade_no}传入订单号查询第三方平台上的真实支付状态。如果查询结果确实是已支付就直接按支付成功处理主动更新本地订单状态。这个兜底逻辑可以放在轮询接口里也可以单独做一个定时任务。放在轮询接口里的好处是不需要额外定时任务简单直接。注意查询频率别太频繁支付宝官方建议查询间隔不要低于5秒。5.3 退款功能是加分项退款功能的实现思路其实不难向支付平台发起退款请求支付宝调用alipay.trade.refund微信调用/v3/refund/domestic/refunds。退款不会像支付那样有异步回调支付宝v2和微信v3都支持退款结果查询所以更简单的做法是退款接口发起成功后更新支付记录状态为# 退款中#然后主动轮询退款结果接口根据返回结果更新为已退款。退款接口的字段比支付少很多主要是订单号、退款金额、退款原因。但注意退款金额必须小于等于原交易金额且单位为分。退款金额超过原交易金额会直接报错。这个功能建议你做出来哪怕只是简单的后台手动退款。因为答辩时评委极大概率会问如果用户要退款怎么办你能演示退款流程说明你对资金操作的理解是完整的。6. 实际运行效果展示与关键操作记录6.1 沙箱环境准备由于真实的支付宝和微信商户需要营业执照、对公账户等资质毕业设计阶段肯定是用沙箱环境。支付宝沙箱的申请和使用比想象中简单得多用你的支付宝账号登录开放平台进入沙箱环境平台会给你一套单独的AppID和应用私钥、支付宝公钥。这个AppID是独立于真实应用的你在沙箱里随便造数据不担心影响真实业务。沙箱环境提供了一个沙箱版支付宝的APP可以在手机应用市场下载如果搜不到就用支付宝官方文档里提供的二维码扫描下载。使用沙箱账号登录这个APP后就能真实模拟扫码、确认支付、输入密码的完整流程页面上的交互和真实支付宝几乎一致。办理一个商户号在真实环境需要营业执照甚至小额账户验证周期长、门槛高所以肯定不做。微信支付的沙箱环境虽然没有支付宝那么完善但有一个模拟商户号可用于测试部分接口。微信支付官方有提供一个测试商户的流程你提交申请后平台会给你一套测试用的商户号用于联调。如果等不及也可以用支付宝沙箱完成主要流程演示微信支付部分用代码展示配合Mock数据说明。但如果你有营业执照那直接申请一个真实的微信支付商户号走真实交易测试效果远好于任何模拟环境。6.2 下单到支付成功的完整演示路径项目运行的完整链路我是这样演示的启动Django开发服务器访问首页注册一个测试账号并登录。浏览商品列表选择一个商品加入购物车点击去结算填写收货地址如果做了后提交订单。此时订单状态为待支付跳转到收银台页面可以选择支付宝或微信。选择支付宝后后端生成支付参数跳转到沙箱支付宝页面。在沙箱APP或网页上确认支付输入支付密码支付成功后支付宝异步回调立刻触发后端收到回调后修改订单为已支付。此时前端页面上轮询到订单状态变化自动跳转到支付成功页展示支付金额和支付流水号。整个演示过程不需要额外操作前后端状态流转完全自动化效果非常直观。答辩时给评委现场演示一遍比自己嘴上讲半个小时PPT都有说服力。6.3 关键日志与排错经验我在实际调试中踩过几个很值得记录的坑这里整理成清单你可以直接对照自己的项目排查第一支付宝回调携带的total_amount是字符串100.00单位是元而我的数据库存储单位是分所以拿到后要int(float(total_amount) * 100)。注意这里必须先转float再乘100如果直接用Decimal就会踩精度坑。第二微信支付v3的回调请求头里有个Wechatpay-Timestamp这个时间戳和当前服务器时间如果差得太多验签会失败。开发时如果服务器时间不准ntpdate校时后立刻重试就好了。第三微信支付的code_url生成的二维码如果扫出来提示参数错误十有八九是description字段里出现了Emoji或特殊字符微信对description的字符集有要求。例如商品名里有【爆款】这种在中括号内的字符就可能导致URL参数解析异常换成纯文本或去掉特殊符号就好。第四回调接口返回的HTTP状态码和内容体要按平台要求来。支付宝要求返回纯文本success微信支付v3要求返回HTTP 200且body为{code: SUCCESS}。如果你返回200但body格式不对微信也会认为通知失败并继续重试。7. 常见问题排查与避坑指南7.1 本地开发环境下的联调问题本地开发最大的痛点是回调地址没法直接访问。支付宝和微信的服务器要回调你的notify_url而你在本机的127.0.0.1地址外网服务器根本访问不到。解决办法有两个。第一用内网穿透工具把本机的8000端口映射到一个公网域名上然后把notify_url配成这个公网域名加/payment/notify/路径。这样支付平台的服务器就能通过公网域名访问到你本机的服务了。注意内网穿透工具可能会有调试请求日志的免费额度联调足够用但不要在生产环境用稳定性没保障。第二也是更推荐的是使用支付宝沙箱自带的调试工具。支付宝开放平台提供了一个API调试工具可以直接传入参数模拟回调。你用这个工具构造一个回调请求POST到你的notify_url就能完全不依赖外网环境验证回调逻辑。缺点是只支持支付宝微信支付没有这种工具需要配合内网穿透。7.2 回调丢失和重复支付的对策如果用户实际支付成功了但你的系统一直显示待支付优先排查回调是否被拦截、服务器日志里有没有收到的POST请求、验签是否通过。如果验签通过但业务处理报错了支付平台会重试。重试的间隔越来越长所以如果第一次失败后你没能及时发现修好Bug后可能要好几个小时才能等到下一次回调。这时候最稳妥的办法是写一个脚本在收到用户反馈后主动调用查询接口补一次订单状态同步。重复支付的问题更隐蔽。用户下了100元订单先发起了支付宝支付但没付完又改用微信支付并成功付款然后支付宝那笔也完成了这时候你收到两笔不同渠道的成功回调。处理方式是在订单状态变成已支付后对后到的那笔回调直接拒绝处理并主动发起退款。在回调处理时通过查询订单状态是否已终态这一步来拦截这类场景。7.3 表格支付宝与微信支付对比速查表对比维度支付宝电脑网站支付微信支付Native扫码支付模式跳转到支付宝页面后端生成二维码用户扫码沙箱支持完善有独立沙箱账号有测试商户号流程复杂回调内容明文参数 sign验签AES-256-GCM加密 平台证书验签回调成功返回纯文本 success{code: SUCCESS}金额单位元字符串分整数同步跳转有return_url不可信无同步跳转全靠回调主动查询alipay.trade.query/v3/pay/transactions/out-trade-no/文档质量全面资料丰富v3版本相对好但仍有不少细节埋坑8. 项目文件组织与答辩准备建议8.1 目录结构的合理规划答辩时老师大概率会问你的项目结构是怎么设计的所以目录结构不能乱。我建议按下面的形式组织order_payment_system/ ├── manage.py ├── requirements.txt ├── config/ # 项目配置文件 │ ├── settings.py │ ├── urls.py │ └── celery.py如果有 ├── apps/ │ ├── users/ # 用户模块 │ ├── products/ # 商品模块 │ ├── orders/ # 订单模块 │ │ ├── models.py │ │ ├── views.py │ │ └── services.py # 订单业务逻辑 │ └── payments/ # 支付模块 │ ├── models.py │ ├── alipay.py # 支付宝对接 │ ├── wechat.py # 微信对接 │ └── notifies.py # 回调处理 ├── static/ # 静态资源 ├── templates/ # 页面模板 └── docs/ # 使用说明、需求文档、答辩PPT把支付SDK的对接代码单独拆成alipay.py和wechat.py两个文件是答辩时一个非常便于展示的亮点。一个是你可以直接告诉老师渠道封装是隔离的以后要加别的支付渠道只需要新增文件这体现了良好的软件设计思维。8.2 使用说明文档的写法一个优秀的毕业设计项目资料使用说明绝对不能只有python manage.py runserver这一行。我建议至少包含环境依赖Python版本、Django版本、MySQL版本、Redis版本、所有pip依赖及版本号。初始化步骤创建虚拟环境、安装依赖、配置数据库包括创建数据库的SQL语句、执行迁移、初始化商品数据。密钥配置说明支付宝和微信支付的密钥文件放哪里、环境变量怎么设置、沙箱参数如何获取。尤其要注意把密钥文件放到不被Git跟踪的路径或者用.env文件加环境变量管理。功能演示路径从首页到完成支付的每个步骤每个步骤应该看到什么页面、产生什么数据库变化。常见问题解决本地启动失败、回调不通、验签失败等问题的排查方法。README文档一定要写详细这不仅是给老师看的也是给自己答辩前快速恢复环境用的。8.3 答辩话术与技巧答辩的时候老师问得最多的几个问题你可以提前准备好回答思路关于你这个项目的难点在哪里不要只回答调通了支付宝接口而是要说把支付宝、微信两套完全不同的支付流程抽象成统一的支付服务通过回调幂等、主动查询兜底、乐观锁扣库存这几个机制保证资金安全。这个回答展现了你的抽象能力和对业务的理解深度。关于如果微信回调一直不来怎么处理要回答支付宝和微信都有主动查询接口我会在前端轮询等待的同时后端定期调用查询接口兜底另外用户主动刷新订单详情也会触发一次查询。而不是只说等回调来。关于数据库扣库存会不会超卖要回答用了乐观锁通过版本号保证数据库层面的原子更新而不是先查出来再手动减。准备这三个问题的回答基本能挡住80%的追问。剩下的问题基本都是从你的项目结构或代码里现场找的只要你确实是自己写的按实际情况回答就好。9. 项目完成后还能怎么扩展说实话这个项目做完并不代表结束它其实是一个非常好的基础框架往上加功能都非常自然。可以加一个订单超时自动关闭的Celery定时任务把那套定时器逻辑做成可视化配置。可以加一个基于DRF的RESTful API接口出来把后端接口独立出来方便对接小程序或APP这样你的项目就从Web网站升级成了前后端分离项目。如果你做完支付又想做消息推送可以接入短信或邮件通知在支付成功回调里触发。这些都是简历上可以写的方向。我个人的建议是优先做API化和接口测试。Django原生的模板渲染虽然简单但现实工作中几乎都是前后端分离架构你能把支付逻辑封装成通用的API服务这个经验比单纯做出来一个能跑的网站值钱得多。另外把关键接口下单、支付、回调、查询写成单元测试答辩时亮出测试覆盖率报告也是很扎实的亮点。毕业设计不是目的通过它把客户端的请求是怎么一步步变成真实的资金流转把回调、验签、幂等、并发控制这些后端核心能力真正摸透才是你花这几个月时间最大的回报。希望这篇整理能让你少走一些弯路也祝你答辩顺利。本文还有配套的精品资源点击获取
返回列表