-
How can I "do something" after a successful PPE order?
This may not be the best place to ask this, but I'll try here first.
When an order is placed and it is successful, the order is taken from Pending to Processing automagically whether or not I'm logged in to see it (if a tree falls in the for forest...)
How can I get I add to the functionality at that stage?
Basically I want to trigger some other code at that point in time. So when a successful order comes in, do "this". How do I hook into that event, so to speak?
Clues?
-
Re: How can I "do something" after a successful PPE order?
I'm thinking it has something to do with $zco_notifier->notify('NOTIFY_, but which one?
I'm digging now, so really this is just a "if you happen to know, tell me" kind of Q :)
-
Re: How can I "do something" after a successful PPE order?
At what point in the overall checkout process do you want to do something, what is the something you want to do (more importantly what data at or after that point do you need. Also for what version(s) of ZC are you developing for?
-
Re: How can I "do something" after a successful PPE order?
Hi MC. Thanks for the reply.
The point I'm after is "success"... the point where the order is considered complete and paid for.
The something I want to do is automatically send the shipping details to the shipping service API. Data I need are the order details (specifically: delivery address, phone number, model and quantities of cart items, shipping service, amount paid for shipping, currency used, order number. I think that's it)
ZC 1.5.4
-
Re: How can I "do something" after a successful PPE order?
So here's what I've done so far:
/includes/auto_loaders/config.myProcessor.php
Code:
<?php
$autoLoadConfig[10][] = array('autoType'=>'class',
'loadFile'=> 'observers/class.myProcessor.php');
$autoLoadConfig[180][] = array('autoType'=>'classInstantiate',
'className'=>'myProcessor',
'objectName'=>'myProcessor');
?>
/includes/classes/observers/class.myProcessor.php
Code:
<?php
class myProcessorextends base {
function __construct() {
$this->attach($this, array('NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES'));
}
function update(&$class, $eventID, $paramsArray = array())
{
if ($eventID == 'NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES')
{
//DO SOMETHING
}
}
}
It seems to be working. What I'm not sure on is if "NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES" is appropriate (I used it because it appeared to be around the right place in the code for tapping in) and I'm especially unsure on the values I used for autloading (10 and 180). I went with 10 because the wiki used that for its example and I used 180 because PayPal uses up to 170 in paypal_ipn.core.php but really I don't understand it enough to say that was an informed guess.
-
Re: How can I "do something" after a successful PPE order?
as far as the "do something", that would be a SOAP exchange with the shipper's service as per their API and, upon receiving success, updating the order in the DP from 'processing' to 'shipped' and sending out an email. My next step is to make a cron-job that periodically poles the shipper's servers for tracking numbers (they aren't immediately available) and sending them to the customer when it is available. I'll either need a new DB table for that, or (perhaps simpler) add a status in between "processing" and "shipped".
I hope to eventually also cron up a summary / audit system so the admin can be notified with info such as amount customer paid for shipping vs. amount we were ultimately charged (that too isn't known right away)
Fun stuff.
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
s_mack
The point I'm after is "success"... the point where the order is considered complete and paid for.
NOTIFY_HEADER_START_CHECKOUT_SUCCESS
... is one suitable hook. I know there are others.
This is the one I use in the ec_analytics module to trigger/send the transaction details of a sale to the Google servers, which is pretty much a similar thing to what you are wanting to do.
Cheers
Rod
-
Re: How can I "do something" after a successful PPE order?
Ahh, I think I saw that but when I read "Start Checkout Success" I mistook as meaning the checkout process started successfully (ie. right after they click "checkout" in their cart). Thanks.
-
Re: How can I "do something" after a successful PPE order?
I was also possibly going to suggest: NOTIFY_ORDER_AFTER_SEND_ORDER_EMAIL as a possibility, though it is "further" down the line in order processing.
As for the trigger points of 10 and 180... There's a bit of various direction... In some cases it appears that it should be something like 0 and 199+, but then in ZC 1.5.3 there is a new auto load observer that loads at 175, and then there is the suggestion that none should be less than 199 without good reason (which means need to know and understand when to use which)... Don't see a problem with what has been used per se. And for the most part as long as it works. :)
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
RodG
NOTIFY_HEADER_START_CHECKOUT_SUCCESS
... is one suitable hook. I know there are others.
This is the one I use in the ec_analytics module to trigger/send the transaction details of a sale to the Google servers, which is pretty much a similar thing to what you are wanting to do.
Cheers
Rod
I'd lean more towards a notifier within the checkout_process path. The checkout_success page can be refreshed, resulting in your processing being re-run.
-
Re: How can I "do something" after a successful PPE order?
OOOHhh... OK, so the last bit of the constant, is that the page name? That makes sense. I was reading it more as a description of the event. So when we're talking about NOTIFY_HEADER_START_CHECKOUT_SUCCESS, is that saying "I'm notifying that the header for checkout_success has started"?
Perhaps not though, because what page would the one I chose relate to?
NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES
I chose that one because I figured that any code relating to handling affiliates, which is normally determined on actual sales, that it would be least likely to be affected by reloads and such.
Thanks for help and suggestions folks.
-
Re: How can I "do something" after a successful PPE order?
The notifier constants are just that -- string constants. You can normally infer the page (or class) from which they're issued by the name ... but not always.
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
lat9
I'd lean more towards a notifier within the checkout_process path. The checkout_success page can be refreshed, resulting in your processing being re-run.
Good point. This potential problem is/was mitigated in the ec_analytics module via a test of one of the session variables (that gets unset after the 1st page load).
Cheers
RodG
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
s_mack
So when we're talking about NOTIFY_HEADER_START_CHECKOUT_SUCCESS, is that saying "I'm notifying that the header for checkout_success has started"?.
Correct.
Quote:
Originally Posted by
s_mack
NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES
I chose that one because I figured that any code relating to handling affiliates, which is normally determined on actual sales, that it would be least likely to be affected by reloads and such.
Thanks for help and suggestions folks.
OK, so I haven't done a complete analysis of the program flow through all the checkout variances, but having just taken a quick review of things, the notifier you chose is probably a better option than the one I chose for ec_analytics.
I suspect that I never even considered this option under the assumption it would only be triggered for affiliate related sales and not for *all* sales.
FWIW, you/we don't need to limit ourselves to using these pre-defined hooks, it is actually quite a trivial task to create and use our own in pretty much any place in the ZenCart code, for almost any purpose. Alas, for this to work does require a very minor change to the existing code to add the 'hook', and in my opinion this defeats the most significant reason for using the notifiers in the 1st place.
On a slightly different note:
Does anyone here know of any reason, circumstance or situation where the checkout success page *wouldn't* be loaded (after a successful checkout)? The reason I ask is because I've had the rare report that not all sales are being tracked by the ec module (I've not been able to confirm or replicate) - and about the only cause I can think of is if this success page is somehow being bypassed or skipped.
If this theoretically possible?
Cheers
RodG
-
Re: How can I "do something" after a successful PPE order?
Over the years, with just the stock checkout, I've had a few extremely rare cases (maybe 3 in 10,000) where a payment went through but the order was never recorded. I don't know if that would coincide with what your users experienced but thought I'd mention it.
So adding hooks is really as simple as just placing a $zco_notifier->notify('WHATEVER'); where convenient for us? I figured each hook was actually registered somewhere but I never really looked.
I *try* to avoid core over-writes as much as possible. I really appreciate the idea behind the overrides, observers, etc... but the fact is no matter how hard I try I always end up extensively modding the core. In practice, the overrides system is limited. It would be greatly enhanced if "pages" could be overridden, and also functions (or, if functions were held to a stricter standard of not including any html output).
Of course, that's off topic.
This topic, we can consider closed from my perspective. They way I did it in post #5 is working just fine. I will change the initiation (or whatever its called) from 180 to "above 199" if that's considered good form. I don't think it makes a difference for my purposes.
Thanks for the assistance and tips, folks.
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
s_mack
...
I *try* to avoid core over-writes as much as possible. I really appreciate the idea behind the overrides, observers, etc... but the fact is no matter how hard I try I always end up extensively modding the core. In practice, the overrides system is limited. It would be greatly enhanced if "pages" could be overridden, and also functions (or, if functions were held to a stricter standard of not including any html output).
...
Me too! Take RodG's advice, though: If you don't see a notifier that's placed where you need it or one that serves up the data you need, add that notifier (a 1-line change, plus comments) to the core file and then do your special processing in the observer-level code. It serves to compartmentalize the changes and makes upgrading a whole lot easier!
Never, ever modify the data payload of a built-in notifier, you'd be asking for a world of hurt when the next version of Zen Cart re-purposes that notifier with different data!
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
lat9
Never, ever modify the data payload of a built-in notifier
Can you explain what that means so I can know exactly what not to do? :)
edit: actually, I think I do know what you're referring to... so a better question is how do I know what notifiers provide what data?
-
Re: How can I "do something" after a successful PPE order?
Sorry to be obtuse! If you look at the structure of a ->notify function call (Zen Cart v1.5.2 and later), that call takes a (required) string notifier and from 1 to 9 additional parameters. The first additional parameter is a read-only value while parameters 2-9 are read/write.
I'm calling those optional parameters the payload.
Let's say that you've looked at /includes/classes/order.php and determined that you'd like to hook the notification:
Code:
$this->notify('NOTIFY_ORDER_CART_ADD_PRODUCT_LIST', array('index'=>$index, 'products'=>$products[$i]));
For whatever reason, you'd like the value of $rowClass to be included. What I'm suggesting is is that it's bad form to modify the order.php class to change that notifier to add the $rowClass value because the next version of Zen Cart might choose to update that data payload:
Code:
$this->notify('NOTIFY_ORDER_CART_ADD_PRODUCT_LIST', array('index'=>$index, 'products'=>$products[$i]), $rowClass);
Instead, since you're editing the file anyway, add a totally new notifier for your use that you control:
Code:
$this->notify('NOTIFY_ORDER_CART_ADD_PRODUCT_LIST_LAT9', array('index'=>$index, 'products'=>$products[$i]), $rowClass);
-
Re: How can I "do something" after a successful PPE order?
Crystal clear, thank you.
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
s_mack
/includes/auto_loaders/config.myProcessor.php
Code:
<?php
$autoLoadConfig[10][] = array('autoType'=>'class',
'loadFile'=> 'observers/class.myProcessor.php');
$autoLoadConfig[180][] = array('autoType'=>'classInstantiate',
'className'=>'myProcessor',
'objectName'=>'myProcessor');
?>
I'm especially unsure on the values I used for autloading (10 and 180). I went with 10 because the wiki used that for its example and I used 180 because PayPal uses up to 170 in paypal_ipn.core.php but really I don't understand it enough to say that was an informed guess.
Since the autoLoadConfig array is processed, and all its loads/requires/instantiations are executed during application_top, the actual "order" of loading your custom added observer classes is moot, save for the fact that yours should typically be above 200. The "order" is used only to ensure necessary prerequisites are handled, such as starting sessions before running init scripts that require the use of sessions, and starting the db before the db is needed, etc. That's all done below 200, and all your userland stuff should typically be done after 200. Additionally, you probably already grok this, but I'll state it to be clear: do your loadFile directive before your classInstantiate, and you're good. (And, yes, doing loadFile directives below 200 is fine, but equally fine to do above 200, as long as they're done before instantiating)
-
Re: How can I "do something" after a successful PPE order?
Also of interest might be lat9's Notifier Trace plugin: https://www.zen-cart.com/downloads.php?do=file&id=1114
-
Re: How can I "do something" after a successful PPE order?
That last bit of advice almost was perfect! I actually ran into an issue with my project. Obviously the notifier I'm using (NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES) isn't appropriate afterall because it happens BEFORE PayPal updates the database. This is important because I want to change the status to something after PayPal changes it to "processing". if I do it before, then it gets clobbered.
I initially figured since they were getting recorded in the same second that perhaps it was just random chance which one appeared first, but I threw a 2 second sleep() in there to force my function to delay... and the PayPal still came after and still shows as the same second.
I installed lat9's Notifier Trace plugin as you suggested, so I could see the order. But NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES doesn't show up in that log at all! How's that possible? I know it is firing because my code is being called properly.
-
Re: How can I "do something" after a successful PPE order?
I now see Lat9's contribution shows just a portion of the log file in the preview, so that text I was searching for wasn't showing. It is in the log itself though. I'm still unsure where I should be tapping in to achieve what I want.
-
Re: How can I "do something" after a successful PPE order?
After looking a little more carefully, I think I've settled on NOTIFY_HEADER_END_CHECKOUT_PROCESS
It gives me all the vars I need, it happens after function after_process() is called (which is what the payment modules uses to update the history), and I think it is tight enough to not have to worry about refreshes. I tried refreshing and there was no ill effect that I could see.
Does that sound right?
-
Re: How can I "do something" after a successful PPE order?
The notifier you chose (NOTIFY_HEADER_END_CHECKOUT_PROCESS) will do the trick for you:
1) It's at the absolute end of the checkout_process processing, just before the redirect to checkout_success.
2) It's not a page that is "easy" to refresh, since it's never visible in the customer's browser.
-
Re: How can I "do something" after a successful PPE order?
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
lat9
The notifier you chose (NOTIFY_HEADER_END_CHECKOUT_PROCESS) will do the trick for you:
1) It's at the absolute end of the checkout_process processing, just before the redirect to checkout_shipping.
2) It's not a page that is "easy" to refresh, since it's never visible in the customer's browser.
A possible downside to using this notifier rather than NOTIFY_HEADER_START_CHECKOUT_PROCESS (both are in the same file) is that many of the session variables are cleared before the END_CHECKOUT is called - These variables could be useful/needed by whatever the new code is designed to do.
BTW, nice discussion going on here. These notifiers can be *so* useful for so many different things I'm surprised that there haven't been more discussions about them. For what they can be used for they seem to be so under utilised, and I suspect that part of this is because although quite well documented there hasn't been enough talk about all the possibilities and options available.
I think it needs a discussion like this to pique the interest of more developers that are still doing things the 'old' way of hacking into core code when it's no longer really necessary.
Cheers
RodG
-
Re: How can I "do something" after a successful PPE order?
Could take from both or a combinatiion. The "earlier" one to gather the session data that is then deleted later (and not otherwise retrievable), the later one to use the previous session data if it is not already captured/transferred to something else useful. This way the information is gathered as necessary/when available and used when desired...
In a way, the worst thing that happens regarding the retriggering action is that the data is set again to what it already was... Meanwhile the "action" waits to observe the call to the notifier that is not "easy" to refresh...
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
mc12345678
Could take from both or a combination. The "earlier" one to gather the session data that is then deleted later (and not otherwise retrievable),
Not really possible. Anything of use saved in the session data will always be available by other means at another time via other methods (generally a DB query).
Quote:
Originally Posted by
mc12345678
the later one to use the previous session data if it is not already captured/transferred to something else useful. This way the information is gathered as necessary/when available and used when desired...
I think you are way over complicating things with this approach.
Quote:
Originally Posted by
mc12345678
In a way, the worst thing that happens regarding the retriggering action is that the data is set again to what it already was... Meanwhile the "action" waits to observe the call to the notifier that is not "easy" to refresh...
The earlier notifier has all the session data needed for most purposes. What it doesn't have would need to be obtained via other means anyway.
The later notifier will require a DB lookup for any data needed for the additional code (assuming all the sessions have been nullified).
The 1st notifier does run the risk of multiple triggering if/when the page is reloaded, but this will be a trivial task to mitigate (see the ec_commerce module).
Rather than trying to 'take from both' I reckon it would be better to ask the question "Is everything I need available from the session data, or do I need to perform a DB lookup.
If the former, then the 1st notifier and a test to page refreshes would (IMO) be the easiest to use, and the most efficient code wise.
If the latter, then since a DB query is going to be needed anyway, then use the last notifier and not have to worry about the page being refreshed.
I really don't see the point of 'taking from both'.
Perhaps I'm missing some important point you are trying to make here? (No offence, but even after all this time I still have a hard time trying to 'decode' many things that you write) <g> Seriously, more often than not, you're right on the money - it is just sometimes hard to see. I think this may be one of those times.
Cheers
RodG
-
Re: How can I "do something" after a successful PPE order?
The concept of "taking from both" is sound ... as in it's allowed. But it isn't always necessary.
One's observer class could certainly listen to multiple notifier hooks, and take action on each, including progressively building up a collection of data in a class variable which is used later in the workflow.
But for s_mack's current application I think using more than one is probably overkill. I agree with lat9's summary:
Quote:
Originally Posted by
lat9
The notifier you chose (NOTIFY_HEADER_END_CHECKOUT_PROCESS) will do the trick for you:
1) It's at the absolute end of the checkout_process processing, just before the redirect to checkout_success.
2) It's not a page that is "easy" to refresh, since it's never visible in the customer's browser.
-
Re: How can I "do something" after a successful PPE order?
I thought you guys were continuing the discussion on a theoretical basis, but if there's still concern for my application (thank you) I had it working @ post 24 above.
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
s_mack
After looking a little more carefully, I think I've settled on NOTIFY_HEADER_END_CHECKOUT_PROCESS
It gives me all the vars I need, it happens after function after_process() is called (which is what the payment modules uses to update the history), and I think it is tight enough to not have to worry about refreshes. I tried refreshing and there was no ill effect that I could see.
Does that sound right?
Quote:
Originally Posted by
lat9
The notifier you chose (NOTIFY_HEADER_END_CHECKOUT_PROCESS) will do the trick for you:
1) It's at the absolute end of the checkout_process processing, just before the redirect to checkout_success.
2) It's not a page that is "easy" to refresh, since it's never visible in the customer's browser.
Thanks to both of you, your suggestions have helped me to implement something similar on one of my local dev sites.
-
Re: How can I "do something" after a successful PPE order?
Quote:
Originally Posted by
s_mack
I thought you guys were continuing the discussion on a theoretical basis
I was/am.
Mainly to get ideas - whether they be sound, practical, efficient, best for purpose, or whatever. It's all good IMO.
I see as a result of this thread we already have one person (frank8) that has taken the idea(s) to do something on his own site(s) -
Something that may possibly never have eventuated otherwise.
The choice of HEADER_START or HEADER_END (or both) is certainly going to be dependent on what is needed and what data is available for that need, and with all that is currently known, I too would say that you have made the right choice for your purpose. I might even go as far to say that I may have made the wrong choice for the purpose of the ec_commerce module.
As a result of this discussion, Frank, and others that follow, have the benefit that neither you or I had when we started our projects - We've covered three possible notifiers (and a combination of them) that *could* be used for a purpose, and we've revealed the benefits and pitfalls for each, and the one instance that wasn't a good choice for the need (the NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES).
It has been (and is) a good discussion even though the initial 'problem' has been solved.
Cheers
RodG
-
Re: How can I "do something" after a successful PPE order?
Agreed Rod. I just wanted to be clear that I wasn't still waiting for help :)