如何在Prestashop中为COD支付方式添加手续费?项目经多开发者修改不知源码位置
Hey there! Adding a COD (Cash on Delivery) fee to a PrestaShop project that’s been tweaked multiple times can feel like navigating a maze—you don’t want to break existing customizations. Let’s walk through the most reliable approaches, ordered from safest (no core/module edits) to more targeted (if you need to work with existing modifications):
1. Use a Custom Module with PrestaShop Hooks (RECOMMENDED)
This method avoids touching any existing modified code, making it future-proof and low-risk. You’ll build a tiny custom module that hooks into PrestaShop’s cart and payment flow to add the fee only when COD is selected.
Step 1: Create the Custom Module
Make a new folder codhandlingfee in your modules/ directory, then add two files:
codhandlingfee.php
<?php if (!defined('_PS_VERSION_')) { exit; } class CodHandlingFee extends Module { public function __construct() { $this->name = 'codhandlingfee'; $this->tab = 'payments_gateways'; $this->version = '1.0.0'; $this->author = 'Your Name'; $this->need_instance = 0; $this->bootstrap = true; parent::__construct(); $this->displayName = $this->l('COD Handling Fee'); $this->description = $this->l('Adds a handling fee for Cash on Delivery payments.'); $this->ps_versions_compliancy = [ 'min' => '1.7', 'max' => _PS_VERSION_ ]; } public function install() { return parent::install() && $this->registerHook('actionCartCalculation') && $this->registerHook('actionPaymentOptions'); } // Add fee to cart when COD is selected public function hookActionCartCalculation($params) { $cart = $params['cart']; $id_currency = $cart->id_currency; $selected_payment_id = (int)Tools::getValue('id_payment'); // Replace with YOUR COD payment method ID (find it in backend Payment Methods URL) $cod_payment_id = 3; if ($selected_payment_id === $cod_payment_id) { // Option 1: Fixed fee $fee_amount = 5.00; // Option 2: Percentage fee (uncomment below, comment fixed fee above) // $subtotal = $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS); // $fee_amount = $subtotal * 0.02; // 2% of product subtotal // Add the fee as a cart rule (shows up in cart summary) $cart->addCartRule( 0, 0, $fee_amount, 'fixed', 1, '', '', 1, 0, 1, 0, $id_currency, 0, '', '', false, $this->l('COD Handling Fee') ); } } // Display fee notice on payment options page public function hookActionPaymentOptions($params) { $cod_payment_id = 3; // Same COD ID as above $fee_amount = 5.00; // Match your fee amount foreach ($params['payment_options'] as &$option) { if ($option->id_module === $cod_payment_id) { $option->extra .= '<br><small>* ' . $this->l('COD Handling Fee') . ': ' . Tools::displayPrice($fee_amount, $params['cart']->id_currency) . '</small>'; } } return $params['payment_options']; } }
config.xml
<?xml version="1.0" encoding="UTF-8"?> <module> <name>codhandlingfee</name> <displayName><![CDATA[COD Handling Fee]]></displayName> <version><![CDATA[1.0.0]]></version> <author><![CDATA[Your Name]]></author> <description><![CDATA[Adds a handling fee for Cash on Delivery payments.]]></description> <tab><![CDATA[payments_gateways]]></tab> <bootstrap><![CDATA[true]]></bootstrap> </module>
Step 2: Install the Module
Go to your PrestaShop backend → Modules → Module Manager, search for "COD Handling Fee", and install it. Don’t forget to update the $cod_payment_id and $fee_amount values to match your setup.
2. Modify the Existing COD Payment Module (If You Must)
If the previous developers already customized the COD module (modules/cod/cod.php), you can add the fee directly there. Always back up the file first!
Edit cod.php
- Add fee to order total: Update the
validateOrdermethod to include the fee when processing the order:
public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Cash on Delivery', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, Shop $shop = null) { $cart = new Cart($id_cart); $fee_amount = 5.00; // Your fee amount $amount_paid += $fee_amount; // Add fee note to order message if ($message) { $message .= '<br>'; } $message .= $this->l('Incl. COD Handling Fee: ') . Tools::displayPrice($fee_amount, $cart->id_currency); parent::validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method, $message, $extra_vars, $currency_special, $dont_touch_amount, $secure_key, $shop); }
- Show fee on payment page: Update the
getPaymentOptionsmethod to display the fee to users:
public function getPaymentOptions() { $options = parent::getPaymentOptions(); $fee_amount = 5.00; $options[0]['extra'] = '<br><small>* ' . $this->l('COD Handling Fee') . ': ' . Tools::displayPrice($fee_amount, Context::getContext()->currency->id) . '</small>'; return $options; }
3. Quick Check for Existing Customizations
Before starting, search your codebase for keywords like COD fee, cash on delivery fee, or handling fee—the previous developers might have already started this work. Use a command like:
grep -r "COD fee" /path/to/your/prestashop/
Critical Notes
- Find your COD Payment ID: Go to Backend → Payment Methods, click on your COD method, and check the URL for
id_payment=X(replace X in the code). - Test thoroughly: Test COD checkout, order confirmation, order history, and refund flows to ensure the fee is applied correctly.
- Backup everything: Especially files that were modified by previous developers—you don’t want to break existing functionality.
内容的提问来源于stack exchange,提问作者Joel Rodrigues

