374 lines
12 KiB
Markdown
374 lines
12 KiB
Markdown
# 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 技术实现细节
|
||
|
||
```php
|
||
// 首次支付时保存支付令牌
|
||
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 技术实现细节
|
||
|
||
```php
|
||
// 处理订阅续费
|
||
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 技术实现细节
|
||
|
||
```php
|
||
// 处理续费失败
|
||
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 技术实现细节
|
||
|
||
```php
|
||
// 处理 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 生态系统的兼容性,为商家提供灵活而强大的支付工具。 |