yoone-wc-moneris-payments/docs/技术文档.md

12 KiB
Raw Permalink Blame History

Yoone Moneris 支付网关技术文档

1. 插件概述

Yoone Moneris 支付网关是一个专为 WooCommerce 设计的支付处理插件,与 Yoone Subscriptions 订阅系统无缝集成,实现信用卡令牌化存储和自动续费功能。本插件支持 Moneris 信用卡支付,并提供完整的订阅支付解决方案。

1.1 核心功能

  • 支持 Yoone Subscriptions 订阅系统的自动续费
  • 信用卡支付令牌化存储
  • 安全的客户支付信息管理
  • 支付失败自动重试机制
  • 与 WooCommerce Subscriptions 插件的兼容性
  • 完整的支付日志记录

2. 系统架构

2.1 整体架构

Yoone Moneris 支付网关采用分层架构设计,与 Yoone Subscriptions 插件紧密集成:

┌─────────────────────────┐
│  WooCommerce 前端界面  │
└────────────────┬────────┘
                 ↓
┌─────────────────────────┐     ┌─────────────────┐
│ Yoone Subscriptions     │────▶│  订阅管理系统   │
└────────────────┬────────┘     └─────────────────┘
                 ↓
┌─────────────────────────┐     ┌─────────────────┐
│ Yoone Moneris 支付网关   │────▶│   Moneris API   │
└─────────────────────────┘     └─────────────────┘

2.2 模块关系

  • 订阅系统:管理订阅计划和生命周期
  • 支付网关:处理支付交易和令牌化
  • Moneris API:与 Moneris 支付处理系统通信
  • 令牌存储:安全保存客户支付令牌
  • 定时任务:处理自动续费和失败重试

3. 支付令牌化实现

3.1 令牌化流程

令牌化是实现自动续费的关键技术,流程如下:

  1. 首次支付流程

    • 客户在结账页面输入信用卡信息
    • 支付信息通过安全通道发送到 Moneris
    • Moneris 处理支付并返回支付令牌
    • 支付令牌安全存储在 WordPress 数据库中
  2. 令牌存储机制

    • 使用 WooCommerce 支付令牌系统存储令牌信息
    • 令牌关联到客户账户和订阅记录
    • 实际信用卡信息不会存储在本地系统

3.2 技术实现细节

// 首次支付时保存支付令牌
public function save_payment_token_for_subscription( $order_id ) {
    $order = wc_get_order( $order_id );
    
    // 检查订单是否包含订阅商品
    if ( ! $order || ! self::order_contains_subscription( $order ) ) {
        return;
    }
    
    // 获取支付方式和网关
    $payment_method = $order->get_payment_method();
    $gateway = WC()->payment_gateways()->get_available_payment_gateways()[ $payment_method ] ?? null;
    
    // 验证支付网关支持订阅功能
    if ( ! $gateway || ! self::gateway_supports_subscriptions( $payment_method ) ) {
        return;
    }
    
    // 获取支付令牌
    $payment_token = null;
    
    // 从订单元数据获取令牌
    $token_id = $order->get_meta( '_payment_token_id' );
    if ( $token_id ) {
        $payment_token = WC_Payment_Tokens::get( $token_id );
    }
    
    // 如果没有找到令牌,尝试从网关获取
    if ( ! $payment_token && method_exists( $gateway, 'get_order_payment_token' ) ) {
        $payment_token = $gateway->get_order_payment_token( $order );
    }
    
    // 保存令牌到订阅记录
    if ( $payment_token ) {
        $subscriptions = self::get_subscriptions_for_order( $order_id );
        
        foreach ( $subscriptions as $subscription_id ) {
            update_post_meta( $subscription_id, '_payment_token_id', $payment_token->get_id() );
            update_post_meta( $subscription_id, '_payment_method', $payment_method );
        }
    }
}

4. 自动续费机制

4.1 续费处理流程

自动续费是订阅系统的核心功能,由定时任务触发:

  1. 续费触发

    • WordPress Cron 系统按计划触发续费任务
    • 检查每个订阅的下次支付日期
    • 对到期订阅执行续费处理
  2. 支付处理

    • 从订阅记录获取保存的支付令牌
    • 创建续费订单
    • 使用令牌进行自动扣款
    • 处理支付结果(成功/失败)
  3. 状态更新

    • 支付成功:更新订阅状态和下次续费日期
    • 支付失败:安排重试或暂停订阅

4.2 技术实现细节

// 处理订阅续费
public function process_subscription_renewal( $subscription_id ) {
    $subscription = get_post( $subscription_id );
    
    if ( ! $subscription || 'yoone_subscription' !== $subscription->post_type ) {
        return;
    }
    
    // 获取支付方式和令牌
    $payment_method = get_post_meta( $subscription_id, '_payment_method', true );
    $payment_token_id = get_post_meta( $subscription_id, '_payment_token_id', true );
    
    if ( ! $payment_method || ! $payment_token_id ) {
        $this->handle_renewal_failure( $subscription_id, '缺少支付方式或支付令牌' );
        return;
    }
    
    // 获取网关和令牌
    $gateway = WC()->payment_gateways()->get_available_payment_gateways()[ $payment_method ] ?? null;
    $payment_token = WC_Payment_Tokens::get( $payment_token_id );
    
    if ( ! $gateway || ! $payment_token ) {
        $this->handle_renewal_failure( $subscription_id, '支付网关或支付令牌无效' );
        return;
    }
    
    // 创建续费订单
    $renewal_order = $this->create_renewal_order( $subscription_id );
    
    if ( ! $renewal_order ) {
        $this->handle_renewal_failure( $subscription_id, '创建续费订单失败' );
        return;
    }
    
    // 处理续费支付
    try {
        $result = $this->process_renewal_payment( $gateway, $renewal_order, $payment_token );
        
        if ( $result ) {
            $this->handle_renewal_success( $subscription_id, $renewal_order );
        } else {
            $this->handle_renewal_failure( $subscription_id, '续费支付处理失败', $renewal_order );
        }
    } catch ( Exception $e ) {
        $this->handle_renewal_failure( $subscription_id, '续费支付异常: ' . $e->getMessage(), $renewal_order );
    }
}

5. 支付失败处理机制

5.1 失败重试策略

支付失败是订阅系统中常见的情况,系统实现了智能重试机制:

  1. 重试配置

    • 最大重试次数3次
    • 重试间隔24小时
    • 超过重试次数后可自动暂停订阅
  2. 失败处理流程

    • 支付失败时,订阅状态设为暂停
    • 记录失败原因到订阅日志
    • 发送失败通知给客户
    • 安排下次重试任务
  3. 客户通知

    • 发送支付失败邮件,提醒客户更新支付方式
    • 提供方便的支付信息更新入口

5.2 技术实现细节

// 处理续费失败
private function handle_renewal_failure( $subscription_id, $error_message, $renewal_order = null ) {
    // 更新订阅状态为暂停
    update_post_meta( $subscription_id, '_status', 'on-hold' );
    
    // 添加失败记录
    $this->add_subscription_note( $subscription_id, '续费失败: ' . $error_message );
    
    // 如果有续费订单,设置为失败状态
    if ( $renewal_order ) {
        $renewal_order->update_status( 'failed', '续费支付失败: ' . $error_message );
    }
    
    // 安排重试24小时后
    wp_schedule_single_event( time() + DAY_IN_SECONDS, 'yoone_subscription_process_renewal', [ $subscription_id ] );
    
    // 发送续费失败邮件
    do_action( 'yoone_subscription_renewal_failed', $subscription_id, $error_message, $renewal_order );
}

6. 与 WooCommerce Subscriptions 的兼容性

插件设计为与 WooCommerce Subscriptions 插件完全兼容,实现了双向集成:

  1. 兼容性功能

    • 支持 WCS 的订阅管理界面
    • 同步处理 WCS 计划支付
    • 处理支付方式变更
    • 共享支付令牌系统
  2. 集成实现

    • 提供 WCS 支持标记
    • 处理 WCS 续费订单
    • 同步支付状态

6.1 技术实现细节

// 处理 WooCommerce Subscriptions 续费订单
public function handle_wcs_renewal_order( $renewal_order, $subscription ) {
    // 如果是 Yoone 订阅,同步处理
    $yoone_subscription_id = $subscription->get_meta( '_yoone_subscription_id' );
    
    if ( $yoone_subscription_id ) {
        $renewal_order->add_meta_data( '_yoone_subscription_renewal', $yoone_subscription_id );
        $renewal_order->save();
    }
    
    return $renewal_order;
}

// 处理 WooCommerce Subscriptions 计划支付
public function handle_wcs_scheduled_payment( $subscription_id ) {
    $subscription = wcs_get_subscription( $subscription_id );
    
    if ( ! $subscription ) {
        return;
    }
    
    $yoone_subscription_id = $subscription->get_meta( '_yoone_subscription_id' );
    
    if ( $yoone_subscription_id ) {
        // 触发 Yoone 订阅续费处理
        do_action( 'yoone_subscription_process_renewal', $yoone_subscription_id );
    }
}

7. 安全考虑

7.1 支付安全措施

  • 信用卡信息通过加密通道传输
  • 不存储实际信用卡信息,仅保存支付令牌
  • 遵循 PCI DSS 合规标准
  • 使用 WooCommerce 安全令牌存储机制
  • 定期安全审计和更新

7.2 数据保护

  • 支付令牌存储在 WordPress 安全的用户元数据中
  • 使用 WordPress 的数据验证和转义机制
  • 访问控制限制对支付数据的访问
  • 敏感操作记录详细日志

8. Moneris API 集成

8.1 API 连接配置

  • API 端点Moneris 测试/生产环境端点
  • 凭证管理商户ID和API令牌安全存储
  • 请求格式XML/JSON请求格式
  • 响应处理:标准化响应解析

8.2 主要 API 功能

  • 支付处理:单次支付和授权
  • 令牌创建:信用卡令牌化
  • 令牌支付:使用令牌进行支付
  • 交易查询:获取交易状态
  • 退款处理:处理退款请求

9. 安装与配置

9.1 系统要求

  • WordPress 6.4 或更高版本
  • WooCommerce 8.0 或更高版本
  • PHP 7.4 或更高版本
  • Yoone Subscriptions 插件
  • SSL 证书(必需,用于安全支付)

9.2 配置步骤

  1. 安装并激活 Yoone Subscriptions 插件
  2. 安装并激活 Yoone Moneris 支付网关插件
  3. 在 WooCommerce 设置中配置 Moneris 凭证
  4. 启用订阅支持选项
  5. 配置支付选项和退款政策
  6. 测试支付流程

10. 开发与扩展

10.1 可用钩子

插件提供了多个钩子用于扩展功能:

  • yoone_moneris_payment_processed:支付处理完成后触发
  • yoone_moneris_token_saved:支付令牌保存后触发
  • yoone_moneris_renewal_before_process:续费处理前触发
  • yoone_moneris_renewal_after_process:续费处理后触发
  • yoone_moneris_payment_failed:支付失败时触发

10.2 自定义开发

  • 添加自定义支付验证
  • 集成第三方通知系统
  • 自定义支付成功/失败页面
  • 扩展支付网关功能

11. 性能优化

11.1 性能考量

  • 优化 API 请求频率
  • 使用缓存减少重复请求
  • 异步处理非关键操作
  • 定时任务优化
  • 数据库查询优化

12. 故障排除

12.1 常见问题

  • 支付失败:检查信用卡信息、余额和有效期
  • 令牌创建失败:验证 Moneris 凭证和 API 端点
  • 自动续费失败:检查支付令牌状态和有效性
  • 定时任务不执行:验证 WordPress Cron 设置

12.2 日志系统

  • 详细的支付处理日志
  • 错误捕获和记录
  • 订阅状态变更日志
  • API 通信日志

13. 总结

Yoone Moneris 支付网关为 WooCommerce 电商平台提供了完整的订阅支付解决方案,通过安全的令牌化机制和可靠的自动续费功能,满足了订阅业务的核心需求。插件设计为高度可扩展,同时保持与 WooCommerce 生态系统的兼容性,为商家提供灵活而强大的支付工具。