From fd0d077a7af3f681deb234c95297657d10bcd4be Mon Sep 17 00:00:00 2001 From: "Loan (LSE)" Date: Tue, 27 Dec 2022 14:16:55 +0000 Subject: [PATCH] [FIX] pos_stripe: use payment provider method for payment capture Before this commit: If you make a PoS payment using a Stripe terminal, you will have the following JS Traceback: ```js TypeError: Cannot read properties of undefined (reading 'data') at Proxy.captureAfterPayment ``` This happens on the line: `capturePayment.charges.data[0].payment_method_details.card_present.brand;` It occurs as Stripe API most recent version does not provide the `charges` value anymore. > The charges property on PaymentIntent has been removed source: https://stripe.com/docs/upgrades#2022-11-15 After this commit: We skip the data if not mentioned on the JS side. In addition of that, we use the `_stripe_make_request` method of the Stripe payment provider as it force in its header to use a certain Stripe API version compatible with the features that we are looking for. opw-3097460 closes odoo/odoo#108851 X-original-commit: 6a6057caf63d7e6a60dac190b2ea1ebb954d8f6a Signed-off-by: Loan (LSE) Signed-off-by: Quentin Lejeune (qle) --- .../pos_stripe/models/pos_payment_method.py | 22 +++++++++---------- .../static/src/js/payment_stripe.js | 3 ++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/addons/pos_stripe/models/pos_payment_method.py b/addons/pos_stripe/models/pos_payment_method.py index 0977971d1eb..69585204d0a 100644 --- a/addons/pos_stripe/models/pos_payment_method.py +++ b/addons/pos_stripe/models/pos_payment_method.py @@ -31,10 +31,17 @@ class PosPaymentMethod(models.Model): raise ValidationError(_('Terminal %s is already used on payment method %s.',\ payment_method.stripe_serial_number, existing_payment_method.display_name)) + def _get_stripe_payment_provider(self): + stripe_payment_provider = self.env['payment.provider'].search([('code', '=', 'stripe')], limit=1) + + if not stripe_payment_provider: + raise UserError(_("Stripe payment provider is missing")) + + return stripe_payment_provider @api.model def _get_stripe_secret_key(self): - stripe_secret_key = self.env['payment.provider'].search([('code', '=', 'stripe')], limit=1).stripe_secret_key + stripe_secret_key = self._get_stripe_payment_provider().stripe_secret_key if not stripe_secret_key: raise ValidationError(_('Complete the Stripe onboarding.')) @@ -95,8 +102,7 @@ class PosPaymentMethod(models.Model): if not self.env.user.has_group('point_of_sale.group_pos_user'): raise AccessError(_("Do not have access to fetch token from Stripe")) - endpoint = ('https://api.stripe.com/v1/payment_intents/%s/capture') % \ - (werkzeug.urls.url_quote(paymentIntentId)) + endpoint = ('payment_intents/%s/capture') % (werkzeug.urls.url_quote(paymentIntentId)) data = None if amount is not None: @@ -104,16 +110,10 @@ class PosPaymentMethod(models.Model): "amount_to_capture": self._stripe_calculate_amount(amount), } - try: - resp = requests.post(endpoint, data=data, auth=(self.sudo()._get_stripe_secret_key(), ''), timeout=TIMEOUT) - except requests.exceptions.RequestException: - _logger.exception("Failed to call stripe_capture_payment endpoint") - raise UserError(_("There are some issues between us and Stripe, try again later.")) - - return resp.json() + return self._get_stripe_payment_provider()._stripe_make_request(endpoint, data) def action_stripe_key(self): - res_id = self.env['payment.provider'].search([('code', '=', 'stripe')], limit=1).id + res_id = self._get_stripe_payment_provider().id # Redirect return { 'name': _('Stripe'), diff --git a/addons/pos_stripe/static/src/js/payment_stripe.js b/addons/pos_stripe/static/src/js/payment_stripe.js index ef3282b7b1b..3f4bbb5418e 100644 --- a/addons/pos_stripe/static/src/js/payment_stripe.js +++ b/addons/pos_stripe/static/src/js/payment_stripe.js @@ -141,7 +141,8 @@ const PaymentStripe = PaymentInterface.extend({ captureAfterPayment: async function (processPayment, line) { const capturePayment = await this.capturePayment(processPayment.paymentIntent.id); - line.card_type = capturePayment.charges.data[0].payment_method_details.card_present.brand; + if (capturePayment.charges) + line.card_type = capturePayment.charges.data[0].payment_method_details.card_present.brand; line.transaction_id = capturePayment.id; },