I'm trying out some of the updates on the dev branch (really interested in the shipment admin). I switched from 2.11 to dev and ran into the error below. I tried both the beta2 and rc1 versions of the Commerce Stripe module. Seem to have the same error regardless. Paypal express gateway still works. The configurations appear to be pulling the api keys into the payment gateway but errors out when doing the ApiRequest.

The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Stripe\Error\Authentication</em>: No API key provided.  (HINT: set your API key using &quot;Stripe::setApiKey(&lt;API-KEY&gt;)&quot;.  You can generate API keys from the Stripe web interface.  See https://stripe.com/api for details, or email support@stripe.com if you have any questions. in <em class="placeholder">Stripe\ApiRequestor-&gt;_requestRaw()</em> (line <em class="placeholder">219</em> of <em class="placeholder">/var/www/html/vendor/stripe/stripe-php/lib/ApiRequestor.php</em>). <pre class="backtrace">Stripe\ApiRequestor-&gt;request(&#039;get&#039;, &#039;/v1/customers/cus_DxiiTbC35pU4XK&#039;, Array, Array) (Line: 31)
Stripe\ApiResource-&gt;refresh() (Line: 132)
Stripe\ApiResource::_retrieve(&#039;cus_DxiiTbC35pU4XK&#039;, NULL) (Line: 40)
Stripe\Customer::retrieve(&#039;cus_DxiiTbC35pU4XK&#039;) (Line: 322)
Drupal\commerce_stripe\Plugin\Commerce\PaymentGateway\Stripe-&gt;doCreatePaymentMethod(Object, Array) (Line: 261)
Drupal\commerce_stripe\Plugin\Commerce\PaymentGateway\Stripe-&gt;createPaymentMethod(Object, Array) (Line: 173)
Drupal\commerce_payment\PluginForm\PaymentMethodAddForm-&gt;submitConfigurationForm(Array, Object) (Line: 186)
Drupal\commerce_payment\Plugin\Commerce\InlineForm\PaymentGatewayForm-&gt;submitInlineForm(Array, Object) (Line: 155)
Drupal\commerce\Plugin\Commerce\InlineForm\InlineFormBase::runSubmit(Array, Object)
call_user_func_array(Array, Array) (Line: 130)
Drupal\commerce_order\Element\ProfileSelect::doExecuteSubmitHandlers(Array, Object) (Line: 123)
Drupal\commerce_order\Element\ProfileSelect::doExecuteSubmitHandlers(Array, Object) (Line: 123)
Drupal\commerce_order\Element\ProfileSelect::doExecuteSubmitHandlers(Array, Object) (Line: 107)
Drupal\commerce_order\Element\ProfileSelect::executeElementSubmitHandlers(Array, Object)
call_user_func_array(Array, Array) (Line: 82)
Drupal\Core\Form\FormValidator-&gt;executeValidateHandlers(Array, Object) (Line: 275)
Drupal\Core\Form\FormValidator-&gt;doValidateForm(Array, Object, &#039;commerce_checkout_flow_multistep_default&#039;) (Line: 118)
Drupal\Core\Form\FormValidator-&gt;validateForm(&#039;commerce_checkout_flow_multistep_default&#039;, Array, Object) (Line: 575)
Drupal\Core\Form\FormBuilder-&gt;processForm(&#039;commerce_checkout_flow_multistep_default&#039;, Array, Object) (Line: 318)
Drupal\Core\Form\FormBuilder-&gt;buildForm(&#039;commerce_checkout_flow_multistep_default&#039;, Object) (Line: 216)
Drupal\Core\Form\FormBuilder-&gt;getForm(Object, &#039;order_information&#039;) (Line: 94)
Drupal\commerce_checkout\Controller\CheckoutController-&gt;formPage(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer-&gt;executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel-&gt;handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel-&gt;handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle-&gt;handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache-&gt;pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware-&gt;handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware-&gt;handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel-&gt;handle(Object, 1, 1) (Line: 669)
Drupal\Core\DrupalKernel-&gt;handle(Object) (Line: 19)

If I roll the commit back to #f9b3442bd590d0f20eb778286b497336de6d6ea0 which is right before the inline form updates I don't have the error. Could always be something else going wrong on my end but I wanted to post this in case someone else had seen this come up. Going to revert back to my latest stable set of modules for now.

Comments

Jon352 created an issue. See original summary.

bojanz’s picture

Drupal\commerce_order\Element\ProfileSelect::doExecuteSubmitHandlers(Array, Object) (Line: 107)

This could be a factor. On a -dev install of Commerce and Shipping ProfileSelect is not supposed to be used.
So if it's used it might be triggering submit from the wrong place.

Jon352’s picture

Just for fun I checked out the dev branches again and tried it against a custom checkout flow. The end result is the same but the ProfileSelect is not being called in this case.

The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Stripe\Error\Authentication</em>: No API key provided.  (HINT: set your API key using &quot;Stripe::setApiKey(&lt;API-KEY&gt;)&quot;.  You can generate API keys from the Stripe web interface.  See https://stripe.com/api for details, or email support@stripe.com if you have any questions. in <em class="placeholder">Stripe\ApiRequestor-&gt;_requestRaw()</em> (line <em class="placeholder">219</em> of <em class="placeholder">/var/www/html/vendor/stripe/stripe-php/lib/ApiRequestor.php</em>). <pre class="backtrace">Stripe\ApiRequestor-&gt;request(&#039;get&#039;, &#039;/v1/customers/cus_DxiiTbC35pU4XK&#039;, Array, Array) (Line: 31)
Stripe\ApiResource-&gt;refresh() (Line: 132)
Stripe\ApiResource::_retrieve(&#039;cus_DxiiTbC35pU4XK&#039;, NULL) (Line: 40)
Stripe\Customer::retrieve(&#039;cus_DxiiTbC35pU4XK&#039;) (Line: 370)
Drupal\commerce_stripe\Plugin\Commerce\PaymentGateway\Stripe-&gt;doCreatePaymentMethod(Object, Array) (Line: 310)
Drupal\commerce_stripe\Plugin\Commerce\PaymentGateway\Stripe-&gt;createPaymentMethod(Object, Array) (Line: 173)
Drupal\commerce_payment\PluginForm\PaymentMethodAddForm-&gt;submitConfigurationForm(Array, Object) (Line: 186)
Drupal\commerce_payment\Plugin\Commerce\InlineForm\PaymentGatewayForm-&gt;submitInlineForm(Array, Object) (Line: 155)
Drupal\commerce\Plugin\Commerce\InlineForm\InlineFormBase::runSubmit(Array, Object)
call_user_func_array(Array, Array) (Line: 130)
Drupal\commerce\Element\CommerceElementTrait::doExecuteSubmitHandlers(Array, Object) (Line: 123)
Drupal\commerce\Element\CommerceElementTrait::doExecuteSubmitHandlers(Array, Object) (Line: 123)
Drupal\commerce\Element\CommerceElementTrait::doExecuteSubmitHandlers(Array, Object) (Line: 107)
Drupal\commerce\Element\CommerceElementTrait::executeElementSubmitHandlers(Array, Object)
call_user_func_array(Array, Array) (Line: 82)
Drupal\Core\Form\FormValidator-&gt;executeValidateHandlers(Array, Object) (Line: 275)
Drupal\Core\Form\FormValidator-&gt;doValidateForm(Array, Object, &#039;commerce_checkout_flow_streamlabs_checkout_flow&#039;) (Line: 118)
Drupal\Core\Form\FormValidator-&gt;validateForm(&#039;commerce_checkout_flow_streamlabs_checkout_flow&#039;, Array, Object) (Line: 575)
Drupal\Core\Form\FormBuilder-&gt;processForm(&#039;commerce_checkout_flow_streamlabs_checkout_flow&#039;, Array, Object) (Line: 318)
Drupal\Core\Form\FormBuilder-&gt;buildForm(&#039;commerce_checkout_flow_streamlabs_checkout_flow&#039;, Object) (Line: 216)
Drupal\Core\Form\FormBuilder-&gt;getForm(Object, &#039;payment_information&#039;) (Line: 94)
Drupal\commerce_checkout\Controller\CheckoutController-&gt;formPage(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer-&gt;executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel-&gt;handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel-&gt;handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle-&gt;handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache-&gt;pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware-&gt;handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware-&gt;handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel-&gt;handle(Object, 1, 1) (Line: 669)
Drupal\Core\DrupalKernel-&gt;handle(Object) (Line: 19)

List of modules I'm using via composer. I tried to loosen up the versions but lock in on the dev versions of commerce and commerce_shipping:

"composer/installers": "^1.2",
        "cweagans/composer-patches": "^1.6",
        "drupal-composer/drupal-scaffold": "^2.5",
        "drupal/adminimal_admin_toolbar": "^1.8",
        "drupal/adminimal_theme": "^1.3",
        "drupal/commerce": "2.x-dev",
        "drupal/commerce_authnet": "~1.0",
        "drupal/commerce_braintree": "~1.0",
        "drupal/commerce_google_tag_manager": "~1.0",
        "drupal/commerce_paypal": "^1.0",
        "drupal/commerce_shipping": "2.x-dev",
        "drupal/commerce_stripe": "~1.0",
        "drupal/commerce_taxjar": "~1.0",
        "drupal/console": "^1.8",
        "drupal/core": "^8.6.0",
        "drupal/imce": "^1.7",
        "drupal/machine_name_widget": "^1.0",
        "drupal/metatag": "^1.7",
        "drupal/paragraphs": "^1.5",
        "drupal/pathauto": "^1.3",
        "drupal/swiftmailer": "^1.0@beta",
        "drupal/webform": "^5.0@RC",
        "drush/config-extra": "^1.0",
        "drush/drush": "^9.0.0",
        "pantheon-systems/terminus": "^1.9",
        "sabre/xml": "^2.1",
        "vlucas/phpdotenv": "^2.4",
        "webflo/drupal-finder": "^1.0.0",
        "webmozart/path-util": "^2.3"

Its very well some combination of modules or configurations I'm using that's causing the issue. I am able to get around the issue right now by targeting some commits in my working composer file. The commits working for me are right before the inline form refactor. The shipping admin updates are pretty great so I want to start using them in my local dev environment.

Targeted commits and patches that work for me. Specific use cases but maybe will help someone else.

"require": {
        "composer/installers": "^1.2",
        "cweagans/composer-patches": "^1.6",
        "drupal-composer/drupal-scaffold": "^2.5",
        "drupal/adminimal_admin_toolbar": "^1.8",
        "drupal/adminimal_theme": "^1.3",
        "drupal/commerce": "2.x-dev#f9b3442bd590d0f20eb778286b497336de6d6ea0",
        "drupal/commerce_authnet": "^1.0@RC",
        "drupal/commerce_braintree": "^1.0",
        "drupal/commerce_google_tag_manager": "^1.0@alpha",
        "drupal/commerce_paypal": "^1.0@beta",
        "drupal/commerce_shipping": "2.x-dev#7f02042324d3f21e319f97e6a4a2663c562c42cb",
        "drupal/commerce_stripe": "^1.0@beta",
        "drupal/commerce_taxjar": "~1.0",
        "drupal/console": "^1.8",
        "drupal/core": "^8.6.0",
        "drupal/imce": "^1.7",
        "drupal/machine_name_widget": "^1.0",
        "drupal/metatag": "^1.7",
        "drupal/paragraphs": "^1.5",
        "drupal/pathauto": "^1.3",
        "drupal/swiftmailer": "^1.0@beta",
        "drupal/webform": "^5.0@RC",
        "drush/config-extra": "^1.0",
        "drush/drush": "^9.0.0",
        "pantheon-systems/terminus": "^1.9",
        "sabre/xml": "^2.1",
        "vlucas/phpdotenv": "^2.4",
        "webflo/drupal-finder": "^1.0.0",
        "webmozart/path-util": "^2.3"
    },
    "extra": {
        "patches": {
            "drupal/commerce": {
                "Commerce checkbox same as shipping": "https://www.drupal.org/files/issues/2018-11-12/commerce_checkbox-same-as-billing_2852207_211.patch"
            },
            "drupal/rabbit_hole": {
                "Rabbit hole bug on entity": "https://www.drupal.org/files/issues/2018-12-04/fixing-operation-method-check--3013968-4.patch"
            },
            "drupal/commerce_shipping": {
                "The tracking_code field must not be shown at checkout": "https://gist.githubusercontent.com/jonpitts/d761c0a04f1ce563c99541145e1d30a7/raw/6bb0608e544a89debf987f5f972d11e45a462f7c/remove_tracking_code_without_inline_form_update.patch"
            }
        }
    }
smccabe’s picture

I am able to reproduce this with -dev of commerce and stripe, will investigate.

smccabe’s picture

Status: Active » Needs review

Ok so this is a problem with the stripe module, but it maybe warrants some extra documentation in the payment gateway examples. Also this involves some form api innards, which I am not an expert on, so my explanation might not be totally correct.

The payment gateway is part of the form, so it gets cached along with everything in the form, which basically serializes everything and saves it in form cache. This means that the constructor isn't called again when the submit is processed, so the static variable assignment of the stripe key doesn't happen. This doesn't effect most other payment modules, as they don't set a static like Stripe does, so any objects or config they have are reloaded just like anything else in Drupal.

I didn't dig into the difference in the Commerce versions too specifically, but I assume the changes with inline forms caused the forms to be called differently so that the constructor doesn't coincidentally get called, thus exposing this bug.

Example:

In stripe, \Stripe\Stripe::setApiKey($key); is called in the constructor, this means the API key is only set on the first run and any subsequent calls don't have the ApiKey set, like when doCreatePaymentMethod is called.

Solution:

I think the solution here is to just save the key to the payment gateway class and call setApiKey before performing any actions.

@bojanz let me know if we should add anything extra to the examples or if I should just kick this issue over to stripe or make a new issue there.

smccabe’s picture

Added in stripe issue w/ patch #3030159: Broken on Commerce 2.12

bojanz’s picture

Thank you Shawn, this is of great help.

We are indeed serializing the payment gateway form instead of reconstructing it on payment submit.
I did not expect gateways to rely on this behavior.

Note that we also have a bug report for the old behavior: #2918420: Plugins are instantiated multiple times when adding/editing the parent entity.

I need to do a grep of other gateways to see whether others also do something like this in the constructor.

EDIT:
Grepped and found the following affected modules:
commerce_moyasar (has -dev release only), commerce_omise and commerce_payjp (in beta).

Jon352’s picture

Thank you so much guys!

bojanz’s picture

Title: Possible regression issue with some payment gateways (Stripe) » Investigate Stripe regression on Commerce 2.12
Category: Bug report » Task
Status: Needs review » Fixed

I discussed this problem with Matt, and we agreed to proceed with the current approach (instead of reverting it).
It is both cleaner code-wise and makes sense conceptually (where a plugin expects it won't get recreated all the time).
We discussed introducing a mandatory init() method, but it didn't make sense to introduce a required convention just to account for a (hopefully small and shrinking) number of SDKs that are still bad enough to depend on static global access.

So, let's fix the individual modules, and document the workaround.

Created a change record:
https://www.drupal.org/node/3031851

Opened a documentation issue:
https://github.com/drupalcommerce/commerce-docs/issues/282

Opened issues for commerce_moyasar, commerce_omise, commerce_payjp:
#3031845: Broken with Commerce 2.12
#3031846: Broken with Commerce 2.12
#3031847: Broken with Commerce 2.12

Status: Fixed » Closed (fixed)

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