| 1 |
<?php |
| 2 |
/* |
| 3 |
This file is part of the plugin Pay with Vipps and MobilePay for WooCommerce |
| 4 |
Copyright (c) 2019 WP-Hosting AS |
| 5 |
|
| 6 |
MIT License |
| 7 |
|
| 8 |
Copyright (c) 2019 WP-Hosting AS |
| 9 |
|
| 10 |
Permission is hereby granted, free of charge, to any person obtaining a copy |
| 11 |
of this software and associated documentation files (the "Software"), to deal |
| 12 |
in the Software without restriction, including without limitation the rights |
| 13 |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 14 |
copies of the Software, and to permit persons to whom the Software is |
| 15 |
furnished to do so, subject to the following conditions: |
| 16 |
|
| 17 |
The above copyright notice and this permission notice shall be included in all |
| 18 |
copies or substantial portions of the Software. |
| 19 |
|
| 20 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 21 |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 22 |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 23 |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 24 |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 25 |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 26 |
SOFTWARE. |
| 27 |
*/ |
| 28 |
if ( ! defined( 'ABSPATH' ) ) { |
| 29 |
exit; // Exit if accessed directly |
| 30 |
} |
| 31 |
|
| 32 |
// This file collects actions, hooks and filters that are specific to third-party plugins that need extra support. |
| 33 |
|
| 34 |
// Support Yith WooCommerce Name your price. We need to load the front-end filters when doing express checkout - otherwise price will be zero. |
| 35 |
// Unfortunately, we can't do this before priority 10 for plugins loaded to support their 'premium' stuff. IOK 2021-09-29 |
| 36 |
add_action('after_setup_theme', function () { |
| 37 |
if (function_exists('YITH_Name_Your_Price_Frontend')) { |
| 38 |
if (is_admin() && defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && $_REQUEST['action'] == 'do_express_checkout') { |
| 39 |
YITH_Name_Your_Price_Frontend(); |
| 40 |
} |
| 41 |
} |
| 42 |
|
| 43 |
// Support Tutor LMS in express checkout/checkout. IOK 2026-02-18 |
| 44 |
if (class_exists('Tutor\WooCommerce')) { |
| 45 |
// IOK 2026-02-18 Pretend express/checout orders are gifts for the purposes of tutor. This will stop the system from trying to enrollment when the order is still partial. |
| 46 |
add_action('woo_vipps_before_create_express_checkout_order', function ($cart) { |
| 47 |
add_filter('tutor_is_gift_item', function ($yesno, $item) { |
| 48 |
return true; |
| 49 |
}, 99,2 ); |
| 50 |
}, 10); |
| 51 |
// After we have the customer, proceed with the tutor logic. IOK 2026-02-18 |
| 52 |
add_action('woo_vipps_set_order_shipping_details', function ($order, $shipping, $user) { |
| 53 |
if (empty($order)) return; |
| 54 |
$order_id = $order->get_id(); |
| 55 |
$enrolled = false; |
| 56 |
// This logic is from the Admin Create Order branch of tutors' enrollment logic. IOK 2026-02-18 |
| 57 |
try { |
| 58 |
foreach ( $order->get_items() as $item ) { |
| 59 |
$product_id = $item->get_product_id(); |
| 60 |
$if_has_course = tutor_utils()->product_belongs_with_course( $product_id ); |
| 61 |
if ( $if_has_course ) { |
| 62 |
$course_id = $if_has_course->post_id; |
| 63 |
$customer_id = $order->get_customer_id(); |
| 64 |
tutor_utils()->do_enroll( $course_id, $order_id, $customer_id ); |
| 65 |
$enrolled = true; |
| 66 |
} |
| 67 |
} |
| 68 |
if ($enrolled) { |
| 69 |
$order->save(); |
| 70 |
} |
| 71 |
} catch (Exception $e) { |
| 72 |
Vipps::instance()->log("An error occured while trying to enroll user: " . $e->getMessage(), 'debug'); |
| 73 |
} |
| 74 |
|
| 75 |
}, 10, 3); |
| 76 |
} |
| 77 |
|
| 78 |
// Snap Pixel for WooCommerce adds javascript to ajax functions if the do add-to-cart. We do that for single product express checkout, |
| 79 |
// so better remove that action. IOK 2022-05-13 |
| 80 |
if (class_exists('snap_pixel_functions')) { |
| 81 |
add_action('woocommerce_add_to_cart', function ($args) { |
| 82 |
$doing_express_checkout = (did_action('wp_ajax_nopriv_do_single_product_express_checkout') || did_action('wp_ajax_do_single_product_express_checkout')); |
| 83 |
if (!$doing_express_checkout) return; |
| 84 |
global $wp_filter; |
| 85 |
$carthooks = @$wp_filter['woocommerce_add_to_cart']; |
| 86 |
if ($carthooks && $carthooks[10]) { |
| 87 |
foreach($carthooks[10] as $callback) { |
| 88 |
$f = $callback['function']; |
| 89 |
if (is_array($f) && $f[1] == 'snap_pixel_code_add_to_cart') { |
| 90 |
remove_action('woocommerce_add_to_cart', array($f[0], $f[1]), 10); |
| 91 |
} |
| 92 |
} |
| 93 |
} |
| 94 |
},1, 2); |
| 95 |
|
| 96 |
} |
| 97 |
|
| 98 |
}, 20); |
| 99 |
|
| 100 |
// IOK 2020-03-17: Klarna Checkout now supports external payment methods, such as Vipps. This is great, but we need first to check |
| 101 |
// that any user hasn't already installed the free plugin for this created by Krokedil. If they have, this filter will be present: |
| 102 |
|
| 103 |
add_action('after_setup_theme', function () { |
| 104 |
if (class_exists('KCO') && defined('KCO_WC_VERSION') && version_compare(KCO_WC_VERSION, '2.0.0', '>=') && Vipps::instance()->gateway()->enabled == 'yes') { |
| 105 |
if (has_filter('kco_wc_api_request_args', 'kcoepm_create_order_vipps')) { |
| 106 |
// Vipps external payment support is already present - do nothing. IOK 2021-09-29 |
| 107 |
} else { |
| 108 |
require_once(dirname(__FILE__) . "/VippsKCSupport.class.php"); |
| 109 |
VippsKCSupport::init(); |
| 110 |
} |
| 111 |
} |
| 112 |
|
| 113 |
|
| 114 |
// IOK 2022-06-28 This plugin erroneously tries to create an order on the order-received page when reached via the |
| 115 |
// Vipps Express Checkout route. Reported, but avoiding the issue by disabling it on this page. |
| 116 |
if (class_exists('DIBS_Easy')) { |
| 117 |
add_action('template_redirect', function () { |
| 118 |
if (is_order_received_page()) { |
| 119 |
global $wp; |
| 120 |
if (!isset($wp->query_vars['order-received'])) return; |
| 121 |
$order_id = absint($wp->query_vars['order-received']); |
| 122 |
$order = wc_get_order($order_id); |
| 123 |
if (!$order || is_wp_error($order)) { |
| 124 |
return; |
| 125 |
} |
| 126 |
if ($order->get_payment_method() != 'vipps') { |
| 127 |
return; |
| 128 |
} |
| 129 |
add_filter('option_woocommerce_dibs_easy_settings', function ($value, $option) { |
| 130 |
if (!empty($value)) { |
| 131 |
$value['enabled'] = 'no'; |
| 132 |
$value['description'] = '#yolo'; |
| 133 |
$value['test_mode'] = 'no'; |
| 134 |
return $value; |
| 135 |
} else { |
| 136 |
} |
| 137 |
return $value; |
| 138 |
}, 10, 2); |
| 139 |
} |
| 140 |
}); |
| 141 |
} |
| 142 |
|
| 143 |
// IOK 2022-11-24 support adwords-tracking with Monster Insights |
| 144 |
if (class_exists('MonsterInsights_eCommerce_WooCommerce_Integration')) { |
| 145 |
add_action('woo_vipps_express_checkout_order_created', function ($orderid) { |
| 146 |
$mi = MonsterInsights_eCommerce_WooCommerce_Integration::get_instance(); |
| 147 |
$vipps = Vipps::instance(); |
| 148 |
if (method_exists($mi, 'save_user_cid')) { |
| 149 |
$vipps->log("Saving monster insights tracking info to order $orderid", 'debug'); |
| 150 |
$mi->save_user_cid($orderid); |
| 151 |
} else { |
| 152 |
$vipps->log("Tried adding monster insights session to order $orderid, but save_user_cid does not exist in object", 'debug'); |
| 153 |
} |
| 154 |
}); |
| 155 |
} |
| 156 |
|
| 157 |
|
| 158 |
// For WooCommerce Smart Coupons, which at 6.9.0 thought that doing_ajax and WP_ADMIN => this was an admin call |
| 159 |
// IOK 2022-12-19 reported, but many older versions are likely to exist |
| 160 |
if (class_exists('WC_SC_Purchase_Credit')) { |
| 161 |
function woo_vipps_pretend_not_doing_ajax ($doingit) { |
| 162 |
if ($doingit && isset($_REQUEST['action']) && |
| 163 |
($_REQUEST['action'] == 'do_single_product_express_checkout' || |
| 164 |
$_REQUEST['action'] == 'do_express_checkout')) { |
| 165 |
return false; |
| 166 |
} |
| 167 |
return $doingit; |
| 168 |
} |
| 169 |
function woo_vipps_add_no_ajax () { |
| 170 |
add_filter('wp_doing_ajax', 'woo_vipps_pretend_not_doing_ajax'); |
| 171 |
} |
| 172 |
function woo_vipps_remove_no_ajax() { |
| 173 |
remove_filter('wp_doing_ajax', 'woo_vipps_pretend_not_doing_ajax'); |
| 174 |
} |
| 175 |
add_action('woo_vipps_before_calculate_totals_partial_order', function ($order) { |
| 176 |
add_action('woocommerce_new_order_item', 'woo_vipps_add_no_ajax' , 9); |
| 177 |
add_action('woocommerce_new_order_item', 'woo_vipps_remove_no_ajax' , 11); |
| 178 |
}); |
| 179 |
} |
| 180 |
|
| 181 |
// Support Woo-Mailerlite in Vipps Checkout |
| 182 |
if (class_exists('MailerLite\Includes\Classes\Settings\MailerLiteSettings')) { |
| 183 |
// If Mailerlite is active as well as Vipps Checkout, then add support for it |
| 184 |
if (get_option('ml_account_authenticated') && (Vipps::instance()->gateway()->get_option('vipps_checkout_enabled') == 'yes')) { |
| 185 |
|
| 186 |
// If checkout is active, don't support saving "lost carts" |
| 187 |
add_filter('option_mailerlite_disable_checkout_sync', function ($value, $option) { |
| 188 |
return 1; |
| 189 |
}, 10, 2); |
| 190 |
|
| 191 |
// Check if the checkout feature is enabled for MailerLite, and if so, add the feature for Vipps Checkout |
| 192 |
$checkout = MailerLite\Includes\Classes\Settings\MailerLiteSettings::getInstance()->getMlOption('checkout', 'no'); |
| 193 |
if ($checkout == 'yes') { |
| 194 |
add_filter('woo_vipps_checkout_consent_query', function ($text) { |
| 195 |
return MailerLite\Includes\Classes\Settings\MailerLiteSettings::getInstance()->getMlOption('checkout_label'); |
| 196 |
}); |
| 197 |
add_action('woo_vipps_set_order_shipping_details', function ($order) { |
| 198 |
if (class_exists('MailerLite\Includes\Classes\Process\OrderProcess')) { |
| 199 |
$consent = intval($order->get_meta('_vipps_custom_consent_provided')); |
| 200 |
if ($consent) { |
| 201 |
MailerLite\Includes\Classes\Process\OrderProcess::getInstance()->setOrderCustomerSubscribe($order->get_id());; |
| 202 |
} |
| 203 |
} |
| 204 |
}); |
| 205 |
// Finalize the job only right before the thankyou page |
| 206 |
add_action('woo_vipps_before_thankyou', function ($orderid, $order) { |
| 207 |
if (class_exists('MailerLite\Includes\Classes\Process\OrderProcess')) { |
| 208 |
$consent = intval($order->get_meta('_vipps_custom_consent_provided')); |
| 209 |
if ($consent) { |
| 210 |
MailerLite\Includes\Classes\Process\OrderProcess::getInstance()->processOrderSubscription($orderid); |
| 211 |
} |
| 212 |
} |
| 213 |
}, 10, 2); |
| 214 |
} |
| 215 |
} |
| 216 |
} |
| 217 |
|
| 218 |
// Support Mailchimp for WooCommerce in Vipps Checkout |
| 219 |
if (function_exists('mailchimp_is_configured') && class_exists('MailChimp_Service')) { |
| 220 |
// If mailchimp is configured and Checkout is on, add actions |
| 221 |
if (mailchimp_is_configured() && (Vipps::instance()->gateway()->get_option('vipps_checkout_enabled') == 'yes')) { |
| 222 |
|
| 223 |
add_filter('woo_vipps_checkout_consent_query', function ($text) { |
| 224 |
$opts = get_option('mailchimp-woocommerce'); |
| 225 |
$text = ($opts['newsletter_label'] ?? false) ? $opts['newsletter_label'] : $text; |
| 226 |
return $text; |
| 227 |
}); |
| 228 |
// This should annotate the order correctly, straight before the order changes status to 'processing'. |
| 229 |
add_action('woo_vipps_set_order_shipping_details', function ($order) { |
| 230 |
if (class_exists('MailChimp_Service')) { |
| 231 |
$is_checkout = $order->get_meta('_vipps_checkout'); |
| 232 |
$consent = intval($order->get_meta('_vipps_custom_consent_provided')); |
| 233 |
if ($consent && $is_checkout) { |
| 234 |
$order->update_meta_data('mailchimp_woocommerce_is_subscribed', true); |
| 235 |
$order->save(); |
| 236 |
} |
| 237 |
} |
| 238 |
}); |
| 239 |
} |
| 240 |
|
| 241 |
} |
| 242 |
|
| 243 |
// Disable Vipps checkout/express in cart - for carts with products from the plugin: all-products-for-woocommerce-subscriptions. LP 2025-06-13 |
| 244 |
if (class_exists('WCS_ATT_Cart')) { |
| 245 |
add_filter('woo_vipps_cart_supports_checkout', function ($supports, $cart) { |
| 246 |
foreach ($cart->get_cart_contents() as $values) { |
| 247 |
// below returns instance if product is subscription -> we dont support it, else false (not subscription). LP 2025-06-13 |
| 248 |
$is_wcs_att_sub = WCS_ATT_Cart::get_subscription_scheme($values); |
| 249 |
if ($is_wcs_att_sub) return false; |
| 250 |
} |
| 251 |
return $supports; |
| 252 |
}, 10, 2); |
| 253 |
|
| 254 |
add_filter('woo_vipps_cart_supports_express_checkout', function ($supports, $cart) { |
| 255 |
foreach ($cart->get_cart_contents() as $values) { |
| 256 |
// below returns instance if product is subscription -> we dont support it, else false (not subscription). LP 2025-06-13 |
| 257 |
$is_wcs_att_sub = WCS_ATT_Cart::get_subscription_scheme($values); |
| 258 |
if ($is_wcs_att_sub) return false; |
| 259 |
} |
| 260 |
return $supports; |
| 261 |
}, 10, 2); |
| 262 |
} |
| 263 |
}); |
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
// Anti-support for WooCommerce subscriptions; but allow turning it off using an (advanced) setting or filter. IOK 2021-10-26 |
| 268 |
// Turn off on "pay for order" too |
| 269 |
add_filter('woo_vipps_is_available', function ($ok, $gateway) { |
| 270 |
if (!$ok) return $ok; |
| 271 |
// Can't do these, so remove Vipps as payment method IOK 2021-05-14 |
| 272 |
if (class_exists( 'WC_Subscriptions_Cart')) { |
| 273 |
$paying_for_order = absint( get_query_var( 'order-pay' ) ); |
| 274 |
if (WC_Subscriptions_Cart::cart_contains_subscription()) { |
| 275 |
$ok = false; |
| 276 |
} |
| 277 |
if (function_exists('wcs_cart_contains_renewal') && wcs_cart_contains_renewal()) { |
| 278 |
$ok = false; |
| 279 |
} |
| 280 |
if ($paying_for_order && class_exists('WC_Subscriptions_Product')) { |
| 281 |
$order = wc_get_order($paying_for_order); |
| 282 |
if (is_a($order,'WC_Order')) { |
| 283 |
foreach ( $order->get_items() as $item_id => $item ) { |
| 284 |
if (is_a($item, 'WC_Order_Item_Product')) { |
| 285 |
$prod = $item->get_product(); |
| 286 |
if (is_a($prod, 'WC_Product')) { |
| 287 |
if (WC_Subscriptions_Product::is_subscription($prod)) { |
| 288 |
$ok = false; break; |
| 289 |
} |
| 290 |
} |
| 291 |
} |
| 292 |
} |
| 293 |
} |
| 294 |
} |
| 295 |
$ok = apply_filters('woo_vipps_support_subscription_cart', $ok); |
| 296 |
} |
| 297 |
return $ok; |
| 298 |
}, 10, 2); |
| 299 |
|