Not sure if this should be a support request, bug report, or what, but anyway:

I've noticed that Drupal Commerce payment method modules calculate the price to be charged based on the order total. I wrote a couple custom modules that do this as well. However, at Everpurse (which runs Drupal Commerce), we've repeatedly run into a use case in which this logic is a problem:

  • A customer adds a product to her cart for, say, $249.
  • She checks out with her payment method of choice and is charged the order total of $249.
  • She then contacts our support team and asks to upgrade her order to something that costs $40 more than what she originally paid.
  • Our support team moves her order back into her shopping cart, removes the $249 item, and adds the $289 item.
  • She begins the checkout process again—but notices that she will be charged $289 at the payment stage, even though she's already paid $249 the first time she checked out.

There are two ways we've been dealing with this:

  1. Issue a refund of the original $249 and have her pay the full $289. This is wasteful, though, as each payment incurs a charge from our payment processor. It also means we're giving back the customer's money, giving her the opportunity to never buy anything at all (if she fails to complete checkout the second time) and thus hurting the sales funnel. (We'd prefer for her to get the $249 product than not get anything at all!)
  2. Add a temporary line item with a total of -$249 that says "credit for previous payment." This requires annoying manual work and has to be removed after she checks out the second time (otherwise, the order balance will be -$249 after she checks out the second time).

In my opinion, payment method modules should charge the order balance, rather than the order total. This way, customers can pay just for an upgrade rather than having to start from scratch.

Am I missing anything? I want to change my custom payment modules to use this logic, but want to make sure first that I'm not missing any problems this would introduce.

Thanks!

Comments

rszrama’s picture

Version: 7.x-1.8 » 7.x-1.x-dev
Category: support » feature

The main reason against doing this is that in the standard checkout screen, there's no indication that payment has already been received. We show the order total with its price components broken down, but we don't actually show any indication of prior payments made (because we assume there haven't been any). I'm not opposed to charging based on the order balance, but we'd need some sort of indication in checkout that the amount charged will be less than the total shown.

This is such an edge case that it doesn't need to be the "perfect" solution to go in, imo. I'd be interested in a few different takes on it. The only things that come to mind are adding this information to the payment checkout pane somehow or near the order total in the review pane.

jessepinho’s picture

I'd be happy to throw together a patch that would do this. Just to make sure we're on the same page, I'm thinking it would, in the order total table (that includes the order total components):

  • Check whether the Payment module is installed.
  • If so, check whether any successful transactions have been posted against the current order.
  • If so, check whether the transactions add up to a total not equal to 0. (Consider refunds, etc.)
  • If so, add two rows to the order total table: "Balance paid" and "Balance due."

Does this sound good? I haven't looked into how the order total table is built; but I'm assuming it's not too complicated to add rows to. If this sounds like a good solution, I'll go ahead and put together a patch.

(Would it be possible then to also officially recommend that payment method modules use the order balance from now on, rather than the order total?)

rszrama’s picture

It could happen there, though it's not guaranteed that that review pane would be on a page anywhere. What you're seeing in that table is technically speaking just the list of price components that are actually a part of the order total price field. The calculation of the balance is a separate affair, and while you could artificially tack it onto that list, it may not look well. You might need to consider some sort of #suffix or something after it if you want it to be inline there or else a separate Views area handler. In fact, I wonder if we can just reuse the area handler from the admin payments tab. : ?

Re: payment method modules, none should need to be updated since they should just be receiving the $charge array from the core payment checkout pane. If I change it to use the order balance there instead of the order total, every other payment method module should just work... hmm, except for maybe modules that use redirect forms.

jessepinho’s picture

Yeah, it appears that modules with an offsite redirect don't get the $charge array passed in at any point...? (I'm looking at both my own Braintree module and the PayPal WPS module; both of these have to use $order->commerce_order_total.)

So, perhaps the solution is twofold:

  • Make it possible to pass $charge in to the redirect_form of offsite payment methods.
  • Make sure the order balance, not the order total, is used when passing in $charge to any payment method.
rszrama’s picture

Yeah, I'd say that we have an inconsistency here that we should flatten out - pass in the $charge amount like you've said and make sure we're passing the balance like we want to update the on-site payment methods to use.

rszrama’s picture

Issue summary: View changes

Fix grammar, etc.

jessepinho’s picture

So, for the time being, should offsite-redirect payment modules simply use the balance instead of the order total, until Commerce Payment is modified to make a $charge variable available?

ropic’s picture

Do you have any advance on this ? i have a similar problem because i'm creating new orders with payments done in other e-commerce site, the user came to my site only for selecting product variation and maybe add new products.

torgosPizza’s picture

It seems like this should be easy enough to do - there are functions to find the balance of an order, and because we are able to multiple transactions per order, I would imagine changing "total" to "balance" across various Commerce systems would be relatively straightforward.

In fact this is how I would expect it to work, and I'm kind of surprised to find out that it doesn't. Is this still true, 2 years after this issue was created?

ropic’s picture

I followed the method 2 creating a custom line item and temporary insert then on complete checkout state i delete the line.

rszrama’s picture

You know what, looking at the code again, it's actually been true since 2011 that we use the order balance, not the order total. Perhaps Jesse's original intention here was related to redirected payment methods? I haven't looked lately at the PayPal module to see if perhaps it was using the order total instead of the balance. I may not have included a mechanism in the core Payment module to submit a "charge" value to modules as they build their redirect forms.