This is a payment gateway for Ubercart which utilizes Braintree's transparent redirection technique to transmit credit card information from the user's browser directly to the Braintree vault. Tokens are substituted for credit card data within the merchant's website to avoid costly audits related to the storage or transmission of credit card information. This module also provides users with the ability to manage payment tokens via the last four card digits, identify and update expired cards, change billing dates, and cancel recurring payments for subscriptions generated via the Braintree Payment Solutions application programming interface. A rebuild/import of the customer, token, and subscription information contained in the Braintree Vault can also be performed to align with Drupal user accounts, allowing a merchant to perform a bulk transfer from one merchant to Braintree under the PCI rules for handling credit card data. The rebuild can also be used for business continuity or disaster recovery purposes. The module enables an administer to run multiple websites using the same merchant account.
git clone --recursive --branch 6.x-2.x http://git.drupal.org/sandbox/MarkHurley/1820348.git uc_braintree_tr_payment
http://drupal.org/sandbox/MarkHurley/1820348
This module is compatible with 6.x only at the present time.
This is the first module I've written for Drupal. I have been working on the package in my spare time over the past two years after a non-profit called me requesting some help. Although they sponsored the first 40 hours, they agreed to open source the project in exchange for free support. They also wanted to contribute to other organizations similar in nature that could make use of the code. All the code now resides entirely in the Drupal repository and will remain there. Pioneering Software, the company I started and am dutifully employed, is pleased to be able to contribute to the Drupal community in this fashion.
There is a module that was started about the same time by targospizza but does not contain the same feature set of this module and is not production ready. I contacted the project owner on a couple of occasions with the mindset of combining features, but collaboration was not ideal in this instance.
Please feel free to contact me with any questions.
| Comment | File | Size | Author |
|---|---|---|---|
| tokenOnFile.png | 37.64 KB | MarkHurley | |
| cancelSubscription.png | 13.05 KB | MarkHurley | |
| updatePaymentMethodForm.png | 25.02 KB | MarkHurley | |
| updatePaymentMethod.png | 24.65 KB | MarkHurley | |
| recurringBilling.png | 6.9 KB | MarkHurley |
Comments
Comment #1
klausiWelcome,
please get a review bonus first. Then try to fix issues raised by automated review tools: http://ventral.org/pareview/httpgitdrupalorgsandboxmarkhurley1820348git
Comment #2
MarkHurley commentedHave fixed the issues raised by the automated review tools. Will try and work on doing some manual reviews of other packages as time permits in order to get a review bonus. Thanks for your help!
mark
Comment #3
beifler commentedI have installed and tested this module - everything functions well. I used a Braintree sandbox account to run the tests.
Some of the items tested:
- Single transactions
- Recurring transactions
- Role subscriptions as related to recurring transactions
- User permissions
- User security (Ensuring one user cannot access other user's profiles or subscriptions)
- Basic layout and functions
This is a well built module that is needed by the community.
Comment #4
klausiSorry for the delay, but you have not listed any reviews of other project applications in your issue summary as strongly recommended in the application documentation.
Review of the 6.x-2.x branch:
This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. You have to get a review bonus to get a review from me.
manual review:
Comment #5
PA robot commentedClosing due to lack of activity. Feel free to reopen if you are still working on this application.
I'm a robot and this is an automated message from Project Applications Scraper.
Comment #6
MarkHurley commentedThank you for the feedback on this module. I must apologize as I am not able to do many reviews at this time due to life events. I will, however, work on items one through five at my next opportunity as there is a non-profit wishing to utilize the code and I have offered to help. Regarding item number six, the uc_braintree_tr_payment_get_email_uid() function is used for the initial load of credit card tokens if a migration from another gateway provider is performed or in the event of disaster recovery. The function is not designed to be executed routinely. I believe the module itself is limited to a 10,000 token ceiling which is the maximum value from the Braintree API. I will make a note of this limitation within the module documentation. Thanks again for taking the time to review.
Comment #7
tr commentedYou know, I would have reviewed this long ago, but you don't mention Ubercart anywhere in your module description above, so when I search for "Ubercart" projects this one isn't found ... You really need to say "this is a payment gateway for Ubercart" somewhere in your description of what the module does.
I'll do a complete review after you address the issues in #4 and set the project status to "needs review".
Comment #8
MarkHurley commentedThank you klausi for the review. Please find my updates below.
mark
1.gpl-3_0.txt: needs to be removed, all code on drupal.org is GPLv2+ and a LICENSE.txt file will be added for packaged downloads.
- Completed
2.uc_braintree_tr_payment.module: that file has more than 3000 lines of code and is loaded on every single page request. Please try to split out stuff into include files that are loaded on demand.
- Still contemplating how to breakdown the class file into multiple includes.
3.uc_braintree_tr_payment.module: no need for the copyright header, you can give credit in README.txt
- Completed
4.uc_braintree_tr_payment_redirect_error_handling(): all user facing text must run through t() for translation. Please check all your strings, there are a lot of places where t() must be used.
- Completed
5.Everywhere you use uc_braintree_tr_payment_log_debug_message() you should wrap the message in t() and use the appropriate placeholders for variables in the message.
- Completed
6.uc_braintree_tr_payment_get_email_uid(): that will not scale if I have a million users. Why do you need to build an array of all users?
- Documented the Braintree API 10k query limitation. The method in question is not for routine use, but used for initializing the database of tokens in an existing Braintree vault or for rebuilding tables after a disaster.
Comment #9
tr commentedPartial review here...
You have license statements in your .install, .info, and .admin.inc files - those statements should be removed.
In your hook_install(), you set a weight for your module. This should be avoided unless you really need your module to be loaded before or after some other module, and in that case instead of just picking an arbitrary weight you should first SELECT the other module's weight out of the DB and add/subtract an offset to make sure your new weight will be less/greater than that other module's.
In your hook_uninstall(), you're deleting row(s) from the {system} table for your module. You should not do that. Also, you're not deleting all the system variables you created in your module, e.g. variable_del('uc_braintree_tr_payment_transaction_debugging').
You're not using hook_schema() correctly. You should define ONE function, called <yourmodulename>_schema(), which declares ALL your tables. You're currently defining four functions, none of which conform to the function-naming pattern required for the hook.
Is this a payment gateway or a payment method? You implement both hook_payment_gateway() and hook_payment_method(), and the hook_payment_gateway() implementation appears wrong because the 'callback' does not name a function used to process a payment.
You're doing the payment settings form wrong. You shouldn't be declaring it explicitly in hook_menu(), the settings form should be declared in the 'settings' case of your payment method 'callback'. See the core Ubercart payment modules for how this should be done.
Please re-examine your use of global variables. You are sometimes declaring them but not using them. Global variables are rarely needed, and should be treated with extreme caution because of the potential for inadvertently causing problems when you change these variables in your functions, especially when dealing with $user.
I didn't really review the .module file yet - too many other things need to be fixed before I can tackle that.
Comment #10
MarkHurley commentedThank you TR for the cursory review. Have noted the change items above and will work to rectify these items. To answer your questions, we are creating a new payment method (the credit card token) using a new gateway with the transparent redirection. In short, the transparent redirect will send the card data directly from the client browser to the gateway provider and redirect back to Drupal/Ubercart with the success/failure. Included in this redirect is a customer token for future transactions. Hence, no card data is placed into the typical credit card data location and the payment processing is performed inline with the checkout process.
Comment #11
tr commentedComment #11.0
tr commentedAdded "This is a payment gateway for Ubercart" per the suggestion by TR. Thanks!
Comment #12
MarkHurley commentedTeam,
We've been working very diligently to apply the changes requested in #4 and #9, including some very large refactoring to move code to include files for on demand loading, correcting our menu callbacks and access permissions, eliminating global values where at all possible, attempting to distinguish the payment method and gateway, and update the code to comply with the many pareview.sh findings. We have also added some additional code in the form of an optional module that will enable non-profits to use a single page donation form for use with the transparent redirection/token processing. I would like to again request that the package receive full project status. I recently added another individual as maintainer, Bethany Ritter. She is helping me go through the code and make changes based on our testing, feedback from a community group, and the online code review tools.
thanks!
mark
Comment #13
PA robot commentedClosing due to lack of activity. Feel free to reopen if you are still working on this application (see also the project application workflow).
I'm a robot and this is an automated message from Project Applications Scraper.
Comment #14
MarkHurley commentedComment #15
kscheirer'last_four' => array('type' => 'text'.... If it's always 4 digits a small int might be easier.require_once 'Braintree.php';this is where the Libraries API is very useful - you don't have to worry about where it gets installed, making your module easier to use in all sorts of environments.$base_url = base_path() . "index.php?q=user/" . $user->uid . "/payment-method&paymentAction=addCard";Drupal provides lots of url management functions. url() shoudl work here. Similarly with the$redirect_url.tr_data, could someone modify this data to register a different credit card or otherwise modify user data? I'm not sure what's happening on the Braintree end, but that looks pretty insecure.$_uc_braintree_tr_payment_connection_exception, we prefer not to add new globals.$form['#action']quite a bit. That's ok when you need to submit to an external server, but within Drupal that's already handled for you. Just implement a form_name_submit() function and all your data will be passed there. This is also true for _validate().INSERT ... ON DUPLICATE KEY UPDATEis mysql-specific. You can use drupal_write_record() to accomplish the same thing, or document that your module requires mysql.UNIX_TIMESTAMP(now()), just call PHP's time() and use that value instead.drupal_goto()if possible.user_access('some permission')instead. Or if it's in a hook_menu, just set the access arguments to array('some permission'). user_access takes care of loading the current user, and granting an exception for uid 1.'required' => TRUE.That's all I can make it through right now, this was not a complete review.
The project application queue is really about the coder and whether or not they have a good grasp of Drupal's API and good practices. You might find it much easier to reduce this module down to it's essential components only, and then once approved, you're free to add in the rest of the features without our interference. Setting to needs work for the number of issues.
----
Top Shelf Modules - Crafted, Curated, Contributed.
Comment #16
MarkHurley commentedThank you kscheirer for your valuable feedback. I will take some time to go through each of these. Thanks again!
mark
Comment #17
kscheirerHmm, not sure why this was back in needs review? Unless I missed some updates already?
----
Top Shelf Modules - Crafted, Curated, Contributed.
Comment #18
PA robot commentedClosing due to lack of activity. Feel free to reopen if you are still working on this application (see also the project application workflow).
I'm a robot and this is an automated message from Project Applications Scraper.