Hi,
I did a lot of further checks and tests.
First, have a look at my log. It really seems that the webhook simply gets triggerd twice (or even more often). So, there is no problem in handling the webhook or processing the payment within woocommerce. The process simply gets startet multiple times.
########################################################################################################################
Mon, 29 Jun 15 22:46:13 +0000 - Webhook subscription.succeeded (Resource-ID: sub_33cd3b85bebda68ace57) triggered - start processing
SELECT * FROM pp_paymill_subscriptions WHERE paymill_sub_id='sub_33cd3b85bebda68ace57'
array (
'order_id' => '2872',
'product_id' => '967',
'variation_id' => '0',
'status' => 'active',
'period' => 'day',
'interval' => '1',
'length' => '0',
'start_date' => '2015-06-28 22:43:12',
'expiry_date' => '0',
'end_date' => '0',
'trial_expiry_date' => '0',
'failed_payments' => '0',
'completed_payments' =>
array (
0 => '2015-06-28 22:43:12',
),
'suspension_count' => '0',
'last_payment_date' => '2015-06-28 22:43:12',
)
Mon, 29 Jun 15 22:46:29 +0000 - Webhook subscription.succeeded finished - end processing
########################################################################################################################
Mon, 29 Jun 15 23:47:11 +0000 - Webhook subscription.succeeded (Resource-ID: sub_33cd3b85bebda68ace57) triggered - start processing
SELECT * FROM pp_paymill_subscriptions WHERE paymill_sub_id='sub_33cd3b85bebda68ace57'
array (
'order_id' => '2872',
'product_id' => '967',
'variation_id' => '0',
'status' => 'active',
'period' => 'day',
'interval' => '1',
'length' => '0',
'start_date' => '2015-06-28 22:43:12',
'expiry_date' => '0',
'end_date' => '0',
'trial_expiry_date' => '0',
'failed_payments' => '0',
'completed_payments' =>
array (
0 => '2015-06-28 22:43:12',
1 => '2015-06-29 22:46:14',
),
'suspension_count' => '0',
'last_payment_date' => '2015-06-29 22:46:14',
)
Mon, 29 Jun 15 23:47:23 +0000 - Webhook subscription.succeeded finished - end processing
########################################################################################################################
Well, this might be a Paymill issue. But maybe it’s not even a bug, but a feature to make sure the webhook gets through. Or this happens due to some strange mix of old data, caching, … (who knows).
Finally, I compared your code to the PayPal-Code, since PayPal works as expected.
So far, I can only tell that the basic handling is the same, but PayPal executes way more security/failure checks.
That’s why I think that the only proper fix would be to keep track of the different payments and reject a payment if it comes in the second time.
There are different ways to do that and I think you have a better idea of how to track.
For now, I implemented a little workaround on my side that keeps it going (however, this only handles standard subscriptions – any special setting might break it).
Change in woocommerce.inc.php at line 248 ff:
`
$whole_period = 0;
switch ($subscription[‘period’]) {
case ‘day’:
default:
$whole_period = intval($subscription[‘interval’]) * 86400;
break;
case ‘week’:
$whole_period = intval($subscription[‘interval’]) * 604800;
break;
case ‘month’:
$whole_period = intval($subscription[‘interval’]) * 2160000; // using 25 days to prevent problems with shorter months
break;
case ‘year’:
$whole_period = intval($subscription[‘interval’]) * 30240000; // using 350 days to prevent any timezone problems whatsoever
break;
}
if (strtotime(date(DATE_RFC822)) > strtotime($subscription[‘last_payment_date’]) + $whole_period – 18000) { // minus 5 hours to prevent any problems with pending triggers
$order = new WC_Order($subscription[‘order_id’]);
//WC_Subscriptions_Manager::process_subscription_payments_on_order($order, $subscription[‘product_id’]);
WC_Subscriptions_Manager::process_subscription_payments_on_order($order);
}
`
Hope this helps to fix this bug! Maybe you can at least include some check (like my workaround) that can be enabled by option.
Best,
Jens