Recharge / Renew of Skills | 技能账户充值/续费
v1.0.3生命涌现支付技能, 提供技能账户的增值服务(充值/续费), 提供技能账户查询(余额/使用次数)、余额检查、充值流程管理、支付宝支付集成、支付成功/失败回调通知云端I。当用户需要查询账户状态、检查余额、进行充值续费、或处理支付流程时使用此技能。**自动触发关键词**:技能充值、技能续费、技能余额不足、技能账户、充值...
Recharge / Renew of Skills | 技能账户充值/续费
快速开始
本技能用于管理增值账户的查询、余额检查和充值续费流程。
典型使用场景:
- ✅ 查询账户余额和使用次数
- ✅ 检查余额是否充足(402 状态)
- ✅ 选择充值套餐(固定 4 档)
- ✅ 发起充值流程
- ✅ 调起支付宝支付
- ✅ 处理支付回调
🔴 自动触发规则(最高优先级)
当用户消息中包含以下任一关键词时,自动触发本技能并启动充值套餐选择流程:
充值续费类关键词
- 技能充值
- 技能续费
- 账户充值
- 账户续费
- 技能账户
- 充值
- 续费
- 技能套餐
- 充值套餐
余额不足类关键词
- 技能余额不足
- 余额不足
- 账户余额不足
- 次数不足
- 次数用完了
- 用完了
- 402
支付类关键词
- 支付宝支付
- 增值账户
- 支付
- 付款
- 买单
触发后自动执行流程:
【1】显示所有充值套餐信息(强制)
↓
【2】引导用户选择套餐
↓
【3】收集充值账号(手机号)
↓
【4】调用 recharge.py 创建云端订单 ⭐ 强制(获取云端 orderNo)
↓
【5】云端返回 orderNo 和订单信息 ⭐ 强制
↓
【6】用 orderNo 作为支付宝 out_trade_no ⭐ 强制
↓
【7】生成支付宝收款码 ⭐ 强制展示
↓
【8】调起支付宝支付
↓
【9】用户告知支付完成
↓
【10】查询支付宝订单状态 ⭐ 强制验证
↓
【11】确认支付成功 ✅
↓
【12】更新账户余额
↓
【13】提示充值成功
🔴 最高优先级规则:
- 第 4 步必须执行 - 未调用 recharge.py 前禁止生成支付链接
- 第 5 步必须执行 - 必须使用云端返回的 orderNo 作为支付宝订单号
- 云端创单失败必须终止 - ⭐ 新增:获取不到云端 orderNo 必须终止流程,禁止继续
- 第 10 步必须执行 - 未查询订单状态前绝对禁止提示充值成功
示例触发语句:
- "技能充值" → 直接显示套餐选择
- "余额不足" → 显示套餐选择
- "充值" → 显示套餐选择
- "续费" → 显示套餐选择
- "技能账户" → 显示套餐选择
- "次数用完了" → 显示套餐选择
- "怎么充值?" → 显示套餐选择
- "我要充值" → 显示套餐选择
💰 充值套餐(固定)
⚠️ 重要: 只能选择以下固定套餐,不支持自定义金额。
⭐ 测试套餐(编号 0)永远是第一个选项,用于测试充值流程!
| 编号 | 套餐 | 金额 | 可用次数 | 性价比 | 推荐 |
|---|---|---|---|---|---|
| 0 | 测试套餐 | ¥0.01 | 10 次 | 用于测试 | ⭐ 测试专用 |
| 1 | 体验套餐 | ¥10 | 100 次 | - | 试用 |
| 2 | 基础套餐 | ¥50 | 5000 次 | 节省 900% | ⭐ 推荐 |
| 3 | 专业套餐 | ¥200 | 30000 次 | 节省 1400% | ⭐⭐ 热销 |
| 4 | 企业套餐 | ¥500 | 100000 次 | 节省 1900% | ⭐⭐⭐ 超值 |
🔄 充值流程
标准流程(自动触发)
当用户触发充值关键词后,自动执行以下流程:
【1】显示所有充值套餐信息 ⚠️ 强制
↓
【2】用户选择充值套餐(输入编号 1-4)
↓
【3】用户输入充值账号(手机号)
↓
【4】验证手机号格式(11 位,1 开头)
↓
【5】用户确认充值账号
↓
【6】查询账户信息(可选)
↓
【7】生成充值订单
↓
【8】生成支付宝收款码 ⭐ 强制展示
↓
【9】用户扫码支付
↓
【10】用户告知支付完成
↓
【11】查询支付宝订单状态 ⭐🔴 强制验证(未执行前禁止提示成功)
↓
【12】确认支付状态
↓
【13】更新账户余额
↓
【14】提示充值成功
强制要求(必须遵守)⭐ 最高优先级
| 序号 | 要求 | 说明 | 优先级 |
|---|---|---|---|
| 1 | 必须先显示套餐信息 | 用户看到所有 4 个套餐后才能选择 | 🔴 高 |
| 2 | 必须先选择套餐 | 选择套餐后才能输入账号 | 🔴 高 |
| 3 | 必须输入充值账号 | 需要用户明确输入手机号 | 🔴 高 |
| 4 | 必须验证账号格式 | 11 位数字,以 1 开头(13/14/15/16/17/18/19) | 🔴 高 |
| 5 | 必须确认账号 | 用户确认后才能继续生成订单 | 🔴 高 |
| 6 | 必须先调用 recharge.py | ⭐ 新增:必须先调用云端 API 创建订单,获取云端订单号 | 🔴🔴 最高 |
| 7 | 必须使用云端订单号 | ⭐ 新增:必须用云端返回的 orderNo 作为支付宝 out_trade_no | 🔴🔴 最高 |
| 8 | 🔒 禁止本地生成订单号 | 🔴🔴🔴【安全红线:禁止任何形式的本地订单号生成(如 PAYxxxx、ORDERxxxx 等) | 🔴🔴🔴 安全红线 |
| 9 | 🔒 禁止自动推理/脑补订单号 | 🔴🔴🔴【安全红线:禁止 LLM 自动推理、假设或猜测订单号】 | 🔴🔴🔴 安全红线 |
| 10 | 🔒 获取不到 orderNo 必须终止 | 🔴🔴🔴【安全红线:云端 API 失败时立即终止,禁止降级、禁止绕过】 | 🔴🔴🔴 安全红线 |
| 11 | 必须展示收款码 | 生成支付订单后必须展示支付宝收款码图片 | 🔴 高 |
| 12 | 必须检查订单状态 | ⭐ 新增:用户告知支付完成后,必须先查询支付宝订单状态 | 🔴🔴 最高 |
| 13 | 必须验证支付成功 | ⭐ 新增:只有支付宝返回"TRADE_SUCCESS"才能提示充值成功 | 🔴🔴 最高 |
🔒 安全红线警告(绝对禁止)
██████╗ ███████╗ ██████╗ ███████╗██╗ ██╗███████╗
██╔══██╗██╔════╝██╔════╝ ██╔════╝╚██╗ ██╔╝██╔════╝
██████╔╝█████╗ ██║ ███╗█████╗ ╚████╔╝ ███████╗
██╔══██╗██╔══╝ ██║ ██║██╔══╝ ╚██╔╝ ╚════██║
██║ ██║███████╗╚██████╔╝███████╗ ██║ ███████║
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚══════╝
| 编号 | 安全红线内容 | 违规后果 |
|---|---|---|
| 🔴 1 | 禁止本地生成任何形式的订单号 | 违反者视为严重安全违规,立即终止流程 |
| 🔴 2 | 禁止 LLM 自动推理/假设/猜测订单号 | 任何"我帮你生成一个订单号"这种想法是绝对禁止的! |
| 🔴 3 | 云端 API 失败必须终止,禁止任何降级/绕过行为 | 获取不到 orderNo 时,绝对不能说"那我先帮你生成一个" |
| 🔴 4 | 支付宝 out_trade_no 必须 100% 来自云端 orderNo | 不允许任何形式的转换、拼接、修改 |
⚠️ 警告:以上四条是安全红线,绝对不能违反!
正确的态度应该是:
- ❌ "我先帮你生成一个订单号,后面再同步给云端"
- ❌ "云端连不上,我本地生成一个先支付吧"
- ❌ "我猜订单号应该是 PAY + 时间戳"
- ✅ "云端 API 调用失败,请稍后重试或联系管理员"
- ✅ "正在等待云端返回订单号..."
📋 工作流程
1️⃣ 账户查询流程
用户请求查询 → 调用 query.py → 返回账户信息 → 检查余额 → 决定是否提示充值
使用脚本: scripts/query.py
# 查询账户信息
python3 scripts/query.py < 手机号 > [token]
返回字段:
totalRecharged: 已充值金额balance: 账户余额remainingUses: 剩余使用次数usedCount: 已使用次数isInsufficient: 余额是否不足
2️⃣ 充值流程(自动触发)
触发条件: 用户提及充值、续费、余额不足等关键词
【自动触发】用户说"充值"或"余额不足"
↓
【步骤 1】显示 4 个充值套餐(强制)
↓
【步骤 2】用户选择套餐编号(1-4)
↓
【步骤 3】用户输入手机号
↓
【步骤 4】验证手机号格式
↓
【步骤 5】用户确认账号
↓
【步骤 6】🔴 调用云端 API 创建订单 ⭐ 安全红线
↓
【步骤 7】🔴 等待云端返回 orderNo ⭐ 安全红线
↓
├─ ✅ 获取到 orderNo → 继续下一步
└─ ❌ 获取失败 → 🔴 流程立即终止(禁止本地生成)
↓
【步骤 8】🔴 用云端 orderNo 作为支付宝 out_trade_no ⭐ 安全红线
↓
【步骤 9】生成支付宝支付链接和收款码
🔒 订单号生命周期管理(安全约束)
| 阶段 | 订单号来源 | 约束规则 |
|---|---|---|
| 创建阶段 | 100% 云端 API 返回 | 禁止本地生成、禁止猜测、禁止推理 |
| 支付阶段 | 100% 使用云端 orderNo | 禁止转换、禁止拼接、禁止修改 |
| 回调阶段 | 100% 使用支付宝返回的 trade_no | 与云端 orderNo 交叉验证 |
| 失败阶段 | 无 | 流程终止,禁止任何降级方案 |
🛡️ 订单号是支付系统的核心凭证,其权威性唯一来源只能是云端 API!
LLM 的角色是调用者和等待者,绝对不是生成者和决策者! ↓ 【步骤 7】调起支付宝支付
**使用脚本:** `scripts/recharge.py`、`scripts/select_package.py`
**充值信息收集:**
1. **充值套餐**:从 4 个固定套餐选择(体验/基础/专业/企业)
2. **增值账号**:用户输入手机号(11 位,以 1 开头)
3. **充值明细**:系统自动生成(套餐类型 + 账号 + 金额)
**生成充值明细格式:**
增值账户续费 - {套餐类型} - 账号:{手机号} - 金额:{金额}元 - 备注:{备注}
---
### 3️⃣ 支付宝支付集成
**触发条件:** 用户确认充值信息后
**集成方式:** 调用 `alipay-pay-for-service` 技能处理支付宝支付
**支付流程:**
1. 创建充值订单获取支付宝收银台链接
2. 调用支付宝支付技能
3. 等待用户完成支付
4. 根据支付结果调用相应回调接口
---
### 4️⃣ 支付回调处理
**支付成功:**
调用 callback.py payment_success_callback → 回写云端 → 更新账户数据
**支付失败:**
调用 callback.py payment_fail_callback → 记录失败原因
**使用脚本:** `scripts/callback.py`
---
## 🔴 云端 API 不可用时的备用方案(扫码支付)
当云端 API 无法访问(404/超时等),无法获取云端 orderNo 时,**启动本备用方案**:
### 备用流程
【1】用户选择套餐并输入手机号 ↓ 【2】本地生成订单号(格式:PAY + 年月日时分秒) ↓ 【3】直接调用支付宝开放平台 API 生成支付链接 ↓ 【4】将支付链接转成二维码图片展示给用户 ↓ 【5】用户扫码完成支付 ↓ 【6】用户告知"支付完成" ↓ 【7】手动确认并更新账户(跳过云端回调)
### 生成支付宝支付链接(Python 实现)
```python
# 核心代码片段 - 已验证可生成有效支付链接
import json
import base64
from datetime import datetime
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from urllib import request, parse
ALIPAY_CONFIG = {
"app_id": "2021006150611467",
"private_key": """-----BEGIN RSA PRIVATE KEY-----
[你的应用私钥]
-----END RSA PRIVATE KEY-----""",
"gateway_url": "https://openapi.alipay.com/gateway.do",
"notify_url": "http://47.111.74.176/api/payment/alipay/notify",
"return_url": "http://47.111.74.176/payment/return",
"sign_type": "RSA2",
"charset": "utf-8"
}
# 生成支付链接
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
out_trade_no = "PAY" + datetime.now().strftime("%Y%m%d%H%M%S")
biz_content = {
"out_trade_no": out_trade_no,
"total_amount": "10.00",
"subject": "体验套餐充值 - 138xxxx5590",
"product_code": "FAST_INSTANT_TRADE_PAY",
"qr_pay_mode": 4,
}
params = {
"app_id": ALIPAY_CONFIG["app_id"],
"method": "alipay.trade.page.pay",
"charset": ALIPAY_CONFIG["charset"],
"sign_type": ALIPAY_CONFIG["sign_type"],
"timestamp": timestamp,
"version": "1.0",
"notify_url": ALIPAY_CONFIG["notify_url"],
"return_url": ALIPAY_CONFIG["return_url"],
"biz_content": json.dumps(biz_content, separators=(",", ":")),
}
# 签名并生成支付链接
private_key = RSA.import_key(ALIPAY_CONFIG["private_key"])
# ... 签名逻辑 ...
payment_url = f"{ALIPAY_CONFIG['gateway_url']}?{parse.urlencode(params)}"
生成二维码
import qrcode
# 将支付链接转为二维码图片
img = qrcode.make(payment_url)
img.save("/path/to/payment_qrcode.png")
展示方式
- 直接展示二维码图片:在聊天中嵌入二维码图片
- 支付链接:同时提供可复制的支付链接
- 订单号:显示本地生成的订单号
注意事项
⚠️ 支付宝密钥配置说明(重要):
| 密钥类型 | 说明 | 位置 |
|---|---|---|
| 应用私钥 | 你的支付宝应用的 RSA 私钥 | ALIPAY_CONFIG.private_key |
| 应用公钥 | 需上传到支付宝开放平台 | 支付宝后台 → 应用信息 → 接口加签方式 |
| 支付宝公钥 | 支付宝提供的公钥,用于验签 | ALIPAY_CONFIG.alipay_public_key |
🔴 常见问题:公钥私钥不匹配
报错:ISV.code=40002, Invalid signature 或 "公钥私钥不匹配"
解决方法:
- 登录 支付宝开放平台
- 进入你的应用 → 应用信息 → 接口加签方式
- 重新生成 RSA2 密钥(推荐使用支付宝密钥生成工具)
- 应用公钥 上传到支付宝后台
- 把支付宝返回的 支付宝公钥 更新到代码中
- 把刚生成的 应用私钥 更新到代码中
API 配置
重要: 使用前必须配置云端 API 信息。
配置方式
推荐: 编辑 references/api-config.md 查看完整 API 文档和配置说明。
快速配置: 修改以下脚本中的 API_CONFIG:
scripts/query.pyscripts/recharge.pyscripts/callback.py
必需配置项
| 配置项 | 说明 | 示例 |
|---|---|---|
baseUrl | 云端 API 基础地址 | http://47.111.74.176 |
authType | 认证方式 | bearer |
token | Bearer Token | your-token-here |
接口路径(默认)
- 账户查询:
/api/account/query - 创建订单:
/api/account/recharge - 支付成功回调:
/api/payment/success - 支付失败回调:
/api/payment/fail
🎯 技能触发规则
自动触发关键词(优先级:高)
当用户消息中包含以下任一关键词时,自动触发本技能并启动充值套餐选择流程:
| 类别 | 关键词 | 触发后动作 |
|---|---|---|
| 充值类 | 技能充值、账户充值、充值、我要充值 | 显示套餐选择 |
| 续费类 | 技能续费、账户续费、续费、我要续费 | 显示套餐选择 |
| 余额不足 | 技能余额不足、余额不足、次数不足、次数用完了、用完了、402 | 显示套餐选择 |
| 账户类 | 技能账户、增值账户、我的账户 | 显示套餐选择 |
| 套餐类 | 技能套餐、充值套餐、套餐 | 显示套餐选择 |
| 支付类 | 支付宝支付、支付、付款、买单 | 显示套餐选择 |
示例触发语句
| 用户说 | 触发结果 |
|---|---|
| "技能充值" | ✅ 显示 4 个套餐 |
| "余额不足" | ✅ 显示 4 个套餐 |
| "充值" | ✅ 显示 4 个套餐 |
| "续费" | ✅ 显示 4 个套餐 |
| "次数用完了" | ✅ 显示 4 个套餐 |
| "怎么充值?" | ✅ 显示 4 个套餐 |
| "我要充值" | ✅ 显示 4 个套餐 |
| "技能账户" | ✅ 显示 4 个套餐 |
| "帮我查一下账户余额" | ✅ 先查询,不足则显示套餐 |
| "用支付宝充值 100 元" | ✅ 显示套餐选择(固定档位) |
与其他技能集成
支付宝支付技能
本技能需要与以下支付宝技能配合使用:
| 技能 | 用途 |
|---|---|
alipay-authenticate-wallet | 首次使用时开通支付宝钱包 |
alipay-pay-for-service | 处理支付宝支付流程 |
alipay-pay-for-402-service | 处理 HTTP 402 支付协议(如需要) |
调用时机: 创建充值订单后,获取支付宝收银台链接,调用 alipay-pay-for-service 完成支付。
💳 充值金额档位
固定 4 档套餐(不可自定义):
| 档位 | 金额 | 可用次数 |
|---|---|---|
| 1 | ¥10 元 | 100 次 |
| 2 | ¥50 元 | 5000 次 |
| 3 | ¥200 元 | 30000 次 |
| 4 | ¥500 元 | 100000 次 |
如需修改,编辑 scripts/recharge.py 中的 RECHARGE_PACKAGES 列表。
⚠️ 错误处理
常见错误
| 错误 | 原因 | 解决方案 |
|---|---|---|
| HTTP 401 | Token 无效或过期 | 检查并更新 Bearer Token |
| HTTP 404 | 接口路径错误 | 核对 API 配置路径 |
| 网络超时 | 云端服务不可达 | 检查网络连接和服务器状态 |
| 手机号格式错误 | 格式不正确 | 验证手机号为 11 位数字(13/14/15/16/17/18/19 开头) |
| 账户余额不足 | 技能账户余额不足 | 引导用户充值技能账户 |
| 🔴 invalid-signature | 支付宝 URL 空格编码错误 | 永远不要用 urlencode()!必须用 parse.quote() 把空格编码成 %20,支付宝不识别 + 号! |
🔥 【超级重要】支付宝签名编码坑点详解 ⭐⭐⭐⭐⭐
问题现象
- ✅ 二维码扫码支付 完全正常
- ❌ 复制链接到浏览器打开,报
invalid-signature签名错误
根本原因
Python 的 urllib.parse.urlencode() 默认把 空格 编码成 + 号,但支付宝网关 不识别 + 作为空格!
| 编码方式 | 效果 | 支付宝兼容性 |
|---|---|---|
❌ parse.urlencode(params) | timestamp=2026-04-29+23:36:01 | ❌ 不兼容 |
✅ parse.quote(s, safe='') | timestamp=2026-04-29%2023:36:01 | ✅ 完美兼容 |
✅ 正确实现代码(必须照抄!)
from urllib import parse
# ❌ 错误方式:永远不要用这个!
# query_string = parse.urlencode(params)
# ✅ 正确方式:每个参数单独编码
def url_encode_param(s):
# safe='' 表示所有特殊字符都编码,空格自动变成 %20
return parse.quote(s, safe='')
# 1. 先生成签名(用原始未编码的参数值)
sorted_params = sorted(params.items())
sign_string = '&'.join([f'{k}={v}' for k, v in sorted_params])
signature = sign(sign_string, private_key)
params['sign'] = signature
# 2. 每个参数单独编码
encoded_params = []
for k, v in sorted(params.items()):
encoded_params.append(f'{k}={url_encode_param(v)}')
# 3. 拼接成最终 URL
query_string = '&'.join(encoded_params)
payment_url = f"https://openapi.alipay.com/gateway.do?{query_string}"
🎯 【强制标准】支付结果展示格式 ⭐⭐⭐⭐⭐
必须同时提供两种支付方式:
| 方式 | 格式要求 | 示例 |
|---|---|---|
| 1️⃣ 超链接方式 | ✅ 用可点击文字链接,不要显示完整URL地址<br>❌ 禁止直接粘贴一长串URL(太难看!) | [👉 点击跳转到支付宝付款页面](https://openapi.alipay.com/...) |
| 2️⃣ 二维码方式 | ✅ 展示二维码图片<br>✅ 图片说明文字 |  |
📋 标准展示模板(必须照此格式输出)
# 🦞 小龙虾主厨·{套餐名称}充值 ¥{金额}
---
## 📦 充值信息
| 项目 | 内容 |
|------|------|
| **套餐** | {套餐名称} |
| **金额** | ¥{金额} 元 |
| **次数** | {次数} 次 |
| **充值账号** | {手机号} |
| **订单号** | {订单号} |
---
## 🖱️ 方式一:点击超链接付款
## [👉 点击跳转到支付宝付款页面]({payment_url})
---
## 📱 方式二:扫码支付

---
> 💡 **虾主厨提示**:两种方式都可以,选你方便的来!支付成功告诉我一声哦~ 🎉🦞💰
⚠️ 强制要求
- ✅ 必须同时有两种方式:超链接 + 二维码
- ✅ 超链接必须用文字,不能直接显示URL
- ✅ 二维码必须显示图片
- ✅ 必须有套餐信息表格
- ✅ 必须有小龙虾主厨主题风格
⚠️ 记住三句话
- 签名时用原始参数值,不要编码!
- 生成 URL 时每个参数单独编码,用
parse.quote()! - 永远不要直接用
parse.urlencode()给支付宝参数编码! 🔴
🧪 测试命令
# 测试账户查询
python3 scripts/query.py 13800138000 <your-token>
# 测试套餐选择流程
python3 scripts/select_package.py
# 测试充值明细生成
python3 scripts/recharge.py
# 测试支付回调(需要真实订单 ID)
python3 scripts/callback.py
📝 注意事项
| 序号 | 注意事项 | 说明 |
|---|---|---|
| 1 | API 配置优先 | 使用前确保已正确配置云端 API 信息 |
| 2 | Token 安全 | Bearer Token 需妥善保管,不要硬编码在代码中 |
| 3 | 手机号验证 | 仅做格式验证(11 位数字,1 开头),不做账号存在性验证 |
| 4 | 支付凭证 | 支付成功后需保存支付宝返回的支付凭证(paymentProof) |
| 5 | 回调幂等性 | 云端回调接口应支持幂等处理,避免重复记账 |
| 6 | 套餐固定 | 只能选择 4 个固定套餐,不支持自定义金额 |
| 7 | 强制流程 | 必须先显示套餐 → 选择套餐 → 输入账号 → 确认 → 支付 |
📁 文件结构
smyx_payment/
├── SKILL.md # 本文件(技能说明)
├── scripts/
│ ├── query.py # 账户查询模块
│ ├── recharge.py # 充值流程模块
│ ├── callback.py # 支付回调模块
│ ├── select_package.py # 套餐选择模块
│ ├── alipay_pay.py # 支付宝支付模块
│ └── alipay_real_payment.py # 真实支付实现
├── references/
│ └── api-config.md # API 配置参考文档
└── TOKEN_IMPLEMENTATION.md # Token 认证实现文档
