首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >ChatGPT Plus 充值后如何核验到账?用 SQL 对齐订单与套餐状态

ChatGPT Plus 充值后如何核验到账?用 SQL 对齐订单与套餐状态

原创
作者头像
用户12688822
发布2026-09-08 14:23:29
发布2026-09-08 14:23:29
390
举报

订单显示“已付款”,交付记录显示“完成”,账户里却还需要确认 Plus 状态:这三个记录回答的是不同问题。自建订单系统如果把它们压成一个“成功”字段,客服和用户就容易各说各话。

下面用一组构造订单和人工套餐观察记录,演示一条 SQLite 对账查询。查询为每个订单给出确认付款、继续处理、补充证据或核对套餐等下一步,方便定位和跟进。

一、先把三种记录分开

支付记录表示系统是否确认收款;交付记录表示订单系统是否完成自己的交付步骤;套餐证据表示某个账户在某个观察时间显示了什么套餐。交付一份操作指引或开通材料,不等于目标账户已经显示 Plus。

示例保留两个数据集合。orders 记录订单代号、目标账户代号、付款状态、交付状态和付款确认时间;evidence 记录关联订单、实际观察账户、套餐名称和观察时间。账户代号用于演示。实际系统应采用稳定的账户标识,确保观察记录对应订单的目标账户。

refunded 表示已有确认的退款记录。退款状态与会员状态分别保留,方便同时核对资金处理和订阅结果。

二、时间和账号都要能对上

查询时点固定为北京时间 2026 年 9 月 8 日 12:00。所有时间先整理成同一种格式;本例只比较时间间隔,不做时区转换,也不混用 Unix 秒和本地时间文本。

“新鲜”暂定为查询前 30 分钟内,并且观察时间不早于付款确认时间。30 分钟是本例采用的证据新鲜度参数,实际取值由业务核验规则确定。超出窗口、晚于查询时点或账号不一致的记录,都转入复核。

同一订单有多条证据时,按观察时间选择最新一条,不按写入编号判断新旧。O04 特意放入一条编号较大、实际更早的 Free 记录,验证旧观察不会盖住较新的 Plus 观察。最新记录若存在账号或时间问题,本例保留问题等待复核,不回退到旧的有利记录。

三、直接运行这段 SQLite 查询

保存下列内容为 reconciliation.sql,使用支持窗口函数的 SQLite 运行:sqlite3 :memory: < reconciliation.sql。数据由 CTE 中的 VALUES 提供,在内存中完成查询,可直接离线复现。

代码语言:sql
复制
-- Constructed data; all timestamps use the same Beijing wall-clock format.
WITH
params(as_of) AS (VALUES ('2026-09-08 12:00:00')),
orders(order_key, target_account, payment_state, delivery_state, paid_at) AS (
  VALUES
  ('O01', 'A01', 'pending',  'none',       NULL),
  ('O02', 'A02', 'paid',     'processing', '2026-09-08 11:20:00'),
  ('O03', 'A03', 'paid',     'completed',  '2026-09-08 11:20:00'),
  ('O04', 'A04', 'paid',     'completed',  '2026-09-08 11:20:00'),
  ('O05', 'A05', 'paid',     'completed',  '2026-09-08 11:20:00'),
  ('O06', 'A06', 'paid',     'completed',  '2026-09-08 11:20:00'),
  ('O07', 'A07', 'refunded', 'completed',  '2026-09-08 11:20:00'),
  ('O08', 'A08', 'paid',     'completed',  '2026-09-08 11:20:00'),
  ('O09', 'A09', 'paid',     'completed',  '2026-09-08 11:20:00')
),
evidence(evidence_id, order_key, account_key, plan_name, observed_at) AS (
  VALUES
  (1, 'O04', 'A04', 'plus', '2026-09-08 11:50:00'),
  (2, 'O04', 'A04', 'free', '2026-09-08 11:10:00'),
  (3, 'O05', 'A05', 'plus', '2026-09-08 11:25:00'),
  (4, 'O06', 'B06', 'plus', '2026-09-08 11:55:00'),
  (5, 'O07', 'A07', 'plus', '2026-09-08 11:55:00'),
  (6, 'O08', 'A08', 'free', '2026-09-08 11:55:00'),
  (7, 'O09', 'A09', 'plus', '2026-09-08 12:05:00')
),
ranked AS (
  SELECT e.*, ROW_NUMBER() OVER (
    PARTITION BY order_key
    ORDER BY julianday(observed_at) DESC, evidence_id DESC
  ) AS rn
  FROM evidence AS e
),
checked AS (
  SELECT o.*, p.as_of,
    CASE
      WHEN e.evidence_id IS NULL THEN 'no_record'
      WHEN o.target_account IS NULL OR trim(o.target_account) = ''
        OR e.account_key IS NULL OR trim(e.account_key) = ''
        OR e.account_key <> o.target_account
        THEN 'account_mismatch'
      WHEN julianday(e.observed_at) IS NULL
        OR julianday(e.observed_at) > julianday(p.as_of)
        THEN 'invalid_time'
      WHEN julianday(o.paid_at) IS NULL THEN 'payment_time_unknown'
      WHEN julianday(e.observed_at) < julianday(o.paid_at)
        OR julianday(e.observed_at) < julianday(p.as_of, '-30 minutes')
        THEN 'stale'
      WHEN e.plan_name = 'plus' THEN 'recent_plus'
      WHEN e.plan_name IS NULL OR trim(e.plan_name) = '' THEN 'unknown_plan'
      ELSE 'recent_other_plan'
    END AS evidence_state
  FROM orders AS o CROSS JOIN params AS p
  LEFT JOIN ranked AS e ON e.order_key = o.order_key AND e.rn = 1
)
SELECT order_key, payment_state, delivery_state, evidence_state,
  CASE
    WHEN payment_state = 'refunded' THEN 'refund_review'
    WHEN payment_state IS NULL OR payment_state <> 'paid' THEN 'confirm_payment'
    WHEN julianday(paid_at) IS NULL OR julianday(paid_at) > julianday(as_of)
      THEN 'check_payment_time'
    WHEN evidence_state = 'recent_plus' THEN 'plus_observed'
    WHEN evidence_state <> 'no_record' THEN 'review_evidence'
    WHEN delivery_state = 'processing' THEN 'processing'
    ELSE 'verify_plan'
  END AS next_step
FROM checked
ORDER BY order_key;

四、怎样读输出

查询保留原始付款和交付状态,另给出 evidence_statenext_step。九个样例的下一步如下:

订单

下一步输出

对应含义

O01

confirm_payment

支付尚未确认

O02

processing

已付,交付记录仍在处理

O03

verify_plan

交付记录完成,套餐尚无证据

O04

plus_observed

有同账号、新鲜且晚于付款的 Plus 观察

O05

review_evidence

观察已超出新鲜度窗口

O06

review_evidence

观察账户与目标账户不同

O07

refund_review

退款记录需与订阅状态分别核对

O08

review_evidence

同账号近期显示 Free,继续复核

O09

review_evidence

观察时间在未来,不采用该证据

O03 接下来补充套餐观察,O08 则核对当前套餐与预期结果的差异。把同账号、带观察时间的记录补齐后,再运行查询更新处理方向。

O04 记录的是“该账号观察时显示 Plus”。续费场景还需对比有效期与本次订单对应的订阅周期,以确认新增时长。

五、把查询结果接入处理流程

实际接入时,把 orders 替换成可靠的订单与付款记录,把 evidence 替换成已关联目标账号的套餐观察。交付完成对应的具体步骤应有统一定义;部分退款、重复事件与同一时刻存在冲突的观察,另设处理分支。

本次离线核验的九个核心情形和十一个边界用例全部通过,覆盖缺少目标账号、付款时间缺失、证据早于付款、窗口边界及更新观察等情况。

保留原始的支付、交付和套餐记录,将查出的差异交给相应处理流程。每次补齐新证据后重新核验,处理人员就能看到问题推进到了哪一步。

语法依据:SQLite 官方的 WITH 子句窗口函数日期时间函数。CTE 用于组织样本,窗口函数选择观察记录,日期函数用于比较统一格式的时间。

相关资料

AIXiamo|ChatGPT Plus / Pro 开通与订单排查资料

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、先把三种记录分开
  • 二、时间和账号都要能对上
  • 三、直接运行这段 SQLite 查询
  • 四、怎样读输出
  • 五、把查询结果接入处理流程
  • 相关资料
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档