实现唯一订单ID生成函数以避免Moneris主机拒绝重复订单 在API请求失败时自动重试一次并生成新订单ID 增加请求/响应日志记录和敏感信息脱敏处理 |
||
|---|---|---|
| assets/js/blocks | ||
| docs | ||
| includes | ||
| README.md | ||
| readme.txt | ||
| yoone-moneris-payments.php | ||
README.md
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(传输层)。
安装与配置
- 将插件目录
yoone-moneris-payments放置于wp-content/plugins/下并启用插件。 - 在 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 对支付网关的关键要求主要集中在两点:
-
令牌化(Tokenization)
- 在首笔支付时(或用户在“我的账户”添加支付方式时),将卡片信息令牌化,返回一个可持久化的令牌(Vault Token)。
- 令牌需绑定到 WooCommerce 的
WC_Payment_Token,并关联用户(user_id)与网关(gateway_id)。 - 建议同时保存卡片
last4、brand、exp_month、exp_year,以便展示与到期提醒。
-
使用令牌进行后续扣款(Scheduled Payments)
- Subscriptions 会在到期时调用网关的
scheduled_subscription_payment( $amount_to_charge, $order )方法; - 网关需查找订单或用户的保存令牌,并使用令牌完成扣款;
- 成功后应调用
$order->payment_complete( $transaction_id )并记录订单备注;失败则更新订单为failed并给出错误说明。
- Subscriptions 会在到期时调用网关的
本插件在 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 }
- 请求:
典型流程说明
-
首笔支付(普通商品或订阅首付)
- 用户在结账页填写卡片信息;
- 网关调用
tokenize_card()获取令牌; - 若用户已登录,保存令牌到
WC_Payment_Token_CC,并关联订单; - 调用
charge_token()进行扣款; - 成功:
payment_complete();失败:显示错误并返回fail。
-
自动续费(订阅)
- Subscriptions 调用
scheduled_subscription_payment(); - 网关查找订单或用户的令牌;
- 调用
charge_token()完成扣款; - 成功:
payment_complete();失败:更新为failed并记录原因。
- Subscriptions 调用
-
我的账户添加支付方式
- 用户在“我的账户 → 支付方式”提交卡片信息;
- 网关调用
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/接口调用。