Files
m2pool_payment/integration/wordpress/api-bridge/main.go

242 lines
5.7 KiB
Go
Raw Normal View History

2025-11-18 17:26:07 +08:00
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)
}