117 lines
7.0 KiB
Markdown
117 lines
7.0 KiB
Markdown
# Yoone Moneris Payments 插件
|
||
|
||
为 WooCommerce 集成 Moneris 支付网关,支持普通支付与 WooCommerce Subscriptions 订阅支付(令牌化与使用令牌自动续费)。本插件可直接对接 Moneris.
|
||
|
||
重点能力一览:
|
||
- 普通支付(首笔扣款):在经典结账表单收集卡片信息,进行令牌化后完成首笔扣款;
|
||
- 令牌化(Tokenization):将卡片信息转换为 Vault 令牌,保存为 WooCommerce 的 Payment Token;
|
||
- 使用令牌支付(Token Payment):使用保存的令牌完成后续扣款,适用于订阅自动续费;
|
||
- Woo Subscriptions 集成:实现 `scheduled_subscription_payment` 自动续费;
|
||
- 我的账户添加支付方式:用户可在“我的账户 → 支付方式”中添加、保存卡片令牌;
|
||
- 退款:提供基础退款接口;
|
||
- 分层架构:`Yoone_Gateway_Moneris`(网关)→ `Yoone_Moneris_API`(领域 API)→ moneryze/Moneris(传输层)。
|
||
|
||
## 安装与配置
|
||
1) 将插件目录 `yoone-moneris-payments` 放置于 `wp-content/plugins/` 下并启用插件。
|
||
2) 在 WooCommerce → 设置 → 付款 → Moneris (Yoone) 中配置:
|
||
- Store ID:Moneris 的 Store ID;
|
||
- API Token:Moneris 的 API Token;
|
||
- Sandbox:开发测试阶段可开启;
|
||
- Moneryze Base URL(可选):指向已部署的 moneryze Node 服务基础 URL,例如 `https://moneryze.example.com/api`。配置后,插件将通过该服务间接调用 Moneris 接口。
|
||
|
||
## 与 WooCommerce Subscriptions 的接口要求说明
|
||
Woo Subscriptions 对支付网关的关键要求主要集中在两点:
|
||
|
||
1. 令牌化(Tokenization)
|
||
- 在首笔支付时(或用户在“我的账户”添加支付方式时),将卡片信息令牌化,返回一个可持久化的令牌(Vault Token)。
|
||
- 令牌需绑定到 WooCommerce 的 `WC_Payment_Token`,并关联用户(`user_id`)与网关(`gateway_id`)。
|
||
- 建议同时保存卡片 `last4`、`brand`、`exp_month`、`exp_year`,以便展示与到期提醒。
|
||
|
||
2. 使用令牌进行后续扣款(Scheduled Payments)
|
||
- Subscriptions 会在到期时调用网关的 `scheduled_subscription_payment( $amount_to_charge, $order )` 方法;
|
||
- 网关需查找订单或用户的保存令牌,并使用令牌完成扣款;
|
||
- 成功后应调用 `$order->payment_complete( $transaction_id )` 并记录订单备注;失败则更新订单为 `failed` 并给出错误说明。
|
||
|
||
本插件在 `class-yoone-gateway-moneris.php` 中实现了上述流程,使用 `WC_Payment_Gateway_CC` 的默认信用卡表单(经典结账页面)。如果使用 Woo Blocks 结账,需要额外实现 Blocks 的网关集成(不在本版范围)。
|
||
|
||
## 架构与代码分层
|
||
- 网关层:`includes/class-yoone-gateway-moneris.php`
|
||
- 负责 WooCommerce 网关注册、设置项、前端表单渲染、订单处理、令牌保存与自动续费对接。
|
||
- 关键方法:
|
||
- `process_payment( $order_id )`:首笔支付流程;
|
||
- `scheduled_subscription_payment( $amount, $order )`:自动续费流程;
|
||
- `add_payment_method()`:我的账户添加支付方式;
|
||
- `process_refund( $order_id, $amount )`:退款;
|
||
|
||
- 领域 API 层:`includes/class-yoone-moneris-api.php`
|
||
- 封装令牌化、令牌扣款、退款等领域动作;
|
||
- 如果配置了 `Moneryze Base URL`,通过 `send_request()` 以 JSON POST 调用 moneryze Node 服务;否则使用占位实现(确保流程可运行,便于集成测试)。
|
||
- 关键方法:
|
||
- `tokenize_card( $card, $customer_id = null )`:令牌化卡片,返回 `{ success, token, last4, brand, exp_month, exp_year }`;
|
||
- `charge_token( $token, $amount, $currency, $order_id, $capture = true )`:使用令牌扣款,返回 `{ success, transaction_id }`;
|
||
- `refund( $transaction_id, $amount )`:退款,返回 `{ success }`;
|
||
|
||
### 与 moneryze 的对接约定(参考)
|
||
为便于与 `/Users/zksu/Developer/work/code/moneryze`(Node.js Moneris 接口)对齐,本插件的 API 层约定以下 HTTP 端点与数据格式(可根据实际服务调整):
|
||
|
||
- POST `{BASE_URL}/tokenize`
|
||
- 请求:`{ number, exp_month, exp_year, cvc, customer_id, store_id, api_token, sandbox }`
|
||
- 响应成功:`{ success: true, token, last4, brand, exp_month, exp_year }`
|
||
- 响应失败:`{ success: false, error }`
|
||
|
||
- POST `{BASE_URL}/charge`
|
||
- 请求:`{ token, amount, currency, order_id, capture, store_id, api_token, sandbox }`
|
||
- 响应成功:`{ success: true, transaction_id }`
|
||
- 响应失败:`{ success: false, error }`
|
||
|
||
- POST `{BASE_URL}/refund`
|
||
- 请求:`{ transaction_id, amount, store_id, api_token, sandbox }`
|
||
- 响应成功:`{ success: true }`
|
||
- 响应失败:`{ success: false, error }`
|
||
|
||
### 典型流程说明
|
||
1. 首笔支付(普通商品或订阅首付)
|
||
- 用户在结账页填写卡片信息;
|
||
- 网关调用 `tokenize_card()` 获取令牌;
|
||
- 若用户已登录,保存令牌到 `WC_Payment_Token_CC`,并关联订单;
|
||
- 调用 `charge_token()` 进行扣款;
|
||
- 成功:`payment_complete()`;失败:显示错误并返回 `fail`。
|
||
|
||
2. 自动续费(订阅)
|
||
- Subscriptions 调用 `scheduled_subscription_payment()`;
|
||
- 网关查找订单或用户的令牌;
|
||
- 调用 `charge_token()` 完成扣款;
|
||
- 成功:`payment_complete()`;失败:更新为 `failed` 并记录原因。
|
||
|
||
3. 我的账户添加支付方式
|
||
- 用户在“我的账户 → 支付方式”提交卡片信息;
|
||
- 网关调用 `tokenize_card()` 并保存到 `WC_Payment_Token_CC`;
|
||
- 成功后返回支付方式列表页面。
|
||
|
||
## 与 WooCommerce 的数据对象
|
||
- `WC_Payment_Token_CC`:保存令牌、用户、到期月/年、后四位等信息;
|
||
- `WC_Order`:订单对象,包含总额、货币、交易号等;通过 `$order->payment_complete( $transaction_id )` 标记成功。
|
||
|
||
## 开发注意事项
|
||
- 生产环境应使用前端令牌化或受控代理(如 moneryze)避免在服务器接收原始卡号;
|
||
- 错误处理与日志:建议在 API 层对异常进行捕获并返回统一错误信息;
|
||
- 安全:`Store ID` 和 `API Token` 不应暴露到前端;
|
||
- Woo Blocks 结账:如需支持,请实现与 Blocks 的支付集成(独立的注册与数据通道)。
|
||
|
||
## 后续扩展建议
|
||
- 支持预授权与完成(preauth/capture)的配置切换;
|
||
- 保存并管理多张卡的默认标记;
|
||
- 交易查询与对账;
|
||
- Webhook/回调:用于异步更新交易状态(若 moneryze 支持)。
|
||
|
||
## 目录结构
|
||
- `includes/class-yoone-gateway-moneris.php`:Woo 网关入口与生命周期;
|
||
- `includes/class-yoone-moneris-api.php`:Moneris 领域 API 封装(支持 moneryze 代理调用)。
|
||
|
||
## 测试
|
||
- 在沙箱模式下使用测试卡进行结账与添加支付方式;
|
||
- 创建订阅商品,验证自动续费路径(到期后查看订单备注与状态)。
|
||
|
||
## 免责声明
|
||
当前内置的直接 Moneris 接口为占位实现,用于演示与集成验证;生产环境请配置并使用 moneryze 服务或替换为官方 SDK/接口调用。
|