integration wordpress
This commit is contained in:
2
go.sum
2
go.sum
@@ -117,8 +117,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A=
|
||||
|
||||
128
integration/wordpress/INSTALL.md
Normal file
128
integration/wordpress/INSTALL.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# 安装指南
|
||||
|
||||
## 前置要求
|
||||
|
||||
1. WordPress 5.0 或更高版本
|
||||
2. WooCommerce 3.0 或更高版本
|
||||
3. PHP 7.4 或更高版本
|
||||
4. M2Pool 支付系统后端(Go 服务)
|
||||
|
||||
## 安装步骤
|
||||
|
||||
### 1. 安装 WordPress 插件
|
||||
|
||||
1. 将 `integration/wordpress` 文件夹复制到 WordPress 的插件目录:
|
||||
```
|
||||
wp-content/plugins/m2pool-eth-payment/
|
||||
```
|
||||
|
||||
2. 在 WordPress 后台激活插件:
|
||||
- 进入 `插件 > 已安装的插件`
|
||||
- 找到 "M2Pool ETH Payment Gateway"
|
||||
- 点击 "启用"
|
||||
|
||||
### 2. 配置插件
|
||||
|
||||
1. 进入 `设置 > M2Pool ETH 支付`
|
||||
2. 配置以下选项:
|
||||
- **API 地址**: 支付系统的 API 地址(如果使用 API Bridge,则为 `http://localhost:8080`)
|
||||
- **API 密钥**: 与后端系统的 `msgKey` 对应的密钥
|
||||
- **接收地址**: 用于接收支付的以太坊地址
|
||||
- **监听间隔**: 检查支付状态的间隔时间(建议 30-60 秒)
|
||||
|
||||
3. 保存设置
|
||||
|
||||
### 3. 配置 WooCommerce 支付网关
|
||||
|
||||
1. 进入 `WooCommerce > 设置 > 支付`
|
||||
2. 找到 "M2Pool ETH 支付"
|
||||
3. 点击 "管理"
|
||||
4. 启用支付方式并配置:
|
||||
- **标题**: 客户看到的支付方式名称
|
||||
- **描述**: 支付方式说明
|
||||
- **发送地址**: 发送支付的地址(可选)
|
||||
- **接收地址**: 接收支付的地址
|
||||
- **链名称**: 选择 ETH
|
||||
- **代币符号**: 选择 ETH 或 USDT
|
||||
|
||||
5. 保存更改
|
||||
|
||||
### 4. 设置 API Bridge(可选)
|
||||
|
||||
如果您的后端系统只支持 RabbitMQ,需要运行 API Bridge 服务:
|
||||
|
||||
1. 进入 `integration/wordpress/api-bridge` 目录
|
||||
2. 安装依赖:
|
||||
```bash
|
||||
go mod download
|
||||
```
|
||||
3. 编译:
|
||||
```bash
|
||||
go build -o api-bridge main.go
|
||||
```
|
||||
4. 运行:
|
||||
```bash
|
||||
./api-bridge
|
||||
```
|
||||
|
||||
5. 在 WordPress 插件设置中,将 API 地址设置为 `http://localhost:8080`
|
||||
|
||||
## 测试支付
|
||||
|
||||
1. 在 WooCommerce 创建一个测试订单
|
||||
2. 选择 "ETH 支付" 作为支付方式
|
||||
3. 完成订单后,您会看到支付说明页面
|
||||
4. 向显示的地址支付指定金额的 ETH
|
||||
5. 系统会自动检测支付并更新订单状态
|
||||
|
||||
## Webhook 配置(推荐)
|
||||
|
||||
为了实时接收支付状态更新,建议配置 Webhook:
|
||||
|
||||
1. 在 WordPress 插件设置页面找到 Webhook URL
|
||||
2. 将此 URL 配置到您的支付系统中
|
||||
3. 当支付状态更新时,系统会自动通知 WordPress
|
||||
|
||||
Webhook URL 格式:
|
||||
```
|
||||
https://your-site.com/wp-json/m2pool-eth/v1/webhook
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 支付状态不更新
|
||||
|
||||
1. 检查 API 地址是否正确
|
||||
2. 检查 API 密钥是否匹配
|
||||
3. 查看 WordPress 错误日志
|
||||
4. 确认后端服务正常运行
|
||||
|
||||
### 无法创建支付请求
|
||||
|
||||
1. 检查 API Bridge 是否运行(如果使用)
|
||||
2. 检查 RabbitMQ 连接是否正常
|
||||
3. 查看后端服务日志
|
||||
|
||||
### 订单状态不更新
|
||||
|
||||
1. 检查定时任务是否运行:
|
||||
- 进入 `工具 > 计划任务`
|
||||
- 查找 `m2pool_eth_check_payments`
|
||||
2. 手动触发支付检查(通过 AJAX)
|
||||
3. 检查数据库表 `wp_m2pool_eth_payments` 中的数据
|
||||
|
||||
## 数据库表
|
||||
|
||||
插件会自动创建以下数据库表:
|
||||
|
||||
- `wp_m2pool_eth_payments`: 存储支付记录
|
||||
|
||||
您可以通过 phpMyAdmin 或 WordPress 数据库工具查看和管理这些表。
|
||||
|
||||
## 支持
|
||||
|
||||
如有问题,请查看:
|
||||
- README.md - 详细文档
|
||||
- WordPress 错误日志
|
||||
- 后端服务日志
|
||||
|
||||
202
integration/wordpress/README.md
Normal file
202
integration/wordpress/README.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# M2Pool ETH Payment Gateway for WordPress
|
||||
|
||||
WordPress 支付网关插件,支持以太坊 (ETH) 交易的支付、监听和返回支付结果。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- ✅ 集成 WooCommerce 支付网关
|
||||
- ✅ 支持 ETH 和 USDT 支付
|
||||
- ✅ 自动监听支付状态
|
||||
- ✅ 支持 Webhook 回调
|
||||
- ✅ 支付状态实时更新
|
||||
- ✅ 完整的订单管理
|
||||
|
||||
## 安装要求
|
||||
|
||||
- WordPress 5.0+
|
||||
- WooCommerce 3.0+
|
||||
- PHP 7.4+
|
||||
|
||||
## 安装步骤
|
||||
|
||||
1. 将插件文件夹上传到 `/wp-content/plugins/` 目录
|
||||
2. 在 WordPress 后台激活插件
|
||||
3. 进入 `设置 > M2Pool ETH 支付` 配置 API 地址和密钥
|
||||
4. 在 `WooCommerce > 设置 > 支付` 中启用并配置支付网关
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 基本设置
|
||||
|
||||
1. **API 地址**: 支付系统的 API 地址(例如: `http://localhost:8080`)
|
||||
2. **API 密钥**: 用于签名验证的密钥(与后端系统的 `msgKey` 对应)
|
||||
3. **接收地址**: 用于接收支付的以太坊地址
|
||||
4. **监听间隔**: 检查支付状态的间隔时间(秒)
|
||||
|
||||
### Webhook 配置
|
||||
|
||||
Webhook URL: `https://your-site.com/wp-json/m2pool-eth/v1/webhook`
|
||||
|
||||
将此 URL 配置到您的支付系统中,以便接收支付状态更新。
|
||||
|
||||
## API 接口说明
|
||||
|
||||
插件需要与后端支付系统通信。如果后端系统只支持 RabbitMQ,您需要创建一个中间 API 服务。
|
||||
|
||||
### 需要的 API 接口
|
||||
|
||||
#### 1. 创建支付请求
|
||||
|
||||
```
|
||||
POST /api/payment/create
|
||||
```
|
||||
|
||||
请求体:
|
||||
```json
|
||||
{
|
||||
"queue_id": "wp_123_1234567890",
|
||||
"chain": "ETH",
|
||||
"symbol": "ETH",
|
||||
"from_address": "0x...",
|
||||
"to_address": "0x...",
|
||||
"amount": 0.1,
|
||||
"fee": 0,
|
||||
"timestamp": 1234567890,
|
||||
"sign": "signature_hash"
|
||||
}
|
||||
```
|
||||
|
||||
响应:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"queue_id": "wp_123_1234567890"
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 查询支付状态
|
||||
|
||||
```
|
||||
GET /api/payment/status/{queue_id}
|
||||
```
|
||||
|
||||
响应:
|
||||
```json
|
||||
{
|
||||
"queue_id": "wp_123_1234567890",
|
||||
"status": 1,
|
||||
"tx_hash": "0x...",
|
||||
"block_height": 12345,
|
||||
"amount": 0.1
|
||||
}
|
||||
```
|
||||
|
||||
状态码说明:
|
||||
- `0`: 待支付
|
||||
- `1`: 支付成功
|
||||
- `2`: 待确认
|
||||
- `3`: 支付失败
|
||||
|
||||
## 中间 API 服务
|
||||
|
||||
如果您的后端系统只支持 RabbitMQ,可以创建一个简单的 HTTP API 服务来桥接 WordPress 和 RabbitMQ。
|
||||
|
||||
示例代码(Go):
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"github.com/streadway/amqp"
|
||||
)
|
||||
|
||||
func createPaymentHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var req PaymentRequest
|
||||
json.NewDecoder(r.Body).Decode(&req)
|
||||
|
||||
// 发送到 RabbitMQ
|
||||
conn, _ := amqp.Dial("amqp://guest:guest@localhost:5672/")
|
||||
ch, _ := conn.Channel()
|
||||
|
||||
body, _ := json.Marshal(req)
|
||||
ch.Publish("pay.exchange", "pay.auto.routing.key", false, false, amqp.Publishing{
|
||||
ContentType: "application/json",
|
||||
Body: body,
|
||||
})
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]bool{"success": true})
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/api/payment/create", createPaymentHandler)
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
```
|
||||
|
||||
## 数据库结构
|
||||
|
||||
插件会自动创建以下数据库表:
|
||||
|
||||
- `wp_m2pool_eth_payments`: 存储支付记录
|
||||
|
||||
表结构:
|
||||
- `id`: 主键
|
||||
- `order_id`: WooCommerce 订单 ID
|
||||
- `queue_id`: 支付队列 ID
|
||||
- `from_address`: 发送地址
|
||||
- `to_address`: 接收地址
|
||||
- `amount`: 支付金额
|
||||
- `fee`: 手续费
|
||||
- `chain`: 链名称
|
||||
- `symbol`: 代币符号
|
||||
- `tx_hash`: 交易哈希
|
||||
- `block_height`: 区块高度
|
||||
- `status`: 支付状态
|
||||
- `created_at`: 创建时间
|
||||
- `updated_at`: 更新时间
|
||||
|
||||
## 使用流程
|
||||
|
||||
1. 客户选择 ETH 支付方式
|
||||
2. 系统生成支付地址和金额
|
||||
3. 客户向指定地址支付
|
||||
4. 系统自动监听支付状态
|
||||
5. 支付确认后自动更新订单状态
|
||||
|
||||
## 开发说明
|
||||
|
||||
### 文件结构
|
||||
|
||||
```
|
||||
m2pool-eth-payment/
|
||||
├── m2pool-eth-payment.php # 主插件文件
|
||||
├── includes/
|
||||
│ ├── class-m2pool-eth-gateway.php # 支付网关类
|
||||
│ ├── class-m2pool-eth-api.php # API 客户端
|
||||
│ └── class-m2pool-eth-listener.php # 支付监听器
|
||||
├── templates/
|
||||
│ ├── settings.php # 设置页面模板
|
||||
│ └── payment-instructions.php # 支付说明模板
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### 扩展开发
|
||||
|
||||
要添加新的功能,可以:
|
||||
|
||||
1. 扩展 `M2Pool_ETH_Gateway` 类添加新的支付方式
|
||||
2. 扩展 `M2Pool_ETH_API` 类添加新的 API 接口
|
||||
3. 修改 `M2Pool_ETH_Listener` 类自定义监听逻辑
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT License
|
||||
|
||||
## 支持
|
||||
|
||||
如有问题,请提交 Issue 或联系开发团队。
|
||||
|
||||
78
integration/wordpress/api-bridge/README.md
Normal file
78
integration/wordpress/api-bridge/README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# M2Pool API Bridge
|
||||
|
||||
这是一个中间 API 服务,用于连接 WordPress 插件和基于 RabbitMQ 的支付系统。
|
||||
|
||||
## 功能
|
||||
|
||||
- 接收 WordPress 插件的 HTTP 请求
|
||||
- 将请求转换为 RabbitMQ 消息
|
||||
- 监听 RabbitMQ 响应并返回给 WordPress
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
cd api-bridge
|
||||
go mod download
|
||||
go build -o api-bridge main.go
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
修改 `main.go` 中的 RabbitMQ 配置:
|
||||
|
||||
```go
|
||||
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",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 运行
|
||||
|
||||
```bash
|
||||
./api-bridge
|
||||
```
|
||||
|
||||
服务将在 `http://localhost:8080` 启动。
|
||||
|
||||
## API 接口
|
||||
|
||||
### 创建支付请求
|
||||
|
||||
```
|
||||
POST /api/payment/create
|
||||
```
|
||||
|
||||
### 查询支付状态
|
||||
|
||||
```
|
||||
GET /api/payment/status/{queue_id}
|
||||
```
|
||||
|
||||
### 创建充值请求
|
||||
|
||||
```
|
||||
POST /api/topup/create
|
||||
```
|
||||
|
||||
### 查询充值状态
|
||||
|
||||
```
|
||||
GET /api/topup/status/{queue_id}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
当前实现是基础版本,实际使用中需要:
|
||||
|
||||
1. 实现状态缓存(Redis 或数据库)
|
||||
2. 监听 RabbitMQ 响应队列
|
||||
3. 实现签名验证
|
||||
4. 添加错误处理和日志记录
|
||||
5. 添加认证和授权
|
||||
|
||||
8
integration/wordpress/api-bridge/go.mod
Normal file
8
integration/wordpress/api-bridge/go.mod
Normal file
@@ -0,0 +1,8 @@
|
||||
module m2pool-api-bridge
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/streadway/amqp v1.1.0
|
||||
)
|
||||
4
integration/wordpress/api-bridge/go.sum
Normal file
4
integration/wordpress/api-bridge/go.sum
Normal file
@@ -0,0 +1,4 @@
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM=
|
||||
github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg=
|
||||
241
integration/wordpress/api-bridge/main.go
Normal file
241
integration/wordpress/api-bridge/main.go
Normal file
@@ -0,0 +1,241 @@
|
||||
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)
|
||||
}
|
||||
160
integration/wordpress/includes/class-m2pool-eth-api.php
Normal file
160
integration/wordpress/includes/class-m2pool-eth-api.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* M2Pool ETH API 客户端
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class M2Pool_ETH_API {
|
||||
|
||||
/**
|
||||
* API 基础 URL
|
||||
*/
|
||||
private $api_url;
|
||||
|
||||
/**
|
||||
* API 密钥
|
||||
*/
|
||||
private $api_key;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->api_url = get_option('m2pool_eth_api_url', 'http://localhost:8080');
|
||||
$this->api_key = get_option('m2pool_eth_api_key', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
*/
|
||||
private function generate_sign($timestamp) {
|
||||
if (empty($this->api_key)) {
|
||||
return '';
|
||||
}
|
||||
return hash('sha256', dechex($timestamp) . $this->api_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 HTTP 请求
|
||||
*/
|
||||
private function request($endpoint, $method = 'GET', $data = array()) {
|
||||
$url = rtrim($this->api_url, '/') . '/' . ltrim($endpoint, '/');
|
||||
|
||||
$args = array(
|
||||
'method' => $method,
|
||||
'timeout' => 30,
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
);
|
||||
|
||||
if (!empty($data)) {
|
||||
$args['body'] = json_encode($data);
|
||||
}
|
||||
|
||||
$response = wp_remote_request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$body = wp_remote_retrieve_body($response);
|
||||
$code = wp_remote_retrieve_response_code($response);
|
||||
|
||||
if ($code >= 200 && $code < 300) {
|
||||
$data = json_decode($body, true);
|
||||
return $data;
|
||||
} else {
|
||||
return new WP_Error('api_error', sprintf(__('API 错误: %s', 'm2pool-eth-payment'), $body), array('status' => $code));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付请求
|
||||
*
|
||||
* 注意:这个方法假设有一个 HTTP API 接口。
|
||||
* 如果后端系统只支持 RabbitMQ,需要创建一个中间 API 服务。
|
||||
*/
|
||||
public function create_payment($queue_id, $from_address, $to_address, $amount, $chain = 'ETH', $symbol = 'ETH') {
|
||||
$timestamp = time();
|
||||
$sign = $this->generate_sign($timestamp);
|
||||
|
||||
$data = array(
|
||||
'queue_id' => $queue_id,
|
||||
'chain' => $chain,
|
||||
'symbol' => $symbol,
|
||||
'from_address' => $from_address,
|
||||
'to_address' => $to_address,
|
||||
'amount' => $amount,
|
||||
'fee' => 0,
|
||||
'timestamp' => $timestamp,
|
||||
'sign' => $sign,
|
||||
);
|
||||
|
||||
// 发送到支付 API
|
||||
// 注意:这里需要根据实际的后端 API 接口调整
|
||||
// 如果后端只支持 RabbitMQ,需要创建一个中间 API 服务来处理
|
||||
$result = $this->request('/api/payment/create', 'POST', $data);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询支付状态
|
||||
*/
|
||||
public function get_payment_status($queue_id) {
|
||||
$result = $this->request('/api/payment/status/' . $queue_id, 'GET');
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建充值监听请求
|
||||
*/
|
||||
public function create_topup($queue_id, $address, $chain = 'ETH', $symbol = 'ETH') {
|
||||
$timestamp = time();
|
||||
$sign = $this->generate_sign($timestamp);
|
||||
|
||||
$data = array(
|
||||
'queue_id' => $queue_id,
|
||||
'chain' => $chain,
|
||||
'symbol' => $symbol,
|
||||
'address' => $address,
|
||||
'timestamp' => $timestamp,
|
||||
'sign' => $sign,
|
||||
);
|
||||
|
||||
$result = $this->request('/api/topup/create', 'POST', $data);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询充值状态
|
||||
*/
|
||||
public function get_topup_status($queue_id) {
|
||||
$result = $this->request('/api/topup/status/' . $queue_id, 'GET');
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
320
integration/wordpress/includes/class-m2pool-eth-gateway.php
Normal file
320
integration/wordpress/includes/class-m2pool-eth-gateway.php
Normal file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
/**
|
||||
* M2Pool ETH 支付网关类
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class M2Pool_ETH_Gateway extends WC_Payment_Gateway {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->id = 'm2pool_eth';
|
||||
$this->icon = apply_filters('woocommerce_m2pool_eth_icon', '');
|
||||
$this->has_fields = false;
|
||||
$this->method_title = __('M2Pool ETH 支付', 'm2pool-eth-payment');
|
||||
$this->method_description = __('接受以太坊 (ETH) 支付', 'm2pool-eth-payment');
|
||||
$this->supports = array(
|
||||
'products',
|
||||
);
|
||||
|
||||
// 加载设置
|
||||
$this->init_form_fields();
|
||||
$this->init_settings();
|
||||
|
||||
// 定义用户可见的设置
|
||||
$this->title = $this->get_option('title', __('ETH 支付', 'm2pool-eth-payment'));
|
||||
$this->description = $this->get_option('description', __('使用以太坊进行支付', 'm2pool-eth-payment'));
|
||||
$this->enabled = $this->get_option('enabled', 'no');
|
||||
|
||||
// 保存设置
|
||||
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
|
||||
|
||||
// 支付完成页面
|
||||
add_action('woocommerce_thankyou_' . $this->id, array($this, 'thankyou_page'));
|
||||
|
||||
// 订单详情页面
|
||||
add_action('woocommerce_order_details_after_order_table', array($this, 'order_details'), 10, 1);
|
||||
|
||||
// 确保在结账页面显示
|
||||
add_filter('woocommerce_available_payment_gateways', array($this, 'ensure_available'), 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保支付网关可用(强制显示)
|
||||
*/
|
||||
public function ensure_available($available_gateways) {
|
||||
// 如果已启用且配置正确,确保在列表中
|
||||
if ($this->enabled === 'yes') {
|
||||
$to_address = $this->get_option('to_address', get_option('m2pool_eth_to_address', ''));
|
||||
if (!empty($to_address) && $this->is_available()) {
|
||||
// 确保网关在可用列表中
|
||||
if (!isset($available_gateways[$this->id])) {
|
||||
$available_gateways[$this->id] = $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $available_gateways;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查支付网关是否可用
|
||||
*/
|
||||
public function is_available() {
|
||||
// 检查是否启用
|
||||
if ($this->enabled !== 'yes') {
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('M2Pool ETH Gateway: Not enabled');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否有接收地址
|
||||
$to_address = $this->get_option('to_address', get_option('m2pool_eth_to_address', ''));
|
||||
if (empty($to_address)) {
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('M2Pool ETH Gateway: No receive address configured');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否有订单(在结账页面)
|
||||
if (is_checkout() || is_checkout_pay_page()) {
|
||||
// 在结账页面,确保有订单
|
||||
$order_id = absint(get_query_var('order-pay'));
|
||||
if ($order_id > 0) {
|
||||
$order = wc_get_order($order_id);
|
||||
if (!$order || $order->get_total() <= 0) {
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('M2Pool ETH Gateway: Invalid order or zero amount');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 调用父类方法
|
||||
$parent_available = parent::is_available();
|
||||
|
||||
// 如果父类返回 false,记录原因(用于调试)
|
||||
if (!$parent_available && defined('WP_DEBUG') && WP_DEBUG) {
|
||||
$order = WC()->cart;
|
||||
$total = $order ? $order->get_total() : 0;
|
||||
error_log(sprintf(
|
||||
'M2Pool ETH Gateway: Parent is_available() returned false. Cart total: %s, Enabled: %s, Address: %s',
|
||||
$total,
|
||||
$this->enabled,
|
||||
!empty($to_address) ? 'set' : 'empty'
|
||||
));
|
||||
}
|
||||
|
||||
return $parent_available;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化表单字段
|
||||
*/
|
||||
public function init_form_fields() {
|
||||
$this->form_fields = array(
|
||||
'enabled' => array(
|
||||
'title' => __('启用/禁用', 'm2pool-eth-payment'),
|
||||
'type' => 'checkbox',
|
||||
'label' => __('启用 M2Pool ETH 支付', 'm2pool-eth-payment'),
|
||||
'default' => 'no',
|
||||
),
|
||||
'title' => array(
|
||||
'title' => __('标题', 'm2pool-eth-payment'),
|
||||
'type' => 'text',
|
||||
'description' => __('客户在结账时看到的支付方式标题', 'm2pool-eth-payment'),
|
||||
'default' => __('ETH 支付', 'm2pool-eth-payment'),
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'description' => array(
|
||||
'title' => __('描述', 'm2pool-eth-payment'),
|
||||
'type' => 'textarea',
|
||||
'description' => __('客户在结账时看到的支付方式描述', 'm2pool-eth-payment'),
|
||||
'default' => __('使用以太坊 (ETH) 进行支付', 'm2pool-eth-payment'),
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'from_address' => array(
|
||||
'title' => __('发送地址', 'm2pool-eth-payment'),
|
||||
'type' => 'text',
|
||||
'description' => __('用于接收支付的以太坊地址', 'm2pool-eth-payment'),
|
||||
'default' => get_option('m2pool_eth_from_address', ''),
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'to_address' => array(
|
||||
'title' => __('接收地址', 'm2pool-eth-payment'),
|
||||
'type' => 'text',
|
||||
'description' => __('用于接收支付的以太坊地址', 'm2pool-eth-payment'),
|
||||
'default' => get_option('m2pool_eth_to_address', ''),
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'chain' => array(
|
||||
'title' => __('链名称', 'm2pool-eth-payment'),
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'ETH' => 'Ethereum',
|
||||
),
|
||||
'default' => 'ETH',
|
||||
),
|
||||
'symbol' => array(
|
||||
'title' => __('代币符号', 'm2pool-eth-payment'),
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'ETH' => 'ETH',
|
||||
'USDT' => 'USDT',
|
||||
),
|
||||
'default' => 'ETH',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理支付
|
||||
*/
|
||||
public function process_payment($order_id) {
|
||||
$order = wc_get_order($order_id);
|
||||
|
||||
if (!$order) {
|
||||
wc_add_notice(__('订单不存在', 'm2pool-eth-payment'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取 API 客户端
|
||||
$api = new M2Pool_ETH_API();
|
||||
|
||||
// 准备支付请求
|
||||
$amount = floatval($order->get_total());
|
||||
$from_address = $this->get_option('from_address', get_option('m2pool_eth_from_address', ''));
|
||||
$to_address = $this->get_option('to_address', get_option('m2pool_eth_to_address', ''));
|
||||
$chain = $this->get_option('chain', 'ETH');
|
||||
$symbol = $this->get_option('symbol', 'ETH');
|
||||
|
||||
if (empty($to_address)) {
|
||||
wc_add_notice(__('支付网关配置错误:接收地址未设置', 'm2pool-eth-payment'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成队列 ID
|
||||
$queue_id = 'wp_' . $order_id . '_' . time();
|
||||
|
||||
// 发送支付请求
|
||||
$result = $api->create_payment($queue_id, $from_address, $to_address, $amount, $chain, $symbol);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
wc_add_notice($result->get_error_message(), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存支付信息到数据库
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'm2pool_eth_payments';
|
||||
|
||||
$wpdb->insert(
|
||||
$table_name,
|
||||
array(
|
||||
'order_id' => $order_id,
|
||||
'queue_id' => $queue_id,
|
||||
'from_address' => $from_address,
|
||||
'to_address' => $to_address,
|
||||
'amount' => $amount,
|
||||
'fee' => isset($result['fee']) ? $result['fee'] : 0,
|
||||
'chain' => $chain,
|
||||
'symbol' => $symbol,
|
||||
'status' => 0, // 待支付
|
||||
),
|
||||
array('%d', '%s', '%s', '%s', '%f', '%f', '%s', '%s', '%d')
|
||||
);
|
||||
|
||||
// 更新订单元数据
|
||||
$order->update_meta_data('_m2pool_queue_id', $queue_id);
|
||||
$order->update_meta_data('_m2pool_payment_address', $to_address);
|
||||
$order->update_meta_data('_m2pool_payment_amount', $amount);
|
||||
$order->update_meta_data('_m2pool_payment_chain', $chain);
|
||||
$order->update_meta_data('_m2pool_payment_symbol', $symbol);
|
||||
$order->save();
|
||||
|
||||
// 将订单状态设置为待支付
|
||||
$order->update_status('pending', __('等待 ETH 支付', 'm2pool-eth-payment'));
|
||||
|
||||
// 启动支付监听
|
||||
$listener = new M2Pool_ETH_Listener();
|
||||
$listener->start_listening($order_id);
|
||||
|
||||
// 返回成功
|
||||
return array(
|
||||
'result' => 'success',
|
||||
'redirect' => $this->get_return_url($order),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 感谢页面
|
||||
*/
|
||||
public function thankyou_page($order_id) {
|
||||
$order = wc_get_order($order_id);
|
||||
|
||||
if (!$order || $order->get_payment_method() !== $this->id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_address = $order->get_meta('_m2pool_payment_address');
|
||||
$payment_amount = $order->get_meta('_m2pool_payment_amount');
|
||||
$payment_symbol = $order->get_meta('_m2pool_payment_symbol');
|
||||
$queue_id = $order->get_meta('_m2pool_queue_id');
|
||||
|
||||
if (!$payment_address || !$payment_amount) {
|
||||
return;
|
||||
}
|
||||
|
||||
include M2POOL_ETH_PLUGIN_DIR . 'templates/payment-instructions.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单详情页面
|
||||
*/
|
||||
public function order_details($order) {
|
||||
if ($order->get_payment_method() !== $this->id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_address = $order->get_meta('_m2pool_payment_address');
|
||||
$payment_amount = $order->get_meta('_m2pool_payment_amount');
|
||||
$payment_symbol = $order->get_meta('_m2pool_payment_symbol');
|
||||
$tx_hash = $order->get_meta('_m2pool_tx_hash');
|
||||
|
||||
if (!$payment_address || !$payment_amount) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<section class="woocommerce-order-details m2pool-eth-payment-details">
|
||||
<h2 class="woocommerce-order-details__title"><?php echo esc_html__('ETH 支付信息', 'm2pool-eth-payment'); ?></h2>
|
||||
<table class="woocommerce-table woocommerce-table--order-details shop_table order_details">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('支付地址', 'm2pool-eth-payment'); ?>:</th>
|
||||
<td><code><?php echo esc_html($payment_address); ?></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('支付金额', 'm2pool-eth-payment'); ?>:</th>
|
||||
<td><?php echo esc_html($payment_amount); ?> <?php echo esc_html($payment_symbol); ?></td>
|
||||
</tr>
|
||||
<?php if ($tx_hash): ?>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('交易哈希', 'm2pool-eth-payment'); ?>:</th>
|
||||
<td><a href="https://etherscan.io/tx/<?php echo esc_attr($tx_hash); ?>" target="_blank"><?php echo esc_html($tx_hash); ?></a></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
255
integration/wordpress/includes/class-m2pool-eth-listener.php
Normal file
255
integration/wordpress/includes/class-m2pool-eth-listener.php
Normal file
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
/**
|
||||
* M2Pool ETH 支付监听器
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class M2Pool_ETH_Listener {
|
||||
|
||||
/**
|
||||
* API 客户端
|
||||
*/
|
||||
private $api;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->api = new M2Pool_ETH_API();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始监听订单支付
|
||||
*/
|
||||
public function start_listening($order_id) {
|
||||
// 创建定时任务检查支付状态
|
||||
if (!wp_next_scheduled('m2pool_eth_check_payments')) {
|
||||
$interval = get_option('m2pool_eth_listen_interval', 30);
|
||||
wp_schedule_event(time(), 'm2pool_eth_interval', 'm2pool_eth_check_payments');
|
||||
}
|
||||
|
||||
// 添加自定义间隔
|
||||
add_filter('cron_schedules', array($this, 'add_cron_interval'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加自定义 Cron 间隔
|
||||
*/
|
||||
public function add_cron_interval($schedules) {
|
||||
$interval = get_option('m2pool_eth_listen_interval', 30);
|
||||
|
||||
$schedules['m2pool_eth_interval'] = array(
|
||||
'interval' => $interval,
|
||||
'display' => sprintf(__('每 %d 秒', 'm2pool-eth-payment'), $interval),
|
||||
);
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查支付状态
|
||||
*/
|
||||
public function check_payment_status($order_id) {
|
||||
$order = wc_get_order($order_id);
|
||||
|
||||
if (!$order) {
|
||||
return array(
|
||||
'success' => false,
|
||||
'message' => __('订单不存在', 'm2pool-eth-payment'),
|
||||
);
|
||||
}
|
||||
|
||||
$queue_id = $order->get_meta('_m2pool_queue_id');
|
||||
|
||||
if (empty($queue_id)) {
|
||||
return array(
|
||||
'success' => false,
|
||||
'message' => __('未找到支付队列 ID', 'm2pool-eth-payment'),
|
||||
);
|
||||
}
|
||||
|
||||
// 从数据库获取支付记录
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'm2pool_eth_payments';
|
||||
$payment = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM $table_name WHERE order_id = %d AND queue_id = %s",
|
||||
$order_id,
|
||||
$queue_id
|
||||
));
|
||||
|
||||
if (!$payment) {
|
||||
return array(
|
||||
'success' => false,
|
||||
'message' => __('未找到支付记录', 'm2pool-eth-payment'),
|
||||
);
|
||||
}
|
||||
|
||||
// 如果已经成功,直接返回
|
||||
if ($payment->status == 1) {
|
||||
return array(
|
||||
'success' => true,
|
||||
'status' => 'completed',
|
||||
'message' => __('支付已完成', 'm2pool-eth-payment'),
|
||||
);
|
||||
}
|
||||
|
||||
// 查询 API 获取最新状态
|
||||
$result = $this->api->get_payment_status($queue_id);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return array(
|
||||
'success' => false,
|
||||
'message' => $result->get_error_message(),
|
||||
);
|
||||
}
|
||||
|
||||
// 更新支付状态
|
||||
$this->update_payment_status($order_id, $result);
|
||||
|
||||
return array(
|
||||
'success' => true,
|
||||
'status' => $this->get_status_text($result['status']),
|
||||
'data' => $result,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Webhook
|
||||
*/
|
||||
public function process_webhook($data) {
|
||||
if (!isset($data['queue_id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$queue_id = $data['queue_id'];
|
||||
|
||||
// 从数据库查找订单
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'm2pool_eth_payments';
|
||||
$payment = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM $table_name WHERE queue_id = %s",
|
||||
$queue_id
|
||||
));
|
||||
|
||||
if (!$payment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 更新支付状态
|
||||
$this->update_payment_status($payment->order_id, $data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新支付状态
|
||||
*/
|
||||
private function update_payment_status($order_id, $data) {
|
||||
$order = wc_get_order($order_id);
|
||||
|
||||
if (!$order) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'm2pool_eth_payments';
|
||||
|
||||
$status = isset($data['status']) ? intval($data['status']) : 0;
|
||||
$tx_hash = isset($data['tx_hash']) ? $data['tx_hash'] : null;
|
||||
$block_height = isset($data['block_height']) ? $data['block_height'] : null;
|
||||
$amount = isset($data['amount']) ? floatval($data['amount']) : null;
|
||||
|
||||
// 更新数据库
|
||||
$update_data = array(
|
||||
'status' => $status,
|
||||
);
|
||||
|
||||
if ($tx_hash) {
|
||||
$update_data['tx_hash'] = $tx_hash;
|
||||
}
|
||||
|
||||
if ($block_height) {
|
||||
$update_data['block_height'] = $block_height;
|
||||
}
|
||||
|
||||
if ($amount !== null) {
|
||||
$update_data['amount'] = $amount;
|
||||
}
|
||||
|
||||
$wpdb->update(
|
||||
$table_name,
|
||||
$update_data,
|
||||
array('order_id' => $order_id),
|
||||
array('%d', '%s', '%d', '%f'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
// 更新订单状态
|
||||
if ($status == 1) {
|
||||
// 支付成功
|
||||
$order->update_meta_data('_m2pool_tx_hash', $tx_hash);
|
||||
$order->payment_complete();
|
||||
$order->add_order_note(__('ETH 支付成功', 'm2pool-eth-payment'));
|
||||
} elseif ($status == 2) {
|
||||
// 待确认
|
||||
$order->update_status('on-hold', __('ETH 支付待确认', 'm2pool-eth-payment'));
|
||||
if ($tx_hash) {
|
||||
$order->update_meta_data('_m2pool_tx_hash', $tx_hash);
|
||||
$order->add_order_note(sprintf(__('ETH 支付待确认,交易哈希: %s', 'm2pool-eth-payment'), $tx_hash));
|
||||
}
|
||||
} elseif ($status == 0 || $status == 3) {
|
||||
// 支付失败
|
||||
$order->update_status('failed', __('ETH 支付失败', 'm2pool-eth-payment'));
|
||||
$order->add_order_note(__('ETH 支付失败', 'm2pool-eth-payment'));
|
||||
}
|
||||
|
||||
$order->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态文本
|
||||
*/
|
||||
private function get_status_text($status) {
|
||||
$statuses = array(
|
||||
0 => 'pending',
|
||||
1 => 'completed',
|
||||
2 => 'processing',
|
||||
3 => 'failed',
|
||||
);
|
||||
|
||||
return isset($statuses[$status]) ? $statuses[$status] : 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量检查所有待支付订单
|
||||
*/
|
||||
public function check_all_pending_payments() {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'm2pool_eth_payments';
|
||||
|
||||
// 获取所有待支付和待确认的订单
|
||||
$payments = $wpdb->get_results(
|
||||
"SELECT * FROM $table_name WHERE status IN (0, 2) ORDER BY created_at ASC LIMIT 50"
|
||||
);
|
||||
|
||||
foreach ($payments as $payment) {
|
||||
$this->check_payment_status($payment->order_id);
|
||||
|
||||
// 避免请求过快
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 注册定时任务处理函数
|
||||
add_action('m2pool_eth_check_payments', 'm2pool_eth_check_all_payments');
|
||||
|
||||
// 定时任务处理函数
|
||||
function m2pool_eth_check_all_payments() {
|
||||
$listener = new M2Pool_ETH_Listener();
|
||||
$listener->check_all_pending_payments();
|
||||
}
|
||||
|
||||
275
integration/wordpress/m2pool-eth-payment.php
Normal file
275
integration/wordpress/m2pool-eth-payment.php
Normal file
@@ -0,0 +1,275 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: M2Pool ETH Payment Gateway
|
||||
* Plugin URI: https://github.com/m2pool/payment-gateway
|
||||
* Description: 支持 ETH 交易的 WordPress 支付网关,支持支付、监听和返回支付结果
|
||||
* Version: 1.0.0
|
||||
* Author: M2Pool
|
||||
* Author URI: https://m2pool.com
|
||||
* Text Domain: m2pool-eth-payment
|
||||
* Domain Path: /languages
|
||||
* Requires at least: 5.0
|
||||
* Requires PHP: 7.4
|
||||
* WC requires at least: 3.0
|
||||
* WC tested up to: 8.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
// 定义插件常量
|
||||
define('M2POOL_ETH_VERSION', '1.0.0');
|
||||
define('M2POOL_ETH_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('M2POOL_ETH_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
define('M2POOL_ETH_PLUGIN_FILE', __FILE__);
|
||||
|
||||
/**
|
||||
* 主插件类
|
||||
*/
|
||||
class M2Pool_ETH_Payment {
|
||||
|
||||
/**
|
||||
* 单例实例
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* 获取单例实例
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化钩子
|
||||
*/
|
||||
private function init_hooks() {
|
||||
// 激活插件时创建数据库表
|
||||
register_activation_hook(__FILE__, array($this, 'activate'));
|
||||
|
||||
// 停用插件时清理
|
||||
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
|
||||
|
||||
// 在 WooCommerce 加载后初始化
|
||||
add_action('plugins_loaded', array($this, 'init'), 11);
|
||||
|
||||
// 添加管理菜单
|
||||
add_action('admin_menu', array($this, 'add_admin_menu'));
|
||||
|
||||
// 注册 AJAX 处理
|
||||
add_action('wp_ajax_m2pool_check_payment', array($this, 'ajax_check_payment'));
|
||||
add_action('wp_ajax_nopriv_m2pool_check_payment', array($this, 'ajax_check_payment'));
|
||||
|
||||
// 注册 Webhook 端点
|
||||
add_action('rest_api_init', array($this, 'register_webhook_routes'));
|
||||
|
||||
// 加载文本域
|
||||
add_action('init', array($this, 'load_textdomain'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件
|
||||
*/
|
||||
public function init() {
|
||||
// 检查 WooCommerce 是否激活
|
||||
if (!class_exists('WooCommerce')) {
|
||||
add_action('admin_notices', array($this, 'woocommerce_missing_notice'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 加载支付网关类
|
||||
require_once M2POOL_ETH_PLUGIN_DIR . 'includes/class-m2pool-eth-gateway.php';
|
||||
require_once M2POOL_ETH_PLUGIN_DIR . 'includes/class-m2pool-eth-api.php';
|
||||
require_once M2POOL_ETH_PLUGIN_DIR . 'includes/class-m2pool-eth-listener.php';
|
||||
|
||||
// 注册支付网关(必须在类加载后)
|
||||
add_filter('woocommerce_payment_gateways', array($this, 'add_gateway'));
|
||||
}
|
||||
|
||||
/**
|
||||
* WooCommerce 缺失通知
|
||||
*/
|
||||
public function woocommerce_missing_notice() {
|
||||
?>
|
||||
<div class="error">
|
||||
<p><?php echo esc_html__('M2Pool ETH Payment Gateway 需要 WooCommerce 插件才能工作。', 'm2pool-eth-payment'); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加支付网关
|
||||
*/
|
||||
public function add_gateway($gateways) {
|
||||
$gateways[] = 'M2Pool_ETH_Gateway';
|
||||
return $gateways;
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活插件
|
||||
*/
|
||||
public function activate() {
|
||||
global $wpdb;
|
||||
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
$table_name = $wpdb->prefix . 'm2pool_eth_payments';
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
|
||||
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
order_id bigint(20) UNSIGNED NOT NULL,
|
||||
queue_id varchar(255) NOT NULL,
|
||||
from_address varchar(255) NOT NULL,
|
||||
to_address varchar(255) NOT NULL,
|
||||
amount decimal(20,8) NOT NULL,
|
||||
fee decimal(20,8) DEFAULT 0,
|
||||
chain varchar(50) DEFAULT 'ETH',
|
||||
symbol varchar(50) DEFAULT 'ETH',
|
||||
tx_hash varchar(255) DEFAULT NULL,
|
||||
block_height bigint(20) UNSIGNED DEFAULT NULL,
|
||||
status int(11) DEFAULT 0 COMMENT '0=待支付,1=成功,2=待确认,3=失败',
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY queue_id (queue_id),
|
||||
KEY order_id (order_id),
|
||||
KEY tx_hash (tx_hash),
|
||||
KEY status (status)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
||||
dbDelta($sql);
|
||||
|
||||
// 设置默认选项
|
||||
if (!get_option('m2pool_eth_api_url')) {
|
||||
update_option('m2pool_eth_api_url', 'http://localhost:8080');
|
||||
}
|
||||
if (!get_option('m2pool_eth_api_key')) {
|
||||
update_option('m2pool_eth_api_key', '');
|
||||
}
|
||||
if (!get_option('m2pool_eth_listen_interval')) {
|
||||
update_option('m2pool_eth_listen_interval', 30); // 30秒轮询一次
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停用插件
|
||||
*/
|
||||
public function deactivate() {
|
||||
// 清理定时任务
|
||||
wp_clear_scheduled_hook('m2pool_eth_check_payments');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加管理菜单
|
||||
*/
|
||||
public function add_admin_menu() {
|
||||
add_options_page(
|
||||
__('M2Pool ETH 支付设置', 'm2pool-eth-payment'),
|
||||
__('M2Pool ETH 支付', 'm2pool-eth-payment'),
|
||||
'manage_options',
|
||||
'm2pool-eth-settings',
|
||||
array($this, 'settings_page')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页面
|
||||
*/
|
||||
public function settings_page() {
|
||||
if (isset($_POST['m2pool_eth_save_settings'])) {
|
||||
check_admin_referer('m2pool_eth_settings');
|
||||
|
||||
update_option('m2pool_eth_api_url', sanitize_text_field($_POST['api_url']));
|
||||
update_option('m2pool_eth_api_key', sanitize_text_field($_POST['api_key']));
|
||||
update_option('m2pool_eth_listen_interval', intval($_POST['listen_interval']));
|
||||
update_option('m2pool_eth_from_address', sanitize_text_field($_POST['from_address']));
|
||||
update_option('m2pool_eth_to_address', sanitize_text_field($_POST['to_address']));
|
||||
|
||||
echo '<div class="notice notice-success"><p>' . esc_html__('设置已保存', 'm2pool-eth-payment') . '</p></div>';
|
||||
}
|
||||
|
||||
$api_url = get_option('m2pool_eth_api_url', 'http://localhost:8080');
|
||||
$api_key = get_option('m2pool_eth_api_key', '');
|
||||
$listen_interval = get_option('m2pool_eth_listen_interval', 30);
|
||||
$from_address = get_option('m2pool_eth_from_address', '');
|
||||
$to_address = get_option('m2pool_eth_to_address', '');
|
||||
|
||||
include M2POOL_ETH_PLUGIN_DIR . 'templates/settings.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX 检查支付状态
|
||||
*/
|
||||
public function ajax_check_payment() {
|
||||
check_ajax_referer('m2pool_eth_check', 'nonce');
|
||||
|
||||
$order_id = intval($_POST['order_id']);
|
||||
$order = wc_get_order($order_id);
|
||||
|
||||
if (!$order) {
|
||||
wp_send_json_error(array('message' => __('订单不存在', 'm2pool-eth-payment')));
|
||||
}
|
||||
|
||||
$listener = new M2Pool_ETH_Listener();
|
||||
$result = $listener->check_payment_status($order_id);
|
||||
|
||||
if ($result['success']) {
|
||||
wp_send_json_success($result);
|
||||
} else {
|
||||
wp_send_json_error($result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册 Webhook 路由
|
||||
*/
|
||||
public function register_webhook_routes() {
|
||||
register_rest_route('m2pool-eth/v1', '/webhook', array(
|
||||
'methods' => 'POST',
|
||||
'callback' => array($this, 'handle_webhook'),
|
||||
'permission_callback' => '__return_true',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Webhook
|
||||
*/
|
||||
public function handle_webhook($request) {
|
||||
$data = $request->get_json_params();
|
||||
|
||||
if (!isset($data['queue_id'])) {
|
||||
return new WP_Error('invalid_data', __('无效的数据', 'm2pool-eth-payment'), array('status' => 400));
|
||||
}
|
||||
|
||||
$listener = new M2Pool_ETH_Listener();
|
||||
$result = $listener->process_webhook($data);
|
||||
|
||||
if ($result) {
|
||||
return new WP_REST_Response(array('success' => true), 200);
|
||||
} else {
|
||||
return new WP_Error('processing_failed', __('处理失败', 'm2pool-eth-payment'), array('status' => 500));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载文本域
|
||||
*/
|
||||
public function load_textdomain() {
|
||||
load_plugin_textdomain('m2pool-eth-payment', false, dirname(plugin_basename(__FILE__)) . '/languages');
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化插件
|
||||
M2Pool_ETH_Payment::get_instance();
|
||||
|
||||
136
integration/wordpress/templates/payment-instructions.php
Normal file
136
integration/wordpress/templates/payment-instructions.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* 支付说明模板
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="m2pool-eth-payment-instructions">
|
||||
<h3><?php echo esc_html__('ETH 支付说明', 'm2pool-eth-payment'); ?></h3>
|
||||
|
||||
<div class="payment-info">
|
||||
<p><strong><?php echo esc_html__('请向以下地址支付:', 'm2pool-eth-payment'); ?></strong></p>
|
||||
<div class="payment-address">
|
||||
<code id="payment-address-code"><?php echo esc_html($payment_address); ?></code>
|
||||
<button type="button" class="button copy-address" data-address="<?php echo esc_attr($payment_address); ?>">
|
||||
<?php echo esc_html__('复制地址', 'm2pool-eth-payment'); ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p><strong><?php echo esc_html__('支付金额:', 'm2pool-eth-payment'); ?></strong></p>
|
||||
<p class="payment-amount"><?php echo esc_html($payment_amount); ?> <?php echo esc_html($payment_symbol); ?></p>
|
||||
|
||||
<div class="payment-status" id="payment-status">
|
||||
<p><?php echo esc_html__('等待支付中...', 'm2pool-eth-payment'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="payment-notes">
|
||||
<p><strong><?php echo esc_html__('注意事项:', 'm2pool-eth-payment'); ?></strong></p>
|
||||
<ul>
|
||||
<li><?php echo esc_html__('请确保支付金额准确', 'm2pool-eth-payment'); ?></li>
|
||||
<li><?php echo esc_html__('支付完成后,系统会自动确认(通常需要几分钟)', 'm2pool-eth-payment'); ?></li>
|
||||
<li><?php echo esc_html__('请勿向此地址发送其他代币', 'm2pool-eth-payment'); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
// 复制地址功能
|
||||
$('.copy-address').on('click', function() {
|
||||
var address = $(this).data('address');
|
||||
var $temp = $('<input>');
|
||||
$('body').append($temp);
|
||||
$temp.val(address).select();
|
||||
document.execCommand('copy');
|
||||
$temp.remove();
|
||||
|
||||
$(this).text('<?php echo esc_js(__('已复制', 'm2pool-eth-payment')); ?>');
|
||||
setTimeout(function() {
|
||||
$('.copy-address').text('<?php echo esc_js(__('复制地址', 'm2pool-eth-payment')); ?>');
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
// 定期检查支付状态
|
||||
var orderId = <?php echo esc_js($order_id); ?>;
|
||||
var checkInterval = setInterval(function() {
|
||||
$.ajax({
|
||||
url: '<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'm2pool_check_payment',
|
||||
order_id: orderId,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('m2pool_eth_check')); ?>'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success && response.data.status === 'completed') {
|
||||
clearInterval(checkInterval);
|
||||
$('#payment-status').html('<p style="color: green;"><?php echo esc_js(__('支付成功!页面将自动刷新...', 'm2pool-eth-payment')); ?></p>');
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
} else if (response.success && response.data.status === 'processing') {
|
||||
$('#payment-status').html('<p style="color: orange;"><?php echo esc_js(__('支付确认中...', 'm2pool-eth-payment')); ?></p>');
|
||||
} else if (response.success && response.data.status === 'failed') {
|
||||
clearInterval(checkInterval);
|
||||
$('#payment-status').html('<p style="color: red;"><?php echo esc_js(__('支付失败', 'm2pool-eth-payment')); ?></p>');
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 10000); // 每10秒检查一次
|
||||
|
||||
// 30秒后停止检查(避免无限检查)
|
||||
setTimeout(function() {
|
||||
clearInterval(checkInterval);
|
||||
}, 300000); // 5分钟
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.m2pool-eth-payment-instructions {
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.payment-address {
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.payment-address code {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.payment-amount {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
color: #0073aa;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.payment-status {
|
||||
margin: 15px 0;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.payment-notes ul {
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
81
integration/wordpress/templates/settings.php
Normal file
81
integration/wordpress/templates/settings.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* 设置页面模板
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<h1><?php echo esc_html__('M2Pool ETH 支付设置', 'm2pool-eth-payment'); ?></h1>
|
||||
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('m2pool_eth_settings'); ?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="api_url"><?php echo esc_html__('API 地址', 'm2pool-eth-payment'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" id="api_url" name="api_url" value="<?php echo esc_attr($api_url); ?>" class="regular-text" />
|
||||
<p class="description"><?php echo esc_html__('支付系统的 API 地址,例如: http://localhost:8080', 'm2pool-eth-payment'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="api_key"><?php echo esc_html__('API 密钥', 'm2pool-eth-payment'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" id="api_key" name="api_key" value="<?php echo esc_attr($api_key); ?>" class="regular-text" />
|
||||
<p class="description"><?php echo esc_html__('用于签名验证的 API 密钥', 'm2pool-eth-payment'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="from_address"><?php echo esc_html__('发送地址', 'm2pool-eth-payment'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" id="from_address" name="from_address" value="<?php echo esc_attr($from_address); ?>" class="regular-text" />
|
||||
<p class="description"><?php echo esc_html__('用于发送支付的以太坊地址(可选)', 'm2pool-eth-payment'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="to_address"><?php echo esc_html__('接收地址', 'm2pool-eth-payment'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" id="to_address" name="to_address" value="<?php echo esc_attr($to_address); ?>" class="regular-text" />
|
||||
<p class="description"><?php echo esc_html__('用于接收支付的以太坊地址', 'm2pool-eth-payment'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="listen_interval"><?php echo esc_html__('监听间隔(秒)', 'm2pool-eth-payment'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" id="listen_interval" name="listen_interval" value="<?php echo esc_attr($listen_interval); ?>" min="10" max="300" />
|
||||
<p class="description"><?php echo esc_html__('检查支付状态的间隔时间(秒),建议 30-60 秒', 'm2pool-eth-payment'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="submit">
|
||||
<input type="submit" name="m2pool_eth_save_settings" class="button button-primary" value="<?php echo esc_attr__('保存设置', 'm2pool-eth-payment'); ?>" />
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2><?php echo esc_html__('Webhook 设置', 'm2pool-eth-payment'); ?></h2>
|
||||
<p><?php echo esc_html__('Webhook URL(用于接收支付状态通知):', 'm2pool-eth-payment'); ?></p>
|
||||
<code><?php echo esc_url(rest_url('m2pool-eth/v1/webhook')); ?></code>
|
||||
<p class="description"><?php echo esc_html__('将此 URL 配置到您的支付系统中,以便接收支付状态更新', 'm2pool-eth-payment'); ?></p>
|
||||
</div>
|
||||
|
||||
13
internal/blockchain/tron/tron.go
Normal file
13
internal/blockchain/tron/tron.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package tron
|
||||
|
||||
// 区块
|
||||
// {
|
||||
// "blockID":,
|
||||
// "block_header": map,
|
||||
// "transactions": map,
|
||||
//}
|
||||
|
||||
type TRONNode struct {
|
||||
decodeKey string
|
||||
ConfirmHeight uint64
|
||||
}
|
||||
1
internal/blockchain/tron/tron_prv.go
Normal file
1
internal/blockchain/tron/tron_prv.go
Normal file
@@ -0,0 +1 @@
|
||||
package tron
|
||||
Reference in New Issue
Block a user