Golang如何实现基础的支付接口调用_Golang 支付接口调用实践

首先构造支付参数并生成RSA2签名,然后通过HTTP POST请求发送至支付宝网关,接着解析返回的JSON数据并验证签名,最后处理异步通知时校验签名与交易状态以确保安全性。

在使用 Golang 开发支付功能时,常见的场景包括对接微信支付、支付宝等第三方支付平台。虽然各平台接口细节不同,但调用流程大体相似:构造请求参数、生成签名、发送 HTTP 请求、处理返回结果。下面以支付宝的统一下单接口为例,展示如何用 Golang 实现一个基础的支付接口调用。

准备支付参数与签名

调用支付接口前,需要按照平台文档组装必要的业务参数和公共参数。以支付宝为例,关键字段包括 app_idmethodtimestampnotify_urlsign_type 等。

签名是安全验证的核心。支付宝支持 RSA2 签名方式,Golang 可通过 crypto/rsacrypto/x509 包实现。

示例代码片段:

func signWithRSA2(data, privateKey string) (string, error) {
    decodedKey, _ := base64.StdEncoding.DecodeString(privateKey)
    pemBlock, _ := pem.Decode(decodedKey)
    privKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
    if err != nil {
        return "", err
    }

    hashed := sha256.Sum256([]byte(data))
    signature, err := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, hashed[:])
    if err != nil {
        return "", err
    }

    return base64.StdEncoding.EncodeToString(signature), nil
}

构建请求并发送

将所有参数按字典序排序后拼接成待签名字符串,完成签名后填入 sign 字段,再以表单或 JSON 形式提交到支付宝网关(如:https://openapi.alipay.com/gateway.do)。

使用 net/http 发送 POST 请求:

func doPost(url string, params map[string]string) ([]byte, error) {
    formData := url.Values{}
    for k, v := range params {
        formData.Set(k, v)
    }

    resp, err := http.PostForm(url, formData)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, _ := io.ReadAll(resp.Body)
    return body, nil
}

解析响应结果

支付接口返回通常是 JSON 格式。注意支付宝的响应结构包含外层签名和业务数据,需先校验签名再解析业务内容。

例如返回:

{
  "alipay_trade_precreate_response": {
    "code": "10000",
    "msg": "Success",
    "out_trade_no": "123456",
    "qr_code": "https://qr.alipay.com/baxxxxx"
  },
  "sign": "abc123..."
}

可定义对应结构体解析:

type AlipayResponse struct {
    Code string `json:"code"`
    Msg  string `json:"msg"`
    QrCode string `json:"qr_code"`
}

判断 Code == "10000" 表示请求成功,可将 QrCode 返回给前端展示二维码。

异步通知处理(Notify)

支付完成后,支付宝会向商户配置的 notify_url 发送异步通知。需在服务端接收并验证通知的签名,防止伪造请求。

核心逻辑包括:

  • 读取请求 Body 并解析参数
  • 提取签名并与本地计算值比对
  • 检查 trade_status 是否为已支付
  • 更新本地订单状态,返回 "success" 防止重复通知

基本上就这些。只要理解签名机制、参数格式和通信流程,Golang 调用支付接口并不复杂,关键是细节处理要严谨,尤其是安全校验部分不能省略。