配置已保存

WLW OpenAPI 测试工具

完整的 API 测试工具和 SDK 示例代码

# 常见问题 ## Q1: 签名验证失败怎么办? ### 排查步骤 1. **检查时间戳** - 确保时间戳在当前时间的 ±300 秒(5分钟)内 - 检查服务器时间是否准确同步 - 使用 NTP 同步系统时间 2. **检查参数顺序** - 确保所有参数按字母顺序排序 - 确保排除 signature 参数 - 参数名大小写要完全匹配 3. **检查密钥** - 确认 SecretKey 正确无误 - 检查是否有前导或后缀空格 - 确认使用的是正确环境的密钥 4. **检查编码** - 确保使用 UTF-8 编码 - 检查特殊字符是否正确转义 - 确认签名字符串构造正确 ### 示例修复 ```python # 问题:密钥包含空格 SECRET_KEY = " sk_abc123 " # 错误 SECRET_KEY = "sk_abc123" # 正确 # 问题:参数顺序错误 params = "b=2&a=1" # 错误 params = "a=1&b=2" # 正确(按字母顺序) # 问题:时间戳过期 timestamp = "1234567890" # 错误(太旧) timestamp = str(int(time.time())) # 正确(当前时间) ``` ### 调试技巧 ```python def debug_signature(method, path, params, secret_key): # 打印签名字符串 sorted_params = "&".join( f"{k}={v}" for k, v in sorted(params.items()) if k != 'signature' ) sign_str = f"{method}{path}{params['timestamp']}{params['nonce']}{sorted_params}" print(f"签名字符串: {sign_str}") # 生成签名 signature = hmac.new( secret_key.encode(), sign_str.encode(), hashlib.sha256 ).hexdigest() print(f"生成签名: {signature}") return signature ``` --- ## Q2: 请求频率超限怎么解决? ### 解决方案 1. **降低请求频率** - 合理规划请求时间 - 批量操作改为分批处理 - 增加请求间隔 2. **实现指数退避重试** - 使用 2^n 秒间隔重试 - 添加随机抖动避免同时重试 - 设置最大重试次数 3. **联系管理员调整限流配置** - 说明业务需求 - 申请更高的频率限制 - 考虑使用多个 AccessKey 分散请求 ### 重试示例 ```python import time import random def api_request_with_backoff(request_func, max_retries=3): """使用指数退避策略重试""" for attempt in range(max_retries): try: return request_func() except APIError as e: if e.code == 429: # 频率限制 if attempt == max_retries - 1: raise # 最后一次尝试失败,抛出异常 # 指数退避: 2^n + 随机抖动 delay = (2 ** attempt) + random.uniform(0, 1) print(f"频率限制,等待 {delay:.2f} 秒后重试...") time.sleep(delay) else: raise # 其他错误直接抛出 # 使用示例 result = api_request_with_backoff(lambda: client.get_card_info("CARD123")) ``` ### 监控告警 建议设置以下监控指标: - 429 错误出现频率 - 请求成功率 - 平均响应时间 - 重试次数统计 --- ## Q3: 卡板状态不允许操作怎么办? ### 状态说明 不同操作对卡板状态有要求: | 操作 | 允许的状态 | 不允许的状态 | |------|-----------------|---------------------| | 复机 | 停机(4) | 已激活(2)、风险停机(5)、销户(6) | | 停机 | 已激活(2) | 停机(4)、销户(6) | | 订购套餐 | 已激活(2) | 其他所有状态 | | 查询信息 | 所有状态 | 无限制 | ### 状态检查 ```python def check_card_status(card_info, operation): """检查卡板状态是否允许操作""" status = card_info.get('status') status_map = { 1: "待激活", 2: "已激活", 3: "机卡分离", 4: "停机", 5: "风险停机", 6: "销户", 7: "库存", 8: "其他", 9: "可测试", 10: "达量断网" } status_name = status_map.get(status, "未知状态") print(f"卡板状态: {status} ({status_name})") # 检查操作权限 allowed_operations = { 'restart': [4], # 复机:仅停机状态 'stop': [2], # 停机:仅已激活状态 'order': [2], # 订购:仅已激活状态 'query': list(range(1, 11)) # 查询:所有状态 } if status in allowed_operations.get(operation, []): return True else: print(f"当前状态 ({status_name}) 不允许执行 {operation} 操作") return False # 使用示例 card_info = client.get_card_info("CARD123") if check_card_status(card_info, 'stop'): client.stop_card("CARD123") ``` ### 处理建议 - **待激活状态**:先激活卡板 - **停机状态**:需要先复机才能使用 - **风险停机**:联系管理员人工处理 - **销户状态**:无法恢复,需重新开户 --- ## Q4: 如何调试签名问题? ### 调试工具 创建一个调试函数,对比客户端和服务器的签名计算过程: ```python def debug_signature_detailed(method, path, params, secret_key): """详细调试签名生成过程""" print("=== 签名调试信息 ===") # 1. 显示原始参数 print("\n1. 原始参数:") for k, v in params.items(): print(f" {k} = {v}") # 2. 排除 signature 并排序 print("\n2. 排序后参数(排除signature):") sorted_params = [] for k in sorted(params.keys()): if k != 'signature': sorted_params.append(f"{k}={params[k]}") print(f" {k} = {params[k]}") # 3. 构造参数字符串 param_str = "&".join(sorted_params) print(f"\n3. 参数字符串:\n {param_str}") # 4. 构造签名字符串 sign_str = f"{method}{path}{params['timestamp']}{params['nonce']}{param_str}" print(f"\n4. 签名字符串:\n {sign_str}") # 5. 生成签名 signature = hmac.new( secret_key.encode('utf-8'), sign_str.encode('utf-8'), hashlib.sha256 ).hexdigest() print(f"\n5. 生成签名:\n {signature}") # 6. 对比 if 'signature' in params: print(f"\n6. 参数中的签名:\n {params['signature']}") print(f"\n7. 签名匹配: {signature == params['signature']}") print("\n===================") return signature ``` ### 在线调试 可以使用在线工具验证 HMAC-SHA256 签名: - https://www.devglan.com/online-tools/hmac-sha256-online - https://tooltt.com/hmac-sha256/ 将签名字符串和密钥输入,对比生成的签名是否一致。 --- ## Q5: 如何验证环境配置? ### 验证清单 在正式使用 API 前,建议验证以下项目: - [ ] 确认 Base URL 正确(包括协议和端口) - [ ] 验证网络连通性(能否访问服务器) - [ ] 检查 AccessKey 和 SecretKey 是否正确 - [ ] 确认服务器时间同步(时间偏差 < 5分钟) - [ ] 测试心跳接口是否正常 ### 验证脚本 ```bash #!/bin/bash echo "=== WLW OpenAPI 环境验证 ===" echo "" # 配置信息 BASE_URL="http://your-api-server.com" ACCESS_KEY="ak_xxxxxxxxxx" SECRET_KEY="sk_xxxxxxxxxx" # 1. 网络连通性测试 echo "1. 网络连通性测试..." if curl -I "$BASE_URL/api/v1/heartbeat" \ --connect-timeout 10 \ --max-time 30 \ -s -o /dev/null -w "%{http_code}" | grep -q "200"; then echo " ✅ 网络连接正常" else echo " ❌ 网络连接失败" exit 1 fi echo "" # 2. 时间同步检查 echo "2. 时间同步检查..." LOCAL_TIME=$(date +%s) echo " 本地时间戳: $LOCAL_TIME" echo " 建议使用 NTP 同步: sudo ntpdate -u pool.ntp.org" echo "" # 3. 心跳接口测试 echo "3. 心跳接口测试..." TIMESTAMP=$(date +%s) NONCE=$(uuidgen) # 构造签名(简化版,实际需要完整实现) PARAMS="access_key=$ACCESS_KEY&nonce=$NONCE&timestamp=$TIMESTAMP" SIGN_STR="GET/api/v1/heartbeat${TIMESTAMP}${NONCE}${PARAMS}" # 这里需要实现 HMAC-SHA256 签名 # SIGNATURE=$(echo -n "$SIGN_STR" | openssl dgst -sha256 -hmac "$SECRET_KEY" | cut -d' ' -f2) echo " 签名字符串: $SIGN_STR" echo " 如果签名验证失败,请检查 SecretKey 是否正确" echo "" # 4. AccessKey 验证 echo "4. AccessKey 验证..." if [[ $ACCESS_KEY == ak_* ]]; then echo " ✅ AccessKey 格式正确" else echo " ⚠️ AccessKey 格式可能不正确(应以 ak_ 开头)" fi echo "" # 5. SecretKey 验证 echo "5. SecretKey 验证..." if [[ ${#SECRET_KEY} -ge 16 ]]; then echo " ✅ SecretKey 长度符合要求" else echo " ❌ SecretKey 长度不足(应至少16字符)" fi echo "" echo "=== 验证完成 ===" ``` ### Python 验证脚本 ```python #!/usr/bin/env python3 """环境配置验证脚本""" import sys import time import socket from urllib.parse import urlparse def check_network(base_url): """检查网络连通性""" try: parsed = urlparse(base_url) host = parsed.hostname port = parsed.port or (443 if parsed.scheme == 'https' else 80) sock = socket.create_connection((host, port), timeout=10) sock.close() print("✅ 网络连接正常") return True except Exception as e: print(f"❌ 网络连接失败: {e}") return False def check_time_sync(): """检查时间同步""" local_time = int(time.time()) print(f"✅ 本地时间戳: {local_time}") print(f" 时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(local_time))}") return True def check_credentials(access_key, secret_key): """检查凭据格式""" if access_key.startswith('ak_'): print("✅ AccessKey 格式正确") else: print("⚠️ AccessKey 格式可能不正确") if len(secret_key) >= 16: print("✅ SecretKey 长度符合要求") else: print("❌ SecretKey 长度不足") return True if __name__ == "__main__": BASE_URL = "http://your-api-server.com" ACCESS_KEY = "ak_xxxxxxxxxx" SECRET_KEY = "sk_xxxxxxxxxx" print("=== WLW OpenAPI 环境验证 ===\n") print("1. 网络连通性测试") check_network(BASE_URL) print() print("2. 时间同步检查") check_time_sync() print() print("3. 凭据格式检查") check_credentials(ACCESS_KEY, SECRET_KEY) print() print("=== 验证完成 ===") ``` --- ## Q6: 如何处理超时问题? ### 超时类型 1. **连接超时**:无法建立 TCP 连接 2. **读取超时**:连接建立但响应缓慢 3. **请求超时**:整体请求时间过长 ### 解决方案 ```python # 设置合理的超时时间 client = WLWOpenAPIClient( base_url="https://api.example.com", access_key="ak_xxx", secret_key="sk_xxx", timeout=30 # 30秒超时 ) # 实现重试机制 def request_with_retry(func, max_retries=3): for attempt in range(max_retries): try: return func() except TimeoutError: if attempt == max_retries - 1: raise print(f"请求超时,重试 {attempt + 1}/{max_retries}") time.sleep(2 ** attempt) ``` --- ## 更多问题? 如果以上内容没有解决您的问题,请: 1. 查看 API 响应中的详细错误信息 2. 检查系统日志获取更多上下文 3. 联系技术支持团队,提供: - 请求 ID(X-Request-ID) - 完整的错误信息 - 请求时间和卡板编号 - 重现步骤