CITV 开放文档
Domainer

Go SDK 接入指南

使用 citv-domainer-sdk-go 快速接入 Domainer 开放接口

Go SDK 接入指南

citv-domainer-sdk-go 是 Domainer 开放接口的 Go 语言 SDK,适用于平台类客户服务端(S2S)调用场景。SDK 封装了 API Token 换取、Bearer Token 维护、商户管理、域名管理、域名配额查询和 DNS 日级解析明细查询等能力。

SDK 源码仓库

github.com/martinYi1210-coder/citv-domainer-sdk-go

适用场景

场景说明
服务端接入在平台客户后端系统中调用 Domainer API,不建议在前端或客户端暴露密钥
商户管理注册、查询、更新和删除商户实名档案
域名管理创建商户域名、更新 CNAME、删除域名和查询域名列表
配额与明细查询当前平台域名配额和 DNS 日级解析明细
调试排障SDK 默认输出脱敏 curl 命令,便于复现请求

安装

go get github.com/martinYi1210-coder/citv-domainer-sdk-go

SDK 要求 Go 1.25+。

快速开始

package main

import (
	"fmt"
	"log"

	citv "github.com/martinYi1210-coder/citv-domainer-sdk-go"
)

func main() {
	client, err := citv.NewClient(citv.Config{
		AccessKey: "your-access-key",
		SecretKey: "your-secret-key",
	})
	if err != nil {
		log.Fatal(err)
	}

	tokenResp, err := client.GetAPIToken(&citv.TokenRequest{
		TTLSeconds: 1800,
		Scope: []string{
			"company:list",
			"merchant:register",
			"domain:create",
		},
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("token expires at:", tokenResp.Data.ExpiresAt)

	quotaResp, err := client.GetDomainQuota()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("allowed root domains:", quotaResp.Data.AllowedRootDomains)
}

客户端配置

type Config struct {
	AccessKey  string
	SecretKey  string
	BaseURL    string
	HTTPClient *http.Client
}
字段说明
AccessKey平台分配的 AccessKey,必填
SecretKey平台分配的 SecretKey,必填
BaseURLAPI 服务地址,未设置时默认使用 https://beta.domainer.citv.cn
HTTPClient自定义 HTTP Client;未设置时默认超时 30 秒

默认创建客户端时会输出脱敏 curl 调试命令。如需关闭:

client, err := citv.NewClient(citv.Config{
	AccessKey: "your-access-key",
	SecretKey: "your-secret-key",
}, false)

鉴权与 Token

SDK 使用 AccessKeySecretKey 调用 Domainer 的 API Token 接口,并在后续请求中携带 Bearer Token。Token 的权限范围由 scope 控制,建议按最小权限申请。

resp, err := client.GetAPIToken(&citv.TokenRequest{
	TTLSeconds: 1800,
	Scope: []string{
		"company:list",
		"merchant:read",
		"domain:read",
	},
})
if err != nil {
	log.Fatal(err)
}

fmt.Println(resp.Data.ExpiresAt)

可通过鉴权检查接口确认 Token 与 scope 是否生效:

resp, err := client.AuthCheck()
if err != nil {
	log.Fatal(err)
}
fmt.Println(resp.Data.Scope)

更多 Token 参数和 scope 说明请参考 API Token 换取与使用指南

商户管理

注册商户

resp, err := client.RegisterMerchant(&citv.RegisterRequest{
	MerchantId:        "merchant-001",
	Name:              "示例商户",
	LicenseNumber:     "913xxxxxxxxxxxxx",
	LicenseImageUrl:   "https://example.com/license.jpg",
	LegalRepName:      "张三",
	LegalRepIdNumber:  "110101199001010000",
	BankName:          "示例银行",
	BankAccountNumber: "6222000000000000000",
	PublicInfoUrl:     "https://example.com/public-info",
	UserAuthorization: "1",
	ContactName:       "李四",
	ContactPhone:      "13800000000",
	ContactEmail:      "contact@example.com",
})
if err != nil {
	log.Fatal(err)
}
fmt.Println(resp.Code, resp.Message)

查询、更新和删除商户

merchantResp, err := client.GetMerchant("merchant-001")
if err != nil {
	log.Fatal(err)
}
fmt.Println(merchantResp.Data.Name)

name := "新的商户名称"
updateResp, err := client.UpdateMerchant("merchant-001", &citv.MerchantUpdateRequest{
	Name: &name,
})
if err != nil {
	log.Fatal(err)
}
fmt.Println(updateResp.Data.Updated)

_, err = client.DeleteMerchant("merchant-001")
if err != nil {
	log.Fatal(err)
}

商户域名管理

createResp, err := client.CreateMerchantDomain("merchant-001", &citv.MerchantDomainRequest{
	RootDomain: "example.com",
	Subdomain:  "shop",
	CnameValue: "target.example.net",
	TTL:        600,
})
if err != nil {
	log.Fatal(err)
}
fmt.Println(createResp.Data.DomainId)

listResp, err := client.ListMerchantDomains("merchant-001")
if err != nil {
	log.Fatal(err)
}
fmt.Println(len(listResp.Data))

_, err = client.UpdateMerchantDomain("merchant-001", "shop.example.com", &citv.MerchantDomainUpdateRequest{
	CnameValue: "new-target.example.net",
	Remark:     "切换 CNAME",
})
if err != nil {
	log.Fatal(err)
}

_, err = client.DeleteMerchantDomain("merchant-001", "shop.example.com")
if err != nil {
	log.Fatal(err)
}

平台 CNAME 域名管理

resp, err := client.CreateCnameDomain(&citv.CnameDomainRequest{
	MerchantId:     "merchant-001",
	PlatformDomain: "example.com",
	Subdomain:      "api",
	CnameValue:     "target.example.net",
	TTL:            600,
})
if err != nil {
	log.Fatal(err)
}
fmt.Println(resp.Data.DomainId)

_, err = client.UpdateDomainCname("api.example.com", &citv.DomainCnameUpdateRequest{
	DomainName: "api.example.com",
	CnameValue: "new-target.example.net",
})
if err != nil {
	log.Fatal(err)
}

_, err = client.DeleteDomain("api.example.com")
if err != nil {
	log.Fatal(err)
}

查询域名配额

resp, err := client.GetDomainQuota()
if err != nil {
	log.Fatal(err)
}
fmt.Println(resp.Data.PlatformDomains.Used)

查询 DNS 日级解析明细

resp, err := client.GetDNSDailyRecords(&citv.DNSDailyRecordsQuery{
	FromDate: "2026-06-01",
	ToDate:   "2026-06-03",
})
if err != nil {
	log.Fatal(err)
}
fmt.Println(resp.Data.RecordCount)

DNS 解析明细接口用于查询日级解析数据文件和临时下载地址,日期范围和返回字段以 平台类客户 API 接口文档 为准。

接入建议

  1. AccessKeySecretKey 只应保存在服务端安全配置中,不能下发到浏览器、App 或小程序。
  2. 生产环境建议显式设置 BaseURL 为正式 Domainer API 地址。
  3. Token 有效期建议设置为业务所需的最短时间,并按最小权限申请 scope
  4. 判断业务结果时优先读取响应体中的 codemessage,不要只依赖 HTTP 状态码。
  5. 创建域名前建议先调用 GetDomainQuota 确认当前平台配额和可用根域。

On this page