yoone-wc-moneris-payments/yoone-moneris-payments.php

146 lines
7.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Plugin Name: Yoone Moneris Payments
* Description: 自定义 Moneris 支付网关,支持 WooCommerce Subscriptions 的令牌化与自动续费(占位实现,待接入 Moneris 实际 API
* Version: 0.1.0
* Author: Yoone
* Requires at least: 5.0
* Requires PHP: 7.4
* Requires Plugins: woocommerce
* WC requires at least: 6.0
* WC tested up to: 10.1.0
*/
// 以上为 WordPress 插件头部信息:
// - Plugin Name/Description/Version/Author 等会在后台插件列表展示;
// - Requires at least/Requires PHP 指定最低 WordPress/PHP 版本要求;
// - Requires Plugins: woocommerce 表示此插件依赖 WooCommerce
// - WC requires at least / WC tested up to 提供与 WooCommerce 版本兼容性提示。
if ( ! defined( 'ABSPATH' ) ) {
exit;
// 说明:这是 WordPress 的常量 ABSPATHWP 根目录路径),未定义通常表示非 WP 环境直接访问 PHP 文件;
// 为安全起见,若未定义则退出,避免被直接访问执行。
}
/**
* 初始化插件
*/
function yoone_moneris_payments_init() {
if ( ! class_exists( 'WooCommerce' ) ) {
// add_action 是 WordPress 的动作钩子 API在 'admin_notices' 钩子上注册一个回调,
// 该钩子用于在后台页面顶部显示提示信息;这里我们输出一条错误提示,提醒需要启用 WooCommerce。
add_action( 'admin_notices', function() {
echo '<div class="error"><p><strong>Yoone Moneris Payments 需要 WooCommerce 插件已启用。</strong></p></div>';
} );
// 由于 Woo 未启用,直接返回,不再继续初始化插件逻辑。
return;
}
// 加载常量/接口/工具与类require_once 是 PHP 语句,确保文件仅加载一次;
// __DIR__ 是当前文件所在目录,拼接 includes 路径以找到类定义文件。
require_once __DIR__ . '/includes/constants/moneris.php';
require_once __DIR__ . '/includes/interfaces/class-yoone-moneris-api-interface.php';
// 加载交易类型常量接口,统一交易类型字符串,避免在使用处多次 require
require_once __DIR__ . '/includes/interfaces/class-yoone-moneris-txn-types.php';
require_once __DIR__ . '/includes/utils/logger.php';
require_once __DIR__ . '/includes/class-yoone-moneris-api.php';
require_once __DIR__ . '/includes/class-yoone-gateway-moneris.php';
// 注册到 WooCommerce 支付网关列表add_filter 是 WordPress 的过滤器钩子 API
// 'woocommerce_payment_gateways' 钩子在 Woo 初始化网关列表时触发,回调接收现有网关类名数组 $methods
// 我们把自定义网关类名 'Yoone_Gateway_Moneris' 追加进去并返回。
add_filter( 'woocommerce_payment_gateways', function( $methods ) {
$methods[] = 'Yoone_Gateway_Moneris';
return $methods;
} );
}
// 在 WordPress 的 'plugins_loaded' 钩子上注册初始化函数:
// 'plugins_loaded' 在所有插件加载完成后触发,优先级 0 表示尽早执行;
// 这样可以保证 WooCommerce 已加载,从而我们的初始化逻辑能正确检测与注册网关。
add_action( 'plugins_loaded', 'yoone_moneris_payments_init', 0 );
/**
* 声明 HPOS 兼容(如启用)
*/
// 说明HPOSHigh-Performance Order Storage是 WooCommerce 的高性能订单存储机制;
// 若站点启用该特性,插件需要声明兼容,避免因订单数据结构变化导致不兼容问题。
function yoone_moneris_declare_hpos_compat() {
if ( class_exists( '\\Automattic\\WooCommerce\\Utilities\\FeaturesUtil' ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
}
}
// 在 WooCommerce 初始化前('before_woocommerce_init' 钩子)注册兼容性声明函数:
// 该钩子在 Woo 启动早期触发,确保 Woo 在初始化过程中已经知道本插件对 HPOS 的兼容性。
add_action( 'before_woocommerce_init', 'yoone_moneris_declare_hpos_compat' );
/**
* 检测是否使用了 WooCommerce Blocks 结账但当前网关未提供 Blocks 集成,提示管理员。
*/
function yoone_moneris_blocks_checkout_admin_notice() {
if ( ! class_exists( 'WooCommerce' ) ) {
return;
}
// 仅在后台提示
if ( ! is_admin() ) {
return;
}
// 网关是否启用
$settings = get_option( 'woocommerce_yoone_moneris_settings', array() );
$enabled = isset( $settings['enabled'] ) ? $settings['enabled'] : 'no';
if ( 'yes' !== $enabled ) {
return;
}
// 检查结账页是否为 Blocks 结账
$checkout_id = function_exists( 'wc_get_page_id' ) ? wc_get_page_id( 'checkout' ) : 0;
if ( $checkout_id && function_exists( 'has_block' ) ) {
$post = get_post( $checkout_id );
if ( $post && has_block( 'woocommerce/checkout', $post ) ) {
// 当前插件未提供 Blocks 前端集成,因此 Blocks 结账不会显示本网关
add_action( 'admin_notices', function() {
echo '<div class="notice notice-warning"><p>Yoone Moneris Payments 当前未集成 WooCommerce Blocks 结账。如果你的结账页使用了 Blocks请改用经典结账在结账页添加短代码 [woocommerce_checkout] 并在 WooCommerce → 设置 → 高级 中设置该页面为结账页),或联系开发者添加 Blocks 集成。</p></div>';
} );
}
}
}
add_action( 'admin_init', 'yoone_moneris_blocks_checkout_admin_notice' );
/**
* Blocks 结账支付方式集成:注册脚本、向前端暴露设置、注册支付方式类型。
*/
function yoone_moneris_blocks_bootstrap() {
// 仅当 WooCommerce Blocks 环境可用时进行注册
if ( ! class_exists( '\\Automattic\\WooCommerce\\Blocks\\Payments\\PaymentMethodRegistry' ) ) {
return;
}
// 注册前端脚本(不打包版本,依赖 Blocks 与 WP 提供的全局模块)
$asset_deps = array( 'wc-blocks-registry', 'wc-settings', 'wp-element', 'wp-i18n' );
wp_register_script(
'yoone-moneris-blocks',
plugins_url( 'yoone-moneris-payments/assets/js/blocks/moneris.js', dirname(__FILE__) ),
$asset_deps,
'1.0.0',
true
);
// 暴露网关基础设置到前端 wcSettings
$settings = get_option( 'woocommerce_yoone_moneris_settings', array() );
$data = array(
'title' => isset( $settings['title'] ) ? (string) $settings['title'] : __( 'Credit Card (Moneris)', 'yoone-moneris' ),
'enabled' => isset( $settings['enabled'] ) && 'yes' === strtolower( (string) $settings['enabled'] ),
'sandbox' => isset( $settings['sandbox'] ) ? (string) $settings['sandbox'] : 'yes',
'currency' => function_exists( 'get_woocommerce_currency' ) ? get_woocommerce_currency() : 'CAD',
);
wp_add_inline_script( 'yoone-moneris-blocks', 'window.wcSettings = window.wcSettings || {}; window.wcSettings.yooneMonerisData = ' . wp_json_encode( $data ) . ';', 'before' );
// 注册 Blocks 支付方式类型(在 Blocks 类型存在时才注册,避免类未定义导致致命错误)
require_once __DIR__ . '/includes/blocks/class-yoone-blocks-moneris.php';
add_action( 'woocommerce_blocks_payment_method_type_registration', function( $payment_method_registry ) {
if ( class_exists( 'Yoone_Moneris_Blocks_Payment_Method' ) ) {
$payment_method_registry->register( new Yoone_Moneris_Blocks_Payment_Method() );
}
} );
}
add_action( 'woocommerce_blocks_loaded', 'yoone_moneris_blocks_bootstrap' );