Article

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"
}
}

❌ 错误码说明

通用错误码

错误码错误类型错误消息处理建议
200Success操作成功-
400ValidationException参数验证失败检查输入参数是否正确
401UnauthorizedException未授权访问请先登录获取有效Token
403ForbiddenException权限不足检查用户权限
404NotFoundException资源不存在确认资源ID是否正确
409ConflictException资源冲突检查资源状态
429RateLimitException请求频率过高请稍后重试
500InternalServerException服务器内部错误稍后重试或联系管理员
502BadGatewayException网关错误稍后重试
503ServiceUnavailableException服务不可用稍后重试

业务错误码

错误码错误类型错误消息处理建议
1001UserNotFound用户不存在确认用户是否已注册
1002InvalidCredentials用户名或密码错误检查登录凭据
1003TokenExpiredToken已过期重新登录获取新Token
1004AccountLocked账号已锁定联系管理员解锁
2001AssetNotFound资产不存在确认资产ID是否正确
2002InsufficientBalance余额不足检查资产余额
2003InvalidAssetType无效的资产类型使用正确的资产类型
3001RecordNotFound记录不存在确认记录ID是否正确
3002InvalidRecordType无效的记录类型使用正确的记录类型
3003InvalidAmount无效的金额检查金额是否为正数
4001GoalNotFound目标不存在确认目标ID是否正确
4002GoalCompleted目标已完成目标已完成,无法修改
4003InsufficientFunds资金不足检查虚拟钱包余额
5001FileNotFound文件不存在确认文件ID是否正确
5002FileTooLarge文件过大使用较小的文件
5003InvalidFileType无效的文件类型使用支持的文件类型

🔧 使用示例

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 requests
import 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 - 让后端集成更简单、更可靠 🚀