diff options
| author | Damien Bouvy <dbo@odoo.com> | 2019-09-19 10:31:07 +0000 |
|---|---|---|
| committer | fw-bot <otis@odoo.com> | 2019-09-20 12:42:09 +0000 |
| commit | 7807bc854eaf68ca3ec723d2eb694e886565fd39 (patch) | |
| tree | 8a5196a13f5c913084126ccc21921420a6906368 | |
| parent | 1067f3bda2957ff696f4dd6f8cc454e2b87b56b9 (diff) | |
[FIX] payment_stripe_sca: on-the-fly customer conversion
Payment tokens created before the installation of this module and that
used the Charge API did not need to keep the card reference on Odoo's
side - since we were allowed by the API to simply specify a customer
reference when creating a charge and it would take the default one for
that customer. Odoo creates one customer per payment token (even if it's
the same partner), so there was no uncertainty there.
Now, with the PaymentIntent API, the payment method reference is
mandatory. We have a field to keep it in db, but this info needs to be
retrieved for tokens created before the module's installation. This fix
introduces that remote call.
closes odoo/odoo#37206
X-original-commit: 1b760a988fdf7bbc08b92e0705929d5620356a2f
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
| -rw-r--r-- | addons/payment_stripe_sca/models/payment.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/addons/payment_stripe_sca/models/payment.py b/addons/payment_stripe_sca/models/payment.py index d1f4b142ed2..7711d7d98d6 100644 --- a/addons/payment_stripe_sca/models/payment.py +++ b/addons/payment_stripe_sca/models/payment.py @@ -177,6 +177,9 @@ class PaymentTransactionStripeSCA(models.Model): "_stripe_create_payment_intent: Values received:\n%s", pprint.pformat(res) ) return res + if not self.payment_token_id.stripe_payment_method: + # old token before installing stripe_sca, need to fetch data from the api + self.payment_token_id._stripe_sca_migrate_customer() charge_params = { "amount": int( self.amount @@ -367,3 +370,38 @@ class PaymentTokenStripeSCA(models.Model): "This method can no longer be used with the payment_stripe_sca module." ) + def _stripe_sca_migrate_customer(self): + """Migrate a token from the old implementation of Stripe to the SCA one. + + In the old implementation, it was possible to create a valid charge just by + giving the customer ref to ask Stripe to use the default source (= default + card). Since we have a one-to-one matching between a saved card, this used to + work well - but now we need to specify the payment method for each call and so + we have to contact stripe to get the default source for the customer and save it + in the payment token. + This conversion will happen once per token, the first time it gets used following + the installation of the module.""" + self.ensure_one() + url = "customers/%s" % (self.acquirer_ref) + data = self.acquirer_id._stripe_request(url, method="GET") + sources = data.get('sources', {}).get('data', []) + pm_ref = False + if sources: + if len(sources) > 1: + _logger.warning('stripe sca customer conversion: there should be a single saved source per customer!') + pm_ref = sources[0].get('id') + else: + url = 'payment_methods' + params = { + 'type': 'card', + 'customer': self.acquirer_ref, + } + payment_methods = self.acquirer_id._stripe_request(url, params, method='GET') + cards = payment_methods.get('data', []) + if len(cards) > 1: + _logger.warning('stripe sca customer conversion: there should be a single saved source per customer!') + pm_ref = cards and cards[0].get('id') + if not pm_ref: + raise ValidationError(_('Unable to convert Stripe customer for SCA compatibility. Is there at least one card for this customer in the Stripe backend?')) + self.stripe_payment_method = pm_ref + _logger.info('converted old customer ref to sca-compatible record for payment token %s', self.id) |
