Hello,

I would like to add a payment through the order payment tab, but commerce stripe is not an option. Is this functionality possible at this time?

Thanks,
Paul

CommentFileSizeAuthor
#87 interdiff-1875234-85-87.txt1.01 KBtorgospizza
#87 1875234-commerce_stripe-terminal-payment-87.patch5.71 KBtorgospizza
#85 1875234-commerce_stripe-terminal-payment-85.patch5.52 KBtorgospizza
#84 1875234-commerce_stripe-terminal-payment-84.patch5.52 KBtorgospizza
#81 commerce_stripe_payment_terminal_error.png15.87 KBpnigro
#76 1875234-commerce_stripe-terminal-payment-76.patch5.48 KBtorgospizza
#72 1875234-commerce_stripe-terminal-72.patch2.85 KBtorgospizza
#68 commerce_stripe-allow-payment-through-terminal-1875234-68.patch11.22 KBpnigro
#67 interdiff.patch682 bytesthejacer87
#67 commerce_stripe-cof_terminal_payments-1875234-67.patch11.21 KBthejacer87
#58 interdiff.patch9.39 KBthejacer87
#58 commerce_stripe-cof_terminal_payments-1875234-58.patch11.21 KBthejacer87
#58 out.gif348.15 KBthejacer87
#50 Strange_Error.gif131.19 KBthejacer87
#50 Normal_Error.gif120.35 KBthejacer87
#36 commerce_stripe-fixforterminal-1875234-36-7.41.patch.diff5.17 KBvincentdemers
#34 commerce_stripe-fixforterminal-1875234-34-7.35.patch.diff5.16 KBMarieKirya
#4 allow-payment-through-terminal-1875234-4.patch3.51 KBpnigro
#8 allow-payment-through-terminal-1875234-8.patch3.5 KBpnigro
#14 commerce_stripe-fix-terminal-1875234-14.patch4.41 KBangms-bh
#20 commerce_stripe-fix-terminal-185234-20.patch8.83 KBangms-bh
#22 commerce_stripe-fixforterminal-1875234-22-7.35.patch12.15 KBangms-bh
#27 commerce_stripe-fixforterminal-1875234-27-7.35.patch0 bytesangms-bh
#29 commerce_stripe-fixforterminal-1875234-28-7.35.patch10.87 KBangms-bh
#30 commerce_stripe-fixforterminal-1875234-30-7.35.patch10.91 KBangms-bh
#32 commerce_stripe-fixforterminal-1875234-32-7.35.patch5.57 KBpnigro

Comments

pnigro’s picture

Title: Commerce Stripe missing from payment options in order payment tab » Allow payments to be made through order payment tab
Category: support » feature

After looking into the Commerce Payment API it looks like terminal is set to false in commerce_stripe_commerce_payment_method_info(). I set it to true and stripe does show up as a pament option under the order payment tab. I created a test payment, but received the following errors:

  • We received the following error processing your card. Please enter you information again or try a different card.
  • You must supply either a card or a customer id

In commerce_stripe_submit_form_submit(), the amount, currency, and description are sent to stripe. The only parameter that is not sent is the token or $_POST['stripeToken']. I believe this is because commerce_strip.js is only targeting the checkout and review forms and not the form on the order payment tab.

The token is only created in commerce_strip.js when stripe is checked as the payment option and the form is submitted. The form in the payment tab does not have a payment option since it is created through ajax. This makes it difficult to target a stripe payment from any other payment. We could add a hidden field to the commerce stripe form with an id and then use this id in commerce_stripe.js. Or is this an issue with commerce payment not providing a payment id on this form? Thoughts?

svouthi’s picture

I too would be very happy to see Stripe as an option on the order payment tab, however that may not be possible because of the way it functions. I believe it needs the checkout form to generate a token, and that does not appear in order admin. If one wishes to make an addition to an existing order and charge the customer's card again, there is another wall encountered. According to Stripe.com, (see here),

Stripe tokens can only be used once, but that doesn't mean you can't save payment information for your users. Stripe provides a Customer abstraction that makes it easy to save this information for later.

Stripe would have you create a Customer (by entering credit card data into your account at Stripe.com) for those you'd like to charge more than once, however in my use case (and surely in others) this would be super annoying as I do not sell by subscription and only need this function if a customer wishes to add additional product to their order, or when there is need for a Total correction in an upward direction. Of course, I can't know ahead of time when these conditions will arise.

aviindub’s picture

Version: 7.x-1.0-rc3 » 7.x-2.x-dev
Issue summary: View changes

it might be possible to make this work by including Stripe.js (the file responsible for generating tokens) in that admin page.

It also might be possible use Card On File to make this work.

Either way would take some work, and might be better suited to the 2.0 branch.

pnigro’s picture

Version: 7.x-2.x-dev » 7.x-1.x-dev
Status: Active » Needs review
StatusFileSize
new3.51 KB

Hello,

It appears that commerce_stripe.js is already added to the admin page when the stripe terminal payment form is generated. Only minor changes are needed to commerce_stripe.js to make it work. Since this is a quick fix, can this basic functionality be considered for the 7.x-1.x branch? Card on file options can be added to 7.x-2.x. Please review attached patch.

Thank you,
Paul

aviindub’s picture

Looks reasonable to me. I am going to leave it up for review for a little while before committing.

pnigro’s picture

Thank you aviindub. The only part of the patch that is tricky is identifying that the terminal form is a stripe payment form since it does not contain a radio button. One similarity between the two payment forms is they both contain stripe classes. Would changing

if ($("input[value*='commerce_stripe|']").is(':checked') || $('.stripe').length) {

to

if ($('.stripe').length) {

make sense or is there a better way?

aviindub’s picture

i think you created this patch against an older version of the code, because i can't get it to apply against the current 7.x-1.x.

Can you re-roll that against the current 7.x-1.x please? it may help if you tell me exactly what commit sha this should apply on to, because i will be updating 7.x-1.x some more over the next few days.

re: your question from #6, i think that selector is probably not specific enough, because i think that will cause the javascript to fire any time stripe is included on the page, even if it isnt selected.

pnigro’s picture

Hello aviindub,

Attached is a new patch applied to 7.x-1.x 2014-Jul-29.

I am not sure what to do about #6. With the attached patch it is my understanding that the javascript will only fire when the checkout submit or terminal submit buttons are clicked. Once clicked, there is a check to verify that the commerce stripe payment form is present on the page before it continues. The current check is to verify that the commerce stripe radio button is selected before continuing. Since the terminal payment form does not have a radio button, this check will fail.

I was thinking the "stripe" class can be used for this check instead because it is only present on the page when the commerce payment form is rendered based on commerce_stripe_submit_form. If a user selects a different payment method the "stripe" class would dissappear from the page because the payment form would be overriden. I agree that the "stripe" class is not very specific. Perhaps adding a hidden id field in commerce_stripe_submit_form would work? Do you have any ideas?

Thank you,
Paul

aviindub’s picture

we definitely need to key this off of something more unique than "stripe". my general approach to this lately has been to use hook_form_alter and hook_widget_form_alter to insert unique classes, but i am having trouble getting that to work for some reason.

Also, please note that i am about to push out a large set of changes that are impossible to merge with this patch, so i will need you to make your new patch (once you have the class thing figured out) against the newest version. I will make another note here when that is posted (shortly).

aviindub’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev
Status: Needs review » Postponed

while this is a seemingly simple change, it has potentially serious consequences that are very difficult to test against due to possible variations in setup and implementation. the word "stripe" especially seems risky to me, because i could easily see a designer using that as a selector for some sort of visual styling involving stripes.

given that any change we make to this part of the code needs to be tested more thoroughly than usual, i don't think we should attempt to cram this in to the 1.0 branch.

mr.andrey’s picture

subscribing... this would be good to have implemented.

angms-bh’s picture

I am also interested in the feature

angms-bh’s picture

Regarding #9 To key off of something more unique then "stripe", you can add a hidden field to the form that handles the terminal page using function
commerce_stripe_form_commerce_payment_order_transaction_add_form_alter(&$form, &$form_state).
You would then check that you are dealing with stripe using
if (!empty($form['payment_terminal']) && $form_state['payment_method']['method_id'] == 'commerce_stripe') {
You can then add your hidden form values to the $form['payment_terminal']
This is how commerce_authnet alters the payment terminal form so see their code for an example if need be.

I have attached a patch which can be applied to the latest dev 7.x-1.x June 2nd

Unfortunately, having a terminal doesn't really make sense unless you have the ability to refund, authorize and capture, and void what has been charged. I have also implemented this and will get it to work with the 7.x-2.x in the future.

angms-bh’s picture

I have created a patch with changes to commerce_stripe.js and commerce_stripe.module.

Please note especially the changes to commerce_stripe.js as I am not a security expert and do not know if my changes would affect the security of the card information.

I created the patch using format-patch and it should be applied to 7.x-1.x from June 2nd 2015.

angms-bh’s picture

Status: Postponed » Needs review

I have attached a patch for #14 that needs review against the latest 7.x-1.x version

pnigro’s picture

Version: 7.x-2.x-dev » 7.x-1.x-dev

Thank you @angms-bh. I will begin testing your patch.

pnigro’s picture

Patch #14 works very well for the stripe.js integration type. However, if the user decides to use the checkout integration type, the terminal form breaks. One way to begin to fix this would be to generalize the javascript that is used for the checkout form so that it can also be used for the terminal form. @angms-bh had a great idea in her patch to include a hidden input element on the terminal form. What if we added this hidden element to both forms? We could then modify the check in commerce_stripe.js from

        $('body').delegate('#edit-continue', 'click', function(event) {

          // Prevent the Stripe actions to be triggered if Stripe is not selected.
          if ($("input[value*='commerce_stripe|']").is(':checked')) {

to

        $('body').delegate('#edit-continue, .page-admin-commerce-orders-payment #edit-submit', 'click', function(event) {
            // Prevent the Stripe actions to be triggered if hidden field hasn't been set
        	var cs_terminal = $('input[name=commerce_stripe_terminal]').val();
        	if ( cs_terminal > 0) {
                  .....

What does everyone think of this idea?

angms-bh’s picture

I was able to reproduce the bug with the code and checkout integration. I think that the form for the terminal is generated by payment module system somehow, and I am not quite sure why it is not rendering the whole form when checkout integration is selected. The #edit-continue only shows up on the checkout page from what I can gather, so I don't think adding the hidden element there will work. We need to figure out why the whole form for the terminal is not being shown. I will look into this some tonight.

angms-bh’s picture

I did my implementation before the checkout integration was implemented and I didn't see that feature when I put my changes in.
I have looked over the code for the $('body').delegate('#edit-continue', 'click', function(event) situation to try to generalize it for the terminal. So far I am seeing an issue with the fact that the submit button for the checkout page is called #edit-continue, but the submit button for the terminal is called #edit-submit. this becomes a factor when the following code is used to get the nearest form submit button.

   var form$ = $("#edit-continue").closest("form");
   var submitButtons$ = form$.find('.checkout-continue');

We need a way to know which submit button is being used.
Alternatively, we could just copy the code under $('body').delegate('#edit-continue', 'click', function(event) and make it work for the terminal case. I haven't tried that yet. I will try this tomorrow.

As an aside, I tried to find a way to know that we were creating a submit form for a terminal from function commerce_stripe_submit_form($payment_method, $pane_values, $checkout_pane, $order) . However, I could see know way of knowing. If we could know this, then we could just tell the system to use stripe.js for the terminal situation and not worry about the checkout integration for terminal.

angms-bh’s picture

I have worked around the issue with the checkout. In the terminal, instead of using the checkout.js when the checkout integration option is checked, I check that we are dealing with the terminal form when the function commerce_stripe_submit_form is called and use stripe.js. This can be known because the terminal form request_path is a system/ajax. commerce_stripe_submit_form is either called on checkout or in the terminal so this is unique to the terminal.

We need to use stripe.js for the terminal because it allows for a variable amount to be entered from the administration page.

I have attached a patch which in sync with 7.x-1.x from 6/5/15

aviindub’s picture

Status: Needs review » Needs work

sorry, i cant get your patch to apply. can you tell me what commit sha it should apply against?

also, please refrain from making unrelated changes in the same patch. your patch for this issue should not contain changes to commerce_stripe.drush.inc

angms-bh’s picture

Sorry for such a long delay in getting this patch posted. Please see my comments in post #20.
The other reason I had to use stripe.js for the terminal was because the checkout.js doesn't seem to work with the terminal.

Instead of the ^ selector, I used the * selector for the cardFieldMap because it wouldn't work with ^ operator when I added cardFields when handling the page-admin-commerce-orders-payment form for the terminal.

As an additional aside, there were some strange characters that were inserted for the #description of the panelLabel when I cloned the repository and I had to delete them to get the file to save. That is why that line was changed.

The patch is created off of the 97f0549 commit on the 7.x.1.x

torgospizza’s picture

Status: Needs work » Needs review

Patch here, so Needs Review.

pnigro’s picture

I received the following error when trying to apply the patch from #22.

patch: **** Only garbage was found in the patch input.

I decided to manually make the changes in commerce_stripe-7.x-1.x-dev (2015-Sep-15) as a quick test and it works. Thank you angms-bh.

Paul

torgospizza’s picture

Status: Needs review » Needs work

It does look like the patch has some tabbing/spacing issues that aren't up to standard and so this patch will need a re-roll. Thank you for testing, @pnigro!

I think also that we could make this available for Stripe Checkout integration. I'm not quite sure why it was decided that Checkout integration should not have terminal (or Card on File) support, since those features aren't mutually exclusive, but we can further integrate in a future patch.

angms-bh’s picture

I am following the instructions from https://www.drupal.org/node/707484 to make the patch. Are there better instructions that I can follow? I will look more closely at the coding standards this weekend and see where it is wrong.

It does work when you choose stripe Checkout integration. It is just that when commerce_stripe_submit_form is called, I use the stripe.js to handle the request when in the terminal under the payment tab. I could not get checkout.js to work with the terminal. One of the reasons for using stripe.js is so that a variable amount can be entered rather than the total amount.

angms-bh’s picture

Ok. I reconfigured my Eclipse on Windows following the instructions at https://www.drupal.org/node/75242. I think the problem was that I was saving as the wrong file format. I think that is why the patch was seen as garbage. Hopefully, this one will work.

I fixed the tabbing issues in commerce_stripe.js.

This patch is built off of the commit on Sept 15, 2015. Commit 97f0549.

angms-bh’s picture

Status: Needs work » Needs review
angms-bh’s picture

Here is the patch file. For some reason it didn't upload earlier.

angms-bh’s picture

I saw some formatting issues in the patch and this one hopefully resolves that.

mesch’s picture

@torgosPizza re #25, it's been a while but I recall at the time there was uncertainty around perceived more stringent security requirements around Stripe Checkout. It was unclear - to me, anyways - whether allowing customers to update their card info via the user menu (as allowed by Commerce Card on File) and storing/using a token for the card would be compatible with those requirements.

pnigro’s picture

@angms-bh - thank you for working on this feature. I tried to apply your patch and unfortunately I am getting the same error "patch: **** Only garbage was found in the patch input." I am not sure why it is doing that.

I modified your patch to bring us closer to implementing checkout integration. The total is now being taken from the terminal form using jQuery. The last steps are posting the payment to stripe and the website.

pnigro’s picture

Status: Needs review » Needs work
MarieKirya’s picture

Based on #20 I rerolled to work with v1.0, this worked for me.

ngreenup’s picture

The patch in #34 did not apply correctly for me. The first three hunks worked but the last failed. I tried the patched module anyway and I was presented with the Stripe credit card option but when I tried to enter a credit card I got the error:

"We received the following error processing your card. Please enter your information again or try a different card.
Must provide source or customer."

vincentdemers’s picture

This patch should apply cleanly to 7.x-1.1

Thanks to everyone who helped with this feature.

torgospizza’s picture

Status: Needs work » Needs review
nickonom’s picture

Indeed the patch in #36 works for 7.x-1.1 as I can add Stripe as payment method on any order's payment page and proceed to entering credit card details. However, it is not applying cleanly giving:

patch < *diff
patching file commerce_stripe.js
Hunk #1 FAILED at 18 (different line endings).
Hunk #2 FAILED at 203 (different line endings).
2 out of 2 hunks FAILED -- saving rejects to file commerce_stripe.js.rej
patching file commerce_stripe.module
aviindub’s picture

theres a substantial amount of code here affecting the most security-sensitive part of this module. i'm sure this patch is awesome, but i just dont have the time to give it the review it needs before rolling out to the community. also, please fix your patch creation process:

$ git apply --check commerce_stripe-fixforterminal-1875234-36-7.41.patch.diff
error: commerce_stripe/commerce_stripe.js: No such file or directory
error: commerce_stripe/commerce_stripe.module: No such file or directory
ice70’s picture

Hi,

the patch on #36 applied to both the 7.x-1.2 2016-Feb-10 and 7.x-1.x-dev 2016-Feb-10

But, I am getting the following error when making payments through the order payment tab

We received the following error processing your card. Please enter your information again or try a different card.
You have passed a blank string for 'card'. You should remove the 'card' parameter from your request or supply a non-blank value.

in stripe logs:
Parsed Request POST Body
amount: "37800"
currency: "EUR"
card: ""
description: "Order Number: 4"
receipt_email: "admin@example.com"
metadata:
order_id: "4"
order_number: "4"
uid: "1"

Response body
error:
type: "invalid_request_error"
message: "You have passed a blank string for 'card'. You should remove the 'card' parameter from your request or supply a non-blank value."
param: "card"

How do I get the correct card data when in the order payments tab admin/commerce/orders/n/payment?

Thank you for your help,
ice70

ice70’s picture

Hi,

in admin/commerce/config/payment-methods/manage/commerce_payment_commerce_stripe/edit/3

I have set the integration type to 'checkout'
Front end this works great.

In the admin area:
admin/commerce/orders/n/payment

I have the option to select 'stripe' and add payment
This builds the form
PAYMENT TERMINAL: STRIPE
Amount: balance to pay

When I save, instead of the Stripe pop up to take the card details, I get in the console:
VM13727:18 Uncaught ReferenceError: Stripe is not defined

Which is the commerce_stripe.js file
Line 18 is: Stripe.setPublishableKey(settings.stripe.publicKey);

The admin page is missing the file: https://checkout.stripe.com/checkout.js

So I have created

function hook_init() {
if (arg(0) == 'admin' and arg(1) == 'commerce' and arg(2) == 'orders' and arg(4) == 'payment') {
drupal_add_js('https://checkout.stripe.com/checkout.js', 'external');
}
}

And https://checkout.stripe.com/checkout.js is on the admin payment page.

But I am still getting the same error: Uncaught ReferenceError: Stripe is not defined

What am I missing?

thank you for your help,
ice70

torgospizza’s picture

the Stripe object is defined not in the checkout.js file but the stripe.js file. You'll need to include that one first for that error to be fixed.

ice70’s picture

Hi torgosPizza,

thank you so much for filling in the missing piece :)

changed the function to

function hook_init() {
if (arg(0) == 'admin' and arg(1) == 'commerce' and arg(2) == 'orders' and arg(4) == 'payment') {
drupal_add_js('https://js.stripe.com/v2/', 'external');
drupal_add_js('https://checkout.stripe.com/checkout.js', 'external');
}
}

and the Stripe not defined error was solved!

But... I had the stripe Integration type setting set to checkout and when I tried to save the transaction, instead of getting the stripe form pop for the credit card details, it seems to just submit the transaction, which of course fails as no card details are included.
If I switch to stripe.js the admin payment works as it should, but the client prefers the front end to use the 'checkout' version.

I have set the /admin/commerce/config/payment-methods/manage/commerce_payment_commerce_stripe
to use stripe.js then modified commerce_stripe.module:

line 350: function commerce_stripe_submit_form($payment_method, $pane_values, $checkout_pane, $order) {

and added at about line 385:

// admin uses system/ajax
// front end uses checkout/n/review
// admin needs to use stripjs, so set that in the rules
// set front end to checkout here.
if (arg(0) == 'checkout' and arg(2) == 'review') {
$integration_type = 'checkout';
}

This does what I want it to do, BUT, that is so not the right way of doing this!!
Ideally getting admin check out to work with the checkout option [with the card details pop up showing] would be great.
But failing that, moving that edit I have added out of commerce_stripe.module and into a custom module would be far safer.
I am just not quite sure how to?

I probably want to do something like:

if (arg(0) == 'checkout' and arg(2) == 'review') {
$payment_method['settings']['integration_type'] = 'checkout';
}

To alter to the $payment_method values used for the method callback: commerce_stripe_submit_form($payment_method, $pane_values, $checkout_pane, $order)

I am just unsure on how to set this up?

I appreciate this is probably more a drupal 'howto' question than a commerce stripe question.

Thank you for your help,
ice70

torgospizza’s picture

I think one of the issues is that the JS looks for a setting on a "Stripe" object but you are probably right that the two are conflicting. For example you should only have to include Checkout.js, and then just alter the javascript to not look for a config value on Stripe.settings. But I would warn against editing any Commerce Stripe files, because any local modifications you've made will break when a new version is released.

You may want to create a new issue for what you are doing, though, as you're talking about steps on the Review page whereas this issue is for the Payment tab in an order edit form.

ice70’s picture

Hi torgosPizza,

> But I would warn against editing any Commerce Stripe files
Yes, I have massive alarm bells ringing in my head!

If we flipped it round and have the front end set to use checkout by default [as in set it in the stripe settings] and then try and pick up the order payment and alter that - for example

if (arg(0) == 'admin' and arg(1) == 'commerce' and arg(2) == 'orders' and arg(4) == 'payment') {
$payment_method['settings']['integration_type'] = 'stripejs';
}

we are back on track for this issue?

How could I implement this without touching the existing source?

Thank you for your help
ice70

angms-bh’s picture

This is not really on topic with this particular issue, but I will answer it.

There is a way to dynamically set the payment method in your hook_init. Just getting the payment method and using `$payment_method['settings']['integration_type] = 'stripejs' `will not work. This is because you are not given a reference to the payment_method to SET the values, just GET the values. Also, the settings array is stored differently because it is a settings array for a rule.

Instead you would need to modify the rule for the payment method.
I would do something like the following:

function set_integration_type($integration_type) {
  $payment_method_str = 'commerce_stripe';  

  $rule_str = 'commerce_payment_' . $payment_method_str;
  $action_str = 'commerce_payment_enable_' . $payment_method_str;

  $rule = rules_config_load($rule_str);
  
  foreach ($rule->actions() as $action) {
    if (is_callable(array($action, 'getElementName')) && $action->getElementName() == $action_str) {
      if (is_array($action->settings['payment_method']) && !empty($action->settings['payment_method']['settings'])) {
        $action->settings['payment_method']['settings']['integration_type']=$integration_type;
      }
    }
  }
  $rule->save();

}

function hook_init() {
if (arg(0) == 'admin' and arg(1) == 'commerce' and arg(2) == 'orders' and arg(4) == 'payment') {
  set_integration_type('stripejs');
} else {
  set_integration_type('checkout');
}

}

See the second answer on http://drupal.stackexchange.com/questions/188058/how-do-you-change-rules...

You will need to remember to set it back

ice70’s picture

Hi angms-bh

first of all, thank you so much for taking the time to provide a solution :)

On the admin/commerce/orders/*/payment
payment page, the arg() at the time of calling is system/ajax, so I have added that in the if statement as well and the stripejs fires up in the admin section

I added the elseif to stop the set_integration_type('checkout'); firing on evrey page load.

function hook_init() {
 if ((arg(0) == 'admin' and arg(1) == 'commerce' and arg(2) == 'orders' and arg(4) == 'payment') or (arg(0) == 'system' and arg(1) == 'ajax')) {
    set_integration_type('stripejs');
  }
  elseif ((arg(0) == 'checkout' and arg(2) == 'review')) {
    set_integration_type('checkout');
  }
}

And it looks like it works as it should :) Thank you so much! And the module code is back to the unedited version :)

Just one thing I am not quite sure about:
> You will need to remember to set it back
set what back to what?

thank you for your help,
ice70

angms-bh’s picture

@ice70 What I meant by you have to set it back is once you set the integration_type to stripejs, it would remain that for all calls to commerce_stripe_submit_form. This function gets called for the Payment Tab and for the regular order checkout. I believe you are handling the situation with the `elseif ((arg(0) == 'checkout' and arg(2) == 'review')) `.

steveoliver’s picture

I believe #40 through #48 are trying to work around this issue: #768128: ajax callbacks can't apply #attached (see comment #14 which prescribes jQuery v1.10 (jquery_update.module) in order for the js files to be loaded with the forms when rendered via ajax (in the Payment tab)).

If jQuery 1.10 gets the Stripe js files to be loaded as expected, then we are back to the issue of just distinguishing the two different forms (i.e edit-continue vs. edit-submit).

I learned of the requirement for jQuery 1.10 while implementing a payment method with terminal support (Vantiv), using commerce_stripe as an example.

thejacer87’s picture

Issue summary: View changes
StatusFileSize
new120.35 KB
new131.19 KB

edit: duplicated post

thejacer87’s picture

Issue summary: View changes

hey guys, the patch in #36 applied cleanly. And it looks like it should work. except I get an error when I submit it. I am using the Commerce Stripe Payment Gateway and I have it working with card on file for regular checkouts.

The one error is what I would expect when not entering the Card number. But the "missing required param: number" I have no idea where it's coming from. I searched my entire project for the string "missing required param" and came up empty.

ice70’s picture

hi @thejacer87

I think the "missing required param: number" is a response from the stripe api [https://stripe.com/docs/api#errors] rather than the drupal stripe module.

Are all the required JS files included in the admin page?

thejacer87’s picture

thanks @ice70, i will start my search there. I'm actually an idiot, I was meaning to post my response to #2212475: Add card on file options to admin payment terminal form. Which I think are possibly related... at least for what I am trying to accomplish. I know some people in this issue mentioned using card on file.

thejacer87’s picture

hey @ice70, wouldn't the JS files be included already since the regular stripe payment works already? Or is it a different file for CoF purchases?

ice70’s picture

hi @thejacer87, sorry, it looks like they probably are as you are getting the response from stripe. I am not using the Card on File module so I am not sure if there are difference files in use.

I guess I was not as awake as I thought I was first thing this morning ^blush^

torgospizza’s picture

@thejacer87: That is a Stripe error - "number" is a parameter passed onto Stripe.js to generate a token for the card data that's been entered. Which, of course, we don't need to generate if we're using a Card on File. So either the issue is that Commerce Stripe's JS needs to be updated to work with this terminal method correctly, or the Card on File patch in the original issue needs some tweaking.

If I can find some time I will try to take a look, but I would start there - making sure that commerce_stripe.js being generated by the terminal form is aware that it does not need to submit values to Stripe.js and receive a token, it just needs to provide a card_id stored through CoF.

thejacer87’s picture

Ya I've been working on it @torgosPizza, and I can't seem to wrap my head around it. I can put a break point in the commerce_stripe.js file on the regular checkout, and I can see it call createToken() when I submit for the payment form. Then I put a break in commerce_stripe_submit_form_submit() , and I can see that the token is there as expected.

But when I do the same in the terminal, the break point in the commerce_stripe.js doesn't hit, yet somehow in the commerce_stripe_submit_form_submit(), the token has been created.

So yah, if you could take a look, and let me know what you can find that would be really helpful!

Added #2212475: Add card on file options to admin payment terminal form as a related issue. Remove it if you think it's inappropriate.

thejacer87’s picture

Issue summary: View changes
StatusFileSize
new348.15 KB
new11.21 KB
new9.39 KB

Here's my patch to make purchases with cards on file for the customer.

torgospizza’s picture

Thanks for contributing the patch. This looks overall like a good change, albeit pretty major.

Did you test to make sure this didn't break Stripe Checkout configurations or break anything else in the checkout flow? I will apply this to my local working copy as well, since there are a few other patches in the queue that may overlap here.

thejacer87’s picture

oh yah! i tested regular checkout everything seems fine.

torgospizza’s picture

Awesome, thanks! That's good to know.

I'll do my own testing and a more thorough review and with any luck we can get this pushed to dev soon. (And hopefully #2212475: Add card on file options to admin payment terminal form will get committed which is a nice enhancement to this feature.)

pnigro’s picture

I tested the patch in #58 and it works great for stripe.js. Unfortunately, it doesn't work for the Checkout integration type. For the regular checkout form, we use the following to identify which integration type is being used.

if (settings.stripe.integration_type == 'stripejs') {
....
}
else if (settings.stripe.integration_type == 'checkout') {
...
}

Should we do the same for the terminal payment form?

thejacer87’s picture

would you want to use the checkout integration type for backend payments by admins? the checkout integration seems more like a customer facing thing.

pnigro’s picture

As of right now we are using stripe.js, but that may change in the future. If we were to switch to the checkout integration type, we would no longer be able to use the terminal payment form. Perhaps the best approach is to allow the user to choose the integration type for both the front end and back end.

torgospizza’s picture

No, it doesn't make sense to me that you'd use Checkout to submit a card as an admin. Checkout is a user-facing mechanism, whereas to add a payment through the backend should be the same no matter which integration you are using. Perhaps the form and other callbacks for adding a payment to an order through the admin UI should be outside of the integration itself.

@thejacer87: Would you be able to take a look at seeing if it is possible to use the patch no matter which integration config is being used at checkout?

pnigro’s picture

@torgosPizza, that works for me.

thejacer87’s picture

The only way I could find, the 'commerce_payment_order_transaction_add_form' in the REQUEST variable. I don't really like it but might be the only way

pnigro’s picture

@thejacer87, thank you for the patch. What if we modify the integration type check in commerce_stripe_submit_form to the following?

if ($integration_type == 'checkout' && isset($checkout_pane)) {
...
}
else {
  // Run for all other integration types, which for now is only stripe.js.
  $form = _commerce_stripe_credit_card_form();
  // Include the stripe.js from stripe.com.
  drupal_add_js('https://js.stripe.com/v2/', 'external');
}

This way stripe Checkout will only work when the checkout pane is set, which occurs during the customer checkout process. For the payment terminal form, stripe.js will be used regardless of the integration type that is set. I tested the attached patch with card on file during customer checkout and both integration types work.

Unfortunately, I wasn't able to get the checkout integration type to work when adding a new card in the user's profile. The function that is responsible for building that form is commerce_stripe_cardonfile_create_form. We can probably create a separate issue to address that functionality. Please test the attached patch which is based on the patch submitted by @thejacer87 and let me know what you think.

Thank you

thejacer87’s picture

@pnigro

was adding a card through user profile working before the patch? you talking about an admin adding a user card? or the user adding their own card?

if this patch didn't affect that, then ya, we should make a new issue for sure. But if our patch here is causing the issue we should probably try to resolve it.

edit: just tested it. the patch DOES break adding a card in the user settings page. although, i think it is kinda broken to begin with... when i added a card to a users account as an admin, it put my admin email as the 'Name on card'.

So maybe we have got to take out the checkout integration for all backend stuff. @torgosPizza, can we commit this patch and create a new issue to take out all backend checkout integration. Or do you want it dealt with in this patch?

pnigro’s picture

@thejacer87

This is for the user adding their own card in user/%/cards/add. Yes, the checkout integration was working in commerce_stripe-7.x-1.x-dev (2016-May-13) before the patch. Something in this patch is causing this functionality to break and I haven't been able to identify it.

After further testing, I have encountered caching issues which prevent the terminal form and the user/%/cards/add form from working on a consistent basis. I encountered #2701857: Card processing error: You have passed a blank string for 'card'. You should remove the 'card' parameter from your request or supply a non-blank value. on the terminal form after applying the patch. If I clear all caches and refresh the page it works. Have you experienced this at all?

torgospizza’s picture

Version: 7.x-1.x-dev » 7.x-3.x-dev

I'm moving this to the 3.x queue as that's where new features should be added - version 1.0 of the Stripe Library is so outdated now, and upgrading is fairly painless, that I think we should try and keep parity. Luckily, the patch applies fairly cleanly (with some fuzz).

I can confirm that the Add to Cart form no longer works with the patch, however, and it appears to be due to the changes to commerce_stripe.js. I reverted just that file and the Checkout widget does appear, and so I can probably add this to the 3.x dev branch now that I've tested it.

@thejacer87:

The patch DOES break adding a card in the user settings page. although, i think it is kinda broken to begin with... when i added a card to a users account as an admin, it put my admin email as the 'Name on card'.

I saw this too, and in 3.x I've added the below to handle this situation:

    // If we're using Checkout integration, and the owner field is an email address,
    // this is probably not wanted; use the Name Line from the billing profile instead.
    if ($payment_method['settings']['integration_type'] == 'checkout'
      && valid_email_address($form_state['values']['credit_card']['owner'])
      && !empty($form_state['values']['commerce_customer_address'][$langcode][0]['name_line'])) {
      $card_data->card_name = check_plain($form_state['values']['commerce_customer_address'][$langcode][0]['name_line']);
    }

Of course this only works if we have a billing address on file. There might be a better way, and I'm open to suggestions.

torgospizza’s picture

StatusFileSize
new2.85 KB

Here's a re-roll.

I'm not sure about this bit:

+/**
+ * Implements hook_form_alter().
+ *
+ * Using form alter to not interfere with another patch adding the same hook.
+ */
+function commerce_stripe_form_alter(&$form, &$form_state, $form_id) {
+  if ($form_id != 'commerce_payment_order_transaction_add_form') {
+     return;
+  }
+
+  if (!empty($form['payment_terminal']) && isset($form_state['payment_method']['method_id']) && $form_state['payment_method']['method_id'] == 'commerce_stripe') {
+    $form['payment_terminal']['commerce_stripe_terminal'] = array(
+      '#value' => 1,
+      '#type' => 'hidden',
+    );
+  }
+}

What was this block accomplishing? Apologies for my density.

pnigro’s picture

@torgosPizza, thank you for working on this issue. The block of code in #72 is used to add a hidden field with a value of 1 on the order terminal form to distinguish it from other payment methods. This value is then checked in commerce_stripe.js using the following code from patch #68:

        $('.page-admin-commerce-orders-payment').delegate('#edit-submit', 'click', function(event) {
          // Prevent the Stripe actions to be triggered if hidden field hasn't been set
          var cs_terminal = $('input[name=commerce_stripe_terminal]').val();
          if ( cs_terminal > 0) {
            $(this).addClass('auth-processing');

            // Prevent the form from submitting with the default action.
            event.preventDefault();


            // Disable the submit button to prevent repeated clicks.
            $('.form-submit').attr("disabled", "disabled");

            var cardFields = {
              number: 'edit-payment-details-credit-card-number',
              cvc: 'edit-payment-details-credit-card-code',
              exp_month: 'edit-payment-details-credit-card-exp-month',
              exp_year: 'edit-payment-details-credit-card-exp-year',
              name: 'edit-payment-details-credit-card-owner'
            };

            var responseHandler = makeResponseHandler(
              $("#edit-submit").closest("form"),
              $('div.payment-errors'),
              function () {
                $(this).removeClass('auth-processing');
                // Enable the submit button to allow resubmission.
                $('.form-submit').removeAttr("disabled");
              },
              function (form$) {
                var $btnTrigger = $('.form-submit.auth-processing').eq(0);
                var trigger$ = $("<input type='hidden' />").attr('name', $btnTrigger.attr('name')).attr('value', $btnTrigger.attr('value'));
                form$.append(trigger$);
              }
            );

            createToken(cardFields, responseHandler);

            // Prevent the form from submitting with the default action.
            return false;
          }
        });

If you add the above code to commerce_stripe.js, the terminal form works.

torgospizza’s picture

@pnigro: Thanks, I'll take a look. I'll see about reimplementing the JS for this page - it'd be great if we could consolidate some code here (and make the delegation react to a more abstract class) if possible, but I think a straightforward approach is also acceptable.

torgospizza’s picture

I can confirm that adding the block of code from #73 into commerce_stripe.js fixes the "You have passed a blank value for 'card'" when using Checkout integration.

I'm going to do some more testing at checkout, using Stripe.js and Checkout, to make sure nothing is broken. If that's the case then I can commit this to the 3.x-dev branch.

torgospizza’s picture

Re-roll against latest 3.x. Please test.

I also moved the hook_form_alter to a hook_form_FORM_ID_alter() as those tend to look a lot cleaner (and sure beat adding switches or if/then all over the place).

thejacer87’s picture

#76 worked for the backend payments.... adding cards through the account page still didn't work though... possibly local server config issues?

edit: im a dummy, remember to clear your caches b4 you post like an idiot :)

torgospizza’s picture

@thejacer87: What happens instead?

Just FYI I was able to test locally on my testing Commerce Kickstart installation. If you have any error messages please post them. (Make sure you clear all your caches first.)

thejacer87’s picture

RTBC+1 talked to @torgosPizza and we figured out the issue...

also, since this issue kinda has COF wrapped into it a little bit, make sure you use the dev version of COF or apply this #2212475: Add card on file options to admin payment terminal form to get access to the saved cards

thejacer87’s picture

Status: Needs review » Reviewed & tested by the community

classic drupal devs... always forget to change the status

pnigro’s picture

StatusFileSize
new15.87 KB

I love the progress on this, but unfortunately #2212475: Add card on file options to admin payment terminal form is not working on the admin payment terminal form. I am getting "Could not find payment information" when selecting a stored card. The steps to reproduce are as follows:

  1. Download commerce_stripe-7.x-3.x-dev - 2016-10-10 and commerce_cardonfile - 7.x-2.0-beta5+7-dev - 2016-09-15
  2. Apply patch from #1875234-76: Allow payments to be made through order payment tab to commerce _stripe
  3. Add a credit card to a user account
  4. Create an order and assign it to the user account
  5. Go to the admin payment terminal form located at admin/commerce/orders/%/payment
  6. Select the stored card and click save
thejacer87’s picture

@pnigro

try applying the COF patch maybe?? thats how i got it working... @torgosPizza said that he was using the dev version in our IM's, but maybe he was mistaken, or maybe the COF module is messed up...

i think at this point though, that is a COF issue... as this patch now allows terminal payments...

torgospizza’s picture

Confirmed, I get the error, too.

I think that's a Stripe error, so we essentially need to prevent Stripe JS from firing if we have selected a Card on File.

I feel like this was working before I added the JS from #73; so it looks like there is a conflict. Without #73 the CoF selections work but Checkout does not. With #73, Checkout works but CoF does not.

torgospizza’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new5.52 KB

Okay, I think I have this solved. We just needed to add one more condition to commerce_stripe_form_commerce_payment_order_transaction_add_form_alter():

&& $form['payment_terminal']['payment_details']['credit_card']['#access'])

Attached is a new patch which includes this. Please try re-applying it against Commerce Stripe 3.x.

torgospizza’s picture

StatusFileSize
new5.52 KB

Sorry, that one had a typo. Try this one instead.

torgospizza’s picture

Status: Needs review » Needs work

Sigh. The patch allows us to select a CoF but now the main form is broken.

Setting to Needs Work. I think the idea is there, it's just not fully baked yet.

torgospizza’s picture

Status: Needs work » Needs review
StatusFileSize
new5.71 KB
new1.01 KB

Okay, I solved this by adding a return in case the #access for credit_card form is not set or set to FALSE, to correctly account for Card on File behavior.

Please give this new patch a shot. Interdiff included.

pnigro’s picture

@torgosPizza, patch #87 works great! Thank you so much!

torgospizza’s picture

@pnigro: Thanks! Glad to hear it. I'll let others test and mark as RTBC. Once that happens I will commit to -dev.

Also if you have a chance please take a look at #2816709: Require Stripe module? I'd like to know your thoughts there. Thanks!

pnigro’s picture

@torgosPizza Great news! Thank you.

I will look into #2816709: Require Stripe module.

thejacer87’s picture

Status: Needs review » Reviewed & tested by the community

@torgosPizza FTW!!!

patch works, both stripe.js and checkout. backend payments and frontend payments... yay!

  • torgosPizza committed 784a251 on 7.x-3.x
    Issue #1875234 by angms-bh, torgosPizza, thejacer87, pnigro,...
torgospizza’s picture

Status: Reviewed & tested by the community » Fixed

Beauty :) Committed.

Thanks everyone!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.