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

On this page