Go语言实战案例:接入支付宝/微信模拟支付回调接口

在实际 Web 开发中,支付宝和微信支付的异步回调接口 是支付系统的重要一环。

当用户完成支付后,第三方支付平台(如支付宝、微信)会向商户的回调地址发送支付结果通知。

商户系统收到回调数据后,需要验证签名、更新订单状态,并返回响应。

本篇我们将用 Go(Gin 框架)实现一个模拟的支付宝/微信支付回调接口,方便本地测试与学习。


一、功能目标

    1. 提供 /alipay/callback/wechat/callback 两个回调接口。
    1. 接收 POST 请求中的支付结果参数(模拟)。
    1. 校验签名(简单模拟,不接入真实加密算法)。
    1. 根据支付状态更新订单状态(内存模拟)。
    1. 返回支付平台期望的响应格式。

二、项目结构

go 复制代码
project/
│── main.go
└── orders.go (订单状态管理模拟)

三、代码实现

go 复制代码
package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "sync"
)

var (
    orderStore = make(map[string]string) // orderID -> status
    mu         sync.Mutex
)

// 模拟订单更新
func updateOrderStatus(orderID, status string) {
    mu.Lock()
    defer mu.Unlock()
    orderStore[orderID] = status
    fmt.Printf("订单 %s 状态更新为 %s\n", orderID, status)
}

// 模拟签名验证(实际需用支付宝/微信 SDK)
func verifySignature(params map[string]string, sign string) bool {
    // 实际业务中应根据支付宝/微信签名算法进行验证
    return sign == "valid-sign"
}

// 支付宝回调
func alipayCallback(c *gin.Context) {
    orderID := c.PostForm("out_trade_no")
    status := c.PostForm("trade_status")
    sign := c.PostForm("sign")

    if !verifySignature(map[string]string{
        "out_trade_no": orderID,
        "trade_status": status,
    }, sign) {
        c.String(http.StatusBadRequest, "invalid sign")
        return
    }

    if status == "TRADE_SUCCESS" {
        updateOrderStatus(orderID, "已支付")
    }

    // 支付宝期望返回 "success"
    c.String(http.StatusOK, "success")
}

// 微信回调(JSON 格式)
func wechatCallback(c *gin.Context) {
    var data struct {
        OrderID string `json:"out_trade_no"`
        Status  string `json:"trade_state"`
        Sign    string `json:"sign"`
    }

    if err := c.ShouldBindJSON(&data); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    if !verifySignature(map[string]string{
        "out_trade_no": data.OrderID,
        "trade_state":  data.Status,
    }, data.Sign) {
        c.JSON(http.StatusBadRequest, gin.H{"message": "invalid sign"})
        return
    }

    if data.Status == "SUCCESS" {
        updateOrderStatus(data.OrderID, "已支付")
    }

    // 微信期望返回 XML 格式
    c.String(http.StatusOK, `<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>`)
}

func main() {
    r := gin.Default()

    r.POST("/alipay/callback", alipayCallback)
    r.POST("/wechat/callback", wechatCallback)

    // 查询订单状态(方便测试)
    r.GET("/order/:id", func(c *gin.Context) {
        id := c.Param("id")
        mu.Lock()
        status, exists := orderStore[id]
        mu.Unlock()
        if !exists {
            c.JSON(http.StatusNotFound, gin.H{"error": "订单不存在"})
            return
        }
        c.JSON(http.StatusOK, gin.H{"order_id": id, "status": status})
    })

    r.Run(":8080")
}

四、测试方法

1. 模拟支付宝回调

bash 复制代码
curl -X POST http://localhost:8080/alipay/callback \
  -d "out_trade_no=12345&trade_status=TRADE_SUCCESS&sign=valid-sign"

返回:

复制代码
success

查询订单:

bash 复制代码
curl http://localhost:8080/order/12345

返回:

json 复制代码
{"order_id":"12345","status":"已支付"}

2. 模拟微信回调

json 复制代码
curl -X POST http://localhost:8080/wechat/callback \
  -H "Content-Type: application/json" \
  -d '{"out_trade_no":"67890","trade_state":"SUCCESS","sign":"valid-sign"}'

返回:

xml 复制代码
<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>

查询订单:

bash 复制代码
curl http://localhost:8080/order/67890

五、注意事项

    1. 签名验证
    • • 示例中只是模拟验证,真实生产环境必须使用支付宝/微信提供的 SDK 和密钥。
    1. 回调幂等性
    • • 支付平台可能会多次发送相同回调,处理逻辑必须保证幂等(不要重复更新订单状态)。
    1. 安全
    • • 回调接口应只允许支付平台访问,可考虑验证来源 IP、HTTPS 等安全措施。

六、总结

本篇示例展示了支付宝与微信异步回调接口的核心流程

接收参数 → 验证签名 → 更新订单状态 → 返回响应。

在真实生产环境中,需要结合官方文档与 SDK,实现完整的签名算法与安全策略。


相关推荐
孟永峰_Java42 分钟前
MySQL 组合IN查询:你的索引为什么罢工了?
后端
ruokkk44 分钟前
一个困扰我多年的Session超时Bug,被我的新AI搭档半天搞定了
javascript·后端·架构
楽码1 小时前
端到端应用Hmac加密
服务器·后端·算法
孟永峰_Java1 小时前
Java程序员的周五:代码没写完,但我的心已经放假了!
后端
uhakadotcom1 小时前
Flink有python的SDK入门教程
后端·面试·github
kong@react1 小时前
spring boot配置es
spring boot·后端·elasticsearch
dl7431 小时前
一文看懂spring事件监听器
后端
Bunny02121 小时前
RBAC权限管理模型中的部门角色绑定方案优化
后端
小镇cxy1 小时前
开发者的新“超能力”——Claude Code 全面解析与使用指南
后端·claude
费益洲1 小时前
Docker 核心技术:Namespace
后端