Fee based on payment method choice

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Hi,

I have a project, where the shop owner wants to charge his clients a fee, based on their payment method choice.

for example, paying by Paypal costs 4 euro, paying on delivery 10 euro. Is there an easy way of doing this in Ubercart? (or a less easy way)

Thanks,

Kees

Posts: 15
Joined: 08/07/2007

It would also be nice to be able to add a discount depending upon payment method (i.e. 3% off of the total for paying with Cash or Cashier's check).

Jeff

Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Hey Guys.

I'll give it a try this evening, cause I need this too. Give me a couple of hours.
But I think it won't (can't) be a module, you have to manipulate the Übercart sourcecode.
I will give you an instruction then.

Stay tuned.

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Hi Michel,

I hope I not crossed your attempts. I did get it to work, but indeed, I had to hack a core .js file.

The situation is simple. The radiobuttons for paymentmethod choice in checkout, already have a "onclick" js event. They do not have a unique ID nor name (bug?) so DHTML is not posible (I think). Thats why I had to change the js function "function get_payment_details".

Changes:

/**
* Display the payment details when a payment method radio button is clicked.
*/
function get_payment_details(path) {
  $.post(path, { },
    function(details) {
      if (details == '') {
        $('#payment_details').empty().addClass('display-none');
      }
      else {
        $('#payment_details').removeClass('display-none').empty().append(details);
      }
    }
  );
  //Start qrios hack
  var q_path;
  q_path = path.replace("payment_details", "method_fee");
  //alert(q_path);
  $.post(q_path, { },
    function(q_details) {
      q_details = q_details.split("||");
      if (q_details == '') {
        //$('#payment_details').empty().addClass('display-none');
      }
      else {
          if (set_line_item != undefined){
            set_line_item("methodfee", q_details[0], q_details[1], 1);
          }
      }
    }
  );
  //end hack
}

Maybe there is a way to make this more like themable/hookable??

q_details var returns one value containing two concatinated strings separated by ||. I didn't see another way. The module is'nt ready yet, if it is, I will post here.

Kees

Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Hi Kees,

I think I don't really understand what your function is doing Smiling
Respectivly I don't understand where I could add a value (fee)? Is there any more code? Your code just adds a new field when the radio-button is clicked, doesn't it?

I found a way to manipulate the uc_payment.module in such a way that you can add a value (e.g +4€, -3%) to every payment method. This Value is also shown as line-item in the checkout review. I think it should work.

I'm actually not in the office. So I think I will post it ca. in 3 hours.
Maybe we can combine our codes.

greetings from germany
mic

Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Did I wrote 3 hours? I meant 3 minutes Smiling

Here is the modified uc_payment.module. You can find the added code by searching the string "#mic". Just replace the old file and test it. Go in the store administration to "payment settings" -> "payment methods" and add some values for the different methods. Then it should work..

Check out the code, maybe you can use it for your module. I'm working with ubercart just since a couple of days, so this code is just alpha, alpha, alpha... Be carefully with it.

add to function uc_payment_order:

<?php
case 'total':
   
$csubtotal = 0;
   
$citems = uc_cart_get_contents();
    foreach (
$citems as $item) {
       
$ctotal = ($item->qty) ? $item->qty * $item->price : $item->price;
       
$csubtotal += $ctotal;
    }

   
$text_of_payment = '';
   
$cost_of_payment = 0;
   
$cost_of_payment = variable_get('uc_payment_method_'. $arg1->payment_method .'_cost', '');
   
$mode = variable_get('uc_payment_method_'. $arg1->payment_method .'_mode', '');
   
   
db_query("DELETE FROM {uc_order_line_items} WHERE order_id = %d AND type = '%s'", $arg1->order_id, 'Cost of Payment');
   
    if (
$cost_of_payment != ""){
       
        if (
$mode == 'percent_plus') {
           
$cost_of_payment = intval($cost_of_payment);
           
$cost_of_payment = ($csubtotal / 100) * $cost_of_payment;
        }
        elseif (
$mode == 'percent_minus') {
           
$cost_of_payment = intval($cost_of_payment);
           
$cost_of_payment = ($csubtotal / 100) * $cost_of_payment;
           
$cost_of_payment *= -1;                   
        }
        elseif (
$mode == 'static') {
           
$cost_of_payment = $cost_of_payment;
        }
       
$text_of_payment = variable_get('uc_payment_method_'. $arg1->payment_method .'_text', '');

       
uc_order_line_item_add($arg1->order_id, 'Cost of Payment', $text_of_payment, $cost_of_payment, 1);

    }
    return
$cost_of_payment;
?>

It's to add the costs as a line item. (see picture)

add to uc_payment_methods_form

<?php
            $form
['pmtable'][$method['id']]['uc_payment_method_'. $method['id'] .'_cost'] = array(
           
'#type' => 'textfield',
           
'#size' => '5',
           
'#default_value' => variable_get('uc_payment_method_'. $method['id'] .'_cost', $method['cost']),
            );
           
//@todo Form Validation
           
$form['pmtable'][$method['id']]['uc_payment_method_'. $method['id'] .'_mode'] = array(
           
'#type' => 'select',
           
'#options' => array ('percent_plus' => '%+', 'percent_minus' => '%-', 'static' => 'static'),
           
'#default_value' => variable_get('uc_payment_method_'. $method['id'] .'_mode', 'none'),
            );
           
$form['pmtable'][$method['id']]['uc_payment_method_'. $method['id'] .'_text'] = array(
           
'#type' => 'textfield',
           
'#size' => '20',
           
'#default_value' => variable_get('uc_payment_method_'. $method['id'] .'_text', $method['cost']),
            );
?>

It extends the form where the payment methods are listed. (See picture)
Check also the attached file to see the changes in the theme_uc_payment_methods_form

add to uc_checkout_pane_payment

<?php
$text
= variable_get('uc_payment_method_'. $method['id'] .'_text', '');
if (
$text != "") $options[$method['id']] .= ' ('.$text.')';
?>

It's to show the text behind the payment method. see picture)

So, I need your feedback now.
Thanks and greetings.
Mic

AttachmentSize
uc_payment.module.txt56.41 KB
display_checkout_review.jpg7.47 KB
display_checkout.jpg10.05 KB
input_payment_fee.jpg24.11 KB
Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Hi Mic and others,

Sorry for late reply.

I don't have time now to dig into your code.
Attached is the small module I created.

It's not ready, but functioning.

For now it is a fixed fee, and uses a setting "variable_get('uc_'.$method_id.'_fee', 0)", for example uc_paypal_ec_fee where the fee value is stored. The admin form to adjust the fee is missing!

I'm sure I can use your code to extend this module or the other way around. I'll get back on this!

Kees

AttachmentSize
uc_methodfee.tar6.5 KB
Posts: 5367
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Awesome work everyone! I'll consider putting this into core, as it's been requested almost as long as we've been making releases. I don't want to add too much complexity, though... what does everyone else think?

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

My thoughts:

Yes, please, in core would be just fine Smiling.
As far as complexity goes: A value, and a calculation method (add or multiply) per payment method would be nice.

I realy like the "one page checkout" Ubercart provides. But digging into this matter I can't help to think that it would be a lot easier to have more steps like :cart>Shipping>paymentmethod>adress+checkout. It would make things like this a lot easier.. but he, the easy way isn't always the best.

Note: I'm a bit concerned about the Javascript reliance of the method I used.

I would love to make it work, I don't have time for it the next two weeks though...

Kees

Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Hey Ryan.

It would be cool if you can add it.
But I have just a problem:

In the script I wrote I add the Line with the cost of payment like this

<?php
uc_order_line_item_add
($arg1->order_id, 'Cost of Payment', $text_of_payment, $cost_of_payment, 1);
?>

That works. But when I view the order (after submiting) as Admin, I can't change the values (like, i.e, the shipping cost). Do you know what I mean? Can you give me some help? Just a hint which functions I shpuld use...

thanks.

Posts: 5367
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

In order to edit it, you can probably just change 'Cost of Payment' to 'generic'. That second argument should be the ID of a line item type that is editable, and my hunch here is that isn't happening. Since it's all internal, you should be able to get by with a generic line item. Otherwise you'll need to use hook_line_item() to add in a line item type to mimic the generic definition:

<?php
 
// Look in uc_order.module for uc_order_line_item() where this code is:

 
$items[] = array(
   
'id' => 'generic',
   
'title' => t('Empty Line'),
   
'weight' => 2,
   
'stored' => TRUE,
   
'add_list' => TRUE,
   
'calculated' => TRUE,
   
'callback' => 'uc_line_item_generic',
  );
?>

Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Hey, cool it seems to work with

<?php
uc_order_line_item_add
($arg1->order_id, 'generic', $text_of_payment, $cost_of_payment, 1);
?>

and some other changes.

I can send you an updated version in the next days if you want?

Posts: 5367
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Yeah, send it to me when you get a chance and I'll try to test it out/add it in. It may take me a few days to get that done, though. Still trying to catch up. Sticking out tongue

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Could you post your version here please?

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

In the module I posted, I use a session var to remember the chosen payment method Shocked . What is the correct way to detect this when I'm in "hook_line_item"?(in the review order page)

Thanks,

Kees

Posts: 5367
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

You can load the order based on the session variable cart_order. It will have the chosen payment method stored in it by then.

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Hi Michel, Ryan, rest of you,

I did complete my module sort of, with a lot of help from Mitchels code. (So I found time after all Eye-wink)

It's a standalone module (no PHP hacks) to make it work in the checkout page (not only in order review) you have to hack uc_payment.js according to included readme file.

The module supports adding and multiplying, per enabled payment method. If you need f.e. 3% discount, simply multiply by 0.97 . Admin settings available in the payment method section under 'Method Fee settings'.

I need your feedback on this please.

Regards,

Kees

AttachmentSize
uc_methodfee0p2.tar12.5 KB
Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Hi Kees.

That's good.
But it seems, that the Fee is not calculated to the the total-amount, isn't it?

greetings
Michael

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Hi Michael, sorry for misspelling your name.

You're right, I didn't test past the 'order review' page, I think I see where I went wrong, wait a sec...

Thanks,

Kees

Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer
Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Here is the improved file.

I did it a bit lighter.
Should work now. Please test it. And if it works we can put it to the contributions.

But there is one (big!) problem. If you change the method fee settings (the values), every order is updated. That's something that shouldn't happened. Any ideas?

AttachmentSize
uc_methodfee0p3.tar12.5 KB
Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Please try again. Attached is new mod.

AttachmentSize
uc_methodfee0p3.tar14.5 KB
Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Oops, crossposted yours. Gonna try!

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Hi Michael, I looked through your code, your change is basicly the same as mine if I'm correct, I had old code in hook _order, refering to a non existent sessionvar.

Please look at my module, it has a few improvements and moved a bit more structure.

Regarding the problem of updating all orders, I really don't have a solution to it, thanks for pointing it out.

Regards,

Kees

AttachmentSize
uc_methodfee0p4.tar14.5 KB
Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

I'll check it this night.
Thanks for your good work. But we should communicate a bit more. instead of doing the same work Eye-wink

The problem with the updating of all orders: This is a problem of the most modules (Shipping Cost etc). That's why I asked this: http://www.ubercart.org/forum/development/504/stored_true_hook_line_item

We will see.

Mic

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Latest mod.
Removed debug something.

AttachmentSize
uc_methodfee0p5.tar14.5 KB
Posts: 82
Joined: 08/12/2007
Uber DonorBug FinderInternationalizationizer

Hi Kees.

I checked this yesterday.
You're module doesn't display the Method Fee-Line under Store Administration -> Orders -> View.

Maybe you want to fix that. Otherwise we can take mine. It works correctly I think.

greetings
Mic

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Are you sure you have the latest? It works fine here... strange. (7b)

Kees

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

sorry, duplicate

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Anyway, I created the contribution here:

http://www.ubercart.org/contrib/748

Feel free to make adjustments or provide feedback.

Thanks,

Kees

Posts: 60
Joined: 09/04/2007

I tested the current uc_methodfee0p6 version with UC alpha 8, and it seems to be somehow working. Anyway, I couldn't get the uc_payment.js hack working.

I have Credit Card, COD and Method Fee payment methods enabled. At checkout, when it comes to the 'Payment Method', only one method can be selected. It is supposed, as configured under 'Method Fee settings' at 'Payment Methods', that a certain price must be applied when COD is selected ('The fee value for payment method: cod: ...). If I choose COD at checkout, I get the correct fee at the review order screen, however -if I select Method Fee-, no payment method at the review order screen seems to have been applied.

Has anyone tested this contribution with the current Übercart's version?

Thanks =)

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

The discriptiont text says something like 'don't display this as a payment method', please uncheck Method Fee as a payment method.

I should review the module, it shouldn't be available as a payment method.

Since no one seemed to need this module (except you now), I did not care much about it.

Regards,

Kees

Posts: 304
Joined: 11/19/2007
Bug FinderGetting busy with the Ubercode.

I posted some code for testing at...
http://www.ubercart.org/contrib/2184
which should add the ability to associate fees or discounts with payment methods.

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

Can't we combine efforts here?

Posts: 304
Joined: 11/19/2007
Bug FinderGetting busy with the Ubercode.

Yeah, that would be cool. I'm running into some problems that you might have already dealt with and taken care of, like how to represent these discounts/fees during the checkout process.

I downloaded your contrib, but I wanted to try to implement something that was simpler to use on the admin side. Instead of creating a new module, I hacked up the existing payment module but tried to keep things straight forward enough that it might be added into core eventually.

If you get a chance could you take a look at what I did? I think we should be able to look at different aspects of our code and come up with a nice solution for this issue.

Posts: 181
Joined: 08/13/2007
Cool profile pic award.Getting busy with the Ubercode.Internationalizationizer

OK, lets do that. Have you looked at 'mine', and do you have suggestions on what to combine?

Posts: 304
Joined: 11/19/2007
Bug FinderGetting busy with the Ubercode.

Ryan has taken some of the code that I wrote, meant to be added to core, and put together a nice contrib module that adds payment method fees/discounts. If anyone wants to test it out and post any issues/suggestions you can find it at http://www.ubercart.org/contrib/2184