The rule event "When an order is first paid in full" isn't triggered by a Paypal payment if the default currency for Paypal payments is different from the currency of the item being bought.

Business Use Case

I'm a business who provides an internet platform for anyone (worldwide). I'm based in the UK so I'd like to take the payments in pounds.

The customers come from multiple different countries however, the pound is not as recognisable as the dollar and to help customers immediately value the service and compare it to my competitors I'd prefer to list the price in dollars.

This means I have the item listed in dollars, but the default currency set as pounds. So for an example purchase of $20 on the site, when you transfer to Paypal, they automatically convert $20 to pounds and the Paypal transaction is for ~ £12.57.

Problem

This means however the that the rule "When an order is first paid in full" isn't triggered.

The problem I think is with the following chunk in commerce_paypal.module:

line:447

function commerce_payment_commerce_payment_transaction_insert($transaction) {
  // If the inserted transaction was marked as a success and placed against a
  // valid order...
  if ($transaction->status == COMMERCE_PAYMENT_STATUS_SUCCESS &&
    $order = commerce_order_load($transaction->order_id)) {
    // Then check to make sure the event hasn't been invoked for this order.
    if (empty($order->data['commerce_payment_order_paid_in_full_invoked'])) {
      // Check the order balance and invoke the event.
      $balance = commerce_payment_order_balance($order);
      if (!empty($balance) && $balance['amount'] <= 0) {

$balance returns blank and so the if check fails.

I think this is then caused by the following code in commerce_payment_order_balance

line:1067

function commerce_payment_order_balance($order, $totals = array()) {
....

if (count($totals) == 1 && isset($totals[$order_total['currency_code']])) {
    return array('amount' => $order_total['amount'] - $totals[$order_total['currency_code']], 'currency_code' => $order_total['currency_code']);
  }
  elseif (empty($totals)) {
    return array('amount' => $order_total['amount'], 'currency_code' => $order_total['currency_code']);
  }
  else {
    return FALSE;
  }

$totals returns £12.59 and this then fails the check against $20. And so it falls over and the event is never triggered although payment is still labelled as received.

Comments

splitsplitsplit’s picture

Issue summary: View changes
splitsplitsplit’s picture

Issue summary: View changes
mglaman’s picture

Project: Commerce Core » Commerce PayPal
Version: 7.x-1.10 » 7.x-2.x-dev
Component: Payment » PayPal WPS
Status: Active » Closed (duplicate)

This is a PayPal specific issue, and fixed in #2595243: Order in unsupported currency does not trigger "payed in full" rule. Which is part of the latest PayPal release.