Hello,
When performing an order, using Paypal or Check method, the module acts as if the order was complete. So when the user goes to his account, in the Product Keys section, a Key is associated to the product and so visible.
The e-mail containing the key is not sent because the order is pending but the user can see his key in My Account.
I used Paypal and when the status is "PayPal pending" the Key is visible an associated to the user.
With the Check method, after confirming the order (so the check is not received by the store) the Key is also visible.
It looks like the "COD payment" issue but its status is "won't fix" so I posted here.
Could anyone help me or explain me if I'm wrong please ?
| Comment | File | Size | Author |
|---|---|---|---|
| #13 | uc_product_keys_for_paypal-6.x-1.0.tar_.gz | 595 bytes | nicolasb_cdip |
Comments
Comment #1
freixas commentedYes, I agree this sounds like the "COD payment" issue.
Perhaps there is a way to fix this. The question is: when do you give the user the product key? My answer so far has been: when the order is completed. This is because I've been thinking of the order process mostly in terms of checkout.
In another bug report, someone pointed out that admin-created orders never issued a product key. Again, this was because I was just thinking of checkout, rather than thinking of the entire life-cycle of the order.
I fixed the admin orders by issuing keys to any product order where the order state transitions from anything to 'completed' AND the order currently has no product keys associated with it.
So I've removed the hook_order_complete() function and now handle everything with hook_order(). Product keys are issued IF the order is transitioning to payment_received OR completed AND the order has no associated product keys.
In theory, this should fix your problem and even the COD problem. Could you test out the dev release dated 3/5/10 or later and see if your problem is fixed (and no new ones cropped up)? Let me know what you find.
Comment #2
freixas commentedComment #3
nicolasb_cdip commentedHello and thanks for your answer !
I have just installed the last dev release and things are a little different. So here is what happen in the two payment method I tested :
Check :
Pending -> nothing (OK)
Payment received -> Key visible in My account (OK)
Completed -> nothing new (should be sending an e-mail with the key)
Paypal :
Paypal Pending -> Key visible in My account (should not be visible)
Payment received -> nothing new (key should be visible now)
Completed -> nothing new (should be sending an e-mail with the key)
So with the Check method it's almost okay (I didn't change the conditionnal action associated). But with the Paypal method, the user shouldn't be able to see his key before the payment is defined as received.
Hope this can help.
Comment #4
freixas commentedThanks for taking the time to check this out. Your diagnostics are puzzling.
When a key is generated, the email should be sent out. So for the Check method, the key should go out when the payment is received. One question is whether you've ever got the email for any payment method. I use uc_free_payment for testing and I have a test product key with a $0.00 price. I wonder if you could install this module and see if you get the email (unless you have some other way of verifying that the email works). Perhaps you haven't set up the conditional action properly?
The PayPal method reveals some sort of problem—it could be on my side or in the PayPal payment code. It's a pain to test since I have to go set up a sandbox account. I'll check this out when I get some free time. I'm assuming you're not a programmer, but if you are, it should be easy to find the code where the order states are checked and add some debug code to find out why the PayPal payment system is prematurely assigning a product key.
Comment #5
nicolasb_cdip commentedI'm gonna perform the following tests to let you have significant results : using the beta version and the dev release and for each one Paypal method, Check and Cybermut (payment module).
I'm a programmer but I'm just starting to learn about Drupal module. I had a look on your .module file and I see where the test concerning the order status has been done. So according to your code, there is no reason it's not working well.
Does the conditionnal action need to be configured ? Because I see there is no predicate and I'm a bit confused about that. I was expecting something like "order status updated : new status = completed" as a predicate for the action "send an e-mail"
EDIT : The conditionnal action just needed to be reset, that was why after re-installing your module in dev release the e-mail action didn't work. So now when the product key appears in My Account, the e-mail is sent. Those two actions are linked as expected.
Test results are coming... ;)
---------------------------------------------------------------------------------------------------------------------
Beta version
Check :
Pending -> Key visible in My account & e-mail sent (BAD)
Payment received -> nothing new
Completed -> nothing new (key should be visible & an e-mail should be sent now)
Paypal :
Paypal Pending -> Key visible in My account & e-mail sent (BAD)
Payment received -> nothing new
Completed -> nothing new (key should be visible & an e-mail should be sent now)
Cybermut :
Pending -> can't be seen
Payment received -> Key visible in My account & e-mail sent (OK)
Completed -> nothing new
---------------------------------------------------------
Dev release
Check :
Pending -> nothing (OK)
Payment received -> Key visible in My account & e-mail sent (OK)
Completed -> nothing new (OK)
Paypal :
Paypal Pending -> Key visible in My account & e-mail sent (should not be visible & should not send e-mail)
Payment received -> nothing new (key should be visible & an e-mail should be sent now)
Completed -> nothing new
Cybermut :
Pending -> can't be seen
Payment received -> Key visible in My account & e-mail sent (OK)
Completed -> nothing new
---------------------------------------------------------------------------------------------------------------------
So as you said there might be a problem with the Paypal Payment, maybe the order status moves like "In Checkout" -> "Payment Received" -> "Paypal Pending" -> "Payment Received" ... or something like that.
I'm gonna try and see if I can fix that.
Comment #6
freixas commentedProgress!
In regards to the conditional action, here's the relevant code:
In other words, the email is sent only if some product keys are assigned.
In regards to PayPal, what I would do is go to uc_product_keys_order() and add the following debug code:
The var_dump() may screw up the checkout process, so you may want to enable it only right before you submit the order. An alternative is to use something like:
This should reveal whatever may be causing the problem. Before making any changes to the PayPal payment code, you may want to do some research to find out why they do whatever they do. One of the problems with using hook_order is that there are a lot of payment modules and they don't all use the state settings in a consistent manner. It's sometimes impossible to write code that will work with all the payment methods.
Comment #7
nicolasb_cdip commentedThanks for your help !
I used this instruction :
file_put_contents('****/trace.log', "at ".date('i:s')." -> $old_state $new_state\n", FILE_APPEND);to see when your function is called and what are the states and here is the result :
As I was expecting, the Paypal module (or just the Sandbox mode) is changing the order state twice in a normal transaction.
After submitting the form which appears after the visiting the Paypal website, the state change from in_checkout to post_checkout which is normal. Without doing anything and after a few seconds, it changed to payment_received (on the order pane : in_checkout -> Paypal pending).
I think the problem is here, the new state should be Paypal pending (the same as on the order pane).
And the last change is because in Sandbox mode we need to validate a payment, and so the state change without effect.
So I'm thinking about having a look over the "uc_order_status_data" function or maybe the Paypal module, but it seems like your module doesn't need to be fixed :)
Comment #8
freixas commentedSince you're new to Drupal/Ubercart, let me point you to a discussion of order states vs. order statuses: http://www.ubercart.org/docs/developer/920/order_states_and_statuses.
I looked at the PayPal payment module code and I see it adds a status of "paypal_pending" and matches it to state "payment_received". It also (in _uc_paypal_pending_message()) lists a number of reasons way a payment may be pending. In some cases, the payment has actually been received from the customer but requires some additional action before you can received the funds.
So why don't I just check for the "completed" state? Some payment modules don't place the order into the completed state.
To get this right, I would have to code the correct condition check for each payment method. This is not possible, but what I've done is added a hook so that people can customize the condition based on whatever payment system they have. Check the revised README.txt file for hook_uc_product_keys_order_ready(). I only did enough testing to make sure that, if no one implements the hook, the code still issued the keys the same as before.
If you've never extended a hook before, you will need to read about creating a module. The module should be pretty simple. You will need an info file and a module file. The module file will include a function called [module name]_uc_product_keys_order_ready($order, $status). I think you can get the payment system from the $order object. Since you know the payment system, you can use the order statuses added by the PayPal module in addition to looking at the states.
Let me know if you have any success using the hook to resolve your problem.
Comment #9
nicolasb_cdip commentedBefore trying to extend the hook you provide, I have made some other tests to sumarize the 3 payment method I use and their calls to your function because I wanted to "see" the difference between states and status myself. So, adding these two instructions :
I got for Cybermut :
for Check :
and for Paypal :
And it seems like if your were testing arg2 instead of $new_state, if think it should work with the Paypal module as well. Don't you think.
I understood why you didn't use a test against a "completed" state or status. But here, using the arg2 value, your test would be the same and it should take care of the Paypal situation.
What do you think about that ?
EDIT : I tried to make this change and it seems to be okay, so if you agree to add it to your dev release, I think it should handle the Paypal Payment ;)
Comment #10
freixas commentedThe reason I don't look at statuses is because of the way they are specified (see http://www.ubercart.org/docs/api/uc_order_status_list):
There is no guarantee that any particular status exists in any instance of Ubercart. Your code may work with your system, but I can't incorporate it.
Comment #11
nicolasb_cdip commentedOkay I understand.
I used the solution you provided and it's okay. So I wrote a module extending the hook and it's well handled. I don't know if I should publish this module because it's very specific to my use. Maybe it should be linked to your module... What do you think ?
Anyway thanks a lot for your help, and now I know more about debugging Drupal and extending modules.
Comment #12
freixas commentedThe PayPal module is used by a lot of people, so your code would probably be a nice little extension to have. Why don't you attach your module here and I'll add it as a sub-module that people can enable if they are using the PayPal payment system. I will credit you as the author, although I will make modifications if needed.
Ideally, the module should check if the payment system is PayPal. If not, it should return NULL for the hook. If it is PayPal, then test for the right conditions under which to issue the keys and return TRUE or FALSE. If it's written properly, it shouldn't be specific to your system, just to PayPal. The real trick is that there are several ways PayPal can be used. I forget the names—I know one is called PayPal Standard. The module should work (and be tested) with all these modes. Since you probably just use one type of payment, you'll need to tell me which type you've tested.
If you want to make a more significant contribution, you'll see if you can make your module work for all the ways in which the PayPal module can be set up.
Thanks for testing my changes!
Comment #13
nicolasb_cdip commentedI see two ways in which the PayPal module can be set up (PayPal Express Checkout [paypal_ec] and PayPal Website Payments Standard [paypal_wps]) so I adapted my module to handle these two ones.
I have tested both ways and it seems to be okay.
If anyone notice an other one (maybe 'credit'), let me know.
My module is attached, it's my first one so let me know for any mistakes.
Cheers
Comment #14
freixas commentedHi,
I finally had time to check out your module. I made a few minor changes in the formatting and such, but it still uses the exact same algorithm you created. I checked it out as far as making sure that I hadn't introduced any typos and that I could place an order with your module enabled. I didn't actually try to set up the PayPal code.
I've created an RC1 release. If you download this, you will see the changes I made to your code. Also, the RC1 should continue to work for you—holler if I screwed up something.
Be sure to disable your module, remove it from the sites/all/modules folder, install the update and then re-enable my version of your module.