Drupal Commerce payment gateway module for Payfirma PayHQ. It uses (optional) Javascript tokenization on credit card information for additional security and easier PCI compliance.
There are no other modules for this payment gateway.
Sponsored by: Payfirma
Project Page: https://drupal.org/sandbox/sleepingmonk/2219871
Git: git clone --branch 7.x-1.x http://git.drupal.org/sandbox/sleepingmonk/2219871.git commerce_payfirma
Reviews:
https://drupal.org/node/2263319#comment-8774547
https://drupal.org/node/2264709#comment-8774603 & https://drupal.org/node/2264709#comment-8774879
https://drupal.org/node/2259343#comment-8775161
Thank You!
Comment | File | Size | Author |
---|---|---|---|
#18 | pareview_results.txt | 2.31 KB | mpdonadio |
Comments
Comment #1
PA robot CreditAttribution: PA robot commentedWe are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and put yourself on the high priority list, then we will take a look at your project right away :-)
Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).
I'm a robot and this is an automated message from Project Applications Scraper.
Comment #2
Botto CreditAttribution: Botto commentedNo negative output from code sniffer, which is great
Comment #3
mpdonadioManual Review (visual only; I don't have a working Commerce install right now)
You should remove the commented out tests in the .info file
I would add a dependency on entity. Commerce requires this, but you are explicitly using entity_metadata_wrapper(), so the dependency is best in case Commerce changes.
You may want to add an index on order_id since you are declaring this as an FK.
The commented out code in the JS should be removed for the public (eg, lines 26, 74--77)
The naked items in commerce_payfirma_menu() give me pause. Can you point to best practice / other commerce payment modules that have handlers w/ access checks?
Is there a reason you have to use cURL directly and not drupal_http_request()?
You can probably get rid of the empty page arguments on line 19.
Setting this back to Needs Work, pending an answer about the naked hook_menu() items. Otherwise, I didn't see anything wrong that wasn't mentioned yet.
Comment #4
sleepingmonkThanks for the feedback!
@Botto
Don't use echo, always use print in the .module line 320
Fixed.
The code could do with a little polish, a lot of newlines that don't need to be there.
Newlines removed.
Code restructured a bit to model Authorize.net module a little closer.
Use $form['#redirect'] instead of drupal_goto in your submit handler
Because of the way this payment gateway can "tokenize" card information in the browser with javascript before transmitting data to the server we end up bypassing the form_submit. We have to move the checkout process along on our own so the #redirect doesn't work in this case. Side note: this changed a bit in D7 https://drupal.org/update/modules/6/7#fapi_changes
--
@mpdonadio
You should remove the commented out tests in the .info file
Done.
I would add a dependency on entity. Commerce requires this, but you are explicitly using entity_metadata_wrapper(), so the dependency is best in case Commerce changes.
Good advice. Done.
You may want to add an index on order_id since you are declaring this as an FK.
Done.
The commented out code in the JS should be removed for the public (eg, lines 26, 74--77)
Done.
The naked items in commerce_payfirma_menu() give me pause. Can you point to best practice / other commerce payment modules that have handlers w/ access checks?
These menu items are needed to capture responses from Payfirma's Tokenization and Push features. Tokenization is done through their included javascript which routes it's response to the /handler. Push is similar to PayPal's IPN so the /response is available to the payment notification that can be sent from Payfirma in the background if the user configures their account to do so. These _menu() items were modeled from PayPal WPS module.
Is there a reason you have to use cURL directly and not drupal_http_request()?
cURL is used to be consistent with Payfirma's API documentation. cURL is also used in the Authorize.net module referenced in the creation of this module.
You can probably get rid of the empty page arguments on line 19.
Removed. Thanks.
--
Thanks again for the review and feedback!
Comment #5
mpdonadioOK, I checked out commerce_paypal, and saw the 'access callback' => TRUE,. I am trusting Commerce Guys in this case, that this is OK.
Understood about curl. Add a comment to the effect about being modeled after the API docs, and also provide the link. Any other Payfirm API references would be good, as they may aid in debug if this module breaks at some point in the future.
Also comment the bit about the drupal_goto(). Any time you need to deviate from best practices or the API, it is always best to comment why.
Leaving this as Needs Review, but I will give everything a proper look over tomorrow.
Comment #6
mpdonadioSorry, noticed a few more small things.
1. You aren't using the context in your JS behavior. This is important for AJAX.
2. You are using Drupal.settings.commerce_payfirma directly instead of the settings passed into the attached.
3. You have a unused variable on line 37 in the JS.
4. commerce_payfirma_submit_form() You should really use #attached on the form instead of drupal_add_js() and drupal_add_css().
As a side note, using a IDE like PhpStorm can help identify unused variables and arguments.
Comment #7
sleepingmonkThanks mpdonadio!
pareview.sh comes back clean now.
http://pareview.sh/pareview/httpgitdrupalorgsandboxsleepingmonk2219871git
Added the suggested comments from #5 above, as well as a link to the API docs in the README.txt
1. You aren't using the context in your JS behavior. This is important for AJAX.
2. You are using Drupal.settings.commerce_payfirma directly instead of the settings passed into the attached.
I wasn't used to doing this. I have now, and will do so in the future.
3. You have a unused variable on line 37 in the JS.
Fixed.
4. commerce_payfirma_submit_form() You should really use #attached on the form instead of drupal_add_js() and drupal_add_css().
Fixed.
--
Thanks very much! I've learned a few things. I appreciate your time and effort!
Comment #8
sleepingmonkComment #9
heddnComment #10
heddn.module
PHPDoc comment does not match function or method signature (at line 218)
PHPDoc comment does not match function or method signature (at line 375)
hook_menu: Consider using https://api.drupal.org/api/drupal/includes%21menu.inc/constant/MENU_CALL.... That seems a better fit.
hook_commerce_payment_method_info: use l() for the link in the display title and pass it in via t() as a variable. Current approach isn't easily translatable.
commerce_payfirma_settings_form:
Use '#type' => 'image' (see theme_image)
commerce_payfirma_process_response: Consider using php://input vs $_POST. See http://stackoverflow.com/questions/8893574/php-php-input-vs-post
No check if all the input values are passed. Null values are quite possible to a menu callback.
drupal_set_message(t('ERROR: @error'), array('@error' => check_plain($response['error'])), 'error');
No need to pass through checkplain.
t()
can do that for you..install
Duplicate array key (at line 80)
.info
No explicit dependency on commerce_customer.module
.js
Code comments should follow all the same standards as PHP code i.e. end in full stops. See https://drupal.org/node/172169
Alert should use Drupal.t(). See https://drupal.org/node/323109
Single letter variable names r, z, v make reading the js difficult. Consider using more meaningful names.
images:
Are all the images usable via GPL v2?
Moving back to needs work, primarily because of the non-translatable string and missing dependency.
In general comment, consider doing the extra work to make commerce_payfirma data an entity. This will make it usable by views and will mean you won't have to write code for loading, saving and deleting a payment. It's almost there already, you mostly need to add in the hook_entity_info. See http://www.phase2technology.com/blog/developing-a-custom-drupal-entity/
Comment #11
sleepingmonkThanks heddn,
I've made the changes you suggested, with the exception of '#type' => 'image'. I looked at theme_image and the forms api and could find documentation or examples of '#type' => 'image' in a form. I tried setting '#type' => 'image' and then using the structure from theme_image for the rest. It didn't seem to work.
Regardless, the images have been removed for now. I don't believe they're GPL. They were provided by the sponsor Payfirma. I'll follow up with them on the licensing before I add them in again.
I'll consider making this data a new entity in a future update, once I look into it more.
Thanks for the review and guidance!
Comment #12
heddnGreat progress.
commerce_payfirma_process_response and commerce_payfirma_handler still don't check for !empty (or equivalent) for all values being gathered from the URL.
Comment #13
sleepingmonkAh! Sorry I missed that.
I updated the function arguments as a few were unused now. Checks are done for each argument.
Thanks again!
Comment #14
heddnThere's still an inherent assumption that certain values exist.
If this isn't called from commerce_payfirma_handler and it doesn't have a POST operation, then $response will be NULL and $order_id will be NULL and so will $order. Try entering the menu path into a browser without any parameters and see what happens.
In commerce_payfirma_handler, rather than using $_REQUEST super global directly, try using drupal_get_query_parameters.
Also, this was introduced:
397 | ERROR | Variable "payRement_method" is camel caps format. do not use
| | mixed case (camelCase), use lower case and _
Plus that value will always be empty (there's no assignment previously).
Last example:
This assumes that the $_REQUEST has card_number, etc populated. It wouldn't if someone only entered the menu path without any parameters.
Comment #15
sleepingmonkHello again,
Also, this was introduced:
397 | ERROR | Variable "payRement_method" is camel caps format. do not use
| | mixed case (camelCase), use lower case and _
Plus that value will always be empty (there's no assignment previously).
I don't see this in my local working copy or in the previous commits to the repo. Is it possible this was accidentally inserted on your end?
--
As for the rest. Sorry I didn't understand what you were expecting here. Only Payfirma processes would access these URLs, with data in an expected format, but I understand why we need these checks. I've referred to the Commerce PayPal module to see how they handle the IPN response which is similar to what we have in this module.
I've added a check for empty $response and a valid $order object in the _process_response function. It also checks for an order id in the $pane_values (passed in or loaded from $_REQUEST), in the _handler function. It returns FALSE if any of these checks fail.
I don't understand the benefit to using drupal_get_query_parameters rather than $_REQUEST, or $_POST.
--
I hope this is sufficient now, and I appreciate your time and guidance in this review process.
Comment #16
heddn@sleepingmonk, sorry about that. It must have been inserted. Moving to RTBCed. The next step is to wait for a git admin to promote.
Comment #17
sleepingmonkAwesome!
Thanks for all the help!
Comment #18
mpdonadioSorry for the delay, it took me longer than expected to confirm the hook_menu() issue mentioned above.
Automated Review
Review of the 7.x-1.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.
Nothing major; fix when you can.
Manual Review
Add a comment somewhere in the code that Commerce Paypal was used as a model.
I think the second jQuery selector on line 25 is missing the context that was passed in.
Missing t() on commerce_payfirma.module, line 120.
It would be best to have some comments w/ URL that refer to the Payfirm API when you are programming against it (eg, the cURL, the responses).
Your date() functions should use format_date() w/ a custom string, and also explictly use REQUEST_TIME.
Form API #default_value gets plained internally. See https://drupal.org/node/28984
I am not seeing any blocking issues on this.
Comment #19
mpdonadioThanks for your contribution, sleepingmonk!
I updated your account so you can promote this to a full project and also create new projects as either a sandbox or a "full" project.
Here are some recommended readings to help with excellent maintainership:
You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and stay involved!
Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.
Thanks to the dedicated reviewer(s) as well.
Comment #20
sleepingmonkThanks very much everyone! I learned a few things and enjoyed review a few other modules. I'll definitely help out with more reviews in the future. I imagine I'll learn even more in the process.
Thanks again!