跳转到内容

Go 示例

此 Go 示例使用标准库 net/http 发起请求

签名类实现

go
package main

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"sort"
	"strings"
)

func Sign(params map[string]string, apiToken string) string {
	keys := make([]string, 0, len(params))
	for k := range params {
		if k != "sign" && params[k] != "" && params[k] != null {
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)

	var builder strings.Builder
	builder.WriteString(apiToken)

	for _, k := range keys {
		builder.WriteString("&" + k + "=" + params[k])
	}

	hash := md5.Sum([]byte(builder.String()))
	return hex.EncodeToString(hash[:])
}

请求下单

以下是代收下单请求,代付请求相似

go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

func main() {
	params := map[string]string{
		"mch_id":       "2050",                          // 商户ID
		"trans_id":     "E1763923463",                   // 交易ID
		"channel":      "bank",                          // 代收通道
		"amount":       "200000.00",                     // 订单金额
		"currency":     "VND",                           // 币种
		"callback_url": "https://api.blackhole.com",     // 回调地址
		"remarks":      "callme",                        // 备注
		"nonce":        RandString(8),                   // 随机串
		"timestamp":    fmt.Sprintf("%d", time.Now().Unix()), // 时间戳
	}

	apiToken := "0xFAKE_TOKENx0"
	params["sign"] = Sign(params, apiToken)

	// 转换为 JSON
	bodyBytes, err := json.Marshal(params)
	if err != nil {
		panic(err)
	}

	// 发起 HTTP 请求
	url := "http://接口域名/api/v1/mch/pmt-orders"
	req, err := http.NewRequest("POST", url, bytes.NewReader(bodyBytes))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 5 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		// todo: 网络错误处理
		fmt.Println("请求失败:", err)
		return
	}
	defer resp.Body.Close()

	respBody, _ := ioutil.ReadAll(resp.Body)

	if resp.StatusCode != http.StatusOK {
		// todo: 请求失败处理
		fmt.Println("HTTP状态码错误:", resp.StatusCode)
	} else {
		var result map[string]interface{}
		if err := json.Unmarshal(respBody, &result); err == nil {
			if code, ok := result["code"].(float64); !ok || int(code) != 200 {
				reason := result["message"]
				// todo: 调用失败处理
				fmt.Println("请求失败:", reason)
			} else {
				// todo: 调用成功,处理数据
				fmt.Println("请求成功:", result)
			}
		} else {
			fmt.Println("解析响应失败:", err)
		}
	}
}

// RandString 生成指定长度的随机字符串
func RandString(n int) string {
	const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, n)
	for i := range b {
		b[i] = letters[time.Now().UnixNano()%int64(len(letters))]
	}
	return string(b)
}

Released under the MIT License.