woocommerce / woocommerce-gateway-stripe

The official Stripe Payment Gateway for WooCommerce
https://wordpress.org/plugins/woocommerce-gateway-stripe/
229 stars 197 forks source link

Always pass Stripe a source ID, even when it's not set on the subscription #1028

Open thenbrent opened 4 years ago

thenbrent commented 4 years ago

The Problem

While working on #1016 to fix #1010 @v18 reached out to Stripe to check if sending a source with a payment intent request was required. The reply:

while this currently works for legacy reasons, we strongly discourage not specifying the source and doing so could create issues in the future.

The problem is, we do not always pass Stripe a source.

Proposed Solution

@NickGreen had a bright idea to fix it:

Idea: what if we populated the src field with the default card token at the time of making that charge (if it's blank)?

That way, over time, the blank src fields would approach zero.

I think that is a really good approach. It fulfills Stripe's (impending) requirement to pass a source, maintains backward compatibility with existing subscriptions setup without a source, and does that by taking advantage of the customer / subscriber facing UI to set a default payment method in WooCommerce.

If customers find a recurring charge on the a payment method they don't want it on, they can also change this with existing UIs on the WooCommerce store by either changing their default payment method or changing the payment method on the subscription.

This should be documented for store owners in the Stripe extension docs.

Alternative Solutions

Nick's other (good) idea:

Idea 2: What if we had a 'sync' button that would pull the payment tokens from the user's account and add it to the account/subscription in the WC store? SkyVerge gateways have a similar functionality, and it would help the merchants populate those fields appropriately.

Additional Context

In additional to #1010 and #1016, this is closely related to https://github.com/woocommerce/woocommerce-gateway-stripe/issues/1029.

jrick1229 commented 4 years ago

Just adding this here for anyone looking: zen-2367859

This customer manually added the src_ ID into their subscriptions that were failing, then successfully processed a renewal. This can be hard for us to identify, since they may have already done this by the time we look.

Since we're looking for an empty source when troubleshooting, we may also want to ask customers if they've made any changes to successfully process renewals that were originally failing.

RadoslavGeorgiev commented 4 years ago

Idea #2: What if we had a 'sync' button that would pull the payment tokens from the user's account and add it to the account/subscription in the WC store? SkyVerge gateways have a similar functionality, and it would help the merchants populate those fields appropriately.

How does it work with their extensions, @jrick1229?

The Stripe gateway already synchronizes all saved payment methods as tokens in WooCommerce. There are no webhooks to automatically handle changes within Stripe's Dashboard, however before the payment tokens of a local user are listed somewhere, we are pulling in all cards from the customer's profile in Stripe.

Now the question is how this would work (UI-wise) within wp-admin. Could you maybe share a screenshot or two of SkyVerge's UI?

jrick1229 commented 4 years ago

@RadoslavGeorgiev - I think you may have meant to tag @thenbrent in your comment.


On another note, @thenbrent - I have a customer recently who is still passing the card_ token in the 'Stripe Source ID' field. This is returning:

Error: stdClass Object
(
    [error] => stdClass Object
        (
            [code] => resource_missing
            [doc_url] => https://stripe.com/docs/error-codes/resource-missing
            [message] => No such source: 
            [param] => source
            [type] => invalid_request_error
        )
)

My guess is that since we aren't sending a src_ ID, the transaction is still being declined. Not sure if this is something that should be taken into consideration when auto-populating these fields being sent to Stripe.

I mentioned this here: https://a8c.slack.com/archives/CHG7MTCAF/p1570109621029100?thread_ts=1569864579.001500&cid=CHG7MTCAF

v18 commented 4 years ago

Note that the reason the above error occurred is because the user was still on Stripe 4.2.4.

NickGreen commented 4 years ago

I have a customer recently who is still passing the card_ token in the 'Stripe Source ID' field.

This should still work. Before Jan, 2018 (I believe), the tokens were all card_ tokens, so there are plenty of stores with those older tokens still in that field.

It sounds like this was just due to an outdated plugin, so no worries there.

How does it work with their extensions

SkyVerge don't use the WooCommerce payment tokenization system, which I would not advocate for. They store the card and customer tokens in the user table for that user.

The part that is nice, though, is that they have a 'sync' button in the user profile page that fetches all the current user and payment tokens for that user and displays them in a table on the user profile page. This makes it easy for admins to compare card tokens to the ones stored in the subscription itself.

Sorry, I don't have a screenshot handy. As soon as I run into another customer site that has this populated, I'll grad a screenshot for you.

It's not clear to me yet how this would work, or be beneficial for, the Stripe plugin. I think the problem that we are solving for is that admins have subscriptions with either:

and there might be a good admin UI for helping them solve this.

The Stripe gateway already synchronizes all saved payment methods as tokens in WooCommerce.

If this is the case, then, it seems like it's just a matter of either:

thenbrent commented 4 years ago

I don't think we need to go down the road of exploring how to implement Idea 2. I included it in an Alternative Solutions section just for posterity and in case Idea 1 proves to not be sufficient.

For now, Idea 1 looks like a suitable fix for this issue, and it's much simpler.