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/Blocks/Payment/Vipps.class.php +247 -35 6.2.2 → 6.3.0 View file →
@@ -8,66 +8,278 @@
8 8
9 9 namespace Automattic\WooCommerce\Blocks\Payments\Integrations;
10 10
11 11 final class Vipps extends AbstractPaymentMethodType {
12 - private $localized=0;
12 + private $localized = 0;
13 + private static $store_api_payment_processor = null;
13 14 protected $name = 'vipps';
14 - protected $payment_method_name = "Vipps";
15 + protected $payment_method_name = 'Vipps';
15 16
17 + /**
18 + * Load gateway settings and register the Store API bridge when Blocks initializes this integration.
19 + */
16 20 public function initialize() {
17 21 $this->settings = get_option( 'woocommerce_vipps_settings', [] );
18 - $this->payment_method_name = \WC_Gateway_Vipps::instance()->get_payment_method_name();
22 + $this->payment_method_name = \WC_Gateway_Vipps::instance()->get_payment_method_name();
23 + $this->register_store_api_payment_processor();
19 24 }
20 25
21 - // Register this payment method IOK 2020-08-10
22 - public static function register() {
23 - add_action( 'woocommerce_blocks_payment_method_type_registration',
24 - function ($registry) {
25 - $registry->register(new static());
26 - });
27 - }
26 + /**
27 + * Register once at priority 10. Setting a result status here lets WooCommerce's
28 + * legacy fallback at priority 999 skip calling process_payment a second time.
29 + */
30 + protected function register_store_api_payment_processor() {
31 + if ( self::$store_api_payment_processor ) {
32 + return;
33 + }
28 34
35 + self::$store_api_payment_processor = $this;
36 +
37 + add_action(
38 + 'woocommerce_rest_checkout_process_payment_with_context',
39 + array( $this, 'process_gutenberg_checkout_payment' ),
40 + 10,
41 + 2
42 + );
43 + }
44 +
45 + // Register this payment method IOK 2020-08-10
46 + /**
47 + * Register the integration with the Blocks payment-method registry.
48 + */
49 + public static function register() {
50 + add_action(
51 + 'woocommerce_blocks_payment_method_type_registration',
52 + function ( $registry ) {
53 + $registry->register( new static() );
54 + }
55 + );
56 + }
57 +
58 + /**
59 + * Expose the method to Blocks only when it is enabled in the gateway settings.
60 + */
29 61 public function is_active() {
30 62 return filter_var( $this->get_setting( 'enabled', false ), FILTER_VALIDATE_BOOLEAN );
31 63 }
64 +
65 + /**
66 + * Load the checkout component after shared gateway code; filemtime invalidates cached JavaScript.
67 + */
32 68 public function get_payment_method_script_handles() {
33 69
34 - $version = filemtime(dirname(__FILE__) . "/js/wc-payment-method-vipps.js");
35 - $path = plugins_url('js/wc-payment-method-vipps.js', __FILE__);
36 - $handle = 'wc-payment-method-vipps';
37 - $dependencies = array('wp-hooks', 'vipps-gw');
70 + $version = filemtime( dirname( __FILE__ ) . '/js/wc-payment-method-vipps.js' );
71 + $path = plugins_url( 'js/wc-payment-method-vipps.js', __FILE__ );
72 + $handle = 'wc-payment-method-vipps';
73 + $dependencies = array( 'wp-hooks', 'wp-element', 'vipps-gw' );
38 74
39 - wp_register_script($handle, $path, $dependencies,$version,true);
75 + wp_register_script( $handle, $path, $dependencies, $version, true );
40 76
77 + // Will not use wp_set_script_translations yet, it seems to be not fully compatible with Loco Translate etc. Instead use
78 + // old-fashioned localize-script IOK 2020-08-11
79 + // wp_set_script_translations( 'wc-payment-method-vipps', 'woo-vipps' );
80 + // VippsLocale is localized for vipps-gw instead of this, as it seems it does no longer work to do localize-script at this point.
81 + // IOK 2022-12-13
41 82
42 - // Will not use wp_set_script_translations yet, it seems to be not fully compatible with Loco Translate etc. Instead use
43 - // old-fashioned localize-script IOK 2020-08-11
44 - // wp_set_script_translations( 'wc-payment-method-vipps', 'woo-vipps' );
45 - // VippsLocale is localized for vipps-gw instead of this, as it seems it does no longer work to do localize-script at this point.
46 - // IOK 2022-12-13
47 -
48 83 return [ 'wc-payment-method-vipps' ];
49 84 }
50 85
86 + /**
87 + * Reuse the gateway shortcode so express checkout retains its existing markup and data attributes.
88 + */
51 89 public function get_express_checkout_button () {
52 - $button = \Vipps::instance()->express_checkout_button_shortcode();
90 + $context = 'checkout_gutenberg';
91 + if (is_cart()) {
92 + $context='cart_gutenberg';
93 + }
94 +
95 + ob_start();
96 + \Vipps::instance()->cart_express_checkout_button_html($context);
97 + $button = ob_get_clean();
53 98 return $button;
54 99 }
55 - public function show_express_checkout_button () {
56 - $gw = \Vipps::instance()->gateway();
57 - if (!$gw->cart_supports_express_checkout()) return false;
58 - return $gw->show_express_checkout();
59 - }
60 100
101 + /**
102 + * Check cart support before exposing the merchant's express-checkout setting.
103 + */
104 + public function show_express_checkout_button() {
105 + $gw = \Vipps::instance()->gateway();
106 + if ( ! $gw->cart_supports_express_checkout() ) return false;
107 + return $gw->show_express_checkout();
108 + }
109 +
110 + /**
111 + * Process an existing Store API order through the gateway and expose its URL as
112 + * widget payment details. The pre-process filter may supply a result instead of
113 + * calling the gateway; subsequent filters may adapt the result, URL and reference.
114 + * Exceptions are surfaced by WooCommerce as checkout errors. A successful result
115 + * means payment initiation succeeded, not that payment has been captured.
116 + * The browser suppresses the normal redirect only after accepting the widget handoff.
117 + */
118 + public function process_gutenberg_checkout_payment( $context, $result ) {
119 +
120 + if ( empty( $context->payment_method ) || 'vipps' !== $context->payment_method ) {
121 + return;
122 + }
123 +
124 + $order = isset( $context->order ) ? $context->order : null;
125 +
126 + if ( ! $order || ! is_callable( array( $order, 'get_id' ) ) ) {
127 + throw new \Exception( $this->get_payment_method_error_message( __( '%s could not process the order.', 'woo-vipps' ) ) );
128 + }
129 +
130 + $gateway = $this->get_gutenberg_checkout_gateway();
131 +
132 + if ( ! $gateway ) {
133 + throw new \Exception( $this->get_payment_method_error_message( __( '%s is not available.', 'woo-vipps' ) ) );
134 + }
135 +
136 + $payment_result = apply_filters(
137 + 'woo_vipps_gutenberg_checkout_process_payment_result',
138 + null,
139 + $context,
140 + $result,
141 + $gateway
142 + );
143 +
144 + if ( null === $payment_result ) {
145 + if ( ! is_callable( array( $gateway, 'process_payment' ) ) ) {
146 + throw new \Exception( $this->get_payment_method_error_message( __( '%s could not start the payment.', 'woo-vipps' ) ) );
147 + }
148 +
149 + $payment_result = $gateway->process_payment( $order->get_id() );
150 + }
151 +
152 + $payment_result = apply_filters(
153 + 'woo_vipps_gutenberg_checkout_processed_payment_result',
154 + $payment_result,
155 + $context,
156 + $result,
157 + $gateway
158 + );
159 +
160 + if ( ! is_array( $payment_result ) ) {
161 + throw new \Exception( $this->get_payment_method_error_message( __( '%s returned an invalid payment response.', 'woo-vipps' ) ) );
162 + }
163 +
164 + if ( isset( $payment_result['result'] ) && 'success' !== $payment_result['result'] ) {
165 + $message = ! empty( $payment_result['message'] )
166 + ? $payment_result['message']
167 + : $this->get_payment_method_error_message( __( '%s could not start the payment.', 'woo-vipps' ) );
168 + throw new \Exception( wp_strip_all_tags( $message ) );
169 + }
170 +
171 + $payment_url = apply_filters(
172 + 'woo_vipps_gutenberg_checkout_payment_url',
173 + isset( $payment_result['redirect'] ) ? $payment_result['redirect'] : '',
174 + $payment_result,
175 + $context,
176 + $result,
177 + $gateway
178 + );
179 +
180 + if ( ! $payment_url ) {
181 + throw new \Exception( $this->get_payment_method_error_message( __( '%s did not return a payment URL.', 'woo-vipps' ) ) );
182 + }
183 +
184 + $payment_reference = apply_filters(
185 + 'woo_vipps_gutenberg_checkout_payment_reference',
186 + $this->get_gutenberg_checkout_payment_reference( $payment_result, $order ),
187 + $payment_result,
188 + $context,
189 + $result,
190 + $gateway
191 + );
192 +
193 + $payment_details = array(
194 + 'vippsPaymentUrl' => esc_url_raw( $payment_url ),
195 + 'vippsPaymentReference' => $payment_reference ? sanitize_text_field( $payment_reference ) : '',
196 + );
197 +
198 + if ( isset( $result->payment_details ) && is_array( $result->payment_details ) ) {
199 + $payment_details = array_merge( $result->payment_details, $payment_details );
200 + }
201 +
202 + $payment_details = apply_filters(
203 + 'woo_vipps_gutenberg_checkout_payment_details',
204 + $payment_details,
205 + $payment_result,
206 + $context,
207 + $result,
208 + $gateway
209 + );
210 +
211 + $result->set_status( 'success' );
212 + $result->set_payment_details( $payment_details );
213 + }
214 +
215 + /**
216 + * Resolve the gateway singleton, allowing the main plugin accessor as a compatibility fallback.
217 + */
218 + protected function get_gutenberg_checkout_gateway() {
219 + if ( class_exists( '\WC_Gateway_Vipps' ) && is_callable( array( '\WC_Gateway_Vipps', 'instance' ) ) ) {
220 + return \WC_Gateway_Vipps::instance();
221 + }
222 +
223 + if ( class_exists( '\Vipps' ) && is_callable( array( '\Vipps', 'instance' ) ) ) {
224 + $vipps = \Vipps::instance();
225 +
226 + if ( is_callable( array( $vipps, 'gateway' ) ) ) {
227 + return $vipps->gateway();
228 + }
229 + }
230 +
231 + return null;
232 + }
233 +
234 + /**
235 + * Prefer the returned payment reference, then known order metadata; a missing reference is optional.
236 + */
237 + protected function get_gutenberg_checkout_payment_reference( $payment_result, $order ) {
238 + foreach ( array( 'paymentReference', 'reference', 'vippsPaymentReference' ) as $key ) {
239 + if ( ! empty( $payment_result[ $key ] ) ) {
240 + return $payment_result[ $key ];
241 + }
242 + }
243 +
244 + foreach ( array( '_vipps_payment_reference', '_vipps_reference', 'vipps_payment_reference' ) as $key ) {
245 + $reference = $order->get_meta( $key, true );
246 +
247 + if ( $reference ) {
248 + return $reference;
249 + }
250 + }
251 +
252 + return '';
253 + }
254 +
255 + /**
256 + * Format customer-facing errors using the configured payment method name.
257 + */
258 + protected function get_payment_method_error_message( $message ) {
259 + return sprintf( $message, $this->payment_method_name );
260 + }
261 +
262 + /**
263 + * Expose localized labels, branding and express eligibility as vipps_data for the JS component.
264 + */
61 265 public function get_payment_method_data() {
266 + $logo = ( $this->payment_method_name == 'Vipps' ) ? plugins_url( '../../img/vipps-mark.svg', __FILE__ ) : plugins_url( '../../img/mobilepay-mark.png', __FILE__ );
267 + $brand = ( $this->payment_method_name == 'Vipps' ) ? 'vipps' : 'mobilepay';
268 + $language = substr( determine_locale(), 0, 2 );
269 + if ( ! in_array( $language, array( 'no', 'en', 'da', 'fi', 'sv' ), true ) ) {
270 + $language = 'en';
271 + }
62 272
63 - $logo = ($this->payment_method_name == "Vipps") ? plugins_url('../../img/vipps-mark.svg', __FILE__) : plugins_url('../../img/mobilepay-mark.png', __FILE__);
273 + $data = [
274 + 'title' => $this->payment_method_name,
275 + 'description' => $this->get_setting( 'description' ),
276 + 'iconsrc' => apply_filters( 'woo_vipps_block_logo_url', $logo ),
277 + 'brand' => apply_filters( 'woo_vipps_block_widget_brand', $brand ),
278 + 'language' => apply_filters( 'woo_vipps_block_widget_language', $language ),
279 + 'show_express_checkout' => $this->show_express_checkout_button(),
280 + 'expressbutton' => $this->get_express_checkout_button(),
281 + ];
64 282
65 - return [
66 - 'title' => $this->payment_method_name,
67 - 'description' => $this->get_setting( 'description' ),
68 - 'iconsrc' => apply_filters('woo_vipps_block_logo_url', $logo),
69 - 'show_express_checkout' => $this->show_express_checkout_button(),
70 - 'expressbutton' => $this->get_express_checkout_button()
71 - ];
283 + return $data;
72 284 }
73 285 }