1

SUMMARY: Below are the details to the question. The issue at hand is that any coupon that is above 8% discount. Sends the UNDISCOUNTED amount to cybersource. On the checkout page, the calculations are done correctly no matter the percentile discount from the coupon.

Relevant Modules & Versions:

  • Cart 7.x-3.2

  • Discount Coupons 7.x-2.1-alpha7

  • Token 7.x-1.4

  • Entity API 7.x-1.0-rc3

  • Views 7.x-3.5

Modules Enabled:

  • ALL of UC core.

  • Catalog, Payment, Product Attributes, Reports, Shipping, Shipping quotes, Tax Reports, Taxes

  • Product Kit, Stock

  • Flat Rate
  • Credit Card, Cyber Source, Discount Coupons

Payment Gateway: Cyber Source Payment Method: SOAP Toolkit API - Everything here is configured correctly here.

Shipping: Flat Rate (We add $30 for next day air)

Coupon Settings:

  • Coupon is Active is checked.
  • Discount amount [we are using percentage based discounts. If the discount is BELOW 9%. It works as it should. If its 9% or HIGHER, it sends the undiscounted amount to the payment gateway.] The calculations on the checkout page are ALWAYS correct. No matter the amount of the coupon percentile.
  • Apply Discount to: We have tried with Order Subtotal, and Total of matching products. Both cause the same results.
  • Redemption Amounts Restrictions are both blank.

This link mentions a similar issue except it is with paypal.

We have also tried with a FRESH & completely bare Drupal 7, UC 7.x-3.2, & Discounted Coupons 7.x-2.1-alpha7. It still did not work.

QUESTION: Why does the uc_coupon calculate correctly on the checkout page. But, any discount of 9% or more sends the undiscounted amount to the payment gateway?

UPDATE:

The problem lies between these lines;

// Add the order total information.
$purchaseTotals = new stdClass();
$purchaseTotals->currency = $currency;

// Specify the total to charge if it's less than the order total.
if ($amount < $order->order_total) {
  $purchaseTotals->grandTotalAmount = $amount;
}
$request->purchaseTotals = $purchaseTotals;

// Separately add products and line item into the request items object if
// we're charging the full order total.
if (round($amount, 2) == round($order->order_total, 2)) {
  $request->item = array();
  $counter = 0;

  // Add the products to the item array.
  foreach ($order->products as $product) {
    $obj = $request->item[] = new stdClass();

    $obj->productName = $product->title;
    $obj->unitPrice = $product->price;
    $obj->quantity = $product->qty;
    $obj->productSKU = $product->model;
    $obj->productCode = 'default';
    $obj->id = $counter;

    $counter++;
  }

  // Add the line items to the item array.
  $discount_amount = 0;
  foreach ((array) $order->line_items as $line_item) {
    // Handle negative line items.
    if ($line_item['amount'] < 0) {
      $discount_amount += -$line_item['amount'];
    }
    // Skip subtotal line items.
    elseif (strpos($line_item['type'], 'subtotal') === FALSE) {
      $obj = $request->item[] = new stdClass();

      $obj->productName = $line_item['title'];
      $obj->unitPrice = $line_item['amount'];
      $obj->quantity = 1;
      $obj->productSKU = $line_item['type'] . '_' . $line_item['line_item_id'];
      $obj->id = $counter;

      $counter++;
    }
  }
}

// Add the total order discount into the request.
if ($discount_amount != 0) {
  $request->purchaseTotals->discountAmount = $discount_amount;
}

Here is a successful order w/ a discount of 8%:

[purchaseTotals] => stdClass Object
    (
        [currency] => usd
        [grandTotalAmount] => 321.58
        [discountAmount] => 23.92
    )

[item] => Array
    (
        [0] => stdClass Object
            (
                [productName] => Signature Pendant - 14K Yellow Gold
                [unitPrice] => 299.00000
                [quantity] => 1
                [productSKU] => USI2541YR5J
                [productCode] => default
                [id] => 0
            )

        [1] => stdClass Object
            (
                [productName] => Next Day Air
                [unitPrice] => 30.00000
                [quantity] => 1
                [productSKU] => shipping_158
                [id] => 1
            )

        [2] => stdClass Object
            (
                [productName] => FL TAX
                [unitPrice] => 16.50480
                [quantity] => 1
                [productSKU] => tax_160
                [id] => 2
            )

    )

Here is what a failure looks like with a 10% discount. The threshold to break it is 9% thou;

[purchaseTotals] => stdClass Object
    (
        [currency] => usd
        [discountAmount] => 29.9
    )

[item] => Array
    (
        [0] => stdClass Object
            (
                [productName] => Signature Pendant - 14K Yellow Gold
                [unitPrice] => 299.00000
                [quantity] => 1
                [productSKU] => USI2541YR5J
                [productCode] => default
                [id] => 0
            )

        [1] => stdClass Object
            (
                [productName] => Next Day Air
                [unitPrice] => 30.00000
                [quantity] => 1
                [productSKU] => shipping_155
                [id] => 1
            )

        [2] => stdClass Object
            (
                [productName] => FL TAX
                [unitPrice] => 16.14600
                [quantity] => 1
                [productSKU] => tax_157
                [id] => 2
            )

    )

The difference is that "grandTotalAmount" is getting populated on 8% or less of a discount. Anything after that and "grandTotalAmount" doesn't get generated. Not sure but is this correct?

// Add the total order discount into the request.
if ($discount_amount != 0) {
  $request->purchaseTotals->discountAmount = $discount_amount;
}

Almost seems like something is missing inside the if statement.

0

Few troubleshooting tips:

  1. Hack the uc_cybersource and uc_coupon modules temporarily and log the values at each step throughout the whole process. Only this way you can find out what is exactly going on and where the values are changed and not calculated properly. You can save everything using watchdog() function.

  2. Make a clone of the site, disable all other modules and try to replicate the same issue.

  3. Do this on a clean install but with the same UC setup.

Also - do you have any custom modules that deal with the checkout process or orders?

  • No other modules are used for the checkout process or orders. – Digital fire Oct 2 '12 at 15:36
  • Did you have any luck with hacking the modules? – Aram Boyajyan Oct 3 '12 at 8:46
  • Posted the results of watchdog and where i think the problem is.. – Digital fire Oct 3 '12 at 17:12
0

Ended up changing the code to the following in the uc_cybersource.module;

    // Specify the total to charge if it's less than the order total.
if ($amount <= $order->order_total || $amount >= $order->order_total) {
  $purchaseTotals->grandTotalAmount = $amount;
}
$request->purchaseTotals = $purchaseTotals;

Lets see how long the maintainer takes to patch this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.