Django对接Square支付后订单模型创建及购物车状态更新异常问题
餐桌点餐应用支付后数据不一致问题排查
应用核心模型定义
class Dish(models.Model): some other fields() class Cart(models.Model): customer = models.ForeignKey(User) session_key = models.CharField(max_length=40) dish = models.ForeignKey(Dish) order = models.ForeignKey(Order) paid = models.CharField(max_length = 3, default = "No") some other fields() class Order(models.Model): customer = models.ForeignKey(User) session_key = models.CharField(max_length=40) some other fields()
未认证用户Session生成逻辑
def create_session(request): session = request.session if not session.session_key: session.create() return session
Square支付处理视图
from square.client import Client def square_payment(request): # 该视图通过POST请求接收订单总额、令牌等必要数据,此处省略细节 if request.method == "POST": # 创建Square客户端对象处理支付 client = Client(access_token= "some access token",environment= "production") body = {} body['amount_money']['amount'] = "some amount" # 按body中指定金额执行支付 result = client.payments.create_payment(body = body) if result.is_success(): if request.user.is_authenticated: order_object = Order.objects.create(customer = request.user) Cart.objects.filter(customer = request.user, paid = "No").update(paid = "Yes") else: session = create_session(request) order_object = Order.objects.create(session_key = session.session_key) Cart.objects.filter(session_key = session.session_key, paid = "No").update(paid = "Yes") elif result.is_error(): return JsonResponse({"Message":"Error"})
现场测试异常现象
- 情况1:支付成功,Order对象创建成功,对应购物车项paid字段更新为“Yes”(正常流程)
- 情况2:支付成功,Order对象创建成功,但购物车项paid字段未更新
- 情况3:支付成功,但Order对象未创建,购物车项paid字段也未更新
排查方向
- 数据库事务缺失:当前代码中创建Order和更新Cart是两个独立的数据库操作,无事务包裹。若创建Order后出现数据库连接中断、锁冲突等问题,会导致Cart更新失败(对应情况2)。需用
transaction.atomic()将两个操作包裹为原子事务,确保要么都成功,要么都回滚。 - Session一致性问题:未认证用户支付时重新调用
create_session获取session_key,可能因生产环境Session存储(如Redis)延迟、请求间Session状态不一致,导致过滤的Cart项与实际购物车不匹配。建议在添加商品到Cart时就固定session_key,支付时直接使用Cart中已存储的session_key进行过滤,而非重新生成。 - 支付结果判断逻辑漏洞:
result.is_success()可能存在误判,比如Square返回的响应中包含隐性错误(如部分金额未到账),或网络波动导致响应解析异常。需在代码中添加日志,记录result的完整返回内容,确认进入成功分支时支付状态是否真的完全正常。 - 并发请求与幂等性问题:现场可能存在用户重复点击支付按钮导致多请求并发处理,引发数据竞争。需给Square支付请求添加
idempotency_key(Square要求的幂等参数),同时在视图中先校验当前购物车是否已有paid为“Yes”的项,避免重复处理。 - 过滤条件准确性验证:检查Cart数据的完整性:已认证用户的Cart是否都正确填充了
customer字段,无Null值;未认证用户的Cart的session_key是否与支付时获取的完全一致(无大小写、空格等差异)。可通过数据库查询统计异常数据,比如Cart.objects.filter(customer__isnull=True, paid="No")查看未认证用户的购物车项情况。 - 日志缺失问题:当前代码无任何日志记录,无法追踪异常发生时的上下文。需在关键节点添加日志:比如支付成功时记录用户ID/session_key、执行的SQL更新语句;支付失败时记录Square的错误码、错误信息;创建Order和更新Cart前后分别记录操作状态。
- 生产环境配置差异:对比本地与生产环境的数据库配置,比如生产环境是否开启了读写分离,导致更新操作未及时同步到读库;或数据库的自动提交模式是否与本地不同,引发部分操作未生效。
- 模型字段约束问题:Cart的
customer和session_key是否允许Null?若未认证用户的Cart中customer为Null,已认证用户的session_key为Null,需确认过滤条件是否准确(比如已认证用户仅用customer过滤,未认证用户仅用session_key过滤),避免因字段值冲突导致过滤不到目标数据。
内容的提问来源于stack exchange,提问作者Gonza Cánepa
相关产品推荐
相关产品推荐

