调用 api-recharge.geely.com 旗下所有接口,自动处理阿里云 API 网关签名(X-Ca)。
支持两种模式:直接注入 authToken(简单)和 全自动 Token 刷新(需配置)。
GeelyRechargeClient/
├── GeelyRechargeClient.sln
├── src/GeelyRechargeClient/ # 类库(net10.0,无第三方依赖)
│ ├── GeelyRechargeClient.csproj
│ ├── GeelyApiConfig.cs # 配置类(init-only,不可变)
│ ├── TokenState.cs # Token 状态基类 + 域特定子类
│ ├── AliApiGatewaySignHelper.cs # 阿里云 API 网关签名工具(多域支持)
│ ├── GeelyRechargeHttpClient.cs # 核心客户端(签名 + 可选自动刷新)
│ └── ServiceCollectionExtensions.cs # DI 注入扩展(ASP.NET Core 用)
├── samples/GeelyRechargeClient.Sample/ # 使用示例(Exe,从 appsettings.json 读取配置)
│ ├── appsettings.json # 配置文件(需自行创建,参考 appsettings.example.json)
│ └── Program.cs
└── README.md
authToken 有效期约 30 分钟,非一次性,可重复使用。从 App 抓包获取一次后可连续使用 30 分钟。
var config = new GeelyApiConfig
{
RechargeApiKey = "<YOUR_RECHARGE_API_KEY>",
RechargeAppSecret = "<YOUR_RECHARGE_APP_SECRET>",
RechargeBaseUrl = "https://api-recharge.geely.com",
UserId = "<YOUR_USER_ID>",
SourceTypeKey = "0010000",
ChannelId = "01701001",
OAuth2ClientId = "<YOUR_OAUTH2_CLIENT_ID>",
};
var client = new GeelyRechargeHttpClient(config);
// 注入已有效的 authToken(从 App 抓包获取,有效期 ~30 分钟)
client.SetAuthToken(
authToken: "<YOUR_AUTH_TOKEN>",
expireInSeconds: 1799); // 提前 60s 失效,填 1799
// 调用接口
var result = await client.PostAsync(
"/gep/v1/home/charge/getMyEquipmentDetail",
new
{
sourceTypeKey = "0010000",
userId = config.UserId,
providerNo = "DIRECT_WDZ",
equipmentId = "70100603425",
});
// result["code"] == "0" 表示成功适用于服务长时间运行,token 过期后自动刷新。通过 appsettings.json 配置(参考 appsettings.example.json)。
var config = new GeelyApiConfig
{
// api-recharge 签名配置
RechargeApiKey = "<YOUR_RECHARGE_API_KEY>",
RechargeAppSecret = "<YOUR_RECHARGE_APP_SECRET>",
// galaxy-user-api 配置(自动刷新需要)
UserApiKey = "<YOUR_USER_API_KEY>",
UserAppSecret = "<YOUR_USER_APP_SECRET>",
UserApiBaseUrl = "https://galaxy-user-api.geely.com",
UserId = "<YOUR_USER_ID>",
DeviceId = "<YOUR_DEVICE_ID>",
DeviceType = "IOS",
CenterRefreshToken = "<YOUR_CENTER_REFRESH_TOKEN>", // 有效期 ~20 天
SourceTypeKey = "0010000",
ChannelId = "01701001",
OAuth2ClientId = "<YOUR_OAUTH2_CLIENT_ID>",
OAuth2Scope = "snsapiUserinfo,snsapiMobile",
};
using var client = new GeelyRechargeHttpClient(config);
// 可选:持久化服务端刷新后的 refreshToken
client.OnCenterRefreshTokenUpdated = newToken => {
// 保存到文件/数据库,下次启动时使用
};
// 直接调用,Token 过期时自动刷新
var result = await client.PostAsync("/gep/v1/home/charge/getMyEquipmentDetail", new { ... });项目通过 GeelyApiConfig 类接收配置,支持两种方式:
复制 appsettings.example.json 为 appsettings.json,填入你的密钥:
cp appsettings.example.json appsettings.json
# 编辑 appsettings.json,替换 <YOUR_XXX> 占位符DI 场景下自动绑定配置节 "GeelyApi":
builder.Services.AddGeelyRechargeClient(builder.Configuration);var config = new GeelyApiConfig
{
RechargeApiKey = "...",
// ...
};| 配置项 | 说明 |
|---|---|
RechargeApiKey |
api-recharge 域 x-ca-key |
RechargeAppSecret |
api-recharge 域签名密钥 |
UserApiKey |
galaxy-user-api 域 x-ca-key |
UserAppSecret |
galaxy-user-api 域签名密钥 |
CenterRefreshToken |
Center refreshToken(有效期 ~20 天) |
UserId |
用户 ID |
DeviceId |
设备 ID |
OAuth2ClientId |
OAuth2 clientId |
调用任意接口
└─> authToken 有效?
├─ YES → 直接请求
└─ NO → [刷新流程]
① Center 短 token 有效?
├─ YES → 跳至 ②
└─ NO → 用 CenterRefreshToken 调 login/refresh 获取新短 token
② 用短 token 调 oauth2/code 获取 code
③ 用 code 调 getTokenByCode 获取新 authToken(有效期 1799s)
└─> 继续原始请求
└─> 响应 code=999(token 在请求途中失效)
└─> 重新执行一次刷新流程,再重试
- 签名原文格式(
\n分隔):METHOD\nACCEPT\nCONTENT-MD5\nCONTENT-TYPE\n\nHEADER1:VALUE1\n...PATH Date不参与签名(签名原文第 5 个字段为空字符串)X-Ca-Signature-Headers:X-Ca-Key,X-Ca-Nonce,X-Ca-Signature-Method,X-Ca-Timestamp,X-Ca-Version,tokenContent-MD5:Base64(MD5(UTF8(body)))
- 签名原文格式:
METHOD\nACCEPT\nCONTENT-MD5\nCONTENT-TYPE\nDATE\nHEADER1:VALUE1\n...PATH Date参与签名(Date头使用 RFC 1123 格式,en-US 区域)X-Ca-Signature-Headers:X-Ca-Key,X-Ca-Nonce,X-Ca-Signature-Method,X-Ca-Timestamp,X-Ca-Version,gl_user_id
-
authToken 有效期 1799 秒(约 30 分钟),非一次性,可重复使用。建议每 25 分钟重新获取一次。
-
CenterRefreshToken 有效期约 20 天,到期后需要重新登录获取。建议持久化,刷新后及时更新。
-
并发安全:内部使用
SemaphoreSlim保证多线程同时调用时只触发一次刷新。 -
不需要 GRIC JWT:
authorization: Bearer <GRIC JWT>是车辆服务用的,充电域完全独立,只需token头。 -
Content-MD5 必须精确匹配请求体:序列化时
WriteIndented = false,不要多余空格。