Jump to content

So I'm developing an addon for selling physical products.


Nathron

Recommended Posts

Well I needed this functionality it's very basic just tax subtotal and basic shipping leveraging fedex and ups remote api. Also added further descriptions to configurable options that show on the product page. Got my shipping pricing showing on the configure page but when going to the cart it doesn't show up. Which I kinda expected anyway so since my shipping calculator populates a select I just gave it a name and figured I'd go ahead and have a second hook for pulling the post from that control into a smarty variable from there I would write a little javascript like I did on the previous page and update the total price. Then on checkout itself I may have to do a little behind the scenes magic to get it posting the new price rather than the one in the db. Anyway it was when I was trying to grab the post variable that I kinda got a little miffed. Mostly because when moving from one cart page to another it posts originally as expected then refreshes twice. Ergo the post variable is gone before I can capture it. Needless to say that's annoying as all get out. Also to get my javascript to play nice and be able to build a proper json array for the descriptions I ripped out the entirety of the {if $configurableoptions}{/endif} and re-wrote the entire thing in my hook as pure php that returns a string to a smarty variable with the output. That works great and keeps me from putting my entire context array into smarty when I don't need it on every page. Aside from that theirs a bit more data replication in there than I realized so half the time I don't need many of the variables. Although I did use it extensively in the admin portion of my code.

 

Either way that leaves me with the issue of getting my posted data into smarty somehow when the hook is hit the data no longer exists... which kinda makes me a sad panda. I suppose I could just slap it into the client area global hook and see if I can catch it there in some kind of.

 

if(!empty($_POST['shipping'])){
$smarty->assign('shipping',$_POST['shipping']);
}

 

That way if the page gets re-posted and the variable is empty it will have already been passed to smarty. As for the normal isset call that you would usually do there I noticed WHMCS doesn't propagate object errors to Apache error log anyway. So I'm omitting it perhaps theirs a setting to do that but I haven't found it. In any case I'll attempt to move that to the global hook but beyond this I don't know what to do to grab the variable before the page gets refreshed and blamo it's gone.

Link to comment
Share on other sites

Well I wrote a function to take my shipping variable and add it to the total it works even with tax on viewcart.tpl I registered the function in my hook so I have access to all the smarty variables during execution. When going to process the payment though it doesn't reflect my new price.

 

function get_new_total($params, &$smarty){
$result = preg_match('/[0-9]*\.[0-9]*|[0-9]*\,[0-9]*|\d+\b/i', $params['oldtotal'], $match);
if(!$result){
$retval = "There was an error parsing your regex again what a suprise!";
} else {
$tmptotal = $match[0] + $params['shipping'];
$retval = preg_replace('/[0-9]*\.[0-9]*|[0-9]*\,[0-9]*|\d+\b/i',number_format($tmptotal,2),$params['oldtotal']);
$smarty->_tpl_vars['rawtotal'] = number_format($tmptotal,2);
}
return $retval;

 

What is the procedure for overriding the product price? Can I get the current order information and send it via api, If I send the information via api will it still go through the entire payment process from step 3? I would really appreciate this bit of help from somebody that knows what's going on with it. Can I just override a different smarty variable. Or is the payment process pulling from the database. Would I need to update the product in the pricing table then reset it on order completion hook?

Link to comment
Share on other sites

Well got mostly through the process I did decide to use the api as I couldn't find another way to inject a price override which would be fine if it actually worked. Either way got my cart showing my shipping values got the individual products showing my additional descriptions in an optional more info window you know three to four images and a bullet list or short paragraph describing the features of the product/configurable option. Really am entirely happy with that portion I now have my addclient call working fine if the client isn't logged in under something call addclient. Although at some point I'll probably do a dbquery to match currently entered fields with existing customers so as to not have duplicates.

 

Anyway my calls are structured as follows.

 

function hook_inject_payment_process($vars){
global $smarty;
$products = $vars['products'];
$paymentmethod = $vars['paymentmethod'];
//print_r($vars);
if(!$_SESSION['uid']){
$values = $smarty->_tpl_vars['clientsdetails'];
$values['currency'] = $smarty->_tpl_vars['currency']['id'];
$command = "$addclient";
$adminuser = "apiadmin";
$results = localAPI($command, $values, $adminuser);
if($results['result'] == "success"){
$uid = $results['message'];
} else if ($results['result'] == "error") {
$error = $results['message'];
print_r($results);
}
} else {
$uid = $_SESSION['uid'];
}

//All above this line works fine... basically it just grabs a user id or makes one if its not available based on what was entered in //the checkout page.
$values['clientid'] = $uid;
$values['domain'][] = '';
//Get my new total just pulls from my math function that displays the total on the cart page.
$values['priceoverride'] = $_SESSION['newtotal'];
//Remove the session variable so it's not used once and stays lodged in memory.
unset($_SESSION['newtotal']);
foreach($products as $product){
$values['pid'][] = $product['pid'];
$values['billingcycle'][] = $product['billingcycle'];
//Looked at configoptions the definition is already formatted properly so encode and slap it into values.
$values['configoption'][] = base64_encode(serialize($product['configoptions']));
}
$values['paymentmethod'] = $paymentmethod;
doAddOrder($values);
}

function doAddOrder($values){
$command = "addorder";
$adminuser = "apiadmin";
//For some reason this call loops about 20 times before soaking up any available memory and crashing php... When printing my //passed value array it returns only 1 array not 20. Of varying length depending on the amount of products. So what's the deal //did I forget a requried argument? Is their something wrong with the way I'm putting the array together? The way I did was //taken directly from the docs. Some of it was educated guessing because the docs are sparse for multiple products.
$results = localAPI($command,$values,$adminuser);
if($results['result'] == "success"){
echo 'success'.$results['message'];
} else if($results['result'] == "error"){
echo 'fail'.$results['message'];
}
}

 

Any guesses? Seriously if I print the results of the api call it just regurgitates my request 20+ times and causes a memory overflow. Id understand if my function was printing that much data but it isn't even with several products it's a very short array. No way that it soaks up 128 256 or even 512 megabytes. Yes I tried to see just how much data it was trying to process. Either way it just prints my request 20 times with different base64_encode value?.

Link to comment
Share on other sites

Well it's done finally well functional anyway still lacking a bit of polish (The code is ugly) and I wanted to do billable weight based on selected configurable options. I know how to do this it's simple since I already have the db-tables/columns set up. Once I finish optimizing it I may release it or I might not depending on how I feel about the thing. Had a couple things in there I wasn't really wanting to have. Setting session variables to pass between cart steps since the flow isn't as linear as it looks. Cleaned all that garbage up though on checking out through my fowardcart.tpl clone. Loaded the payment gateway using variable includes. Executed the link function by doing the same and trial and error to find out what variables everything needs. Now it mirrors the end user experience exactly from my customized order form. Leaves the initial form alone for un-modified products. Need to add a db query to the install/remove function to add an empty link custom field for each of the shipping products. So far have 89 shipping methods. More to come with DHL and UPS. Even considered making everything class based and oop then creating a mini-modification api. Much like the gateway addons for whmcs itself. Since basically shipping modules just have a few things in common they take the clientdetails from whmcs and weight information from my module. Return an array of rates like.

$rate['code'] The carrier code

$rate['description'] The description which is name cost shown as currency estimated time of delivery(All this info is available in the request response.)

$rate['cost'] Plain 2 decimal terminated number representing cost

$rate['name'] Human readable name

 

Array merged those badboys together created a dropdown that calls an ajax request or simply posts to a=view to update the cart. Template takes the value from $smarty.post.shipping and displays it if it's set runs it through a regex function to combine total and new shipping together displays the result.

 

The invoice shows shipping method as a separate product depending on which is selected. All of them are hidden products with 0 price created on module install in their own hidden group.

 

Then mirror the checkout functionality two tpl files one with redirect one without depending on settings. Return to the checkout confirm page that has a reference to our manually created invoice.

 

I guess I could create a custom invoice that takes the shipping product and moves it into a row like tax but I may do that later. Just happy it wasn't a waste of time trying to do this.

 

Then I guess I need to let recurring billing work on shipables for monthly payment plans people with good credit etc.

Edited by Nathron
Link to comment
Share on other sites

  • 2 weeks later...
  • 1 month later...

Yes another +1 for WHMCS to be able to support physical products (shipping) charges. If anyone out there has something I can use NOW, or any idea about a workaround, please let me know. I'm being HAMMERED by my boss for choosing WHMCS as a billing solution for our SaaS product because we also sell hardware and without a way to calculate shipping I'm DEAD.

Link to comment
Share on other sites

  • 7 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated