$query->fieldCondition('commerce_recurring_payment', 'value', 0, '=') returns recurring orders with payments. This is causing duplicate payments to process every time cron runs.


/**
 * Rules action callback: Load orders
*/
function commerce_recurring_load_payments_due() {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'commerce_order');
  $query->entityCondition('bundle', 'recurring_order');
  $now = new DateObject('now');
  $query->fieldCondition('commerce_recurring_payment_due', 'value', $now->format('U'), '<=');
  $query->fieldCondition('commerce_recurring_payment', 'value', 0, '=');
  $query->range(0, variable_get('commerce_recurring_batch_process', 20));
  $results = $query->execute();
  if (!empty($results['commerce_order'])) {
    return array('orders' => commerce_order_load_multiple(array_keys($results['commerce_order'])));
  }
  return array('orders' => array());
}

Discovered over here #1418348: Integration with Commerce Recurring Framework

Comments

larowlan’s picture

Status: Active » Postponed (maintainer needs more info)

So if I'm hearing you correct you're saying that the 'payment processed' field on your recurring orders is not being updated to 'processed' when your rules run?

R.J. Steinert’s picture

I suppose so. If that is what is expected to happen in the charge callback, I haven't written it into my patch for the Authorize.net module (see http://drupal.org/files/commerce_authnet-integrationForRecurringPaymentF...). Any advice?

R.J. Steinert’s picture

@larowland I just found your Commerce ezypay module in your sandbox (link on the commerce_recurring page is broken). I see http://drupalcode.org/sandbox/larowlan/1339888.git/blob/refs/heads/7.x-1...

I suppose that's the step I'm missing. Anything else you can see in my patch that doesn't follow assumptions in the commerce_recurring module?

larowlan’s picture

Hi
No that step is a different thing altogether.
Commerce Ezypay doesn't process at time of recurring module processing payments.
It processes them in a batch, once per day - and then fetches the processed transactions from the previous day - ie async.

This is where the order is marked as processed (in commerce recurring).
http://drupalcode.org/project/commerce_recurring.git/blob/refs/heads/7.x...
Does your charge callback return TRUE?

R.J. Steinert’s picture

Title: Duplicate payments for every recurring order with due date > now every time CRON runs » Document what charge callbacks should return
Component: Code » Documentation
Status: Postponed (maintainer needs more info) » Active

Nope, I wasn't returning TRUE, I totally missed that in the commerce_recurring code.

Here's what an update to the documentation on the project page might look like:

<?php
/*
 * Implements commerce_cardonfile charge callback
 *
 * @param $order object
 *    The order being charged
 * @param $parent_order object
 *    The parent order from which the recurring order was derived
 *
 * @return
 *   TRUE if the transaction was succesful
 */
function foo_cardonfile_charge($order, $parent_order) {
  // Retrieve the card on file
  $wrapper = entity_metadata_wrapper('commerce_order', $order);
  $instance_id = $parent_order->data['payment_method'];
  $payment_method = commerce_payment_method_instance_load($instance_id);
  $settings = $payment_method['settings'];
  $cards_on_file = commerce_cardonfile_data_load_multiple($order->uid, $payment_method['instance_id']);
  // do something with our $cards_on_file

  // Return TRUE if the transaction was successful

}
?>
larowlan’s picture

Status: Active » Fixed

Updated

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.