跳转至

查询钱包余额/授信

本文说明如何通过 MagikCloud Open API,查询租户当前钱包余额与授信额度。

前置条件

请先完成 接入流程 中的 AK/SK 获取;请求须按 构建请求 完成 AK/SK 签名。

查询钱包余额与授信

接口说明

项 值
Base URL https://openapi.magikcloud.cn
路径 /api/v1/wallets/balance
方法 GET

查询参数

无。租户由 AK/SK 自动识别,无需传 tenant_id。

请求 URL 示例

GET https://openapi.magikcloud.cn/api/v1/wallets/balance

响应示例

{
  "code": 0,
  "reason": "OK",
  "message": "success",
  "data": {
    "tenantId": "tn-xxx",
    "balance": "1200.00",
    "giftBalance": "50.00",
    "unpaidAmount": "0.00",
    "creditLimit": "5000.00",
    "usedCredit": "0.00",
    "availableCredit": "5000.00",
    "updatedAt": "2026-05-27T08:00:00Z"
  }
}

响应字段说明

字段 类型 说明
tenantId string 租户 ID
balance string 现金余额,已扣减预付在途消费
giftBalance string 代金券余额:所有有效代金券剩余金额之和
unpaidAmount string 账单欠费(后付),只有这部分消费占用授信
creditLimit string 运营授予的授信额度,"0" 表示无授信(纯预付租户)
usedCredit string 已用授信,等于 unpaidAmount(仅账单欠费)。预付在途消费不计入授信,因其已从 balance 中扣减
availableCredit string 可用授信,等于 creditLimit - usedCredit。超额时可能为负数,服务端不做截断处理
updatedAt string(时间) 钱包更新时间,RFC 3339

金额字段均为字符串,与控制台余额页面一致。

数据时效性:balance 已扣减预付在途消费(分钟级更新),与实时消费存在至多几分钟的滞后;usedCredit 和 availableCredit 由账单欠费驱动,按出账节奏更新。请勿将这些数值当作秒级准确值使用。

Go 示例

package main

import (
    "bytes"
    "crypto/hmac"
    "crypto/rand"
    "crypto/sha256"
    "encoding/base64"
    "fmt"
    "io"
    "net/http"
    "os"
    "strings"
    "time"
)

const (
    baseURL = "https://openapi.magikcloud.cn"
    path    = "/api/v1/wallets/balance"
)

func main() {
    accessKeyID := os.Getenv("ACCESS_KEY_ID")
    secretKey := []byte(os.Getenv("SECRET_ACCESS_KEY"))
    if accessKeyID == "" || len(secretKey) == 0 {
        panic("请设置 ACCESS_KEY_ID 和 SECRET_ACCESS_KEY")
    }

    req, err := http.NewRequest(http.MethodGet, baseURL+path, nil)
    if err != nil {
        panic(err)
    }
    if err := signRequest(req, accessKeyID, secretKey); err != nil {
        panic(err)
    }

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    fmt.Println(resp.Status)
    fmt.Println(string(body))
}

func signRequest(req *http.Request, accessKeyID string, secretKey []byte) error {
    if req.Body != nil {
        bodyBytes, err := io.ReadAll(req.Body)
        if err != nil {
            return err
        }
        _ = req.Body.Close()
        sum := sha256.Sum256(bodyBytes)
        digest := base64.URLEncoding.EncodeToString(sum[:])
        req.Header.Set("Content-Digest", "sha-256="+digest)
        req.Body = io.NopCloser(bytes.NewReader(bodyBytes))
    } else {
        sum := sha256.Sum256(nil)
        req.Header.Set("Content-Digest", "sha-256="+base64.URLEncoding.EncodeToString(sum[:]))
    }

    nonceBytes := make([]byte, 32)
    if _, err := rand.Read(nonceBytes); err != nil {
        return err
    }
    nonce := base64.RawURLEncoding.EncodeToString(nonceBytes)
    created := time.Now().Unix()

    query := "?"
    if req.URL.RawQuery != "" {
        query += req.URL.RawQuery
    }
    cd := req.Header.Get("Content-Digest")

    reqPath := req.URL.Path
    if reqPath == "" {
        reqPath = "/"
    }

    escape := func(s string) string {
        s = strings.ReplaceAll(s, `\`, `\\`)
        s = strings.ReplaceAll(s, `"`, `\"`)
        return s
    }

    sigParams := `("@method" "@query" "@path" "content-digest")` + ";" + strings.Join([]string{
        fmt.Sprintf("created=%d", created),
        fmt.Sprintf(`nonce="%s"`, escape(nonce)),
        fmt.Sprintf(`keyid="%s"`, escape(accessKeyID)),
        `alg="hmac-sha256"`,
    }, ";")

    signatureBase := strings.Join([]string{
        fmt.Sprintf(`"@method": %s`, req.Method),
        fmt.Sprintf(`"@query": %s`, query),
        fmt.Sprintf(`"@path": %s`, reqPath),
        fmt.Sprintf(`"content-digest": %s`, cd),
        fmt.Sprintf(`"@signature-params": %s`, sigParams),
    }, "\n")

    mac := hmac.New(sha256.New, secretKey)
    mac.Write([]byte(signatureBase))
    sig := base64.RawURLEncoding.EncodeToString(mac.Sum(nil))

    req.Header.Set("Signature-Input", "magik="+sigParams)
    req.Header.Set("Signature", "magik=:"+sig+":")
    return nil
}

Postman 调试

使用与 日账单/用量查询 相同的 postman_pre_request_script.js 脚本,在每次发送前自动计算 Content-Digest、Signature-Input、Signature。

1. 环境变量(Environment)

在 Postman 里新建 Environment,配置:

变量 示例 说明
access_key_id AK... 控制台 Access Key ID
secret_access_key SK... Secret(勿提交到 Git)

2. 配置请求

  • Method:GET
  • URL:
https://openapi.magikcloud.cn/api/v1/wallets/balance
  • Body:无(GET)
  • 右上角选中上一步创建的 Environment