The Foxy forums are on the move!

We're in the process of moving our forums over to a new system, and so these forums are now read-only.
If you have a question about your store in the meantime, please don't hesitate to reach out to us via email.

Shipping price / service manipulation

oskayoskay Member
in Bugs & Feature Requests edited December 2010
We just had an order come in for a large/heavy object, with the shipping service selected as "USPS Express Mail International Flat Rate Envelope."

Our custom checkout javascript does disable this shipping option for large/heavy objects. However, it appears that the customer managed to place the order that way despite our javascript.

Now, I know that javascript "hacks" are not officially supported, but perhaps you can help me determine whether this is a bug or willful fraud-- so I should know whether to ship or cancel the order.

The specifics: We're using a variation on the "Free Shipping on orders over 199.00" code to jquery hide/show different shipping options based on different criteria. It is stable code that works extremely well; it hides and shows different options and allows us to offer (amongst other things) free shipping under certain circumstances.

I have checked the cart contents on this order (all OK) and tried to replicate the situation. It only offers me the correct shipping choices-- the ones that are supposed to be hidden are hidden. So, when jquery .hide() and .show() operations are used, is this something that the user can just override? Apparently the answer is yes. But if/when this happens, is it something that happens accidentally, or is it something that requires a user to willfully manipulate? If it can happen here, I must assume that it's possible for anyone to select free shipping on any order.

Related: I'm curious what browser was being used for the transaction. A pity that there's so little data available for a successful transaction as compared to one where there's an error.
Comments
  • fc_adamfc_adam FoxyCart Team
    Hey oskay,

    Could you let us know which order number this order is?
  • (Replied via whisper.)
  • brettbrett FoxyCart Team
    Related: I'm curious what browser was being used for the transaction. A pity that there's so little data available for a successful transaction as compared to one where there's an error.
    Yeah... That's occurred to me in fleeting thoughts before, but I'm glad you verbalized it. We'll ticket that, as it'd be really good data to collect.
  • I wrote to the customer about this, and his reply indicated that it was just one of the options presented. If that's really true (for some set of browsers out there) then all of these hide/show kinds of actions are actually quite vulnerable. Do you have any thoughts on this Brett?
  • brettbrett FoxyCart Team
    @fc_adam would be the best person to take a look, but there could be _something_ that would cause the javascript not to fire. If that's the case perhaps you could set it on a setInterval or something to make sure it runs (which Adam could help with).

    We're working on improving all this stuff so those shipping customizations would be server-side, so it'd be way more locked down. At this point though... let's let Adam take a look to see if he sees anything.
  • fc_adamfc_adam FoxyCart Team
    oskay, did you ask your user what browser they were running? I've looked over the code and didn't see anything obvious, but Brett's thought is probably the likeliest, that there was a javascript error preventing it running.
  • I don't think that it's fair to identify this as a "javascript error." It's a CSS issue. A simple CSS override, for example if the customer is elderly and has their own large-typeface stylesheet, would do the trick.

    I can override any of these javascript "hide" methods in FireFox by just choosing View>Page Style>No Style. Ugh.
  • fc_adamfc_adam FoxyCart Team
    @oskay, in terms of it happening without any interaction with the customer, it would be a javascript issue most likely that causes that. If the customer knew you were doing javascript functionality to customise shipping, then yes, they could try to change some things manually like removing css styles to get around your setup if that's the way they were inclined.

    If you can find out what browser the customer was using, we can take a look to see if there is anything javascript-wise that may be messing up things. Your customer said that it was "just one of the options presented" - did he specify how many options were presented?
  • @fc_adam
    That's not really the answer I'm looking for.

    (1) I can see now that all of these methods based on ".hide" can be easily (and even accidentally) overridden. That's good to know, but it would have been better to be up front about it, and especially to warn about it in the documentation pages that reference this kind of method. (Again, I acknowledge that the shipping hacks are unsupportable, but the documentation does reference these methods in other contexts.)

    (2) I expect that you have access to more information about this particular transaction than I do. Also, I shouldn't have to ask a customer, especially more than once, for information about their configuration.

    (3) This is a customization on our end, so it's convenient to blame us or a javascript error. But that's misdirection. Indeed, a great many of the problems that I see reported on the forums here are end-user javascript errors. But, the issue that I was asking about is real and universal when CSS hide/show methods are used; it doesn't take an error of any sort.
  • brettbrett FoxyCart Team
    edited December 2010
    @oskay, we're taking another look.
    #1) You said it's stable code that works extremely well, but obviously it didn't run here. And yes, while we technically say they're unsupported you can see that we do quite a lot of support on them. But we are working on rebuilding shipping to make it much more robust.

    #2) Yes, but unfortunately it's not always immediately available, and not everybody on our team has access to the server logs which is where we may have to look. (At the moment I'm not on a computer that can connect to our APP environment to check the logs, but one of us will take a look there when we can.) Also, as you noted above and we've already ticketed, we'll need to collect a little more browser info on successful transactions like we do with errors.

    #3) The showing/hiding is done with js, so that's why we think it's a js issue. It's not CSS, since you don't have any CSS hiding the options; only the jQuery .hide(). Given that it looks like a javascript issue, a js error is hands down the most likely cause, hence Adam's questioning about that. But in this situation ... not sure. A real js error is unlikely given your track record with running a tight ship and being on top of things. Also, you'd know if you changed things. (Many users don't, unfortunately.) Adam's not trying to put the blame on you, but (to me too, at least) it definitely looks like whatever went wrong went wrong in the js.

    So, all that said, I think it's exceedingly unlikely that this was caused by any sort of intentional tampering by the customer. What makes more sense to me is that your custom shipping function (which I'm guessing one of us helped you create at some point ages ago) didn't get fired on the ajaxComplete. Why it didn't get called I'm not sure. The shipping rate request clearly was made, but your myCustomShipping() wasn't called, which means jQuery apparently didn't fire ajaxComplete().

    Here's what I'm seeing. Correct me if I'm misunderstanding what's going on.
    * On ajaxComplete, all possible all international and the "free ground" shipping options are hidden.
    * If the subtotal is > 75, you show the free ground option.
    * Based on optional product options called Sizecode you show others (for international).
    * I'm not entirely sure how you're handing US shipping. You have Priority and Express (PO) displaying regardless and don't use the sizecode?

    In this case, the product should have defaulted to a sizecode = 1000, which would have _not_ shown anything but one of the options (and _not_ the Envelope option that was selected). That's not what happened though. And I'm not sure why other than ajaxComplete wasn't triggered by jQuery. One possibility is that the ajax request to get the shipping rates returned a 404 or something (as I think that will _not_ trigger ajaxComplete). We'll dig through the logs for the customer's IP to see if there were any weird requests.

    Beyond that, the next steps would be to determine if you want to take preventative measures now or wait for us to dig in a little more. One thought in terms of recommended "fixes" would be to move the hiding of the #fc_shipping_methods_inner label elements to CSS in addition to doing it by js in your myCustomShipping() function. That'd kind of force the function to be required. So if ajaxComplete doesn't get called again, you're not relying on myCustomShipping() to hide the radio buttons, but rather the CSS (which should be pretty bulletproof, at least against accidental issues). The downside is that if this happens again for whatever reason there wouldn't be any options available at all, which isn't good either. Though we could perhaps work something up to work around that.

    So, we'll look at the logs a bit. If you want to wait for us to figure that out before you take action, cool. If you want to move quickly to try to make your myCustomShipping() a little more robust we could do that too.
  • lukeluke FoxyCart Team
    Hey oskay. I'm sorry for your frustration on this one and we will do what we can to help but I do want to be clear that when we say something is unsupported, we're trying to set the expectation that it really is "unsupported". With a high enough order volume, it's not uncommon for most eCommerce systems to have a screwy order now and again which needs to be handled via direct interaction with the customer. In all my years of eCommerce experience ranging from systems costing tens of thousands of dollars, to $19 a month there always seems to be an issue now and again that has to be dealt with manually. The easiest solution is to void the order and place a new one correctly while on the phone with the customer explaining the situation.

    We're definitely interested to continue the discussion for this order so we can improve the hacks we have (if there's an obvious, reproducible problem), but in order to serve your customer quickly, you may be better off placing a new order and voiding the old one. UOE may help in this regard as well. As for spending too much time tracking down a bug that we can't reproduce... that time might be better spent on our current goals to improve shipping so there won't be a need for "unsupported" javascript tweaks.
  • brettbrett FoxyCart Team
    Looks like the user was IE8 on Vista. I'm not seeing any 404s though, so I'm not sure why jQuery wouldn't have fired the ajaxComplete. Let me know your response to my earlier post and we can further discuss depending on how you'd like to proceed.
  • #1) You said it's stable code that works extremely well, but obviously it didn't run here.

    That's not obvious, at all, and I'm not sure how you jump to that conclusion. Yes, it's possible that the script didn't execute for some reason. But it's also possible that this issue is completely unrelated to javascript. I also know that it's possible to (even accidentally) override all of these methods, without malice.

    But we are working on rebuilding shipping to make it much more robust.

    Truly appreciated.

    #2) Yes, but unfortunately it's not always immediately available, and not everybody on our team has access to the server logs which is where we may have to look.

    Understood. Still, I think that it would be more appropriate for you folks to check on basics like these through backchannels than to ask me to ask the customer for more information, especially after having asked them once.

    #3) The showing/hiding is done with js, so that's why we think it's a js issue. It's not CSS, since you don't have any CSS hiding the options; only the jQuery .hide().

    I'm no expert in CSS or js. But I do know that it's 100% possible to reproduce this issue by overriding styles alone. That is, it is obvious (to me) that no js error is required. It also appears as though the jQuery .hide() command works through a style at a low level, since its effect can be overridden through styles.

    Here's what I'm seeing. Correct me if I'm misunderstanding what's going on.

    Yes, you've got the gist of it. But, I don't see any reason for you to spend time debugging my javascript (I'd rather you spend time on deeper solutions!). It's not relevant to the actual problem, and I was quite clear up front in acknowledging that customer-code is (rightly so) unsupportable. Also, so long as your proposed solutions are still CSS based, they're obviously still vulnerable in the same way.
  • Hey oskay. I'm sorry for your frustration on this one and we will do what we can to help but I do want to be clear that when we say something is unsupported, we're trying to set the expectation that it really is "unsupported".

    Fully acknowledged. However, in this particular case, it looks like you might want to go out of your way to recommend that people *do not* use this particular method, because it's very thin ice. Or at least, to advise people to double-check shipping costs on orders when these methods are used.
  • brettbrett FoxyCart Team
    #1) You said it's stable code that works extremely well, but obviously it didn't run here.
    That's not obvious, at all, and I'm not sure how you jump to that conclusion. Yes, it's possible that the script didn't execute for some reason. But it's also possible that this issue is completely unrelated to javascript. I also know that it's possible to (even accidentally) override all of these methods, without malice.

    I'll try to clarify. The way it is now is using javascript to hide elements _after_ they're shown. If the js doesn't fire (which I believe is what happened here), they're still shown. If we were to reverse that and have the elements hidden by CSS by default, then shown by js, if the js didn't run then the elements would still be hidden.

    Since the shipping option was indeed shown and selected by the user, the FoxyCart AJAX worked. Since the custom javascript is the _only_ thing that'd hide the element after that point, and since it wasn't hidden, my conclusion is that it didn't run at all. Could something else have happened? Definitely, but from the code on the page, the only thing that seems likely to me is that the custom javascript didn't run for some reason.

    So the _only_ way this could happen is if it was related to javascript (imo), since the js is the only thing that's impacting what's shown and hidden. (Yes, it uses inline CSS to do the showing/hiding, but it's highly unlikely that if the jQuery show/hide worked that there'd be CSS impacting that unless it was manually and very deliberately added.)

    So that's why I believe it's related to the script just not running, or perhaps running at the wrong time. Or something. But that's why I came to the conclusion I did.

    But I could definitely be wrong. ;)
  • Since the shipping option was indeed shown and selected by the user, the FoxyCart AJAX worked. Since the custom javascript is the _only_ thing that'd hide the element after that point, and since it wasn't hidden, my conclusion is that it didn't run at all. Could something else have happened? Definitely, but from the code on the page, the only thing that seems likely to me is that the custom javascript didn't run for some reason.

    Please ignore that particular order and listen to what I've been saying: In Firefox, select View>Page Style>No Style. (Or, disable styles in Safari.) Javascripts still work just fine, only the hide and show methods simply have no effect. Look at your own checkout page, and recognize that this is the case.

    Now, realizing that, wouldn't you agree that a shipping script that selectively hides and shows "free ground shipping" (via .hide/.show) will always leave that option available to anyone who has disabled or overridden CSS for accessibility reasons? The AJAX works *beautifully* but options hidden (via .hide/.show) are always visible. (Well, actually it's rather ugly without the CSS, but the scripts still work beautifully.)

    So, for (hopefully) the last time: no error of any sort is needed to explain what's happened here.


    Now, to your point: "my conclusion is that it didn't run at all." That's not certain, but I acknowledge that it is possible. If somehow, the page loaded enough that the main checkout javascript completed successfully -- and it did, or it wouldn't have been able to output the list of international shipping options --and yet not enough to load our ajaxComplete script. But even if so, that's just a freak error that happened to bring my attention to the primary issue here.
  • brettbrett FoxyCart Team
    Yes, if you disable _all_ styles then indeed the javascript added style="display:none" attributes don't do anything. To be entirely honest, I didn't even know that was an option. I'm familiar with testing without stylesheets, but disabling even inline styles isn't something I've ever really been aware of.

    I don't _think_ anybody would do that for accessibility reasons, since I dont' think it'd make for a more accessible experience except for the most atrocious sites to begin with. But you're right, it's certainly a possibility.

    In that light, you could easily replace the .hide() with .remove() and you'd avoid that problem without causing any additional problems. Thanks for hammering that point home and making me understand what you were talking about.
Sign In or Register to comment.