# 雲策外部API接入文件 貴司在申請到系統之後,會拿到一組唯一的「API Key」,和公司單位識別號「Company Number」,所有跟 API Server 的互動都是透過這組API Key來產生「檢查碼(X-CHECKSUM)」。 為了保證資料傳輸的正確性,在呼叫任何一隻API之前,都必須在檔頭(Header)填入檢查碼,以確保所有的API呼叫都是由貴司服務發出。 檢查碼的計算公式為: X-CHECKSUM = sha256(jsonToString(body) + api_key) SHA256 Online: https://emn178.github.io/online-tools/sha256.html 範例: api_key = abc123 body = { "sportname": "football", "gamestatus": "inplay" } 將 body 轉成字串之後跟 api_key 串接,會得到 {"sportname":"football","gamestatus":"inplay"}abc123 對字串做 sha256雜湊 之後,得到檢查碼: e9f9962fa91bb9d7a02fda394c3c0d9e8753ebd81629b2a503cf85caba6c147c 將檢查碼(X-CHECKSUM),公司單位識別號(X-COMPANY-NUM)塞到檔頭Header,跟body一起傳送到 API Server Header: { "Content-Type": "application/json", "X-COMPANY-NUM": "1", "X-CHECKSUM": "e9f9962fa91bb9d7a02fda394c3c0d9e8753ebd81629b2a503cf85caba6c147c" } Golang程式範例: ```golang= package main import ( "bytes" "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "io" "log" "net/http" "time" ) const ( SPORT_FOOTBALL = 0 SPORT_BASKETBALL = 1 SPORT_TENNIS = 2 SPORT_BASEBALL = 3 STATUS_IN_PLAY = 0 STATUS_PRE_MATCH = 1 STATUS_EARLY_MATCH = 2 STATUS_FINISHED = 3 ) type GetMatchesRequest struct { SportName int `json:"SportName"` GameStatus int `json:"gameStatus"` TournamentName []string `json:"tournamentName"` MarketType []int32 `json:"marketType"` StartTime *string `json:"startTime"` EndTime *string `json:"endTime"` } var ( ApiKey = "abc123" // Company key CompanyNum = "1" // Company number ApiServer = "http://localhost:8080" ) func main() { req := GetMatchesRequest{ SportName: SPORT_FOOTBALL, GameStatus: STATUS_IN_PLAY, TournamentName: []string{"歐冠"}, MarketType: []int32{1}, StartTime: nil, EndTime: nil, } path := "/v1/getMatches" respBody, isErr := PostDataToTP(req, path) if isErr { log.Printf("post data to TP failed\n") return } log.Println("respBody: ", string(respBody)) } func PostDataToTP(data interface{}, path string) (respBody []byte, isErr bool) { jsonData, checksum, isErr := GenCheckSum(data) if isErr { isErr = true log.Println("[PostDataToTP] checksum data failed.") return } targetUrl := fmt.Sprintf("%s%s", ApiServer, path) req, err := http.NewRequest("POST", targetUrl, bytes.NewBuffer(jsonData)) if err != nil { isErr = true log.Printf("[PostDataToTP] req setup failed. err: %s\n", err) return } req.Header.Set("X-CHECKSUM", checksum) req.Header.Set("X-COMPANY-NUM", CompanyNum) req.Header.Set("Content-Type", "application/json") client := &http.Client{ Timeout: 30 * time.Second, } resp, err := client.Do(req) if err != nil { isErr = true log.Printf("[PostDataToTP] connect to TP failed. err: %s\n", err) return } defer resp.Body.Close() respBody, err = io.ReadAll(resp.Body) if err != nil { isErr = true log.Printf("[PostDataToTP] respBody transfer failed. err: %s\n", err) return } return } func GenCheckSum(anything any) (jsonData []byte, checksum string, isErr bool) { var err error jsonData, err = json.Marshal(anything) if err != nil { isErr = true log.Printf("[GenCheckSum] jsonEncode failed. err: %s\n", err) return } hash := sha256.New() hash.Write([]byte(string(jsonData) + ApiKey)) preChecksum := hash.Sum(nil) Checksum := hex.EncodeToString(preChecksum) checksum = Checksum return } ```