如何在 PrestaShop 1.7 中禁用付款功能?
结论
PrestaShop 1.7 不能靠”禁用所有付款模块”实现只下单、不付款。付款模块除了收款,还会在结账时调用 PaymentModule::validateOrder(),把购物车转换为正式订单。如果关闭所有付款方式,客户通常会停在付款步骤,系统也不会生成订单。
合适的处理方式是提供一种”线下付款”方式。它不连接支付网关,也不扣款,只负责创建订单,并把订单设为”等待 ERP 处理”等状态。可以先考虑使用现有的货到付款模块。如果前台文案和流程需要准确对应业务,再开发一个简单的线下付款模块。
方案一:使用现有的货到付款模块
如果当前安装的 PrestaShop 包含 ps_cashondelivery,使用它最方便。
进入后台并完成以下设置:
- 打开”模块管理”。
- 搜索并安装”Cash on delivery”或”货到付款”模块。
- 检查模块对国家、货币、客户组和配送方式的限制,确保目标客户可以使用。
- 通过后台翻译功能,把前台显示的”货到付款”改成”线下付款”或”提交订单”。
- 按照业务需要,把对应的订单状态重命名为”等待 ERP 处理”。
结账时,客户仍需选择一次这种付款方式,但系统不会跳转到第三方支付页面,也不会发起在线支付。客户确认后,PrestaShop 会照常创建订单,ERP 再读取或同步这笔订单。
不要直接修改 modules/ps_cashondelivery 里的翻译文本,因为模块升级可能覆盖这些改动。应优先使用后台的国际化翻译功能。
方案二:创建专用的线下付款模块
如果”货到付款”不符合实际业务含义,可以创建自己的 PaymentModule。模块只显示一个”线下结算”选项,客户确认后立即创建订单。
下面是一个精简示例。正式项目还需要补充订单状态安装、异常处理、日志和 ERP 同步逻辑。
目录结构可以是:
modules/
└── erpofflinepayment/
├── erpofflinepayment.php
├── controllers/
│ └── front/
│ └── validation.php
└── views/
└── templates/
└── front/
└── payment_info.tpl
模块主文件
modules/erpofflinepayment/erpofflinepayment.php:
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
use PrestaShop\PrestaShop\Core\Payment\PaymentOption;
class ErpOfflinePayment extends PaymentModule
{
public function __construct()
{
$this->name = 'erpofflinepayment';
$this->tab = 'payments_gateways';
$this->version = '1.0.0';
$this->author = 'Your Company';
$this->bootstrap = true;
$this->controllers = ['validation'];
parent::__construct();
$this->displayName = $this->l('Offline ERP payment');
$this->description = $this->l(
'Creates an order without collecting an online payment.'
);
}
public function install()
{
return parent::install()
&& $this->registerHook('paymentOptions');
}
public function hookPaymentOptions($params)
{
if (!$this->active) {
return [];
}
$option = new PaymentOption();
$option->setCallToActionText($this->l('Place order without online payment'))
->setAction(
$this->context->link->getModuleLink(
$this->name,
'validation',
[],
true
)
)
->setAdditionalInformation(
$this->fetch(
'module:' . $this->name
. '/views/templates/front/payment_info.tpl'
)
);
return [$option];
}
}
创建订单的控制器
modules/erpofflinepayment/controllers/front/validation.php:
<?php
class ErpOfflinePaymentValidationModuleFrontController
extends ModuleFrontController
{
public function postProcess()
{
$cart = $this->context->cart;
if (
!$cart->id
|| !$cart->id_customer
|| !$cart->id_address_delivery
|| !$cart->id_address_invoice
) {
Tools::redirect('index.php?controller=order');
}
$customer = new Customer((int) $cart->id_customer);
if (
!Validate::isLoadedObject($customer)
|| $customer->secure_key !== $cart->secure_key
) {
Tools::redirect('index.php?controller=order');
}
$currency = new Currency((int) $cart->id_currency);
$total = (float) $cart->getOrderTotal(true, Cart::BOTH);
/*
* 示例暂用 PrestaShop 已有的“等待银行转账”状态。
* 正式项目建议由模块安装程序创建专用的
* “等待 ERP 处理”订单状态,并从 Configuration 中读取其 ID。
*/
$orderStateId = (int) Configuration::get('PS_OS_BANKWIRE');
if ($orderStateId <= 0) {
throw new PrestaShopException(
'Offline payment order state is not configured.'
);
}
$this->module->validateOrder(
(int) $cart->id,
$orderStateId,
$total,
$this->module->displayName,
null,
[],
(int) $currency->id,
false,
$customer->secure_key
);
Tools::redirect(
'index.php?controller=order-confirmation'
. '&id_cart=' . (int) $cart->id
. '&id_module=' . (int) $this->module->id
. '&id_order=' . (int) $this->module->currentOrder
. '&key=' . urlencode($customer->secure_key)
);
}
}
付款方式说明模板
modules/erpofflinepayment/views/templates/front/payment_info.tpl:
<p>
提交订单后无需在线付款,款项将由 ERP 系统在线下处理。
</p>
模块安装并启用后,还要检查”模块管理 → 付款 → 偏好设置”中的国家、货币、客户组和配送方式限制。如果当前条件不符合限制,结账页面不会显示这种付款方式。
是否可以彻底隐藏付款步骤
PrestaShop 1.7 的标准结账流程要求客户选择一个付款选项,有时还要接受服务条款。更稳妥的处理是保留付款步骤,只显示一个”提交订单,无需在线付款”的选项。
可以修改主题 JavaScript,让页面自动选择唯一的付款方式,少一次手动点击。不过,这种做法容易受主题、结账模块和 PrestaShop 升级影响。直接删除付款步骤的风险更高,可能跳过服务条款确认、付款选项校验或订单创建逻辑。
如果业务要求客户点击”提交订单”后直接完成结账,可以定制结账组件,让它自动选中线下付款模块。订单最终仍应由该模块调用 validateOrder() 创建,不要直接向 orders 数据表写入记录。
注意事项
- 不要禁用所有付款模块,否则购物车通常无法转换成订单。
- 不要修改 PrestaShop 核心控制器。这类改动升级时会丢失,也可能破坏其他结账功能。
validateOrder()创建的是正式订单,不只是保存购物车。- 示例中的
PS_OS_BANKWIRE只是临时复用了现有状态。生产环境最好创建独立的”等待 ERP 处理”状态。 - ERP 同步需要具备幂等机制,重复推送同一个订单时,不能在 ERP 中重复创建。
- ERP 接收成功后,可以通过 Webservice、模块接口或定时任务更新 PrestaShop 的订单状态。
- 页面上的”已下单”不能显示为”已付款”。订单邮件、订单状态名称和客户中心文案也要一并调整。
- 上线前应分别测试游客结账、注册客户、优惠券、免运费、多币种和不同配送方式。
备注:内容仅供参考。
