SuperAPI AI 工具集

perfex-payment-gateway

编程与开发

查看项目

更新于 10-16 07:07

技能介绍

用途

本技能用于在 Perfex CRM 中创建、修改或调试支付网关模块。Perfex 自 v2.3.4 起支持以模块形式扩展自定义支付网关:网关是位于 modules/<module>/libraries/<Id>_gateway.php 中的一个类,继承 App_gateway 并实现 process_payment($data)。

主要能力

  • 模块文件结构:模块入口文件(注册钩子与 register_payment_gateway)、可选的 install.php(模块自有表)、libraries 下的网关类、controllers 下的 Webhook 接收控制器、可选的内联支付表单视图与语言文件。库文件名必须以 _gateway.php 结尾,类名与文件名一致(首字母大写)。
  • 网关类骨架:在构造函数中调用 setId()、setName()、setSettings(),并实现 process_payment($data)。
  • 注册:在模块入口文件调用 register_payment_gateway('my_gateway_gateway', 'my_gateway'),第一个参数为类名(小写),第二个参数为模块系统名;激活后网关出现在 Setup → Settings → Payment Gateways。
  • 设置系统:input 渲染文本输入、textarea 渲染多行输入(均可为明文或加密字符串)、yes_no 渲染开关并存储为 '1' 或 '0'、无 type 时渲染文本输入并存为明文字符串。含密钥的设置应设 'encrypted' => true,通过 $this->decryptSetting('name') 读取;非加密设置通过 getSetting() 读取。
  • Webhook 处理:需要两项配置——在模块内提供 config/csrf_exclude_uris.php 排除 CSRF(条目为正则,与 URI 做 ^…$ 匹配,不要使用 (:any)),以及编写继承 App_Controller 的 Webhook 控制器;控制器中读取原始请求体、校验签名(如 hash_hmac 配合 hash_equals)、对不处理的事件返回 200、对未知发票与重复交易做记录,并通过 $gateway->addPayment() 写入付款。此外,核心对 REQUEST_URI 含 gateways/ 子串的请求会完全关闭 CSRF。
  • process_payment 的 $data:包含 invoice(tblinvoices 整行对象)、invoiceid、amount(已含 gateway_fee,支持部分付款)、paymentmode、gateway_fee、payment_attempt(3.x 的 tblpayment_attempts 行),以及表单 POST 的其余内容。没有 currency 键,需读取 $data['invoice']->currency_name 或 get_currency()。核心在 POST 时不会重新校验网关,建议在 process_payment() 顶部重新检查 is_payment_mode_allowed_for_invoice() 与币种,并在必要时于服务端重新推导金额。
  • 处理费(3.x):在类上声明 public bool $processingFees = true 后才会启用 fee_fixed / fee_percent 设置并使 getFee() 返回非零;需通过 payment_attempt_reference 回传引用以便 addPayment() 扣减费用并删除尝试记录。
  • Stripe API(Basil)变更(Perfex 3.3.0+):升级到 3.3.0 后需重建 Webhook(事件负载格式变化);Stripe 现在遵循 Stripe Dashboard 中允许的支付方式(不再由 Perfex 硬编码);after_invoice_added 钩子在 3.2.0 起改为在邮件发送前触发。
  • 参考实现:可研究内置网关 application/libraries/gateways/(Stripe、PayPal、2Checkout、Mollie)与 application/controllers/gateways/。

适用场景

适用于为 Perfex CRM 新增自定义支付网关模块,或调试已有网关的支付流程、Webhook 回调、加密设置读取、处理费对账、多币种可用性判断与重复回调处理等问题。

限制与注意事项

  • 文件名必须以 _gateway.php 结尾,否则不会被识别。
  • setId() 只能使用小写 [a-z0-9_],可用下划线,不可含连字符或空格;该 ID 会成为每笔付款记录中的 paymentmode 及 paymentmethod_<id>_* 选项键,发布后不可更改。
  • 不要存储卡数据,PCI 合规交由外部网关处理,模块只存交易 ID。
  • process_payment 在每次点击“Pay Now”时都会调用,必须幂等或每次都创建新的结账会话,避免重复扣款。
  • 需以多种币种测试;currencies 为逗号分隔字符串,Perfex 据此判断网关对某发票是否可用。
  • Webhook 可能重试,处理程序必须幂等:插入前通过 transactionid 检查是否已记录,并验证发票仍存在。
  • 公开发票 URL 上可能存在过期 paymentmode:若客户页面打开期间网关被停用,POST 到达时核心可能无法解析,需自行防护(如 if (!$gateway || empty($gateway->instance)) return false;)。

相关技能与上游文档

相关技能:perfex-security、perfex-module-dev、perfex-database。

上游文档:Perfex 支付网关指南 https://help.perfexcrm.com/module-as-payment-gateway/;Perfex 模块基础 https://help.perfexcrm.com/module-basics/;Stripe API 变更日志 https://stripe.com/docs/changelog。

本文档基于 2026-09-15 的 Perfex CRM 3.4.0 核心源码验证(使用 scripts/verify-against-core.sh),版本相关说明来自官方变更日志。