在自动化脚本任务中如何在自己的后端服务中使用open api进行卡密相关操作?

在自动化运维、设备批量管理、账号授权等场景中,卡密是实现设备时长、脚本权限、用户授权的核心载体。开发者可在自有 Java 后台无缝对接卡密创建、查询、转移、管理等能力,实现自动化授权、分销系统、设备计费、权限管控等业务闭环。本文从接入准备、核心接口解析、Java 实战 Demo、异常处理到最佳实践,全方位讲解如何在后台服务中调用冰狐 OpenAPI 完成卡密全生命周期操作,助力开发者快速落地集成。

一、冰狐 OpenAPI 与卡密核心认知

1. 冰狐 OpenAPI 基础

冰狐智能辅助 OpenAPI 是平台提供的后端服务调用接口 ,支持设备管理、用户管理、卡密操作、脚本执行、微服务调用等能力,所有接口统一返回 JSON 格式,成功 state=1,失败 state=-1,data 字段承载返回数据或错误描述,接入门槛低、适配性强,适合 Java、Python、Go 等多种后端语言集成。

2. 卡密核心价值

冰狐卡密是设备授权、时长兑换、脚本权限绑定的凭证,核心能力包括:

  • 绑定设备可用时长,控制设备使用周期;
  • 限定支持的脚本,实现脚本权限精细化管控;
  • 支持主账户 / 子账户分配,适配多用户分销场景;
  • 可批量创建、查询、转移,满足自动化运营需求。

卡密相关接口是 OpenAPI 的高频核心模块,涵盖创建卡密、获取卡密列表、转移卡密三大核心能力,覆盖卡密全生命周期管理。

3. 接入前置条件

  1. 注册冰狐智能辅助开发者账号,获取clientKey(开发者 Key)clientSecret(开发者密钥)
  2. 完成开发者认证,开通 OpenAPI 调用权限;
  3. 准备 Java 开发环境(JDK8+),引入 HTTP 请求、JSON 解析依赖;
  4. 牢记:get_token 接口禁止频繁调用,否则会被系统拉黑 IP。

二、卡密相关 OpenAPI 核心接口详解

卡密操作依赖Token 认证 ,所有接口必须携带有效 accessToken,调用流程为:获取 Token→卡密操作→Token 刷新(过期时),以下是卡密核心接口完整参数说明。

1. 前置接口:获取 Token(必调)

  • 请求地址:GET /api/get_token
  • 请求参数:clientKey(必填)、clientSecret(必填)
  • 响应参数:accessToken(访问凭证)、refreshToken(刷新凭证)、expiresIn(过期时间,秒)
  • 注意:Token 有过期时间,需缓存 accessToken,过期后用 refreshToken 刷新,避免重复调用 get_token。

2. 前置接口:刷新 Token

  • 请求地址:GET /api/refresh_token
  • 请求参数:clientKey(必填)、refreshToken(必填)
  • 作用:替换过期 accessToken,保证接口调用连续性。

3. 卡密核心接口

(1)创建卡密
  • 请求地址:GET /api/passport/create

  • 核心功能:批量生成卡密,绑定时长、脚本权限、所属账户

  • 请求参数:

    参数名 类型 必填 说明
    clientKey string 开发者 Key
    accessToken string 访问 Token
    hours integer 卡密时长(分钟)
    count integer 创建数量,默认 1
    supportScripts string 支持脚本,多脚本用 #分割
    childOpenId string 子账户 OpenID,默认主账户
  • 响应:data=1 成功,0 失败。

(2)获取卡密列表
  • 请求地址:GET /api/passport/list
  • 核心功能:分页查询卡密,支持按子账户、设备筛选
  • 请求参数:clientKey、accessToken(必填);childOpenId、uuid、cursor、count(选填)
  • 响应:返回卡密数组(含卡密、时长、创建时间等)、总数量。
(3)转移卡密
  • 请求地址:GET /api/passport/transfer
  • 核心功能:将卡密分配给子账户,实现权限下放
  • 请求参数:clientKey、accessToken、passport(卡密)、openId(子账户 ID)(均必填)
  • 响应:data=1 成功,0 失败。

三、Java 后端集成 Demo(完整可运行)

本文基于SpringBoot 2.7.x + OkHttp3 + Fastjson2 实现,封装冰狐 OpenAPI 客户端,完成 Token 管理、卡密创建 / 查询 / 转移全流程,代码可直接嵌入生产环境。

1. 项目依赖(Maven)

XML 复制代码
<!-- SpringBoot核心 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- OkHttp3 HTTP客户端 -->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.10.0</version>
</dependency>
<!-- Fastjson2 JSON解析 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.24</version>
</dependency>
<!-- 工具类 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.20</version>
</dependency>

2. 配置文件(application.yml)

复制代码
# 冰狐OpenAPI配置
binghu:
  open-api:
    base-url: https://aznfz.com
    client-key: 你的开发者clientKey
    client-secret: 你的开发者clientSecret
    # Token缓存时间(提前5分钟过期)
    token-cache-expire: 3500

3. 核心配置类

java 复制代码
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 冰狐OpenAPI配置类
 */
@Data
@Component
@ConfigurationProperties(prefix = "binghu.open-api")
public class BingHuOpenApiConfig {
    /**
     * 接口基础地址
     */
    private String baseUrl;
    /**
     * 开发者Key
     */
    private String clientKey;
    /**
     * 开发者密钥
     */
    private String clientSecret;
    /**
     * Token缓存过期时间(秒)
     */
    private Long tokenCacheExpire;
}

4. Token 实体与响应实体

java 复制代码
import lombok.Data;

/**
 * 冰狐Token实体
 */
@Data
public class BingHuToken {
    /**
     * 访问Token
     */
    private String accessToken;
    /**
     * 刷新Token
     */
    private String refreshToken;
    /**
     * 过期时间(秒)
     */
    private Integer expiresIn;
    /**
     * 创建时间戳
     */
    private Long createTime;
}

/**
 * 冰狐接口通用响应
 */
@Data
public class BingHuResponse<T> {
    /**
     * 状态:1成功,-1失败
     */
    private Integer state;
    /**
     * 数据
     */
    private T data;
}

5. 卡密实体

java 复制代码
import lombok.Data;

/**
 * 冰狐卡密实体
 */
@Data
public class BingHuPassport {
    /**
     * 设备UUID
     */
    private String uuid;
    /**
     * 卡密
     */
    private String skv;
    /**
     * 更新时间
     */
    private Integer verifyTime;
    /**
     * 创建时间
     */
    private Integer time;
    /**
     * 卡密有效时长(分钟)
     */
    private Integer hours;
}

6. 冰狐 OpenAPI 客户端

java 复制代码
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 冰狐OpenAPI客户端
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class BingHuOpenApiClient {
    private final BingHuOpenApiConfig openApiConfig;
    private final OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();
    /**
     * Token本地缓存
     */
    private final TimedCache<String, BingHuToken> tokenCache = CacheUtil.newTimedCache(
            openApiConfig.getTokenCacheExpire() * 1000
    );
    private static final String TOKEN_CACHE_KEY = "binghu_open_api_token";

    /**
     * 获取有效Token(缓存+自动刷新)
     */
    public String getAccessToken() {
        BingHuToken token = tokenCache.get(TOKEN_CACHE_KEY);
        if (token == null) {
            token = getTokenFromApi();
            tokenCache.put(TOKEN_CACHE_KEY, token);
        }
        return token.getAccessToken();
    }

    /**
     * 调用接口获取Token
     */
    private BingHuToken getTokenFromApi() {
        String url = String.format("%s/api/get_token?clientKey=%s&clientSecret=%s",
                openApiConfig.getBaseUrl(),
                openApiConfig.getClientKey(),
                openApiConfig.getClientSecret());
        try {
            Request request = new Request.Builder().get().url(url).build();
            try (Response response = okHttpClient.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new RuntimeException("获取Token失败,HTTP状态码:" + response.code());
                }
                String responseBody = response.body().string();
                BingHuResponse<BingHuToken> result = JSON.parseObject(responseBody,
                        JSON.parseObject(responseBody).getClass(), BingHuToken.class);
                if (result.getState() != 1) {
                    throw new RuntimeException("获取Token失败,错误信息:" + result.getData());
                }
                BingHuToken token = result.getData();
                token.setCreateTime(System.currentTimeMillis());
                return token;
            }
        } catch (Exception e) {
            log.error("获取冰狐Token异常", e);
            throw new RuntimeException("获取Token异常:" + e.getMessage());
        }
    }

    /**
     * 发送GET请求(通用)
     */
    private <T> BingHuResponse<T> sendGetRequest(String path, Map<String, String> params, Class<T> dataClass) {
        // 拼接公共参数
        params.put("clientKey", openApiConfig.getClientKey());
        params.put("accessToken", getAccessToken());
        // 构建URL
        StringBuilder urlBuilder = new StringBuilder(openApiConfig.getBaseUrl()).append(path).append("?");
        params.forEach((k, v) -> urlBuilder.append(k).append("=").append(v).append("&"));
        String url = urlBuilder.substring(0, urlBuilder.length() - 1);
        try {
            Request request = new Request.Builder().get().url(url).build();
            try (Response response = okHttpClient.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new RuntimeException("接口调用失败,HTTP状态码:" + response.code());
                }
                String responseBody = response.body().string();
                return JSON.parseObject(responseBody,
                        JSON.parseObject(responseBody).getClass(), dataClass);
            }
        } catch (Exception e) {
            log.error("调用冰狐接口[{}]异常", path, e);
            throw new RuntimeException("接口调用异常:" + e.getMessage());
        }
    }

    // ==================== 卡密相关接口 ====================

    /**
     * 创建卡密
     * @param minutes 卡密时长(分钟)
     * @param count 创建数量
     * @param supportScripts 支持脚本(多脚本#分割)
     * @param childOpenId 子账户ID
     * @return true成功 false失败
     */
    public Boolean createPassport(Integer minutes, Integer count, String supportScripts, String childOpenId) {
        Map<String, String> params = new HashMap<>();
        params.put("hours", String.valueOf(minutes));
        if (count != null) {
            params.put("count", String.valueOf(count));
        }
        if (supportScripts != null) {
            params.put("supportScripts", supportScripts);
        }
        if (childOpenId != null) {
            params.put("childOpenId", childOpenId);
        }
        BingHuResponse<Integer> response = sendGetRequest("/api/passport/create", params, Integer.class);
        return response.getState() == 1 && response.getData() == 1;
    }

    /**
     * 获取卡密列表
     * @param childOpenId 子账户ID
     * @param uuid 设备UUID
     * @param cursor 分页游标
     * @param count 页大小
     * @return 卡密列表+总数
     */
    public Map<String, Object> getPassportList(String childOpenId, String uuid, Integer cursor, Integer count) {
        Map<String, String> params = new HashMap<>();
        if (childOpenId != null) {
            params.put("childOpenId", childOpenId);
        }
        if (uuid != null) {
            params.put("uuid", uuid);
        }
        if (cursor != null) {
            params.put("cursor", String.valueOf(cursor));
        }
        if (count != null) {
            params.put("count", String.valueOf(count));
        }
        BingHuResponse<Map<String, Object>> response = sendGetRequest("/api/passport/list", params, Map.class);
        return response.getData();
    }

    /**
     * 转移卡密给子账户
     * @param passport 卡密
     * @param childOpenId 子账户ID
     * @return true成功 false失败
     */
    public Boolean transferPassport(String passport, String childOpenId) {
        Map<String, String> params = new HashMap<>();
        params.put("passport", passport);
        params.put("openId", childOpenId);
        BingHuResponse<Integer> response = sendGetRequest("/api/passport/transfer", params, Integer.class);
        return response.getState() == 1 && response.getData() == 1;
    }
}

7. 测试接口(Controller)

java 复制代码
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * 冰狐卡密测试接口
 */
@RestController
@RequestMapping("/binghu/passport")
@RequiredArgsConstructor
public class BingHuPassportController {
    private final BingHuOpenApiClient openApiClient;

    /**
     * 创建卡密
     */
    @GetMapping("/create")
    public Boolean createPassport(
            @RequestParam Integer minutes,
            @RequestParam(defaultValue = "1") Integer count,
            @RequestParam(required = false) String supportScripts,
            @RequestParam(required = false) String childOpenId) {
        return openApiClient.createPassport(minutes, count, supportScripts, childOpenId);
    }

    /**
     * 获取卡密列表
     */
    @GetMapping("/list")
    public Map<String, Object> getPassportList(
            @RequestParam(required = false) String childOpenId,
            @RequestParam(required = false) String uuid,
            @RequestParam(defaultValue = "0") Integer cursor,
            @RequestParam(defaultValue = "-1") Integer count) {
        return openApiClient.getPassportList(childOpenId, uuid, cursor, count);
    }

    /**
     * 转移卡密
     */
    @GetMapping("/transfer")
    public Boolean transferPassport(
            @RequestParam String passport,
            @RequestParam String childOpenId) {
        return openApiClient.transferPassport(passport, childOpenId);
    }
}

四、Demo 运行与测试

  1. 替换配置文件中clientKeyclientSecret为自己的开发者凭证;
  2. 启动 SpringBoot 项目,访问测试接口:
    • 创建卡密:https://aznfz.com /api/passport/create?minutes=60&count=5&supportScripts=抖音#快手
    • 查询卡密:https://aznfz.com/api/passport/list
    • 转移卡密:https://aznfz.com/api/passport/transfer?passport=XXX&childOpenId=XXX
  3. 查看响应结果,state=1 且 data 返回对应数据即调用成功。

五、生产环境最佳实践

1. Token 管理优化

  • 本地缓存 Token,禁止频繁调用 get_token,避免 IP 被拉黑;
  • 提前刷新 Token(如过期前 5 分钟),防止业务中断;
  • 分布式环境下,可改用 Redis 缓存 Token,保证多实例一致性。

2. 异常处理

  • 捕获接口调用异常,增加重试机制(最多 3 次);
  • 针对 state=-1 的错误,记录日志并返回友好提示;
  • 处理网络超时、参数错误、Token 过期等常见问题。

3. 安全规范

  • clientKey 和 clientSecret严禁硬编码,放入配置中心或环境变量;
  • 接口调用日志脱敏,不打印敏感凭证;
  • 卡密数据加密存储,防止泄露。

4. 性能优化

  • 批量创建卡密时,合理设置 count 值,避免单次创建过多;
  • 卡密列表查询使用分页,减少数据传输量;
  • 复用 OkHttpClient 实例,避免频繁创建连接。

六、常见问题排查

  1. 获取 Token 失败:检查 clientKey、clientSecret 是否正确,确认开发者权限已开通;
  2. IP 被拉黑:减少 get_token 调用频率,改用缓存 + 刷新机制;
  3. 卡密创建失败:检查 hours 参数是否为正整数,supportScripts 格式是否正确;
  4. 转移卡密失败:确认卡密未被使用、子账户 OpenID 有效。

七、总结

通过冰狐智能辅助 OpenAPI,Java 后端可快速实现卡密创建、查询、转移、权限绑定等全流程操作,适配自动化设备管理、授权分销、脚本管控等业务场景。本文提供的 Demo 已封装 Token 自动缓存、刷新、通用请求逻辑,开发者只需替换配置即可快速集成,大幅降低接入成本。

相关推荐
weixin_408099671 天前
身份证OCR识别API接入实战:6种自动化脚本3分钟搞定(含天诺/按键精灵/易语言/C#示例)
ocr·图像识别·api对接·易语言·自动化脚本·身份证ocr·石榴智能
Bear on Toilet1 天前
【JSON-RPC远程过程调用组件库】测试报告
开发语言·软件测试·后端·自动化脚本
ai_coder_ai1 天前
在自动化脚本中如何在自己的后端服务中调用open api进行用户相关操作?
autojs·自动化脚本·冰狐智能辅助·easyclick
weixin_408099672 天前
触动精灵调用身份证OCR识别API实现智能信息录入(Lua脚本实战)
junit·ocr·lua·自动化脚本·石榴智能·身份证ocr识别·触动精灵
ai_coder_ai2 天前
在自动化脚本中如何在自己的后端服务中调用open api获取所有设备信息?
autojs·open·自动化脚本·冰狐智能辅助·easyclick·open api
ai_coder_ai7 天前
使用颜色来实现自动化脚本
autojs·自动化脚本·冰狐智能辅助·easyclick
ai_coder_ai8 天前
在自动化脚本中如何实现文本转语音?
tts·autojs·自动化脚本·冰狐智能辅助·easyclick
ai_coder_ai9 天前
在自动化脚本中如何使用websocket?
websocket·autojs·自动化脚本·冰狐智能辅助·easyclick
ai_coder_ai10 天前
在自动化脚本中如何实现录音功能?
autojs·录音·自动化脚本·冰狐智能辅助·easyclick