package main import ( "encoding/json" "log" "net/http" "github.com/gorilla/mux" "github.com/streadway/amqp" ) // PaymentRequest 支付请求 type PaymentRequest struct { QueueID string `json:"queue_id"` Chain string `json:"chain"` Symbol string `json:"symbol"` FromAddress string `json:"from_address"` ToAddress string `json:"to_address"` Amount float64 `json:"amount"` Fee float64 `json:"fee"` Timestamp uint64 `json:"timestamp"` Sign string `json:"sign"` } // TopupRequest 充值请求 type TopupRequest struct { QueueID string `json:"queue_id"` Chain string `json:"chain"` Symbol string `json:"symbol"` Address string `json:"address"` Timestamp uint64 `json:"timestamp"` Sign string `json:"sign"` } // APIResponse API 响应 type APIResponse struct { Success bool `json:"success"` Data interface{} `json:"data,omitempty"` Message string `json:"message,omitempty"` } // RabbitMQConfig RabbitMQ 配置 type RabbitMQConfig struct { URL string Exchange string Queues map[string]string } var rmqConfig RabbitMQConfig var rmqConn *amqp.Connection var rmqCh *amqp.Channel func main() { // 初始化 RabbitMQ 配置 rmqConfig = RabbitMQConfig{ URL: "amqp://m2pool:m2pool@localhost:5672", Exchange: "pay.exchange", Queues: map[string]string{ "pay": "pay.auto.routing.key", "topup": "pay.recharge.routing.key", "status": "pay.auto.return.routing.key", }, } // 连接 RabbitMQ var err error rmqConn, err = amqp.Dial(rmqConfig.URL) if err != nil { log.Fatalf("Failed to connect to RabbitMQ: %v", err) } defer rmqConn.Close() rmqCh, err = rmqConn.Channel() if err != nil { log.Fatalf("Failed to open channel: %v", err) } defer rmqCh.Close() // 设置路由 r := mux.NewRouter() // 支付相关接口 r.HandleFunc("/api/payment/create", createPaymentHandler).Methods("POST") r.HandleFunc("/api/payment/status/{queue_id}", getPaymentStatusHandler).Methods("GET") // 充值相关接口 r.HandleFunc("/api/topup/create", createTopupHandler).Methods("POST") r.HandleFunc("/api/topup/status/{queue_id}", getTopupStatusHandler).Methods("GET") // 健康检查 r.HandleFunc("/health", healthCheckHandler).Methods("GET") log.Println("API Bridge Server starting on :8080") log.Fatal(http.ListenAndServe(":8888", r)) } // createPaymentHandler 创建支付请求 func createPaymentHandler(w http.ResponseWriter, r *http.Request) { var req PaymentRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondJSON(w, http.StatusBadRequest, APIResponse{ Success: false, Message: "Invalid request body", }) return } // 发送到 RabbitMQ body, err := json.Marshal(req) if err != nil { respondJSON(w, http.StatusInternalServerError, APIResponse{ Success: false, Message: "Failed to marshal request", }) return } err = rmqCh.Publish( rmqConfig.Exchange, rmqConfig.Queues["pay"], false, false, amqp.Publishing{ ContentType: "application/json", Body: body, }, ) if err != nil { log.Printf("Failed to publish payment request: %v", err) respondJSON(w, http.StatusInternalServerError, APIResponse{ Success: false, Message: "Failed to send payment request", }) return } respondJSON(w, http.StatusOK, APIResponse{ Success: true, Data: map[string]string{ "queue_id": req.QueueID, }, }) } // getPaymentStatusHandler 查询支付状态 func getPaymentStatusHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) queueID := vars["queue_id"] // 这里应该从数据库或缓存中查询状态 // 为了演示,我们返回一个模拟响应 // 实际实现中,应该监听 RabbitMQ 的响应队列并存储状态 respondJSON(w, http.StatusOK, APIResponse{ Success: true, Data: map[string]interface{}{ "queue_id": queueID, "status": 0, // 0=待支付, 1=成功, 2=待确认, 3=失败 }, }) } // createTopupHandler 创建充值请求 func createTopupHandler(w http.ResponseWriter, r *http.Request) { var req TopupRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondJSON(w, http.StatusBadRequest, APIResponse{ Success: false, Message: "Invalid request body", }) return } // 发送到 RabbitMQ body, err := json.Marshal(req) if err != nil { respondJSON(w, http.StatusInternalServerError, APIResponse{ Success: false, Message: "Failed to marshal request", }) return } err = rmqCh.Publish( rmqConfig.Exchange, rmqConfig.Queues["topup"], false, false, amqp.Publishing{ ContentType: "application/json", Body: body, }, ) if err != nil { log.Printf("Failed to publish topup request: %v", err) respondJSON(w, http.StatusInternalServerError, APIResponse{ Success: false, Message: "Failed to send topup request", }) return } respondJSON(w, http.StatusOK, APIResponse{ Success: true, Data: map[string]string{ "queue_id": req.QueueID, }, }) } // getTopupStatusHandler 查询充值状态 func getTopupStatusHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) queueID := vars["queue_id"] // 这里应该从数据库或缓存中查询状态 respondJSON(w, http.StatusOK, APIResponse{ Success: true, Data: map[string]interface{}{ "queue_id": queueID, "status": 0, }, }) } // healthCheckHandler 健康检查 func healthCheckHandler(w http.ResponseWriter, r *http.Request) { respondJSON(w, http.StatusOK, APIResponse{ Success: true, Message: "API Bridge is running", }) } // respondJSON 返回 JSON 响应 func respondJSON(w http.ResponseWriter, status int, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) json.NewEncoder(w).Encode(data) }