PluginProbe
Pay with Vipps and MobilePay for WooCommerce / 6.3.0
Pay with Vipps and MobilePay for WooCommerce v6.3.0
6.2.6 6.3.0 6.2.5 6.2.4 6.2.3 6.2.2 6.2.1 6.2.0 6.1.10 6.1.9 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1.0 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 6.0.0 All 189 releases
← All changes | payment/WC_Gateway_Vipps.class.php +36 -43 6.1.9 → 6.3.0 View file →
@@ -227,9 +227,9 @@
227 227 return $enabled;
228 228 }
229 229 $is_vipps_express = (bool) $order->get_meta( '_vipps_express_checkout' );
230 230 $has_billing_email = (bool) $order->get_billing_email();
231 - if ( $is_vipps_express && ! $has_billing_email ) {
231 + if ( $is_vipps_express) {
232 232 return false;
233 233 }
234 234 return $enabled;
235 235 }, 10, 3);
@@ -621,22 +621,8 @@
621 621 }
622 622 public function shipping_details_callback_url($token='',$reference=0) {
623 623 return $this->make_callback_urls('vipps_shipping_details',$token,$reference);
624 624 }
625 - // Callback for the consetn removal callback. Must use template redirect directly, because wc-api doesn't handle DELETE.
626 - // IOK 2018-05-18
627 - public function consent_removal_callback_url () {
628 - $queryargs = [];
629 - $url = home_url("/", 'https');
630 - if ( !get_option('permalink_structure')) {
631 - $queryargs['vipps-consent-removal']=1;
632 - } else {
633 - $url = trailingslashit(home_url('vipps-consent-removal', 'https'));
634 - }
635 - // And we need to add an empty "callback" query arg as the very last arg to receive the actual callback.
636 - // We can't use add_query_arg for that, as an empty argument will remove the equals-sign.
637 - return add_query_arg($queryargs, $url) . "&callback=";
638 - }
639 625
640 626 // Allow user to select the template to be used for the special Vipps MobilePay pages. IOK 2020-02-17
641 627 public function get_theme_page_templates() {
642 628 if (!$this->page_templates) {
@@ -648,22 +634,8 @@
648 634 }
649 635 return $this->page_templates;
650 636 }
651 637
652 - // We can't use get_pages to get a default list of pages for our settings, because it triggers
653 - // actions that can be used by other plugins. Therefore we must use the database directly and cache the results. IOK 2023-08-22
654 - public function get_pagelist () {
655 - if (!$this->page_list) {
656 - global $wpdb;
657 - $page_list = array(''=>__('Use a simulated page (default)', 'woo-vipps'));
658 - foreach($wpdb->get_results("SELECT ID,post_title FROM {$wpdb->prefix}posts WHERE post_type='page' and post_status='publish'") as $page) {
659 - $page_list[$page->ID] = $page->post_title;
660 - }
661 - $this->page_list = $page_list;
662 - }
663 - return $this->page_list;
664 - }
665 -
666 638 // Check to see if the product in question can be bought with express checkout IOK 2018-12-04
667 639 public function product_supports_express_checkout($product) {
668 640 // IOK 2023-12-12 Can only support express checkout for Vipps - not MobilePay (yet!)
669 641 // IOK 2025-09-01 Now supports mobilepay
@@ -1073,9 +1045,8 @@
1073 1045 global $Vipps;
1074 1046
1075 1047 // Used for defaults in the admin interface; however this functions is called a loot more often than that.
1076 1048 $page_templates = $this->get_theme_page_templates();
1077 - $page_list = $this->get_pagelist();
1078 1049
1079 1050 $orderprefix = $Vipps->generate_order_prefix();
1080 1051
1081 1052 // Default handling based on other parameters and earlier values.
@@ -1093,9 +1064,8 @@
1093 1064
1094 1065 // We will only show the Checkout options if the user has activated the feature (thus creating the pages involved etc). IOK 2021-10-01
1095 1066 $vipps_checkout_activated = get_option('woo_vipps_checkout_activated', false);
1096 1067
1097 -
1098 1068 // This is used for new options,to set reasonable defaults based on older settings. We can't use WC_Settings->get_option for this unfortunately.
1099 1069 $current = get_option('woocommerce_vipps_settings');
1100 1070 // New defaults based on old defaults
1101 1071 $default_static_shipping_for_checkout = 'no';
@@ -1620,22 +1590,24 @@
1620 1590 'description' => __('Turn this on to add support for Woos Order Attribution API for Checkout and Express Checkout. Some stores have reported problems when using this API together with Vipps, so be sure to test this if you turn it on.', 'woo-vipps'),
1621 1591 ),
1622 1592
1623 1593 'vippsspecialpagetemplate' => array(
1624 - 'title' => sprintf(__('Override page template used for the special %1$s pages', 'woo-vipps'), Vipps::CompanyName()),
1594 + 'title' => sprintf(__('Legacy: Override page template used for the special %1$s page', 'woo-vipps'), Vipps::CompanyName()),
1625 1595 'label' => sprintf(__('Use specific template for %1$s', 'woo-vipps'), Vipps::CompanyName()),
1626 1596 'type' => 'select',
1627 1597 'options' => $page_templates,
1628 - 'description' => sprintf(__('Use this template from your theme or child-theme to display all the special %1$s pages. You will probably want a full-width template and it should call \'the_content()\' normally.', 'woo-vipps'), Vipps::CompanyName()),
1598 + 'description' => sprintf(__('Use this template from your theme or child-theme for the special %1$s page.<br>Legacy: This is not necessary anymore - you should instead choose a template by editing the page like any other page.','woo-vipps'), Vipps::CompanyName()),
1629 1599 'default' => ''),
1630 1600
1601 + // Deprecated, not shown anymore: TODO: remove this option in future. LP 2026-09-01
1631 1602 'vippsspecialpageid' => array(
1632 1603 'title' => sprintf(__('Use a real page ID for the special %1$s pages - neccessary for some themes', 'woo-vipps'), Vipps::CompanyName()),
1633 1604 'label' => __('Use a real page ID', 'woo-vipps'),
1634 1605 'type' => 'select',
1635 - 'options' => $page_list,
1606 + 'options' => [],
1636 1607 'description' => sprintf(__('Some very few themes do not work with the simulated pages used by this plugin, and needs a real page ID for this. Choose a blank page for this; the content will be replaced, but the template and other metadata will be present. You only need to use this if the plugin seems to break on the special %1$s pages.', 'woo-vipps'), Vipps::CompanyName()),
1637 - 'default'=>''),
1608 + 'default' => ''
1609 + ),
1638 1610
1639 1611 'sendreceipts' => array(
1640 1612 'title' => __("Send receipts and order confirmation info to the customers' app on completed purchases.", 'woo-vipps'),
1641 1613 'label' => sprintf(__("Send receipts to the customers %1\$s app", 'woo-vipps'), Vipps::CompanyName()),
@@ -2384,15 +2356,15 @@
2384 2356 // Default should never happen, but just to ensure we are in our enumeration
2385 2357 return "initiated";
2386 2358 }
2387 2359
2388 - // This does not normally call Vipps, so if you need to refresh status, please use callback_check_order_status first. IOK 2019-01-23
2360 + // This does not normally call Vipps, so if you need to refresh status, please use poll_and_check_order_status first. IOK 2019-01-23
2389 2361 public function check_payment_status($order) {
2390 2362 if (!$order) return 'cancelled';
2391 2363 $status = $this->interpret_vipps_order_status($order->get_meta('_vipps_status'));
2392 2364 // This can happen if the vipps status is set from the back end for instance. IOK 2020-08-14
2393 2365 if ($order->get_status() == 'pending' && $status != 'initiated') {
2394 - $this->callback_check_order_status($order);
2366 + $this->poll_and_check_order_status($order);
2395 2367 $order = wc_get_order($order->get_id()); // refresh to get the new status IOK 2021-01-20
2396 2368 $status = $this->interpret_vipps_order_status($order->get_meta('_vipps_status'));
2397 2369 }
2398 2370 return $status;
@@ -2397,9 +2369,9 @@
2397 2369 }
2398 2370 return $status;
2399 2371 }
2400 2372
2401 - // Called by callback_check_order_status and handle_callback to handle the situation where
2373 + // Called by poll_and_check_order_status and handle_callback to handle the situation where
2402 2374 // the payment method has been set to something else *after* Vipps has gotten the order.
2403 2375 // This happens very rarely for people who use Vipps as an external payment method in Klarna, so
2404 2376 // we only do it for orders that match this. IOK 2023-02-03
2405 2377 public function reset_erroneous_payment_method($order) {
@@ -2426,9 +2398,9 @@
2426 2398 }
2427 2399
2428 2400 // Check status of order at Vipps, in case the callback has been delayed or failed.
2429 2401 // Should only be called if in status 'pending'; it will modify the order when status changes.
2430 - public function callback_check_order_status($order, $allow_retry = true) {
2402 + public function poll_and_check_order_status($order, $allow_retry = true) {
2431 2403 global $Vipps;
2432 2404 $orderid = $order->get_id();
2433 2405
2434 2406 clean_post_cache($order->get_id());
@@ -3218,9 +3190,14 @@
3218 3190 $is_base64 = $shipping_table ? ( $shipping_table['_is_base64'] ?? false) : false;
3219 3191
3220 3192 if (is_array($shipping_table) && isset($shipping_table[$key])) {
3221 3193 $decoded = $is_base64 ? @base64_decode($shipping_table[$key]) : $shipping_table[$key];
3222 - $shipping_rate = $decoded ? @unserialize($decoded) : null;
3194 +
3195 + // Ensure no shop manager has injected an evil object (that they would have had to add as a plugin) here. IOK 2026-09-18
3196 + $allowed_classes = apply_filters('woo_vipps_express_checkout_allowed_shipping_classes', [WC_Shipping_Rate::class, \stdClass::class]);
3197 + $shipping_rate = $decoded ? @unserialize($decoded, ['allowed_classes' => $allowed_classes]) : null;
3198 + $shipping_rate = is_a($shipping_rate,'WC_Shipping_Rate') ? $shipping_rate : null;
3199 +
3223 3200 if (!$shipping_rate) {
3224 3201 $this->log(sprintf(__("%1\$s: Could not deserialize the chosen shipping method %2\$s for order %3\$d", 'woo-vipps'), Vipps::ExpressCheckoutName(), $method, $order->get_id()), 'error');
3225 3202 $this->log(sprintf(__("Serialized data was %1\$s", 'woo-vipps'), $decoded), 'error');
3226 3203 } else {
@@ -3404,9 +3381,9 @@
3404 3381 $shipping_rate = apply_filters('woo_vipps_express_checkout_shipping_rate',$shipping_rate,$costExTax,$tax,$method,$product);
3405 3382 return $shipping_rate;
3406 3383 }
3407 3384
3408 - // Used by both callback_check_order_status and handle_callback - sets the neccessary order metadata after a successful (or not vipps transaction). IOK 2025-08-13
3385 + // Used by both poll_and_check_order_status and handle_callback - sets the neccessary order metadata after a successful (or not vipps transaction). IOK 2025-08-13
3409 3386 public function order_set_transaction_metadata($order, $transaction) {
3410 3387 // Set Vipps metadata as early as possible
3411 3388 $vippsstamp = strtotime($transaction['timeStamp']);
3412 3389 $vippsamount = $transaction['amount'] ?? '';
@@ -3786,9 +3763,9 @@
3786 3763 }
3787 3764 do_action('woo_vipps_payment_complete_at_shutdown', $order, $this);
3788 3765 } catch (Exception $e) {
3789 3766 // This is/should be non-critical so just log it.
3790 - $this->log(sprintf(__("Could not do all payment-complete actions on %1\$s order %2\$d: %3\$s ", 'woo-vipps'), Vipps::CompanyName(), $orderid, $e->etMessage()), "error");
3767 + $this->log(sprintf(__("Could not do all payment-complete actions on %1\$s order %2\$d: %3\$s ", 'woo-vipps'), Vipps::CompanyName(), $orderid, $e->getMessage()), "error");
3791 3768 }
3792 3769 }
3793 3770
3794 3771 // This is run on payment complete. Per default will it only add a link to the order confirmation page, but
@@ -3895,9 +3872,9 @@
3895 3872
3896 3873 $contents = WC()->cart->get_cart_contents();
3897 3874 $contents = apply_filters('woo_vipps_create_express_checkout_cart_contents',$contents);
3898 3875 try {
3899 - $cart_hash = md5(json_encode(wc_clean($contents)) . WC()->cart->total);
3876 + $cart_hash = WC()->cart->get_cart_hash();
3900 3877 $order = new WC_Order();
3901 3878 $order->set_status('pending');
3902 3879 $order->set_payment_method($this);
3903 3880 if ($ischeckout) {
@@ -3908,8 +3885,9 @@
3908 3885 }
3909 3886 // We use 'checkout' as the created_via key as per requests, but allow merchants to use their own. IOK 2022-09-15
3910 3887 $created_via = apply_filters('woo_vipps_express_checkout_created_via', 'checkout', $order, $ischeckout);
3911 3888 $order->set_created_via($created_via);
3889 + $order->set_cart_hash($cart_hash);
3912 3890
3913 3891 $dummy = sprintf(__('Vipps Express Checkout', 'woo-vipps')); // this is so gettext will find this string.
3914 3892 $dummy = sprintf(__('Vipps Checkout', 'woo-vipps')); // this is so gettext will find this string.
3915 3893
@@ -4134,8 +4112,23 @@
4134 4112 // If enabling this, ensure the page in question exists
4135 4113 if ($this->get_option('vipps_checkout_enabled') == 'yes') {
4136 4114 update_option('woo_vipps_checkout_activated', true, true); // This must be true here, but still, make sure
4137 4115 Vipps::instance()->maybe_create_vipps_pages();
4116 + }
4117 +
4118 + // Ensure special page has the necessary shortcode. LP 2026-09-01
4119 + $special_page = get_post(Vipps::get_special_page_id());
4120 + if ($special_page && !has_shortcode($special_page->post_content, 'vipps_special_page')) {
4121 + $new_content = $special_page->post_content . "\n\n<!-- wp:shortcode -->[vipps_special_page]<!-- /wp:shortcode -->";
4122 + wp_update_post([
4123 + 'ID' => Vipps::get_special_page_id(),
4124 + 'post_content' => $new_content,
4125 + ]);
4126 + } else if (!Vipps::get_special_page_id()) {
4127 + // We shouldn't really get here, the page should be ensured to exist in init. LP 2026-09-03
4128 + /* translators: %s is current method name */
4129 + $this->log(sprintf(__('Missing special page in %s, attempting to fix', 'woo-vipps'), 'process_admin_options'), 'warning');
4130 + Vipps::instance()->ensure_special_page_exists();
4138 4131 }
4139 4132
4140 4133 return $saved;
4141 4134 }