276 lines
8.7 KiB
PHP
276 lines
8.7 KiB
PHP
<?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();
|
|
|