Version Description
17/04/2018 =
New - WooCommerce Subscriptions: add support for 'subscription_payment_method_change', shop-customers can change payment method if renewal payment fails (SEPA incasso, credit card)
New - WooCommerce Subscriptions: disable Mollie payment methods on shop-customer's my account page for "Payment method change", keep it enabled for "Pay now" link in emails
New - WooCommerce Subscriptions: improve handling and update messages and notices for Subscription switch to better explain what's happening
New - WooCommerce Subscriptions: set renewal orders and subscriptions to 'On-Hold' if renewal payment fails
Fix - Fallback for getUserMollieCustomerId, get Mollie Customer ID from recent subscription if it's empty in WordPress user meta
Fix - Improve support for Polylang option "Hide URL language information for default language" in webhook and return URLs,
Fix - Only check if customer ID is valid on current API key if there is a customer ID (not empty)(and improve log messages)
Fix - Make sure payment instructions (Bank Transfer) are styled the same as WooCommerce content (Order received, payment pending)
Fix - Don't update/process/expire Mollie payments on WooCommerce orders that have been paid with other payment gateways
Fix - Updated text strings for Bancontact/Mister Cash to just Bancontact
Fix - Use the exact same translation as WooCommerce for order statuses
Fix - Resolve error (fatal error get_payment_method()) that occurred when users made certain custom changes to the WooCommerce template files
Fix - Add order note and log message when customer returns to the site but payment is open/pending
Fix - Improved order note for charged back renewal payments
Release Info
Developer | davdebcom |
Plugin | Mollie Payments for WooCommerce |
Version | 3.0.0 |
Comparing to | |
See all releases |
Code changes from version 2.9.0 to 3.0.0
- includes/mollie/wc/gateway/abstract.php +227 -223
- includes/mollie/wc/gateway/abstractsubscription.php +104 -0
- includes/mollie/wc/gateway/creditcard.php +3 -1
- includes/mollie/wc/gateway/directdebit.php +8 -0
- includes/mollie/wc/gateway/mistercash.php +1 -1
- includes/mollie/wc/helper/data.php +33 -8
- includes/mollie/wc/helper/settings.php +2 -2
- includes/mollie/wc/plugin.php +64 -3
- mollie-payments-for-woocommerce.php +2 -2
- readme.txt +20 -2
@@ -307,183 +307,184 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
307 |
return false;
|
308 |
}
|
309 |
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
if (!$order)
|
319 |
-
{
|
320 |
-
Mollie_WC_Plugin::debug($this->id . ': Could not process payment, order ' . $order_id . ' not found.');
|
321 |
|
322 |
-
|
|
|
323 |
|
324 |
-
|
325 |
-
}
|
326 |
|
327 |
-
|
|
|
328 |
|
329 |
-
|
330 |
-
$initial_order_status = apply_filters(Mollie_WC_Plugin::PLUGIN_ID . '_initial_order_status', $initial_order_status);
|
331 |
|
332 |
-
|
333 |
-
|
334 |
|
335 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
336 |
|
337 |
-
|
338 |
-
$test_mode = $settings_helper->isTestModeEnabled();
|
339 |
-
$customer_id = $this->getUserMollieCustomerId($order,$test_mode);
|
340 |
-
$paymentRequestData = $this->getPaymentRequestData($order, $customer_id);
|
341 |
-
|
342 |
-
$data = array_filter($paymentRequestData);
|
343 |
-
|
344 |
-
$data = apply_filters('woocommerce_' . $this->id . '_args', $data, $order);
|
345 |
-
|
346 |
-
// If this is a subscription switch and customer has a valid mandate, process the order internally
|
347 |
-
try {
|
348 |
-
|
349 |
-
if ( ( '0.00' === $order->get_total() ) && ( $this->is_subscription( $order_id ) == true ) &&
|
350 |
-
0 != $order->get_user_id() && ( wcs_order_contains_switch( $order ) )
|
351 |
-
) {
|
352 |
-
try {
|
353 |
-
Mollie_WC_Plugin::debug( $this->id . ': Subscription switch, fetch mandate ' . $order_id );
|
354 |
-
$mandates = Mollie_WC_Plugin::getApiHelper()->getApiClient( $test_mode )->customers_mandates->withParentId( $customer_id )->all();
|
355 |
-
$validMandate = false;
|
356 |
-
foreach ( $mandates as $mandate ) {
|
357 |
-
if ( $mandate->status == 'valid' ) {
|
358 |
-
$validMandate = true;
|
359 |
-
$data['method'] = $mandate->method;
|
360 |
-
break;
|
361 |
-
}
|
362 |
-
}
|
363 |
-
if ( $validMandate ) {
|
364 |
|
365 |
-
|
|
|
366 |
|
367 |
-
|
368 |
-
__( 'Order completed internally because of an existing valid mandate at Mollie.', 'mollie-payments-for-woocommerce' ) ) );
|
369 |
|
370 |
-
|
|
|
|
|
|
|
371 |
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
|
377 |
-
|
378 |
-
Mollie_WC_Plugin::debug( $this->id . ': Subscription switch, payment problem ' . $order_id );
|
379 |
-
throw new Mollie_API_Exception( __( 'Subscription switch cannot be processed, no valid mandate.', 'mollie-payments-for-woocommerce-mandate-problem' ) );
|
380 |
-
}
|
381 |
-
}
|
382 |
-
catch ( Mollie_API_Exception $e ) {
|
383 |
-
if ( $e->getField() ) {
|
384 |
-
throw $e;
|
385 |
-
}
|
386 |
-
}
|
387 |
|
388 |
-
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
|
|
|
|
|
|
|
|
395 |
|
396 |
-
|
397 |
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
{
|
407 |
-
throw $e;
|
408 |
-
}
|
409 |
-
|
410 |
-
// Retry without customer id.
|
411 |
-
unset($data['customerId']);
|
412 |
-
$payment = Mollie_WC_Plugin::getApiHelper()->getApiClient($test_mode)->payments->create($data);
|
413 |
-
}
|
414 |
|
415 |
-
|
|
|
|
|
|
|
416 |
|
417 |
-
|
418 |
|
419 |
-
|
420 |
-
Mollie_WC_Plugin::debug( $this->id . ': Payment ' . $payment->id . ' (' . $payment->mode . ') created for order ' . $order->id );
|
421 |
-
} else {
|
422 |
-
Mollie_WC_Plugin::debug( $this->id . ': Payment ' . $payment->id . ' (' . $payment->mode . ') created for order ' . $order->get_id() );
|
423 |
-
}
|
424 |
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
|
|
429 |
|
430 |
-
|
431 |
-
|
432 |
-
|
|
|
433 |
|
434 |
-
|
|
|
|
|
435 |
|
436 |
-
|
437 |
|
438 |
-
|
439 |
-
$order,
|
440 |
-
$initial_order_status,
|
441 |
-
__( 'Awaiting payment confirmation.', 'mollie-payments-for-woocommerce' ) . "\n"
|
442 |
-
);
|
443 |
|
444 |
-
|
445 |
-
|
|
|
|
|
|
|
446 |
|
|
|
|
|
447 |
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
}
|
473 |
|
474 |
-
|
475 |
-
|
476 |
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
}
|
481 |
|
482 |
-
|
483 |
-
|
484 |
|
485 |
-
|
486 |
-
|
487 |
|
488 |
/**
|
489 |
* @param $order
|
@@ -808,7 +809,7 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
808 |
$order_id = $order->get_id();
|
809 |
}
|
810 |
|
811 |
-
Mollie_WC_Plugin::debug( $this->id . ": Order $order_id does not need a payment (payment
|
812 |
|
813 |
}
|
814 |
|
@@ -983,54 +984,6 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
983 |
|
984 |
}
|
985 |
|
986 |
-
/**
|
987 |
-
* @param WC_Order $order
|
988 |
-
* @param Mollie_API_Object_Payment $payment
|
989 |
-
*/
|
990 |
-
protected function onWebhookChargedback( WC_Order $order, Mollie_API_Object_Payment $payment ) {
|
991 |
-
|
992 |
-
// Get order ID in the correct way depending on WooCommerce version
|
993 |
-
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
994 |
-
$order_id = $order->id;
|
995 |
-
} else {
|
996 |
-
$order_id = $order->get_id();
|
997 |
-
}
|
998 |
-
|
999 |
-
// Add messages to log
|
1000 |
-
Mollie_WC_Plugin::debug( __METHOD__ . ' called for order ' . $order_id );
|
1001 |
-
|
1002 |
-
// New order status
|
1003 |
-
$new_order_status = self::STATUS_ON_HOLD;
|
1004 |
-
|
1005 |
-
// Overwrite plugin-wide
|
1006 |
-
$new_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_order_status_on_hold', $new_order_status );
|
1007 |
-
|
1008 |
-
// Overwrite gateway-wide
|
1009 |
-
$new_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_order_status_on_hold_' . $this->id, $new_order_status );
|
1010 |
-
|
1011 |
-
$paymentMethodTitle = $this->getPaymentMethodTitle( $payment );
|
1012 |
-
|
1013 |
-
// Update order status for order with charged_back payment, don't restore stock
|
1014 |
-
$this->updateOrderStatus(
|
1015 |
-
$order,
|
1016 |
-
$new_order_status,
|
1017 |
-
sprintf(
|
1018 |
-
/* translators: Placeholder 1: payment method title, placeholder 2: payment ID */
|
1019 |
-
__( '%s payment charged back via Mollie (%s). You will need to manually review the payment and adjust product stocks if you use them.', 'mollie-payments-for-woocommerce' ),
|
1020 |
-
$paymentMethodTitle,
|
1021 |
-
$payment->id . ( $payment->mode == 'test' ? ( ' - ' . __( 'test mode', 'mollie-payments-for-woocommerce' ) ) : '' )
|
1022 |
-
),
|
1023 |
-
$restore_stock = false
|
1024 |
-
);
|
1025 |
-
|
1026 |
-
// Send a "Failed order" email to notify the admin
|
1027 |
-
$emails = WC()->mailer()->get_emails();
|
1028 |
-
if ( ! empty( $emails ) && ! empty( $order_id ) ) {
|
1029 |
-
$emails['WC_Email_Failed_Order']->trigger( $order_id );
|
1030 |
-
}
|
1031 |
-
|
1032 |
-
}
|
1033 |
-
|
1034 |
/**
|
1035 |
* @param WC_Order $order
|
1036 |
*
|
@@ -1222,8 +1175,10 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
1222 |
}
|
1223 |
else
|
1224 |
{
|
1225 |
-
echo '<
|
|
|
1226 |
echo wpautop($instructions) . PHP_EOL;
|
|
|
1227 |
}
|
1228 |
}
|
1229 |
}
|
@@ -1271,6 +1226,7 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
1271 |
if ( is_order_received_page() && get_the_ID() === $id ) {
|
1272 |
global $wp;
|
1273 |
|
|
|
1274 |
$order_id = apply_filters( 'woocommerce_thankyou_order_id', absint( $wp->query_vars['order-received'] ) );
|
1275 |
$order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['key'] ) ? '' : wc_clean( $_GET['key'] ) );
|
1276 |
if ( $order_id > 0 ) {
|
@@ -1287,6 +1243,10 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
1287 |
}
|
1288 |
}
|
1289 |
|
|
|
|
|
|
|
|
|
1290 |
$order = Mollie_WC_Plugin::getDataHelper()->getWcOrder( $order );
|
1291 |
|
1292 |
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
@@ -1320,6 +1280,28 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
1320 |
}
|
1321 |
|
1322 |
if ( $payment->isOpen() ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1323 |
$title .= __( ', payment pending.', 'mollie-payments-for-woocommerce' );
|
1324 |
|
1325 |
return $title;
|
@@ -1363,6 +1345,11 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
1363 |
*/
|
1364 |
protected function orderNeedsPayment (WC_Order $order)
|
1365 |
{
|
|
|
|
|
|
|
|
|
|
|
1366 |
// Check whether the order is processed and paid via Mollie
|
1367 |
if ( ! $this->isOrderPaidAndProcessed( $order ) ) {
|
1368 |
return true;
|
@@ -1490,38 +1477,39 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
1490 |
return $url;
|
1491 |
}
|
1492 |
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
1504 |
|
1505 |
-
|
1506 |
-
$slug = ''; // default is NO slug/language
|
1507 |
|
1508 |
-
|
1509 |
-
|| is_plugin_active('polylang-pro/polylang-pro.php')
|
1510 |
-
|| is_plugin_active('mlang/mlang.php')
|
1511 |
-
|| is_plugin_active('mlanguage/mlanguage.php')
|
1512 |
-
)
|
1513 |
-
{
|
1514 |
-
// we probably have a multilang site. Retrieve current language.
|
1515 |
-
$slug = get_bloginfo('language');
|
1516 |
-
$pos = strpos($slug, '-');
|
1517 |
-
if ($pos !== false)
|
1518 |
-
$slug = substr($slug, 0, $pos);
|
1519 |
-
|
1520 |
-
$slug = '/' . $slug;
|
1521 |
-
}
|
1522 |
|
1523 |
-
|
1524 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1525 |
|
1526 |
/**
|
1527 |
* @return string|NULL
|
@@ -1596,6 +1584,22 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
|
|
1596 |
|
1597 |
}
|
1598 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1599 |
|
1600 |
/**
|
1601 |
* @return mixed
|
307 |
return false;
|
308 |
}
|
309 |
|
310 |
+
/**
|
311 |
+
* @param int $order_id
|
312 |
+
*
|
313 |
+
* @return array
|
314 |
+
*/
|
315 |
+
public function process_payment( $order_id ) {
|
316 |
+
$order = Mollie_WC_Plugin::getDataHelper()->getWcOrder( $order_id );
|
|
|
|
|
|
|
|
|
317 |
|
318 |
+
if ( ! $order ) {
|
319 |
+
Mollie_WC_Plugin::debug( $this->id . ': Could not process payment, order ' . $order_id . ' not found.' );
|
320 |
|
321 |
+
Mollie_WC_Plugin::addNotice( sprintf( __( 'Could not load order %s', 'mollie-payments-for-woocommerce' ), $order_id ), 'error' );
|
|
|
322 |
|
323 |
+
return array ( 'result' => 'failure' );
|
324 |
+
}
|
325 |
|
326 |
+
$initial_order_status = $this->getInitialOrderStatus();
|
|
|
327 |
|
328 |
+
// Overwrite plugin-wide
|
329 |
+
$initial_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_initial_order_status', $initial_order_status );
|
330 |
|
331 |
+
// Overwrite gateway-wide
|
332 |
+
$initial_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_initial_order_status_' . $this->id, $initial_order_status );
|
333 |
+
|
334 |
+
$settings_helper = Mollie_WC_Plugin::getSettingsHelper();
|
335 |
+
|
336 |
+
// Is test mode enabled?
|
337 |
+
$test_mode = $settings_helper->isTestModeEnabled();
|
338 |
+
$customer_id = $this->getUserMollieCustomerId( $order, $test_mode );
|
339 |
+
$paymentRequestData = $this->getPaymentRequestData( $order, $customer_id );
|
340 |
+
|
341 |
+
$data = array_filter( $paymentRequestData );
|
342 |
+
|
343 |
+
$data = apply_filters( 'woocommerce_' . $this->id . '_args', $data, $order );
|
344 |
+
|
345 |
+
//
|
346 |
+
// PROCESS SUBSCRIPTION SWITCH - If this is a subscription switch and customer has a valid mandate, process the order internally
|
347 |
+
//
|
348 |
+
if ( ( '0.00' === $order->get_total() ) && ( $this->is_subscription( $order_id ) == true ) &&
|
349 |
+
0 != $order->get_user_id() && ( wcs_order_contains_switch( $order ) )
|
350 |
+
) {
|
351 |
+
|
352 |
+
try {
|
353 |
+
Mollie_WC_Plugin::debug( $this->id . ': Subscription switch started, fetching mandate(s) for order #' . $order_id );
|
354 |
+
$mandates = Mollie_WC_Plugin::getApiHelper()->getApiClient( $test_mode )->customers_mandates->withParentId( $customer_id )->all();
|
355 |
+
$validMandate = false;
|
356 |
+
foreach ( $mandates as $mandate ) {
|
357 |
+
if ( $mandate->status == 'valid' ) {
|
358 |
+
$validMandate = true;
|
359 |
+
$data['method'] = $mandate->method;
|
360 |
+
break;
|
361 |
+
}
|
362 |
+
}
|
363 |
+
if ( $validMandate ) {
|
364 |
|
365 |
+
$order->payment_complete();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
|
367 |
+
$order->add_order_note( sprintf(
|
368 |
+
__( 'Order completed internally because of an existing valid mandate at Mollie.', 'mollie-payments-for-woocommerce' ) ) );
|
369 |
|
370 |
+
Mollie_WC_Plugin::debug( $this->id . ': Subscription switch completed, valid mandate for order #' . $order_id );
|
|
|
371 |
|
372 |
+
return array (
|
373 |
+
'result' => 'success',
|
374 |
+
'redirect' => $this->get_return_url( $order ),
|
375 |
+
);
|
376 |
|
377 |
+
} else {
|
378 |
+
Mollie_WC_Plugin::debug( $this->id . ': Subscription switch failed, no valid mandate for order #' . $order_id );
|
379 |
+
Mollie_WC_Plugin::addNotice( __( 'Subscription switch failed, no valid mandate found. Place a completely new order to change your subscription.', 'mollie-payments-for-woocommerce' ), 'error' );
|
380 |
+
throw new Mollie_API_Exception( __( 'Subscription switch failed, no valid mandate.', 'mollie-payments-for-woocommerce' ) );
|
381 |
+
}
|
382 |
+
}
|
383 |
+
catch ( Mollie_API_Exception $e ) {
|
384 |
+
if ( $e->getField() ) {
|
385 |
+
throw $e;
|
386 |
+
}
|
387 |
+
}
|
388 |
|
389 |
+
return array ( 'result' => 'failure' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
|
391 |
+
}
|
392 |
|
393 |
+
//
|
394 |
+
// PROCESS REGULAR PAYMENT
|
395 |
+
//
|
396 |
+
try {
|
397 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
398 |
+
Mollie_WC_Plugin::debug( $this->id . ': Create payment for order ' . $order->id, true );
|
399 |
+
} else {
|
400 |
+
Mollie_WC_Plugin::debug( $this->id . ': Create payment for order ' . $order->get_id(), true );
|
401 |
+
}
|
402 |
|
403 |
+
do_action( Mollie_WC_Plugin::PLUGIN_ID . '_create_payment', $data, $order );
|
404 |
|
405 |
+
// Create Mollie payment with customer id.
|
406 |
+
try {
|
407 |
+
$payment = Mollie_WC_Plugin::getApiHelper()->getApiClient( $test_mode )->payments->create( $data );
|
408 |
+
}
|
409 |
+
catch ( Mollie_API_Exception $e ) {
|
410 |
+
if ( $e->getField() !== 'customerId' ) {
|
411 |
+
throw $e;
|
412 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
413 |
|
414 |
+
// Retry without customer id.
|
415 |
+
unset( $data['customerId'] );
|
416 |
+
$payment = Mollie_WC_Plugin::getApiHelper()->getApiClient( $test_mode )->payments->create( $data );
|
417 |
+
}
|
418 |
|
419 |
+
$this->saveMollieInfo( $order, $payment );
|
420 |
|
421 |
+
do_action( Mollie_WC_Plugin::PLUGIN_ID . '_payment_created', $payment, $order );
|
|
|
|
|
|
|
|
|
422 |
|
423 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
424 |
+
Mollie_WC_Plugin::debug( $this->id . ': Payment ' . $payment->id . ' (' . $payment->mode . ') created for order ' . $order->id );
|
425 |
+
} else {
|
426 |
+
Mollie_WC_Plugin::debug( $this->id . ': Payment ' . $payment->id . ' (' . $payment->mode . ') created for order ' . $order->get_id() );
|
427 |
+
}
|
428 |
|
429 |
+
// Update initial order status for payment methods where the payment status will be delivered after a couple of days.
|
430 |
+
// See: https://www.mollie.com/nl/docs/status#expiry-times-per-payment-method
|
431 |
+
// Status is only updated if the new status is not the same as the default order status (pending)
|
432 |
+
if ( ( $payment->method == 'banktransfer' ) || ( $payment->method == 'directdebit' ) ) {
|
433 |
|
434 |
+
// Don't change the status of the order if it's Partially Paid
|
435 |
+
// This adds support for WooCommerce Deposits (by Webtomizer)
|
436 |
+
// See https://github.com/mollie/WooCommerce/issues/138
|
437 |
|
438 |
+
$order_status = ( version_compare( WC_VERSION, '3.0', '<' ) ) ? $order->status : $order->get_status();
|
439 |
|
440 |
+
if ( $order_status != 'wc-partially-paid ' ) {
|
|
|
|
|
|
|
|
|
441 |
|
442 |
+
$this->updateOrderStatus(
|
443 |
+
$order,
|
444 |
+
$initial_order_status,
|
445 |
+
__( 'Awaiting payment confirmation.', 'mollie-payments-for-woocommerce' ) . "\n"
|
446 |
+
);
|
447 |
|
448 |
+
}
|
449 |
+
}
|
450 |
|
451 |
+
$order->add_order_note( sprintf(
|
452 |
+
/* translators: Placeholder 1: Payment method title, placeholder 2: payment ID */
|
453 |
+
__( '%s payment started (%s).', 'mollie-payments-for-woocommerce' ),
|
454 |
+
$this->method_title,
|
455 |
+
$payment->id . ( $payment->mode == 'test' ? ( ' - ' . __( 'test mode', 'mollie-payments-for-woocommerce' ) ) : '' )
|
456 |
+
) );
|
457 |
|
458 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
459 |
+
Mollie_WC_Plugin::debug( "For order " . $order->id . " redirect user to payment URL: {$payment->getPaymentUrl()}" );
|
460 |
+
} else {
|
461 |
+
Mollie_WC_Plugin::debug( "For order " . $order->get_id() . " redirect user to payment URL: {$payment->getPaymentUrl()}" );
|
462 |
+
}
|
463 |
|
464 |
+
return array (
|
465 |
+
'result' => 'success',
|
466 |
+
'redirect' => $this->getProcessPaymentRedirect( $order, $payment ),
|
467 |
+
);
|
468 |
+
}
|
469 |
+
catch ( Mollie_API_Exception $e ) {
|
470 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
471 |
+
Mollie_WC_Plugin::debug( $this->id . ': Failed to create payment for order ' . $order->id . ': ' . $e->getMessage() );
|
472 |
+
} else {
|
473 |
+
Mollie_WC_Plugin::debug( $this->id . ': Failed to create payment for order ' . $order->get_id() . ': ' . $e->getMessage() );
|
474 |
+
}
|
|
|
475 |
|
476 |
+
/* translators: Placeholder 1: Payment method title */
|
477 |
+
$message = sprintf( __( 'Could not create %s payment.', 'mollie-payments-for-woocommerce' ), $this->title );
|
478 |
|
479 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
480 |
+
$message .= ' ' . $e->getMessage();
|
481 |
+
}
|
|
|
482 |
|
483 |
+
Mollie_WC_Plugin::addNotice( $message, 'error' );
|
484 |
+
}
|
485 |
|
486 |
+
return array ( 'result' => 'failure' );
|
487 |
+
}
|
488 |
|
489 |
/**
|
490 |
* @param $order
|
809 |
$order_id = $order->get_id();
|
810 |
}
|
811 |
|
812 |
+
Mollie_WC_Plugin::debug( __METHOD__ . ' - ' . $this->id . ": Order $order_id does not need a payment by Mollie (payment {$payment->id}).", true );
|
813 |
|
814 |
}
|
815 |
|
984 |
|
985 |
}
|
986 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
987 |
/**
|
988 |
* @param WC_Order $order
|
989 |
*
|
1175 |
}
|
1176 |
else
|
1177 |
{
|
1178 |
+
echo '<section class="woocommerce-order-details mollie-instructions abc">';
|
1179 |
+
echo '<h2 class="woocommerce-order-details__title">' . __('Payment', 'mollie-payments-for-woocommerce') . '</h2>';
|
1180 |
echo wpautop($instructions) . PHP_EOL;
|
1181 |
+
echo '</section>';
|
1182 |
}
|
1183 |
}
|
1184 |
}
|
1226 |
if ( is_order_received_page() && get_the_ID() === $id ) {
|
1227 |
global $wp;
|
1228 |
|
1229 |
+
$order = false;
|
1230 |
$order_id = apply_filters( 'woocommerce_thankyou_order_id', absint( $wp->query_vars['order-received'] ) );
|
1231 |
$order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['key'] ) ? '' : wc_clean( $_GET['key'] ) );
|
1232 |
if ( $order_id > 0 ) {
|
1243 |
}
|
1244 |
}
|
1245 |
|
1246 |
+
if ( $order == false){
|
1247 |
+
return $title;
|
1248 |
+
}
|
1249 |
+
|
1250 |
$order = Mollie_WC_Plugin::getDataHelper()->getWcOrder( $order );
|
1251 |
|
1252 |
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
1280 |
}
|
1281 |
|
1282 |
if ( $payment->isOpen() ) {
|
1283 |
+
|
1284 |
+
// Add a message to log and order explaining a payment with status "open", only if it hasn't been added already
|
1285 |
+
if ( get_post_meta( $order_id, '_mollie_open_status_note', true ) !== '1' ) {
|
1286 |
+
|
1287 |
+
// Get payment method title
|
1288 |
+
$paymentMethodTitle = $this->getPaymentMethodTitle( $payment );
|
1289 |
+
|
1290 |
+
// Add message to log
|
1291 |
+
Mollie_WC_Plugin::debug( $this->id . ': Customer returned to store, but payment still pending for order #' . $order_id . '. Status should be updated automatically in the future, if it doesn\'t this might indicate a communication issue between the site and Mollie.' );
|
1292 |
+
|
1293 |
+
// Add message to order as order note
|
1294 |
+
$order->add_order_note( sprintf(
|
1295 |
+
/* translators: Placeholder 1: payment method title, placeholder 2: payment ID */
|
1296 |
+
__( '%s payment still pending (%s) but customer already returned to the store. Status should be updated automatically in the future, if it doesn\'t this might indicate a communication issue between the site and Mollie.', 'mollie-payments-for-woocommerce' ),
|
1297 |
+
$paymentMethodTitle,
|
1298 |
+
$payment->id . ( $payment->mode == 'test' ? ( ' - ' . __( 'test mode', 'mollie-payments-for-woocommerce' ) ) : '' )
|
1299 |
+
) );
|
1300 |
+
|
1301 |
+
update_post_meta( $order_id, '_mollie_open_status_note', '1' );
|
1302 |
+
}
|
1303 |
+
|
1304 |
+
// Update the title on the Order received page to better communicate that the payment is pending.
|
1305 |
$title .= __( ', payment pending.', 'mollie-payments-for-woocommerce' );
|
1306 |
|
1307 |
return $title;
|
1345 |
*/
|
1346 |
protected function orderNeedsPayment (WC_Order $order)
|
1347 |
{
|
1348 |
+
// Check whether the order is processed and paid via another gateway
|
1349 |
+
if ( $this->isOrderPaidByOtherGateway( $order ) ) {
|
1350 |
+
return false;
|
1351 |
+
}
|
1352 |
+
|
1353 |
// Check whether the order is processed and paid via Mollie
|
1354 |
if ( ! $this->isOrderPaidAndProcessed( $order ) ) {
|
1355 |
return true;
|
1477 |
return $url;
|
1478 |
}
|
1479 |
|
1480 |
+
/**
|
1481 |
+
* Check if any multi language plugins are enabled and return the correct site url.
|
1482 |
+
*
|
1483 |
+
* @return string
|
1484 |
+
*/
|
1485 |
+
protected function getSiteUrlWithLanguage() {
|
1486 |
+
/**
|
1487 |
+
* function is_plugin_active() is not available. Lets include it to use it.
|
1488 |
+
*/
|
1489 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
|
|
1490 |
|
1491 |
+
$site_url = get_site_url();
|
|
|
1492 |
|
1493 |
+
if ( is_plugin_active( 'polylang/polylang.php' ) || is_plugin_active( 'polylang-pro/polylang-pro.php' ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1494 |
|
1495 |
+
$lang = PLL()->model->get_language( pll_current_language() );
|
1496 |
+
$polylang_url = $lang->search_url;
|
1497 |
+
$site_url = str_replace( $site_url, $polylang_url, $site_url );
|
1498 |
+
|
1499 |
+
} else if ( is_plugin_active( 'mlang/mlang.php' ) || is_plugin_active( 'mlanguage/mlanguage.php' ) ) {
|
1500 |
+
|
1501 |
+
$slug = get_bloginfo( 'language' );
|
1502 |
+
$pos = strpos( $slug, '-' );
|
1503 |
+
if ( $pos !== false ) {
|
1504 |
+
$slug = substr( $slug, 0, $pos );
|
1505 |
+
}
|
1506 |
+
$slug = '/' . $slug;
|
1507 |
+
$site_url = str_replace( $site_url, $site_url . $slug, $site_url );
|
1508 |
+
|
1509 |
+
}
|
1510 |
+
|
1511 |
+
return $site_url;
|
1512 |
+
}
|
1513 |
|
1514 |
/**
|
1515 |
* @return string|NULL
|
1584 |
|
1585 |
}
|
1586 |
|
1587 |
+
/**
|
1588 |
+
* @return bool
|
1589 |
+
*/
|
1590 |
+
protected function isOrderPaidByOtherGateway( WC_Order $order ) {
|
1591 |
+
|
1592 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
1593 |
+
$order_id = $order->id;
|
1594 |
+
$paid_by_other_gateway = get_post_meta( $order_id, '_mollie_paid_by_other_gateway', $single = true );
|
1595 |
+
} else {
|
1596 |
+
$paid_by_other_gateway = $order->get_meta( '_mollie_paid_by_other_gateway', true );
|
1597 |
+
}
|
1598 |
+
|
1599 |
+
return $paid_by_other_gateway;
|
1600 |
+
|
1601 |
+
}
|
1602 |
+
|
1603 |
|
1604 |
/**
|
1605 |
* @return mixed
|
@@ -37,6 +37,8 @@ abstract class Mollie_WC_Gateway_AbstractSubscription extends Mollie_WC_Gateway_
|
|
37 |
'subscription_amount_changes',
|
38 |
'subscription_date_changes',
|
39 |
'multiple_subscriptions',
|
|
|
|
|
40 |
);
|
41 |
|
42 |
$this->supports = array_merge($this->supports,$supportSubscriptions);
|
@@ -649,6 +651,7 @@ abstract class Mollie_WC_Gateway_AbstractSubscription extends Mollie_WC_Gateway_
|
|
649 |
{
|
650 |
if ( $this->id === $payment_method_id ) {
|
651 |
|
|
|
652 |
if ( ! isset( $payment_meta['post_meta']['_mollie_customer_id']['value'] ) || empty( $payment_meta['post_meta']['_mollie_customer_id']['value'] ) ) {
|
653 |
throw new Exception( 'A "_mollie_customer_id" value is required.' );
|
654 |
}
|
@@ -689,6 +692,107 @@ abstract class Mollie_WC_Gateway_AbstractSubscription extends Mollie_WC_Gateway_
|
|
689 |
|
690 |
}
|
691 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
692 |
/**
|
693 |
* @param $order_id
|
694 |
* @return bool
|
37 |
'subscription_amount_changes',
|
38 |
'subscription_date_changes',
|
39 |
'multiple_subscriptions',
|
40 |
+
'subscription_payment_method_change',
|
41 |
+
'subscription_payment_method_change_customer',
|
42 |
);
|
43 |
|
44 |
$this->supports = array_merge($this->supports,$supportSubscriptions);
|
651 |
{
|
652 |
if ( $this->id === $payment_method_id ) {
|
653 |
|
654 |
+
// Check that a Mollie Customer ID is entered
|
655 |
if ( ! isset( $payment_meta['post_meta']['_mollie_customer_id']['value'] ) || empty( $payment_meta['post_meta']['_mollie_customer_id']['value'] ) ) {
|
656 |
throw new Exception( 'A "_mollie_customer_id" value is required.' );
|
657 |
}
|
692 |
|
693 |
}
|
694 |
|
695 |
+
/**
|
696 |
+
* @param WC_Order $order
|
697 |
+
* @param Mollie_API_Object_Payment $payment
|
698 |
+
*/
|
699 |
+
protected function onWebhookFailed( WC_Order $order, Mollie_API_Object_Payment $payment ) {
|
700 |
+
|
701 |
+
// Get order ID in the correct way depending on WooCommerce version
|
702 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
703 |
+
$order_id = $order->id;
|
704 |
+
} else {
|
705 |
+
$order_id = $order->get_id();
|
706 |
+
}
|
707 |
+
|
708 |
+
// Add messages to log
|
709 |
+
Mollie_WC_Plugin::debug( __METHOD__ . ' called for order ' . $order_id );
|
710 |
+
|
711 |
+
if ( wcs_order_contains_renewal( $order_id ) ) {
|
712 |
+
|
713 |
+
// New order status
|
714 |
+
$new_order_status = self::STATUS_ON_HOLD;
|
715 |
+
|
716 |
+
// Overwrite plugin-wide
|
717 |
+
$new_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_order_status_on_hold', $new_order_status );
|
718 |
+
|
719 |
+
// Overwrite gateway-wide
|
720 |
+
$new_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_order_status_on_hold_' . $this->id, $new_order_status );
|
721 |
+
|
722 |
+
$paymentMethodTitle = $this->getPaymentMethodTitle( $payment );
|
723 |
+
|
724 |
+
// Update order status for order with failed payment, don't restore stock
|
725 |
+
$this->updateOrderStatus(
|
726 |
+
$order,
|
727 |
+
$new_order_status,
|
728 |
+
sprintf(
|
729 |
+
/* translators: Placeholder 1: payment method title, placeholder 2: payment ID */
|
730 |
+
__( '%s renewal payment failed via Mollie (%s). You will need to manually review the payment and adjust product stocks if you use them.', 'mollie-payments-for-woocommerce' ),
|
731 |
+
$paymentMethodTitle,
|
732 |
+
$payment->id . ( $payment->mode == 'test' ? ( ' - ' . __( 'test mode', 'mollie-payments-for-woocommerce' ) ) : '' )
|
733 |
+
),
|
734 |
+
$restore_stock = false
|
735 |
+
);
|
736 |
+
|
737 |
+
Mollie_WC_Plugin::debug( __METHOD__ . ' called for order ' . $order_id . ' and payment ' . $payment->id . ', renewal order payment failed, order set to On-Hold for shop-owner review. ' . $mollie_payment_id );
|
738 |
+
|
739 |
+
|
740 |
+
// Send a "Failed order" email to notify the admin
|
741 |
+
$emails = WC()->mailer()->get_emails();
|
742 |
+
if ( ! empty( $emails ) && ! empty( $order_id ) ) {
|
743 |
+
$emails['WC_Email_Failed_Order']->trigger( $order_id );
|
744 |
+
}
|
745 |
+
}
|
746 |
+
}
|
747 |
+
|
748 |
+
/**
|
749 |
+
* @param WC_Order $order
|
750 |
+
* @param Mollie_API_Object_Payment $payment
|
751 |
+
*/
|
752 |
+
protected function onWebhookChargedback( WC_Order $order, Mollie_API_Object_Payment $payment ) {
|
753 |
+
|
754 |
+
// Get order ID in the correct way depending on WooCommerce version
|
755 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
756 |
+
$order_id = $order->id;
|
757 |
+
} else {
|
758 |
+
$order_id = $order->get_id();
|
759 |
+
}
|
760 |
+
|
761 |
+
// Add messages to log
|
762 |
+
Mollie_WC_Plugin::debug( __METHOD__ . ' called for order ' . $order_id );
|
763 |
+
|
764 |
+
// New order status
|
765 |
+
$new_order_status = self::STATUS_ON_HOLD;
|
766 |
+
|
767 |
+
// Overwrite plugin-wide
|
768 |
+
$new_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_order_status_on_hold', $new_order_status );
|
769 |
+
|
770 |
+
// Overwrite gateway-wide
|
771 |
+
$new_order_status = apply_filters( Mollie_WC_Plugin::PLUGIN_ID . '_order_status_on_hold_' . $this->id, $new_order_status );
|
772 |
+
|
773 |
+
$paymentMethodTitle = $this->getPaymentMethodTitle( $payment );
|
774 |
+
|
775 |
+
// Update order status for order with charged_back payment, don't restore stock
|
776 |
+
$this->updateOrderStatus(
|
777 |
+
$order,
|
778 |
+
$new_order_status,
|
779 |
+
sprintf(
|
780 |
+
/* translators: Placeholder 1: payment method title, placeholder 2: payment ID */
|
781 |
+
__( '%s renewal payment charged back via Mollie (%s). You will need to manually review the payment and adjust product stocks if you use them.', 'mollie-payments-for-woocommerce' ),
|
782 |
+
$paymentMethodTitle,
|
783 |
+
$payment->id . ( $payment->mode == 'test' ? ( ' - ' . __( 'test mode', 'mollie-payments-for-woocommerce' ) ) : '' )
|
784 |
+
),
|
785 |
+
$restore_stock = false
|
786 |
+
);
|
787 |
+
|
788 |
+
// Send a "Failed order" email to notify the admin
|
789 |
+
$emails = WC()->mailer()->get_emails();
|
790 |
+
if ( ! empty( $emails ) && ! empty( $order_id ) ) {
|
791 |
+
$emails['WC_Email_Failed_Order']->trigger( $order_id );
|
792 |
+
}
|
793 |
+
|
794 |
+
}
|
795 |
+
|
796 |
/**
|
797 |
* @param $order_id
|
798 |
* @return bool
|
@@ -8,9 +8,11 @@ class Mollie_WC_Gateway_Creditcard extends Mollie_WC_Gateway_AbstractSubscriptio
|
|
8 |
{
|
9 |
$this->supports = array(
|
10 |
'products',
|
11 |
-
'refunds'
|
12 |
);
|
|
|
13 |
$this->initSubscriptionSupport();
|
|
|
14 |
parent::__construct();
|
15 |
}
|
16 |
|
8 |
{
|
9 |
$this->supports = array(
|
10 |
'products',
|
11 |
+
'refunds'
|
12 |
);
|
13 |
+
|
14 |
$this->initSubscriptionSupport();
|
15 |
+
|
16 |
parent::__construct();
|
17 |
}
|
18 |
|
@@ -1,6 +1,14 @@
|
|
1 |
<?php
|
2 |
|
3 |
class Mollie_WC_Gateway_DirectDebit extends Mollie_WC_Gateway_Abstract {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
/**
|
5 |
* @return string
|
6 |
*/
|
1 |
<?php
|
2 |
|
3 |
class Mollie_WC_Gateway_DirectDebit extends Mollie_WC_Gateway_Abstract {
|
4 |
+
/**
|
5 |
+
*
|
6 |
+
*/
|
7 |
+
public function __construct ()
|
8 |
+
{
|
9 |
+
parent::__construct();
|
10 |
+
}
|
11 |
+
|
12 |
/**
|
13 |
* @return string
|
14 |
*/
|
@@ -27,7 +27,7 @@ class Mollie_WC_Gateway_MisterCash extends Mollie_WC_Gateway_AbstractSepaRecurri
|
|
27 |
*/
|
28 |
public function getDefaultTitle ()
|
29 |
{
|
30 |
-
return __('Bancontact
|
31 |
}
|
32 |
|
33 |
/**
|
27 |
*/
|
28 |
public function getDefaultTitle ()
|
29 |
{
|
30 |
+
return __('Bancontact', 'mollie-payments-for-woocommerce');
|
31 |
}
|
32 |
|
33 |
/**
|
@@ -570,16 +570,37 @@ class Mollie_WC_Helper_Data
|
|
570 |
} else {
|
571 |
$customer = new WC_Customer( $user_id );
|
572 |
$customer_id = $customer->get_meta( 'mollie_customer_id' );
|
573 |
-
}
|
574 |
|
575 |
-
|
576 |
-
|
577 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
578 |
}
|
579 |
-
catch ( Exception $e ) {
|
580 |
-
Mollie_WC_Plugin::debug( __FUNCTION__ . ": Mollie Customer ID " . $customer_id . " not valid for this API key, try to create a new one (" . ( $test_mode ? 'test' : 'live' ) . ")." );
|
581 |
-
$customer_id = '';
|
582 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
}
|
584 |
|
585 |
// If there is no Mollie Customer ID set, try to create a new Mollie Customer
|
@@ -608,7 +629,9 @@ class Mollie_WC_Helper_Data
|
|
608 |
|
609 |
$customer_id = $customer->id;
|
610 |
|
611 |
-
Mollie_WC_Plugin::debug( __FUNCTION__ . ": Created a Mollie Customer for WordPress user with ID $user_id (" . ( $test_mode ? 'test' : 'live' ) . ")." );
|
|
|
|
|
612 |
|
613 |
}
|
614 |
catch (Exception $e)
|
@@ -617,6 +640,8 @@ class Mollie_WC_Helper_Data
|
|
617 |
}
|
618 |
}
|
619 |
|
|
|
|
|
620 |
return $customer_id;
|
621 |
}
|
622 |
|
570 |
} else {
|
571 |
$customer = new WC_Customer( $user_id );
|
572 |
$customer_id = $customer->get_meta( 'mollie_customer_id' );
|
|
|
573 |
|
574 |
+
// If there is no Mollie Customer ID set, check the most recent active subscription
|
575 |
+
if ( empty( $customer_id ) ) {
|
576 |
+
|
577 |
+
$customer_latest_subscription = wc_get_orders( array (
|
578 |
+
'limit' => 1,
|
579 |
+
'customer' => $user_id,
|
580 |
+
'type' => 'shop_subscription',
|
581 |
+
'status' => 'wc-active',
|
582 |
+
) );
|
583 |
+
|
584 |
+
if ( ! empty( $customer_latest_subscription ) ) {
|
585 |
+
$customer_id = get_post_meta( $customer_latest_subscription[0]->get_id(), '_mollie_customer_id', $single = true );
|
586 |
+
|
587 |
+
// Store this customer ID as user meta too
|
588 |
+
$this->setUserMollieCustomerId( $user_id, $customer_id );
|
589 |
+
}
|
590 |
+
|
591 |
+
}
|
592 |
}
|
|
|
|
|
|
|
593 |
|
594 |
+
// If there is a Mollie Customer ID set, check that customer ID is valid for this API key
|
595 |
+
if ( ! empty( $customer_id ) ) {
|
596 |
+
|
597 |
+
try {
|
598 |
+
$this->api_helper->getApiClient( $test_mode )->customers->get( $customer_id );
|
599 |
+
}
|
600 |
+
catch ( Exception $e ) {
|
601 |
+
Mollie_WC_Plugin::debug( __FUNCTION__ . ": Mollie Customer ID ($customer_id) not valid for user $user_id on this API key, try to create a new one (" . ( $test_mode ? 'test' : 'live' ) . ")." );
|
602 |
+
$customer_id = '';
|
603 |
+
}
|
604 |
}
|
605 |
|
606 |
// If there is no Mollie Customer ID set, try to create a new Mollie Customer
|
629 |
|
630 |
$customer_id = $customer->id;
|
631 |
|
632 |
+
Mollie_WC_Plugin::debug( __FUNCTION__ . ": Created a Mollie Customer ($customer_id) for WordPress user with ID $user_id (" . ( $test_mode ? 'test' : 'live' ) . ")." );
|
633 |
+
|
634 |
+
return $customer_id;
|
635 |
|
636 |
}
|
637 |
catch (Exception $e)
|
640 |
}
|
641 |
}
|
642 |
|
643 |
+
Mollie_WC_Plugin::debug( __FUNCTION__ . ": Mollie Customer ID ($customer_id) found and valid for user $user_id on this API key. (" . ( $test_mode ? 'test' : 'live' ) . ")." );
|
644 |
+
|
645 |
return $customer_id;
|
646 |
}
|
647 |
|
@@ -376,8 +376,8 @@ class Mollie_WC_Helper_Settings
|
|
376 |
'title' => __('Order status after cancelled payment', 'mollie-payments-for-woocommerce'),
|
377 |
'type' => 'select',
|
378 |
'options' => array(
|
379 |
-
'pending' => __('Pending', '
|
380 |
-
'cancelled' => __('Cancelled', '
|
381 |
),
|
382 |
'desc' => __('Status for orders when a payment is cancelled. Default: pending. Orders with status Pending can be paid with another payment method, customers can try again. Cancelled orders are final. Set this to Cancelled if you only have one payment method or don\'t want customers to re-try paying with a different payment method.', 'mollie-payments-for-woocommerce'),
|
383 |
'default' => 'pending',
|
376 |
'title' => __('Order status after cancelled payment', 'mollie-payments-for-woocommerce'),
|
377 |
'type' => 'select',
|
378 |
'options' => array(
|
379 |
+
'pending' => __('Pending', 'woocommerce'),
|
380 |
+
'cancelled' => __('Cancelled', 'woocommerce'),
|
381 |
),
|
382 |
'desc' => __('Status for orders when a payment is cancelled. Default: pending. Orders with status Pending can be paid with another payment method, customers can try again. Cancelled orders are final. Set this to Cancelled if you only have one payment method or don\'t want customers to re-try paying with a different payment method.', 'mollie-payments-for-woocommerce'),
|
383 |
'default' => 'pending',
|
@@ -7,7 +7,7 @@ class Mollie_WC_Plugin
|
|
7 |
{
|
8 |
const PLUGIN_ID = 'mollie-payments-for-woocommerce';
|
9 |
const PLUGIN_TITLE = 'Mollie Payments for WooCommerce';
|
10 |
-
const PLUGIN_VERSION = '
|
11 |
|
12 |
const DB_VERSION = '1.0';
|
13 |
const DB_VERSION_PARAM_NAME = 'mollie-db-version';
|
@@ -188,12 +188,18 @@ class Mollie_WC_Plugin
|
|
188 |
// Listen to return URL call
|
189 |
add_action( 'woocommerce_api_mollie_return', array ( __CLASS__, 'onMollieReturn' ) );
|
190 |
|
191 |
-
//
|
192 |
add_action( 'woocommerce_order_details_after_order_table', array ( __CLASS__, 'onOrderDetails' ), 10, 1 );
|
193 |
|
194 |
-
|
195 |
add_filter( 'woocommerce_available_payment_gateways', array ( __CLASS__, 'disableSEPAInCheckout' ), 10, 1 );
|
196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
self::initDb();
|
198 |
self::schedulePendingPaymentOrdersExpirationCheck();
|
199 |
// Mark plugin initiated
|
@@ -509,5 +515,60 @@ class Mollie_WC_Plugin
|
|
509 |
return $available_gateways;
|
510 |
}
|
511 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
}
|
513 |
|
7 |
{
|
8 |
const PLUGIN_ID = 'mollie-payments-for-woocommerce';
|
9 |
const PLUGIN_TITLE = 'Mollie Payments for WooCommerce';
|
10 |
+
const PLUGIN_VERSION = '3.0.0';
|
11 |
|
12 |
const DB_VERSION = '1.0';
|
13 |
const DB_VERSION_PARAM_NAME = 'mollie-db-version';
|
188 |
// Listen to return URL call
|
189 |
add_action( 'woocommerce_api_mollie_return', array ( __CLASS__, 'onMollieReturn' ) );
|
190 |
|
191 |
+
// Show Mollie instructions on order details page
|
192 |
add_action( 'woocommerce_order_details_after_order_table', array ( __CLASS__, 'onOrderDetails' ), 10, 1 );
|
193 |
|
194 |
+
// Disable SEPA as payment option in WooCommerce checkout
|
195 |
add_filter( 'woocommerce_available_payment_gateways', array ( __CLASS__, 'disableSEPAInCheckout' ), 10, 1 );
|
196 |
|
197 |
+
// Disable Mollie methods on some pages
|
198 |
+
add_filter( 'woocommerce_available_payment_gateways', array ( __CLASS__, 'disableMollieOnPaymentMethodChange' ), 10, 1 );
|
199 |
+
|
200 |
+
// Set order to paid and processed when eventually completed without Mollie
|
201 |
+
add_action( 'woocommerce_payment_complete', array ( __CLASS__, 'setOrderPaidByOtherGateway' ), 10, 1 );
|
202 |
+
|
203 |
self::initDb();
|
204 |
self::schedulePendingPaymentOrdersExpirationCheck();
|
205 |
// Mark plugin initiated
|
515 |
return $available_gateways;
|
516 |
}
|
517 |
|
518 |
+
/**
|
519 |
+
* Don't show Mollie Payment Methods in WooCommerce Account > Subscriptions
|
520 |
+
*/
|
521 |
+
public static function disableMollieOnPaymentMethodChange( $available_gateways ) {
|
522 |
+
|
523 |
+
// Can't use $wp->request or is_wc_endpoint_url() to check if this code only runs on /subscriptions and /view-subscriptions,
|
524 |
+
// because slugs/endpoints can be translated (with WPML) and other plugins.
|
525 |
+
// So disabling on is_account_page and $_GET['change_payment_method'] for now.
|
526 |
+
|
527 |
+
if ( is_account_page() || ! empty( $_GET['change_payment_method'] ) ) {
|
528 |
+
foreach ( $available_gateways as $key => $value ) {
|
529 |
+
if ( strpos( $key, 'mollie_' ) !== false ) {
|
530 |
+
unset( $available_gateways[ $key ] );
|
531 |
+
}
|
532 |
+
}
|
533 |
+
|
534 |
+
}
|
535 |
+
|
536 |
+
return $available_gateways;
|
537 |
+
}
|
538 |
+
|
539 |
+
/**
|
540 |
+
* If an order is paid with another payment method (gateway) after a first payment was
|
541 |
+
* placed with Mollie, set a flag, so status updates (like expired) aren't processed by
|
542 |
+
* Mollie Payments for WooCommerce.
|
543 |
+
*/
|
544 |
+
public static function setOrderPaidByOtherGateway( $order_id ) {
|
545 |
+
|
546 |
+
$order = wc_get_order( $order_id );
|
547 |
+
|
548 |
+
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
|
549 |
+
|
550 |
+
$mollie_payment_id = get_post_meta( $order_id, '_mollie_payment_id', $single = true );
|
551 |
+
$order_payment_method = get_post_meta( $order_id, '_payment_method', $single = true );
|
552 |
+
|
553 |
+
if ( $mollie_payment_id !== '' && ( strpos( $order_payment_method, 'mollie' ) === false ) ) {
|
554 |
+
update_post_meta( $order->id, '_mollie_paid_by_other_gateway', '1' );
|
555 |
+
}
|
556 |
+
|
557 |
+
} else {
|
558 |
+
|
559 |
+
$mollie_payment_id = $order->get_meta( '_mollie_payment_id', $single = true );
|
560 |
+
$order_payment_method = $order->get_payment_method();
|
561 |
+
|
562 |
+
if ( $mollie_payment_id !== '' && ( strpos( $order_payment_method, 'mollie' ) === false ) ) {
|
563 |
+
|
564 |
+
$order->update_meta_data( '_mollie_paid_by_other_gateway', '1' );
|
565 |
+
$order->save();
|
566 |
+
}
|
567 |
+
}
|
568 |
+
|
569 |
+
return true;
|
570 |
+
|
571 |
+
}
|
572 |
+
|
573 |
}
|
574 |
|
@@ -1,9 +1,9 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: Mollie Payments for WooCommerce
|
4 |
-
* Plugin URI: https://
|
5 |
* Description: Accept payments in WooCommerce with the official Mollie plugin
|
6 |
-
* Version:
|
7 |
* Author: Mollie
|
8 |
* Author URI: https://www.mollie.com
|
9 |
* Requires at least: 3.8
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: Mollie Payments for WooCommerce
|
4 |
+
* Plugin URI: https://www.mollie.com
|
5 |
* Description: Accept payments in WooCommerce with the official Mollie plugin
|
6 |
+
* Version: 3.0.0
|
7 |
* Author: Mollie
|
8 |
* Author URI: https://www.mollie.com
|
9 |
* Requires at least: 3.8
|
@@ -4,7 +4,7 @@ Tags: mollie, payments, woocommerce, payment gateway, e-commerce, credit card, i
|
|
4 |
Requires at least: 3.8
|
5 |
Tested up to: 4.9
|
6 |
Requires PHP: 5.3
|
7 |
-
Stable tag:
|
8 |
Requires PHP: 5.3
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
@@ -164,6 +164,24 @@ Automatic updates should work like a charm; as always though, ensure you backup
|
|
164 |
|
165 |
== Changelog ==
|
166 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
= 2.9.0 - 13/02/2018 =
|
168 |
|
169 |
* New - Added support for new payment method: [ING Home'Pay](https://www.mollie.com/en/payments/ing-homepay)
|
@@ -307,7 +325,7 @@ WooCommerce -> Settings -> Checkout -> Mollie - Bank Transfer.
|
|
307 |
|
308 |
= 2.0.1 - 02/10/2015 =
|
309 |
* Add support for SEPA Direct Debit.
|
310 |
-
* Add message for Belfius, Bitcoin, Bancontact
|
311 |
|
312 |
= 2.0.0 - 17/08/2015 =
|
313 |
* Complete rewrite of our WooCommerce plugin to better follow WordPress and WooCommerce standards and add better support for other plugins.
|
4 |
Requires at least: 3.8
|
5 |
Tested up to: 4.9
|
6 |
Requires PHP: 5.3
|
7 |
+
Stable tag: 3.0.0
|
8 |
Requires PHP: 5.3
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
164 |
|
165 |
== Changelog ==
|
166 |
|
167 |
+
= 3.0.0 - 17/04/2018 =
|
168 |
+
|
169 |
+
* New - WooCommerce Subscriptions: add support for 'subscription_payment_method_change', shop-customers can change payment method if renewal payment fails (SEPA incasso, credit card)
|
170 |
+
* New - WooCommerce Subscriptions: disable Mollie payment methods on shop-customer's my account page for "Payment method change", keep it enabled for "Pay now" link in emails
|
171 |
+
* New - WooCommerce Subscriptions: improve handling and update messages and notices for Subscription switch to better explain what's happening
|
172 |
+
* New - WooCommerce Subscriptions: set renewal orders and subscriptions to 'On-Hold' if renewal payment fails
|
173 |
+
|
174 |
+
* Fix - Fallback for getUserMollieCustomerId, get Mollie Customer ID from recent subscription if it's empty in WordPress user meta
|
175 |
+
* Fix - Improve support for Polylang option "Hide URL language information for default language" in webhook and return URLs,
|
176 |
+
* Fix - Only check if customer ID is valid on current API key if there is a customer ID (not empty)(and improve log messages)
|
177 |
+
* Fix - Make sure payment instructions (Bank Transfer) are styled the same as WooCommerce content (Order received, payment pending)
|
178 |
+
* Fix - Don't update/process/expire Mollie payments on WooCommerce orders that have been paid with other payment gateways
|
179 |
+
* Fix - Updated text strings for Bancontact/Mister Cash to just Bancontact
|
180 |
+
* Fix - Use the exact same translation as WooCommerce for order statuses
|
181 |
+
* Fix - Resolve error (fatal error get_payment_method()) that occurred when users made certain custom changes to the WooCommerce template files
|
182 |
+
* Fix - Add order note and log message when customer returns to the site but payment is open/pending
|
183 |
+
* Fix - Improved order note for charged back renewal payments
|
184 |
+
|
185 |
= 2.9.0 - 13/02/2018 =
|
186 |
|
187 |
* New - Added support for new payment method: [ING Home'Pay](https://www.mollie.com/en/payments/ing-homepay)
|
325 |
|
326 |
= 2.0.1 - 02/10/2015 =
|
327 |
* Add support for SEPA Direct Debit.
|
328 |
+
* Add message for Belfius, Bitcoin, Bancontact and paysafecard when the payment is paid successfully.
|
329 |
|
330 |
= 2.0.0 - 17/08/2015 =
|
331 |
* Complete rewrite of our WooCommerce plugin to better follow WordPress and WooCommerce standards and add better support for other plugins.
|