Penny Lens API 接口文档
2026年6月24日 · 10 分钟阅读 · ixNieStudio
详细的 API 接口文档,包含所有端点的请求参数、响应格式、错误码和使用示例,为开发者提供完整的接口参考。
Penny Lens API 接口文档
🎯 概述
Penny Lens API 是基于支付宝小程序云 Serverless 的统一后端接口,为 PC 端和移动端提供完整的数据服务和业务逻辑处理。本文档详细介绍了所有 API 端点的使用方法。
🔧 基础信息
基础URL
https://your-domain.com/api认证方式
所有需要认证的接口都需要在请求头中包含 JWT Token:
Authorization: Bearer <your-jwt-token>请求格式
所有请求都使用 JSON 格式:
{ "action": "service.method", "params": { // 请求参数 }}响应格式
所有响应都遵循统一格式:
{ "code": 200, "message": "操作成功", "data": { // 响应数据 }}📊 用户认证接口
1. 用户登录
接口地址: POST /api
请求参数:
{ "action": "user.login", "params": { "platform": "email", "email": "user@example.com", "password": "password123", "deviceId": "device123", "deviceInfo": "iOS 15.0, iPhone 13" }}响应示例:
{ "code": 200, "message": "登录成功", "data": { "id": "61c0c50b6d1b2c001fd2a345", "username": "user123", "email": "user@example.com", "avatar": "https://example.com/avatar.jpg", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "createdAt": 1639149835278, "updatedAt": 1642345678901 }}2. 微信登录
请求参数:
{ "action": "user.login", "params": { "platform": "wechat", "code": "wx_auth_code", "deviceId": "device123", "deviceInfo": "iOS 15.0, iPhone 13" }}3. 支付宝登录
请求参数:
{ "action": "user.login", "params": { "platform": "alipay", "authCode": "alipay_auth_code", "deviceId": "device123", "deviceInfo": "iOS 15.0, iPhone 13" }}4. 用户注册
请求参数:
{ "action": "user.register", "params": { "username": "newuser", "email": "newuser@example.com", "password": "password123", "deviceId": "device123", "deviceInfo": "iOS 15.0, iPhone 13" }}5. Token 验证
请求参数:
{ "action": "user.verifyToken", "params": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }}6. 用户注销
请求参数:
{ "action": "user.logout", "params": {}}💰 资产管理接口
1. 创建资产
请求参数:
{ "action": "asset.create", "params": { "name": "招商银行储蓄卡", "type": "bankCard", "balance": 10000, "currency": "CNY", "description": "工资卡", "icon": "bank-card", "isDefault": false }}响应示例:
{ "code": 200, "message": "创建资产成功", "data": { "id": "61c0c50b6d1b2c001fd2a345" }}2. 查询资产列表
请求参数:
{ "action": "asset.query", "params": { "type": "bankCard", "status": "normal", "page": 1, "pageSize": 10 }}响应示例:
{ "code": 200, "message": "查询成功", "data": { "list": [ { "_id": "61c0c50b6d1b2c001fd2a345", "name": "招商银行储蓄卡", "type": "bankCard", "balance": 10000, "currency": "CNY", "description": "工资卡", "status": "normal", "icon": "bank-card", "isDefault": false, "createdAt": 1639149835278, "updatedAt": 1639149835278, "delFlag": false } ], "total": 1, "page": 1, "pageSize": 10 }}3. 获取资产详情
请求参数:
{ "action": "asset.detail", "params": { "id": "61c0c50b6d1b2c001fd2a345" }}4. 更新资产
请求参数:
{ "action": "asset.update", "params": { "id": "61c0c50b6d1b2c001fd2a345", "name": "招商银行储蓄卡(更新)", "description": "工资卡和日常消费", "isDefault": true }}5. 删除资产
请求参数:
{ "action": "asset.delete", "params": { "id": "61c0c50b6d1b2c001fd2a345" }}📝 记账管理接口
1. 创建收入记录
请求参数:
{ "action": "accounting.create", "params": { "type": "income", "amount": 5000, "category": "salary", "asset": "61c0c50b6d1b2c001fd2a345", "description": "工资收入", "date": 1642345678901, "tags": ["工资", "收入"] }}2. 创建支出记录
请求参数:
{ "action": "accounting.create", "params": { "type": "expense", "amount": 100, "category": "food", "asset": "61c0c50b6d1b2c001fd2a345", "description": "午餐", "date": 1642345678901, "tags": ["餐饮", "日常"] }}3. 创建转账记录
请求参数:
{ "action": "accounting.create", "params": { "type": "transfer", "amount": 1000, "fromAsset": "61c0c50b6d1b2c001fd2a345", "toAsset": "61c0c50b6d1b2c001fd2a346", "description": "转账到支付宝", "date": 1642345678901, "fee": 2 }}4. 查询记账记录
请求参数:
{ "action": "accounting.query", "params": { "type": "expense", "startDate": 1642345678901, "endDate": 1642345678901, "category": "food", "page": 1, "pageSize": 20 }}5. 更新记账记录
请求参数:
{ "action": "accounting.update", "params": { "id": "61c0c50b6d1b2c001fd2a347", "amount": 120, "description": "午餐(更新)", "category": "food" }}6. 删除记账记录
请求参数:
{ "action": "accounting.delete", "params": { "id": "61c0c50b6d1b2c001fd2a347" }}🎯 储蓄游戏接口
1. 创建储蓄目标
请求参数:
{ "action": "savings.createGoal", "params": { "title": "旅行基金", "description": "存钱去日本旅行", "targetAmount": 10000, "startDate": 1642345678901, "endDate": 1673881678901, "category": "vacation", "priority": "high", "isPublic": true }}2. 查询储蓄目标
请求参数:
{ "action": "savings.queryGoals", "params": { "status": "active", "category": "vacation", "page": 1, "pageSize": 10 }}3. 更新目标进度
请求参数:
{ "action": "savings.updateProgress", "params": { "goalId": "61c0c50b6d1b2c001fd2a348", "amount": 500 }}4. 虚拟交易 - 买入股票
请求参数:
{ "action": "savings.buyStock", "params": { "stockId": "61c0c50b6d1b2c001fd2a349", "quantity": 100 }}5. 虚拟交易 - 卖出股票
请求参数:
{ "action": "savings.sellStock", "params": { "stockId": "61c0c50b6d1b2c001fd2a349", "quantity": 50 }}6. 获取虚拟钱包
请求参数:
{ "action": "savings.getWallet", "params": {}}7. 获取持仓信息
请求参数:
{ "action": "savings.getPositions", "params": {}}8. 获取成就列表
请求参数:
{ "action": "savings.getAchievements", "params": { "category": "savings", "completed": false }}9. 获取排行榜
请求参数:
{ "action": "savings.getLeaderboard", "params": { "type": "total_savings", "period": "monthly" }}📊 统计分析接口
1. 收支统计
请求参数:
{ "action": "stats.getIncomeExpense", "params": { "startDate": 1642345678901, "endDate": 1642345678901, "groupBy": "day" }}响应示例:
{ "code": 200, "message": "查询成功", "data": { "income": { "total": 10000, "count": 5, "average": 2000, "trend": "up" }, "expense": { "total": 3000, "count": 15, "average": 200, "trend": "stable" }, "netIncome": 7000, "period": { "startDate": 1642345678901, "endDate": 1642345678901 } }}2. 分类统计
请求参数:
{ "action": "stats.getCategoryStats", "params": { "type": "expense", "startDate": 1642345678901, "endDate": 1642345678901, "limit": 10 }}3. 资产统计
请求参数:
{ "action": "stats.getAssetStats", "params": {}}4. 趋势分析
请求参数:
{ "action": "stats.getTrend", "params": { "type": "income", "startDate": 1642345678901, "endDate": 1642345678901, "groupBy": "week" }}📁 文件管理接口
1. 上传文件
请求参数:
{ "action": "file.upload", "params": { "fileName": "receipt.jpg", "fileType": "image/jpeg", "fileSize": 1024000, "category": "receipt" }}响应示例:
{ "code": 200, "message": "上传成功", "data": { "fileId": "61c0c50b6d1b2c001fd2a350", "url": "https://oss.example.com/files/receipt.jpg", "uploadUrl": "https://oss.example.com/upload/receipt.jpg" }}2. 查询文件列表
请求参数:
{ "action": "file.query", "params": { "category": "receipt", "page": 1, "pageSize": 20 }}3. 删除文件
请求参数:
{ "action": "file.delete", "params": { "fileId": "61c0c50b6d1b2c001fd2a350" }}🔗 短链接接口
1. 创建短链接
请求参数:
{ "action": "shortlink.create", "params": { "url": "https://example.com/very-long-url", "title": "示例链接", "description": "这是一个示例链接", "expireAt": 1673881678901, "isPublic": true }}2. 查询短链接
请求参数:
{ "action": "shortlink.query", "params": { "code": "abc123" }}3. 更新短链接
请求参数:
{ "action": "shortlink.update", "params": { "id": "61c0c50b6d1b2c001fd2a351", "title": "更新后的标题", "description": "更新后的描述" }}4. 删除短链接
请求参数:
{ "action": "shortlink.delete", "params": { "id": "61c0c50b6d1b2c001fd2a351" }}❌ 错误码说明
通用错误码
| 错误码 | 错误类型 | 错误消息 | 处理建议 |
|---|---|---|---|
| 200 | Success | 操作成功 | - |
| 400 | ValidationException | 参数验证失败 | 检查输入参数是否正确 |
| 401 | UnauthorizedException | 未授权访问 | 请先登录获取有效Token |
| 403 | ForbiddenException | 权限不足 | 检查用户权限 |
| 404 | NotFoundException | 资源不存在 | 确认资源ID是否正确 |
| 409 | ConflictException | 资源冲突 | 检查资源状态 |
| 429 | RateLimitException | 请求频率过高 | 请稍后重试 |
| 500 | InternalServerException | 服务器内部错误 | 稍后重试或联系管理员 |
| 502 | BadGatewayException | 网关错误 | 稍后重试 |
| 503 | ServiceUnavailableException | 服务不可用 | 稍后重试 |
业务错误码
| 错误码 | 错误类型 | 错误消息 | 处理建议 |
|---|---|---|---|
| 1001 | UserNotFound | 用户不存在 | 确认用户是否已注册 |
| 1002 | InvalidCredentials | 用户名或密码错误 | 检查登录凭据 |
| 1003 | TokenExpired | Token已过期 | 重新登录获取新Token |
| 1004 | AccountLocked | 账号已锁定 | 联系管理员解锁 |
| 2001 | AssetNotFound | 资产不存在 | 确认资产ID是否正确 |
| 2002 | InsufficientBalance | 余额不足 | 检查资产余额 |
| 2003 | InvalidAssetType | 无效的资产类型 | 使用正确的资产类型 |
| 3001 | RecordNotFound | 记录不存在 | 确认记录ID是否正确 |
| 3002 | InvalidRecordType | 无效的记录类型 | 使用正确的记录类型 |
| 3003 | InvalidAmount | 无效的金额 | 检查金额是否为正数 |
| 4001 | GoalNotFound | 目标不存在 | 确认目标ID是否正确 |
| 4002 | GoalCompleted | 目标已完成 | 目标已完成,无法修改 |
| 4003 | InsufficientFunds | 资金不足 | 检查虚拟钱包余额 |
| 5001 | FileNotFound | 文件不存在 | 确认文件ID是否正确 |
| 5002 | FileTooLarge | 文件过大 | 使用较小的文件 |
| 5003 | InvalidFileType | 无效的文件类型 | 使用支持的文件类型 |
🔧 使用示例
JavaScript/TypeScript 示例
// API 客户端类class PennyLensAPI { private baseURL: string; private token: string | null = null;
constructor(baseURL: string) { this.baseURL = baseURL; }
// 设置认证Token setToken(token: string) { this.token = token; }
// 发送请求 async request(action: string, params: any = {}) { const response = await fetch(`${this.baseURL}/api`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...(this.token && { 'Authorization': `Bearer ${this.token}` }) }, body: JSON.stringify({ action, params }) });
const data = await response.json();
if (data.code !== 200) { throw new Error(data.message); }
return data.data; }
// 用户登录 async login(platform: string, credentials: any) { return this.request('user.login', { platform, ...credentials }); }
// 创建资产 async createAsset(assetData: any) { return this.request('asset.create', assetData); }
// 查询资产列表 async getAssets(params: any = {}) { return this.request('asset.query', params); }
// 创建记账记录 async createRecord(recordData: any) { return this.request('accounting.create', recordData); }
// 查询记账记录 async getRecords(params: any = {}) { return this.request('accounting.query', params); }}
// 使用示例const api = new PennyLensAPI('https://your-domain.com');
// 用户登录try { const loginResult = await api.login('email', { email: 'user@example.com', password: 'password123', deviceId: 'device123', deviceInfo: 'iOS 15.0, iPhone 13' });
api.setToken(loginResult.token); console.log('登录成功:', loginResult);} catch (error) { console.error('登录失败:', error.message);}
// 创建资产try { const asset = await api.createAsset({ name: '招商银行储蓄卡', type: 'bankCard', balance: 10000, currency: 'CNY', description: '工资卡' }); console.log('创建资产成功:', asset);} catch (error) { console.error('创建资产失败:', error.message);}
// 创建支出记录try { const record = await api.createRecord({ type: 'expense', amount: 100, category: 'food', asset: 'asset-id', description: '午餐', date: Date.now() }); console.log('创建记录成功:', record);} catch (error) { console.error('创建记录失败:', error.message);}Python 示例
import requestsimport json
class PennyLensAPI: def __init__(self, base_url): self.base_url = base_url self.token = None
def set_token(self, token): self.token = token
def request(self, action, params=None): if params is None: params = {}
headers = { 'Content-Type': 'application/json' }
if self.token: headers['Authorization'] = f'Bearer {self.token}'
response = requests.post( f'{self.base_url}/api', headers=headers, data=json.dumps({'action': action, 'params': params}) )
data = response.json()
if data['code'] != 200: raise Exception(data['message'])
return data['data']
def login(self, platform, **credentials): return self.request('user.login', {'platform': platform, **credentials})
def create_asset(self, asset_data): return self.request('asset.create', asset_data)
def get_assets(self, params=None): if params is None: params = {} return self.request('asset.query', params)
def create_record(self, record_data): return self.request('accounting.create', record_data)
def get_records(self, params=None): if params is None: params = {} return self.request('accounting.query', params)
# 使用示例api = PennyLensAPI('https://your-domain.com')
# 用户登录try: login_result = api.login('email', email='user@example.com', password='password123', deviceId='device123', deviceInfo='iOS 15.0, iPhone 13' )
api.set_token(login_result['token']) print('登录成功:', login_result)except Exception as e: print('登录失败:', str(e))
# 创建资产try: asset = api.create_asset({ 'name': '招商银行储蓄卡', 'type': 'bankCard', 'balance': 10000, 'currency': 'CNY', 'description': '工资卡' }) print('创建资产成功:', asset)except Exception as e: print('创建资产失败:', str(e))📚 最佳实践
1. 错误处理
- 始终检查响应状态码
- 实现重试机制处理网络错误
- 提供用户友好的错误提示
- 记录错误日志便于调试
2. 性能优化
- 使用分页查询避免一次性加载大量数据
- 实现本地缓存减少重复请求
- 使用批量操作提高效率
- 合理设置请求超时时间
3. 安全考虑
- 妥善保管API Token
- 使用HTTPS传输敏感数据
- 验证所有输入参数
- 定期更新Token
4. 开发建议
- 使用TypeScript获得更好的类型安全
- 实现统一的错误处理机制
- 编写单元测试确保接口稳定性
- 使用API文档工具生成文档
Penny Lens API - 让后端集成更简单、更可靠 🚀