This patch adds support for the CyberSource Hosted Order Page service to uc_cybersource.module.
It was originally based on the standalone contrib module proposed by wisdom at http://drupal.org/node/677906 but includes a lot of rewriting to make it work with the current HOP API and make the CS Payment page a bit more descriptive, and also adds configurable options for a custom receipt ("Thanks for your order") page and the text on the CS order page "buy now" button.
To test this patch developers need to download a copy of HOP.php and rename the l() and, if using devel.module, dd() functions per http://drupal.org/node/492758 .
Also, after checkout and payment is processed, the cart is not cleared because uc_cart_complete_sale() is called from the POST callback and therefore not associated with the user.
We could clear the cart when the payment confirmation is POSTed back by CyberSource, but that seems potentially confusing to the user because the cart could be cleared without any clear connection to the user's actions. Looking through the code, the PayPal WPS payment method does not clear the cart, so I followed that convention.
Testing is appreciated. Thanks!
| Comment | File | Size | Author |
|---|---|---|---|
| #33 | 809972-e.patch | 25.57 KB | ezra-g |
| #20 | 809972-d.patch | 25.5 KB | ezra-g |
| #14 | 809972-c.patch | 24.49 KB | ezra-g |
| #9 | 809972.patch | 22.91 KB | ezra-g |
| #7 | Screen shot 2010-06-09 at 3.22.46 PM.png | 29.91 KB | jumpfightgo |
Comments
Comment #1
jumpfightgo commentedGreat work, I am experiencing an error on checkout but most of the functionality is here. Here's some feedback:
In the uc_cybersource_hop_form function on line 354 the HOP file is referenced inside a non-existant module, which causes a fatal error. You actually added a few lines to check that the file exists, which is nice, but the error check appears after the line requiring the file.
On that note, is the uc_cybersource directory actually the best place to put the HOP.php file, though? I can imagine someone upgrading ubercart and losing their HOP.php file. I'm not sure about the standard drupal way to handle this situation, but for a different module I put this kind of file below the root folder and added a configuration settings where you can specify the location of the required file.
Should the credit card module no longer be listed as a dependency of uc_cybersource any more? HOP doesn't actually use the credit card module so it's confusing to have all the credit card info showing up.
Perhaps we should add a few lines explaining how to generate the HOP.php file? I'm not sure where that documentations should go, but here's an explanation based on cybersource's documentation from http://www.cybersource.com/resources/quickstart/HOP/PHP_HOP_QRG.pdf
It also might be helpful to include a script or something to rename the dd() and L() functions in HOP.php - that took me a little while to do correctly and I bet a lot of people will have trouble with that.
Hope that helps! I'll let you know if I find anything else.
Comment #2
gregglessites/all/libraries is the increasingly common place to put stuff like HOP.php
I think instructions are better than a script for renaming dd and L - most users will be on environments where they can't run scripts, but "Find and replace..." works reasonably well.
We might be able to put in a hook_requirements that does a token_get_all on the HOP.php and looks for dd and l functions.
Comment #3
ezra-g commentedThis revised patch resolves an issue where non-shippable orders resulted in declined orders and an error in the CyberSource logs. It also adds a check to hook_requirements to make sure that HOP.php can be located, and adds a uc_cybersource_hop_include() helper function that includes HOP.php and returns TRUE or FALSE if it cannot be included. Existing calls to include the file are rewritten to use this function.
I think we should add a bit of documentation to the README that guides users to generate HOP.php.
I'd like to make another round of revisions that make the CyberSource visual styling more customizable from the Drupal side, but here's the current state of the patch for folks to test and comment on the approach. Thanks!
Comment #4
tr commentedI'm all in favor of this patch. But before I commit it I'd like to hear from someone who currently uses the uc_cybersource module to make sure this patch doesn't break the existing functionality and to check that the upgrade path works.
Comment #5
ezra-g commentedThanks, TR.
I'd like to re-roll this to make a configurable option to list the products purchased in the order comments within CyberSource.
The specific use-case I'm working on involves listing nodes created by purchasing uc_node_checkout nodes.
Any objections to doing a module_exists() for uc_node_checkout and providing that feature as an option, given that this is within uc core?
Comment #6
ezra-g commentedActually, a drupal_alter would be more useful here than a module-specific solution. Thanks to jumpfightgo for that suggestion.
Comment #7
jumpfightgo commentedThe phone number is not being passed to cybersource. Though it's not required, I do think users would expect to see their phone number at this step if they entered it on a previous screen.
Comment #8
jumpfightgo commentedIt looks like you changed this and do actually call uc_cart_complete_sale() which is great, but we need to update the form so that users actually see the description that tells them to set the Merchant POST url in cybersource account - that took me a while to figure out what was going on...
line 339: '#description' => t('The post url in your Cybersource account need to be set to http://yourdomain/cybersource/hop-post'),Also, when this url is called an error is returned - is that why my orders aren't being completed after they're paid for, see: https://classifieds.harvardmagazine.com/cybersource/hop-post
Comment #9
ezra-g commentedHere's an updated patch that removes the form value that jumpfightgomentioned. In fact it's totally unnecessary as this url is defined by merchantURLPostAddress and shouldn't change. The variable being defined there was never checked for -- cruft left over from the original patch.
This version also adds a uc_cybersource_data_alter() hook via drupal_alter(), so that other modules can alter the value of the comments field sent to CyberSource, and also use merchant-defined fields. We're testing this with a small custom module and it successfully gets the values into the post that's sent to CyberSource.
Comment #10
jumpfightgo commentedOn the checkout review page the Payment Method is set to "Paying By: Cybersource", which doesn't really make sense to someone expecting to pay for their purchases using a credit card...
I think we should just "review" to "credit card" in the function uc_cybersource_payment_method() so that users see "Paying By: Credit Card" because that's what they'll expect to see.
Comment #11
ezra-g commentedI am locally testing a revision to the patch that changes this text in both places to "Credit/Debit card payment processed by CyberSource".
I'll post the revised patch when I settle on a solution for clearing the cart.
Comment #12
jumpfightgo commentedComment #13
ezra-g commentedHere's a revised version that makes the payment method more descriptive per #11. It also removes the configurable "thank you" page option and replaces it with a non-configurable callback that redirects users to 'cart/checkout/complete', which clears their cart and finalizes the order. The message that users see is configurable and more consistent than a cybersource-specific thank you page, since it uses the site-wide checkout completion message.
Comment #14
ezra-g commentedHere's the patch ;)
Comment #15
jumpfightgo commented#13/14 is a major improvement, thanks, automatically redirecting to the appropriate page and using the site-wide completion message makes a lot of sense.
Comment #16
tr commented@jumpfightgo: Are you using just the new HOP functionality?
@ezra-g: In hook_requirements() can you check the $phase argument to differentiate between install and runtime invocations of hook_requirements()? Because the variable uc_cybersource_method will never be set during the initial install phase, install will always fail if HOP.php isn't present, even if the site owner intends to use the SOAP method. Maybe change hook_requirements() so that it returns a REQUIREMENT_INFO message about HOP.php during install instead of a REQUREMENT_ERROR, but retain the REQUIREMENT_ERROR for the runtime condition? Likewise, in hook_requirements(), the error message says "For instructions on how to generate this file, please refer to your CyberSource Documentation" - can this be made into a link so users won't have to go fumbling around searching for the info?
I would still prefer to see a review of this patch from someone who is using the non-HOP version of uc_cybersource, just to make sure it doesn't inadvertently break the existing functionality, but I'm not going to hold up committing the patch because of that.
Comment #17
jumpfightgo commented@TR - yes we're just using the HOP functionality.
Unfortunately Cybersource documentation is either in PDF or iframed HTML, so direct links are challenging. How about the following:
Comment #18
tr commentedYes, that message looks great. I just don't want to leave the user dangling with no idea where to look or what to do.
Comment #19
jumpfightgo commentedI think this issue still needs to be resolved. We're using this patch on a live site now. Today I went in to check a configuration setting and clicked on "payment gateways" under "store administration" > "Configuration" > "Payment settings". The "cybersource settings" on that page are for using cybersource silent post or soap, but NOT for HOP. That was very confusing, and I imagine will be even more confusing and frustrating to new users.
Comment #20
ezra-g commentedHere's a revised patch that implements the following new changes
- Removes uc_credit as a dependency, returns FALSE from uc_cybersource_payment_gateway() when uc_credit is not enabled to avoid unknown function errors
- Improves hook_requirements help text with the text and links from above
- Changes requirement severity to REQUIREMENT_INFO during install
- Changes the name of the CyberSource payment gateway (non-hop) to make the difference between settings for the HOP payment method and the non-HOP payment gateway more clear
- Adds an 'authorize only' setting for HOP so that store administrators can authorize via Ubercart and capture via the CS administrative panel.
Comment #21
mitchellshelton commentedJust curious if there is any update on the progress with this. We are looking into a few options and required to use Cybersource, so this patch would be a big help to us.
Thanks,
-Mitchell
Comment #22
tr commented@juncmodule: Did you test the patch? Does it work? "Progress" on an issue only happens via community participation to review the proposed changes and help address any concerns raised. No one has done that since ezra-g posted the latest patch two months ago.
Comment #23
druderman commentedI would love for us to be able to add this to a subequent Ubercart release.
I downloaded Ubercart 6.x-2.x-dev and have applied patch 809972-d.patch above and with some minor changes got things working. I was able to checkout by using the Cybersource HOP in my browser. So far so good.
My notes to get it working:
Immediately I got an error that function uc_cybersource_hop_include() was not found, so I needed to add this line to the top of uc_cybersource.install:
require_once("uc_cybersource.module");
I also had to do the following:
edit uc_cybersource.module and replace getPublicKey() with getSharedSecret(). See http://www.ubercart.org/contrib/139
And of course I had generated and edited a Cybersource HOP.php file.
1) Log into Cybersource and go to Tools & Settings > Hosted Order Page > Security
2) Generate and save PHP security script HOP.php
3) Edit it and replace instances of L( with csL( by hand.
4) Copy it to modules/ubercart/payment/uc_cybersource
Comment #24
gregglesI think nobody who uses the cybersource regular gateway is going to review this. They just won't even look for it.
My suggestion is to commit it somewhere early in a 6.x-2.x-dev and then try to get some attention for testing that out (i.e. via twitter) prior to the next release.
Comment #25
druderman commentedPatch 809972-d for cybersource is still has a dependency upon the Credit Card module.
If I turn off CC, I get this msg when I hit /admin/store/settings/payment/edit/gateways.
Fatal error: Call to undefined function uc_credit_encryption_key() in modules/ubercart/payment/uc_cybersource/uc_cybersource.module on line 67
I see reference to a few other uc_credit_xxx functions in uc_cybersource.module, so it appears to be still dependent.
Comment #26
rocheking commentedSo far so good...
undefined function uc_cybersource_hop_include()
...added require_once("uc_cybersource.module"); to the top of .install as instructed -- No Problem
Cannot redeclare l() ...made the changes listed above -- No Problem
Will be testing this in the next couple days! Thanks for getting this going.
Comment #27
rocheking commentedI'm getting this error when I go from checkout to review (/cart/checkout/review)
Call to undefined function getpublickey() in /home/uanative/public_html/sites/all/modules/ubercart/payment/uc_cybersource/uc_cybersource.module on line 457
oops sorry... trying to keep it all straight... missed the comment about this above :-)
Comment #28
rocheking commentedI put in http://www.[domain].com/cart/checkout/complete
... in the Merchant POST URL field in Cybersource --> Not sure what this is doing
... and in the Custom Receipt URL --> This seems to pass back some needed info to me.
I'm not sure if this is a cybersource test environment problem or ubercart or what, but my balance is coming back without being paid (so in UC store interface, the balance is basically the unpaid total from their cart).
Where am I going awry ? Thanks as always !
Comment #29
druderman commentedJohn, Can you try logging into Cybersource (probably the "Test Business Center") and doing a transaction search? All transactions and attempts should be listed, so see if yours are there.
I have my own issue where failed transactions are not returned to my test server. I use the HOP for another e-commerce site (not running Ubercart), so I may have the cybersource decline response URL set wrong. I'm actually not sure where it should go or perhaps it should not be set.
I'd appreciate any advise anyone has regarding that.
Comment #30
rocheking commentedThanks so much. Yes the transactions are showing up in CS. AND... I simply didn't understand what pending meant in the realm of cc processing (ie, the payment went through but the money won't be delivered to the bank until midnight). So... I just need to key off of the change to pending status and set up the proper triggers. Almost there. Thanks all!
Comment #31
druderman commentedWhen I used another e-commerce system with CyberSource, there were transactions that did not push through fully which is a possible outcome. So I had to change parameters that were sent to the CS hop. I'm guessing in your case maybe the transaction is similar to when your credit card is approved to pump gas, but the final amount is not known until you are done.
What are your Cybersource HOP settings in Ubercart?
I have "Authorize and capture" selected and I'm using the "Test Center".
Comment #32
jyee commentedThe 809972-d.patch worked as expected in my testing. Let's roll this into the uc_cybersource code!
Comment #33
ezra-g commentedHere's a re-roll that addresses the feedback from above. If this was already RTBC, then it's even more so now ;).
#23, #26 -- Undefinded function ic_cybersource_hop_include()
This was easy to reproduce attempting to enable uc_cybersource on a fresh install.
I added the require_once('uc_cybersource.module') to uc_cybersource.install, and this resolved the problem.
#23:
> edit uc_cybersource.module and replace getPublicKey() with getSharedSecret().
> See http://www.ubercart.org/contrib/139
Folks shouldn't need to edit uc_cybersource.modue. I can't speak to the differences in the CS-provided HOP.php files, but this version of the patch uses getSharedSecret() if that function is present, and otherwise uses getPublicKey(. I tested on a HOP.php with getPublicKey().
I also removed the block of code that invoked hook_order() similarly to the approach that was recently removed from UC's Paypal WPS processing at http://drupal.org/node/700270.
Comment #34
ezra-g commentedI tested this on a site with HOP in testing mode and it still processes CS posts successfully.
Comment #35
tr commentedThanks for all your hard work Ezra. Committed.
Comment #36
druderman commentedI've enabled shipping and taxes.
When I submit the payment below to Cybersource HOP, it sends the subtotal of $5.00.
Is this a configuration or a coding issue?
Calculate shipping cost
Standard shipping: $5.95
Payment method
Subtotal: $5.00
Standard shipping: $5.95
Subtotal excluding taxes: $10.95
Massachusetts sales tax: $0.31
Total: $11.26
Paying by: Credit/Debit card payment processed by CyberSource
Comment #38
sfontes commentedHi there-
So I'm trying to applythe patch uc_cs_hop.diff, but its failing. It says:
Hunk #@ FAILED at 77.
1 out of 2 hunks FAILED -- saving rejects to file uc_cybersource.install.rej
patching file uc_cybersource.module
Is there a reason this is failing? I really need to use a HOP so that I'm PCI compliant and need to get this to work.
Thanks in advance.
Comment #39
tr commented@sfonte: Use Ubercart 6.x-2.x-dev, the patch is already in there. Or use 6.x-2.4, and the patch should apply cleanly.
Comment #40
sfontes commentedOK so I had to install the -dev version for it to work. I was using 6.x-2.4, and was getting the error.
Now it seems to work, but I just want to verify that ic3.com is a CyberSource url? It just seems odd.
Thanks in advance for your help- its really appreciated.
Comment #42
druderman commentedHas anyone been able to apply this patch to the production release 6.x-2.4?
Comment #43
ezra-g commentedPer comment 39, "Use Ubercart 6.x-2.x-dev, the patch is already in there. Or use 6.x-2.4, and the patch should apply cleanly."