Update by Qphoria: I've added a version that works with ALL VERSIONS of OpenCart 1.5.x and 2.x now and attached it here.
Attachments
for ALL versions of OpenCart
vQmod file: Apply coupon during checkout
Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig
Have you successfully used it with paypal.
In my end paypal didnt seem to minus the coupon amount from the total amount.
Just wondering if you guys are facing the same thing.
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
Did the coupon show up on the Step 6: Confirm ?Maansy wrote:Thanks. It's indeed needed.
Have you successfully used it with paypal.
In my end paypal didnt seem to minus the coupon amount from the total amount.
Just wondering if you guys are facing the same thing.
If so, then it might be an issue with Paypal.
I just tested it with Paypal Standard, and it works fine. The Paypal module puts all of the shipping, taxes, and discounts into one line.
Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig
it shows in step 6, but when it took me to paypal page there was no coupon value at all.JNeuhoff wrote:Did the coupon show up on the Step 6: Confirm ?Maansy wrote:Thanks. It's indeed needed.
Have you successfully used it with paypal.
In my end paypal didnt seem to minus the coupon amount from the total amount.
Just wondering if you guys are facing the same thing.
If so, then it might be an issue with Paypal.
I just tested it with Paypal Standard, and it works fine. The Paypal module puts all of the shipping, taxes, and discounts into one line.
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
I am unable to reproduce your error. Any URL of your website where I can see this error?it shows in step 6, but when it took me to paypal page there was no coupon value at all.
Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig
Will check if i somehow fixed it and forgot about it (has been known)
lines 80-88 of original 1.5.0.5 download:
Code: Select all
$this->data['products'][] = array(
'name' => $this->language->get('text_total'),
'model' => '',
'price' => $this->currency->format($order_info['total'] - $this->cart->getSubTotal(), $currency, false, false),
'quantity' => 1,
'option' => array(),
'weight' => 0
);
Code: Select all
$this->data['discount_amount_cart'] = 0;
$total = $this->currency->format($order_info['total'] - $this->cart->getSubTotal(), $currency, false, false);
if ($total > 0) {
$this->data['products'][] = array(
'name' => $this->language->get('text_total'),
'model' => '',
'price' => $total,
'quantity' => 1,
'option' => array(),
'weight' => 0
);
} else {
$this->data['discount_amount_cart'] -= $this->currency->format($total, $currency, FALSE, FALSE);
}
uksitebuilder wrote:OK, the only thing I can think of it being is in catalog/controll/payment/pp_standard.php
lines 80-88 of original 1.5.0.5 download:
In my file I have:Code: Select all
$this->data['products'][] = array( 'name' => $this->language->get('text_total'), 'model' => '', 'price' => $this->currency->format($order_info['total'] - $this->cart->getSubTotal(), $currency, false, false), 'quantity' => 1, 'option' => array(), 'weight' => 0 );
I can only assume I fixed this from the SVNCode: Select all
$this->data['discount_amount_cart'] = 0; $total = $this->currency->format($order_info['total'] - $this->cart->getSubTotal(), $currency, false, false); if ($total > 0) { $this->data['products'][] = array( 'name' => $this->language->get('text_total'), 'model' => '', 'price' => $total, 'quantity' => 1, 'option' => array(), 'weight' => 0 ); } else { $this->data['discount_amount_cart'] -= $this->currency->format($total, $currency, FALSE, FALSE); }
this is the one i am using:
Code: Select all
<?php
class ControllerPaymentPPStandard extends Controller {
protected function index() {
$this->language->load('payment/pp_standard');
$this->data['text_testmode'] = $this->language->get('text_testmode');
$this->data['button_confirm'] = $this->language->get('button_confirm');
$this->data['testmode'] = $this->config->get('pp_standard_test');
if (!$this->config->get('pp_standard_test')) {
$this->data['action'] = 'https://www.paypal.com/cgi-bin/webscr';
} else {
$this->data['action'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
}
$this->load->model('checkout/order');
$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
if ($order_info) {
$currencies = array(
'AUD',
'CAD',
'EUR',
'GBP',
'JPY',
'USD',
'NZD',
'CHF',
'HKD',
'SGD',
'SEK',
'DKK',
'PLN',
'NOK',
'HUF',
'CZK',
'ILS',
'MXN',
'MYR',
'BRL',
'PHP',
'TWD',
'THB',
'TRY'
);
if (in_array($order_info['currency_code'], $currencies)) {
$currency = $order_info['currency_code'];
} else {
$currency = 'USD';
}
$this->data['business'] = $this->config->get('pp_standard_email');
$this->data['item_name'] = html_entity_decode($this->config->get('config_name'), ENT_QUOTES, 'UTF-8');
$this->data['products'] = array();
foreach ($this->cart->getProducts() as $product) {
$option_data = array();
foreach ($product['option'] as $option) {
$option_data[] = array(
'name' => $option['name'],
'value' => $option['option_value']
);
}
$this->data['products'][] = array(
'name' => $product['name'],
'model' => $product['model'],
'price' => $this->currency->format($product['price'], $currency, false, false),
'quantity' => $product['quantity'],
'option' => $option_data,
'weight' => $product['weight']
);
}
$this->data['discount_amount_cart'] = 0;
$total = $this->currency->format($order_info['total'] - $this->cart->getSubTotal(), $currency, false, false);
if ($total > 0) {
$this->data['products'][] = array(
'name' => $this->language->get('text_total'),
'model' => '',
'price' => $total,
'quantity' => 1,
'option' => array(),
'weight' => 0
);
} else {
$this->data['discount_amount_cart'] -= $this->currency->format($total, $currency, FALSE, FALSE);
}
$this->data['currency_code'] = $currency;
$this->data['first_name'] = html_entity_decode($order_info['payment_firstname'], ENT_QUOTES, 'UTF-8');
$this->data['last_name'] = html_entity_decode($order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
$this->data['address1'] = html_entity_decode($order_info['payment_address_1'], ENT_QUOTES, 'UTF-8');
$this->data['address2'] = html_entity_decode($order_info['payment_address_2'], ENT_QUOTES, 'UTF-8');
$this->data['city'] = html_entity_decode($order_info['payment_city'], ENT_QUOTES, 'UTF-8');
$this->data['zip'] = html_entity_decode($order_info['payment_postcode'], ENT_QUOTES, 'UTF-8');
$this->data['country'] = $order_info['payment_iso_code_2'];
$this->data['notify_url'] = $this->url->link('payment/pp_standard/callback');
$this->data['email'] = $order_info['email'];
$this->data['invoice'] = $this->session->data['order_id'] . ' - ' . html_entity_decode($order_info['payment_firstname'], ENT_QUOTES, 'UTF-8') . ' ' . html_entity_decode($order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
$this->data['lc'] = $this->session->data['language'];
$this->data['return'] = $this->url->link('checkout/success');
$this->data['notify_url'] = $this->url->link('payment/pp_standard/callback');
$this->data['cancel_return'] = $this->url->link('checkout/checkout', '', 'SSL');
if (!$this->config->get('pp_standard_transaction')) {
$this->data['paymentaction'] = 'authorization';
} else {
$this->data['paymentaction'] = 'sale';
}
$this->load->library('encryption');
$encryption = new Encryption($this->config->get('config_encryption'));
$this->data['custom'] = $encryption->encrypt($this->session->data['order_id']);
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/pp_standard.tpl')) {
$this->template = $this->config->get('config_template') . '/template/payment/pp_standard.tpl';
} else {
$this->template = 'default/template/payment/pp_standard.tpl';
}
$this->render();
}
}
public function callback() {
$this->load->library('encryption');
$encryption = new Encryption($this->config->get('config_encryption'));
if (isset($this->request->post['custom'])) {
$order_id = $encryption->decrypt($this->request->post['custom']);
} else {
$order_id = 0;
}
$this->load->model('checkout/order');
$order_info = $this->model_checkout_order->getOrder($order_id);
if ($order_info) {
$request = 'cmd=_notify-validate';
foreach ($this->request->post as $key => $value) {
$request .= '&' . $key . '=' . urlencode(html_entity_decode($value, ENT_QUOTES, 'UTF-8'));
}
if (!$this->config->get('pp_standard_test')) {
$curl = curl_init('https://www.paypal.com/cgi-bin/webscr');
} else {
$curl = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
}
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
if (!$response) {
$this->log->write('PP_STANDARD :: CURL failed ' . curl_error($curl) . '(' . curl_errno($curl) . ')');
}
if ($this->config->get('pp_standard_debug')) {
$this->log->write('PP_STANDARD :: IPN REQUEST: ' . $request);
$this->log->write('PP_STANDARD :: IPN RESPONSE: ' . $response);
}
if ((strcmp($response, 'VERIFIED') == 0 || strcmp($response, 'UNVERIFIED') == 0) && isset($this->request->post['payment_status'])) {
$order_status_id = $this->config->get('config_order_status_id');
switch($this->request->post['payment_status']) {
case 'Canceled_Reversal':
$order_status_id = $this->config->get('pp_standard_canceled_reversal_status_id');
break;
case 'Completed':
if ((float)$this->request->post['mc_gross'] == $this->currency->format($order_info['total'], $order_info['currency_code'], $order_info['currency_value'], false)) {
$order_status_id = $this->config->get('pp_standard_completed_status_id');
}
break;
case 'Denied':
$order_status_id = $this->config->get('pp_standard_denied_status_id');
break;
case 'Expired':
$order_status_id = $this->config->get('pp_standard_expired_status_id');
break;
case 'Failed':
$order_status_id = $this->config->get('pp_standard_failed_status_id');
break;
case 'Pending':
$order_status_id = $this->config->get('pp_standard_pending_status_id');
break;
case 'Processed':
$order_status_id = $this->config->get('pp_standard_processed_status_id');
break;
case 'Refunded':
$order_status_id = $this->config->get('pp_standard_refunded_status_id');
break;
case 'Reversed':
$order_status_id = $this->config->get('pp_standard_reversed_status_id');
break;
case 'Voided':
$order_status_id = $this->config->get('pp_standard_voided_status_id');
break;
}
if (!$order_info['order_status_id']) {
$this->model_checkout_order->confirm($order_id, $order_status_id);
} else {
$this->model_checkout_order->update($order_id, $order_status_id);
}
} else {
$this->model_checkout_order->confirm($order_id, $this->config->get('config_order_status_id'));
}
curl_close($curl);
}
}
}
?>
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
has this been fixed in the svn at least?Qphoria wrote:This is a known paypal issue with discounts in 1.5.x
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
its hasn't been fixed in my end. i posted the pp_stander.php that i am using to see if its identical to yours.uksitebuilder wrote:Looks like we both have used SVN to fix it then.
Not tested Gift Vouchers yet though.
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
around line: 23
Code: Select all
<?php if ($discount_amount_cart) { ?>
<input type="hidden" name="discount_amount_cart" value="<?php echo $discount_amount_cart; ?>" />
<?php } ?>
yes i douksitebuilder wrote:do you have these lines in catalog/view/theme/default/template/payment/pp_standard.tpl
around line: 23
Code: Select all
<?php if ($discount_amount_cart) { ?> <input type="hidden" name="discount_amount_cart" value="<?php echo $discount_amount_cart; ?>" /> <?php } ?>
Code: Select all
<?php if ($testmode) { ?>
<div class="warning"><?php echo $text_testmode; ?></div>
<?php } ?>
<form action="<?php echo $action; ?>" method="post" id="payment">
<input type="hidden" name="cmd" value="_cart" />
<input type="hidden" name="upload" value="1" />
<input type="hidden" name="business" value="<?php echo $business; ?>" />
<?php $i = 1; ?>
<?php foreach ($products as $product) { ?>
<input type="hidden" name="item_name_<?php echo $i; ?>" value="<?php echo $product['name']; ?>" />
<input type="hidden" name="item_number_<?php echo $i; ?>" value="<?php echo $product['model']; ?>" />
<input type="hidden" name="amount_<?php echo $i; ?>" value="<?php echo $product['price']; ?>" />
<input type="hidden" name="quantity_<?php echo $i; ?>" value="<?php echo $product['quantity']; ?>" />
<input type="hidden" name="weight_<?php echo $i; ?>" value="<?php echo $product['weight']; ?>" />
<?php $j = 0; ?>
<?php foreach ($product['option'] as $option) { ?>
<input type="hidden" name="on<?php echo $j; ?>_<?php echo $i; ?>" value="<?php echo $option['name']; ?>" />
<input type="hidden" name="os<?php echo $j; ?>_<?php echo $i; ?>" value="<?php echo $option['value']; ?>" />
<?php $j++; ?>
<?php } ?>
<?php $i++; ?>
<?php } ?>
<?php if ($discount_amount_cart) { ?>
<input type="hidden" name="discount_amount_cart" value="<?php echo $discount_amount_cart; ?>" />
<?php } ?>
<input type="hidden" name="currency_code" value="<?php echo $currency_code; ?>" />
<input type="hidden" name="first_name" value="<?php echo $first_name; ?>" />
<input type="hidden" name="last_name" value="<?php echo $last_name; ?>" />
<input type="hidden" name="address1" value="<?php echo $address1; ?>" />
<input type="hidden" name="address2" value="<?php echo $address2; ?>" />
<input type="hidden" name="city" value="<?php echo $city; ?>" />
<input type="hidden" name="zip" value="<?php echo $zip; ?>" />
<input type="hidden" name="country" value="<?php echo $country; ?>" />
<input type="hidden" name="address_override" value="0" />
<input type="hidden" name="email" value="<?php echo $email; ?>" />
<input type="hidden" name="invoice" value="<?php echo $invoice; ?>" />
<input type="hidden" name="lc" value="<?php echo $lc; ?>" />
<input type="hidden" name="rm" value="2" />
<input type="hidden" name="no_note" value="1" />
<input type="hidden" name="charset" value="utf-8" />
<input type="hidden" name="return" value="<?php echo $return; ?>" />
<input type="hidden" name="notify_url" value="<?php echo $notify_url; ?>" />
<input type="hidden" name="cancel_return" value="<?php echo $cancel_return; ?>" />
<input type="hidden" name="paymentaction" value="<?php echo $paymentaction; ?>" />
<input type="hidden" name="custom" value="<?php echo $custom; ?>" />
</form>
<div class="buttons">
<div class="right"><a id="button-confirm" class="button" onclick="$('#payment').submit();"><span><?php echo $button_confirm; ?></span></a></div>
</div>
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
Code: Select all
$this->db->query("INSERT INTO `" . DB_PREFIX . "coupon_history` SET coupon_id = '" . (int)$coupon_id . "', order_id = '" . (int)$order_id . "', customer_id = '" . (int)$customer_id . "', amount = '" . (float)$amount . "', date_added = NOW()");
Just doing a file compare on 1.5.0.5 against my local copy which I svn'd the bugfixes and picking out any differences that may be related
yes i douksitebuilder wrote:Do you have this:
Near the bottom of: catalog/model/checkout/coupon.phpCode: Select all
$this->db->query("INSERT INTO `" . DB_PREFIX . "coupon_history` SET coupon_id = '" . (int)$coupon_id . "', order_id = '" . (int)$order_id . "', customer_id = '" . (int)$customer_id . "', amount = '" . (float)$amount . "', date_added = NOW()");
Just doing a file compare on 1.5.0.5 against my local copy which I svn'd the bugfixes and picking out any differences that may be related
this is the file i am using
catalog/model/checkout/coupon.php
Code: Select all
<?php
class ModelCheckoutCoupon extends Model {
public function getCoupon($code) {
$status = true;
$coupon_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "coupon WHERE code = '" . $this->db->escape($code) . "' AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) AND status = '1'");
if ($coupon_query->num_rows) {
if ($coupon_query->row['total'] >= $this->cart->getSubTotal()) {
$status = false;
}
$coupon_history_query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "coupon_history` ch WHERE ch.coupon_id = '" . (int)$coupon_query->row['coupon_id'] . "'");
if ($coupon_query->row['uses_total'] > 0 && ($coupon_history_query->row['total'] >= $coupon_query->row['uses_total'])) {
$status = false;
}
if ($coupon_query->row['logged'] && !$this->customer->getId()) {
$status = false;
}
if ($this->customer->getId()) {
$coupon_history_query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "coupon_history` ch WHERE ch.coupon_id = '" . (int)$coupon_query->row['coupon_id'] . "' AND ch.customer_id = '" . (int)$this->customer->getId() . "'");
if ($coupon_query->row['uses_customer'] > 0 && ($coupon_history_query->row['total'] >= $coupon_query->row['uses_customer'])) {
$status = false;
}
}
$coupon_product_data = array();
$coupon_product_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "coupon_product WHERE coupon_id = '" . (int)$coupon_query->row['coupon_id'] . "'");
foreach ($coupon_product_query->rows as $result) {
$coupon_product_data[] = $result['product_id'];
}
if ($coupon_product_data) {
$coupon_product = false;
foreach ($this->cart->getProducts() as $product) {
if (in_array($product['product_id'], $coupon_product_data)) {
$coupon_product = true;
break;
}
}
if (!$coupon_product) {
$status = false;
}
}
} else {
$status = false;
}
if ($status) {
return array(
'coupon_id' => $coupon_query->row['coupon_id'],
'code' => $coupon_query->row['code'],
'name' => $coupon_query->row['name'],
'type' => $coupon_query->row['type'],
'discount' => $coupon_query->row['discount'],
'shipping' => $coupon_query->row['shipping'],
'total' => $coupon_query->row['total'],
'product' => $coupon_product_data,
'date_start' => $coupon_query->row['date_start'],
'date_end' => $coupon_query->row['date_end'],
'uses_total' => $coupon_query->row['uses_total'],
'uses_customer' => $coupon_query->row['uses_customer'],
'status' => $coupon_query->row['status'],
'date_added' => $coupon_query->row['date_added']
);
}
}
public function redeem($coupon_id, $order_id, $customer_id, $amount) {
$this->db->query("INSERT INTO `" . DB_PREFIX . "coupon_history` SET coupon_id = '" . (int)$coupon_id . "', order_id = '" . (int)$order_id . "', customer_id = '" . (int)$customer_id . "', amount = '" . (float)$amount . "', date_added = NOW()");
}
}
?>
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
When you get to checkout confirm, before it fires you off to PayPal, that page will have all the hidden paypal form fields in it.
can you view source and find the hidden input field item_2 and amount_2
On mine,
item_2 = "Shipping, Handling, Discounts & Taxes"
amount_2 = (shipping + taxes - discounts)
here are my 3 files (attached)
feel free to drop on top of yours to see if it works. it has helped another user on a different thread with same problem.
Attachments
at step 6 (just before paypal page)uksitebuilder wrote:OK, I can't find any other files differences that relate now.
When you get to checkout confirm, before it fires you off to PayPal, that page will have all the hidden paypal form fields in it.
can you view source and find the hidden input field item_2 and amount_2
On mine,
item_2 = "Shipping, Handling, Discounts & Taxes"
amount_2 = (shipping + taxes - discounts)
i view the page source with FF but i cant seem to find item_2 and amount_2
ALL Templates :: 1.5.1+ Templates :: 50%-75% PRICE DROP ONLY at OpencartStuff.com
Users browsing this forum: No registered users and 18 guests