# 雲策外部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
}
```