Select Woocommerce payment method conditionally in PHP - php

I want to programmatically set a default payment method (radio is checked) in woocommerce checkout page based on a condition using php (not jquery).
Lets say I have two payment methods:
'pay_method1' and 'pay_method2'
Most solutions suggest removing a method in order to select the other:
unset($gateways['pay_method1']) //auto selects pay_method2 naturally
But I don't want to remove the method. I only want to set a default when the checkout page loads / reloads, so the the user can still switch methods if needed.
I plan on having the following action in functions.php:
add_action("woocommerce_before_checkout_form", "custom_before_checkout_action");
function custom_before_checkout_action() {
if ($my_condition) {
//default to pay_method1 - how??
}
else {
//default to pay_method2 - how??
}
}
Is this possible to tell woocommerce which payment method should be checked this way?

You can see woocommerce template structure checkout folder have file payment-method.php. There are payment method $gateway object
have property $gateway->chosen to access true default checked payment gateway.
add_filter('woocommerce_available_payment_gateways', 'show_custom_payment_gateways');
function show_custom_payment_gateways( $available_gateways){
global $woocommerce;
$available_gateways = $woocommerce->payment_gateways->get_available_payment_gateways();
if( $myconditon ){
$available_gateways['pay_method2']->chosen = true;
$available_gateways['pay_method1']->chosen = false // default to false unchecked.
}
}

Related

How to execute a custom hook from another hook in prestashop?

I'm developping a module for prestashop 1.7.3 which handle price reductions depending on the cart content. I'm using two hooks (1. displayFidelityProgramCartTop and 2. actionCartSave) and perform actions inside the hookActionCartSave($params) method : depending on the result, I need to refresh the data returned by the first hook.
I use the Hook::exec('displayFidelityProgramCartTop', array()) at the end of the hookActionCartSave($params) method but it seems that the hook isn't executed. The hook is correctly called once, at the initialization. How can I manage to refresh the data returned by the hook (= re-executing the hook to update the template) ?
My code :
cart.tpl
..
{hook h='displayFidelityProgramCartTop' mod='programmeproplus'}
..
programmeproplus.php (main module file)
public function install(){
..
$this->registerHook('displayFidelityProgramCartTop') &&
$this->registerHook('actionCartSave')
..
}
public function hookActionCartSave() {
// Perform some actions ..
Hook::exec('displayFidelityProgramCartTop', array());
}
public function hookDisplayFidelityProgramCartTop(){
// Perform some actions ..
return "<p>List of promotions : ".$promotions."</p>";
}

How to call function after payment in prestashop?

I am building a custom module in prestashop and I need to execute something after payment accepted and after the emails have been sent. In mymodule.php I have the following hooks:
public function hookActionValidateOrder($params) {
$order = $params['order'];
$customer = $params['customer'];
$valuesToinsert="";
$attrValue=array();
etc...
}
Which is executed normally. I tried actionOrderStatusPostUpdate, actionPaymentConfirmation but none of these seems to be called. I dont know whether it is relevant but I am using opc module and the product is free of charge.
This hook is call when an order is placed after a client confirm his cart. The function that triggers this hook is validateOrder from PaymentModule class. It is call by payment modules when client click en confirm button in checkout. Every payment module should call this function in some moment. But, if you don't have a payment module in your specific process due to free product this hook could maybe be never called.
Anyway, you can subscribe to actionObjectOrderAddAfter hook or similar to get notified when a new order is placed:
public function hookActionObjectOrderAddAfter($params)
{
//$params['object'] contains specific object, in this case your Order object
}
If you need information about order status you could subscribe to hook actionOrderHistoryAddAfter too. Hook actionOrderStatusUpdate is only trigger inside changeIdOrderState function. If for some reason order status change with no call to this function you will miss notification.
Good luck
As you have mentioned in your question that the order you are trying is free, in this case any hook that is called on payment, will never call.
Hence the hooks (i.e. actionOrderStatusPostUpdate, actionPaymentConfirmation, hookActionObjectOrderAddAfter etc.) will never be called as they are called from the PaymentModule.php class and it is not called at all in case of a free order.
Unfortunately, there are no hooks that are called when a free order is placed. In case you want to take any action on a Free order then you can only do that by overriding the FreeOrder class or _checkFreeOrder() function in ParentOrderController.php
Old post, but wanted to drop a comment to help others. This function calls after an order is submitted and they get the confirmation page, whether a payment was submitted with it or not:
public function hookDisplayOrderConfirmation($params) { }

How prevent PrestaShop from updating product quantities after order validation

I am new to prestashop and I am trying to make a payment module where I need to duplicate an order for statistical issues. My problem is that the duplicate order also substracts from product stock and I need to know where, after an order validation, does prestashop update stock to avoid calling the corresponding function. In few words, I call validateOrder() twice but I need that StockAvailable be updated once.
By the way, I examined the whole validateOrder() function searching for the update section / function but I haven't been able to find it.
The only related code that I have been able to find was this:
// updates stock in shops
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
{
$product_list = $order->getProducts();
foreach ($product_list as $product)
{
// if the available quantities depends on the physical stock
if (StockAvailable::dependsOnStock($product['product_id']))
{
// synchronizes
StockAvailable::synchronize($product['product_id'], $order->id_shop);
}
}
}
but this is only works when advanced stock management is enabled.
Thanks.
The code you're looking for is located in the OrderDetail::create method which uses OrderDetail::checkProductStock which in turn calls StockAvailable::updateQuantity
$update_quantity = StockAvailable::updateQuantity(...
What's interesting is that before updating the quantity there's this condition
if (!StockAvailable::dependsOnStock($product['id_product']))
I suggest that you override this method and return true when you need to.
You might set a global flag before duplicating the order and then check that flag and if it's true return true to prevent updating the stock.
the override code in override/classes/stock/StockAvailable.php
class StockAvailable extends StockAvailableCore
{
public static function dependsOnStock($id_product, $id_shop = null)
{
$no_quantity_update = isset($GLOBALS['no_quantity_update']) && $GLOBALS['no_quantity_update'];
if ($no_quantity_update)
return true;
else return parent::dependsOnStock($id_product, $id_shop = null);
}
}
To make this override effective, delete the file cache/class_index.php to refresh the overrides list
Your module code:
//set to false just to be sure
$GLOBALS['no_quantity_update'] = false;
$this->module->validateOrder($cart->id, Configuration...
//set to true to prevent quantity update
$GLOBALS['no_quantity_update'] = true;
$this->module->validateOrder($cart->id, Configuration...
You can modify directly on the core code but that's not recommended

Hide custom shipping method from checkout form in Magento

I created custom shipping method for magento. And this method needed only for orders created programmatically from others modules.
Question: How i can to hide this method from checkout form without disabling this method in store settings?
I assume the other modules will use your shipping method from admin context; so you could do something like this:
update your collectRates method like this:
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
if (!Mage::app()->getStore()->isAdmin())) {
return false;
}
// rest of your code
This way, you should be able to have the shipping method active but only usable in admin context.

OpenCart: Get $this->session->data['order_id'] in module before ControllerCheckoutSuccess class unsets it

I am developing an OpenCart module and struggling with getting the order_id by using $this->session->data['order_id'].
My module is working fine if I comment out the part which unsets the order_id session variable in ControllerCheckoutSuccess class.
How can I ensure that I get the order_id before ControllerCheckoutSuccess unsets it?
Edit1: I need the order id to extract details like customer name, total amount, subtotal etc for that particular order. Is there some other method by which I can get the order id?
Edit2: Added this code in 'store/catalog/controller/module/myModule.php' in index() function. Using it to store order_id in temp session variable and use it on order success -
if (isset($this->session->data['temp_order_id'])
&& isset($this->request->get['route'])
&& $this->request->get['route'] == 'checkout/success')
{
// perform custom action
unset($this->session->data['temp_order_id']);
}
elseif (isset($this->session->data['order_id']))
{
$this->session->data['temp_order_id'] = $this->session->data['order_id'];
}
Please help!
In catalog/controller/checkout/success.php file, add:
$this->session->data['temp_order_id'] = $this->session->data['order_id'];
After:
if (isset($this->session->data['order_id'])) {
Then call your custom module or call your custom module before checkout success page controller is called.
Couldn't find any solution for this so sorted it by dynamically adding code (as mentioned by Sankar V) using vQmod. However, it adds a dependency that vQmod should be installed already.
Hope it helps someone facing similar problem.

Categories