From f4a95639d4700a5dd1ce3ed168272bef5ae706f4 Mon Sep 17 00:00:00 2001 From: lejeune quentin Date: Tue, 18 Oct 2022 10:07:36 +0000 Subject: [PATCH] [FIX] pos_stripe: Improves error handling Currently if an error occurs on the server side it is not reported to the POS interface and therefore to the user. With this commit all responses to requests to the Stripe server are managed in the POS so that the cashier is correctly informed of any errors that may occur closes odoo/odoo#104870 X-original-commit: a9c794ed31cfe1527f0e480729212859338bca60 Signed-off-by: Trinh Jacky (trj) --- .../pos_stripe/models/pos_payment_method.py | 18 +--- .../static/src/js/payment_stripe.js | 90 ++++++++++++------- 2 files changed, 60 insertions(+), 48 deletions(-) diff --git a/addons/pos_stripe/models/pos_payment_method.py b/addons/pos_stripe/models/pos_payment_method.py index d6e6efeb13a..0977971d1eb 100644 --- a/addons/pos_stripe/models/pos_payment_method.py +++ b/addons/pos_stripe/models/pos_payment_method.py @@ -54,11 +54,7 @@ class PosPaymentMethod(models.Model): _logger.exception("Failed to call stripe_connection_token endpoint") raise UserError(_("There are some issues between us and Stripe, try again later.")) - if resp.ok: - return resp.json() - - _logger.error("Unexpected stripe_connection_token response: %s", resp.status_code) - raise UserError(_("Unexpected error between us and Stripe.")) + return resp.json() def _stripe_calculate_amount(self, amount): currency = self.journal_id.currency_id or self.company_id.currency_id @@ -85,11 +81,7 @@ class PosPaymentMethod(models.Model): _logger.exception("Failed to call stripe_payment_intent endpoint") raise UserError(_("There are some issues between us and Stripe, try again later.")) - if resp.ok: - return resp.json() - - _logger.error("Unexpected stripe_payment_intent response: %s", resp.status_code) - raise UserError(_("Unexpected error between us and Stripe.")) + return resp.json() @api.model def stripe_capture_payment(self, paymentIntentId, amount=None): @@ -118,11 +110,7 @@ class PosPaymentMethod(models.Model): _logger.exception("Failed to call stripe_capture_payment endpoint") raise UserError(_("There are some issues between us and Stripe, try again later.")) - if resp.ok: - return resp.json() - - _logger.error("Unexpected stripe_capture_payment response: %s", resp.status_code) - raise UserError(_("Unexpected error between us and Stripe.")) + return resp.json() def action_stripe_key(self): res_id = self.env['payment.provider'].search([('code', '=', 'stripe')], limit=1).id diff --git a/addons/pos_stripe/static/src/js/payment_stripe.js b/addons/pos_stripe/static/src/js/payment_stripe.js index 1c5ba674a04..b5f41646e23 100644 --- a/addons/pos_stripe/static/src/js/payment_stripe.js +++ b/addons/pos_stripe/static/src/js/payment_stripe.js @@ -24,18 +24,23 @@ let PaymentStripe = PaymentInterface.extend({ this._showError(_t('Reader disconnected')); }, - stripeFetchConnectionToken: function () { + stripeFetchConnectionToken: async function () { // Do not cache or hardcode the ConnectionToken. - return rpc.query({ - model: 'pos.payment.method', - method: 'stripe_connection_token', - }, { - silent: true, - }).catch(function (error) { - this._showError(_t('error')); - }).then(function (data) { + try { + let data = await rpc.query({ + model: 'pos.payment.method', + method: 'stripe_connection_token', + }, { + silent: true, + }); + if (data.error) { + throw data.error; + } return data.secret; - }); + } catch (error) { + this._showError(error.message); + return false; + }; }, discoverReaders: async function () { @@ -90,11 +95,19 @@ let PaymentStripe = PaymentInterface.extend({ } } } + this._showError(_.str.sprintf( + this.env._t('Stripe readers %s not listed in your account'), + this.payment_method.stripe_serial_number + )); }, collectPayment: async function (amount) { let line = this.pos.get_order().selected_paymentline; let clientSecret = await this.fetchPaymentIntentClientSecret(line.payment_method, amount); + if (!clientSecret) { + line.set_payment_status('retry'); + return false; + } line.set_payment_status('waitingCard'); let collectPaymentMethod = await this.terminal.collectPaymentMethod(clientSecret); if (collectPaymentMethod.error) { @@ -120,35 +133,46 @@ let PaymentStripe = PaymentInterface.extend({ captureAfterPayment: async function (processPayment, line) { let capturePayment = await this.capturePayment(processPayment.paymentIntent.id); + line.card_type = capturePayment.charges.data[0].payment_method_details.card_present.brand; line.transaction_id = capturePayment.id; }, - capturePayment: function (paymentIntentId) { - let self = this; - return rpc.query({ - model: 'pos.payment.method', - method: 'stripe_capture_payment', - args: [paymentIntentId], - }, { - silent: true, - }).catch(function (error) { - self._showError(_t('error')); - }); + capturePayment: async function (paymentIntentId) { + try { + let data = await rpc.query({ + model: 'pos.payment.method', + method: 'stripe_capture_payment', + args: [paymentIntentId], + }, { + silent: true, + }); + if (data.error) { + throw data.error; + } + return data; + } catch (error) { + this._showError(error.message); + return false; + }; }, - fetchPaymentIntentClientSecret: function (payment_method, amount) { - let self = this; - return rpc.query({ - model: 'pos.payment.method', - method: 'stripe_payment_intent', - args: [[payment_method.id], amount], - }, { - silent: true, - }).catch(function (error) { - self._showError(_t('error')); - }).then(function (data) { + fetchPaymentIntentClientSecret: async function (payment_method, amount) { + try { + let data = await rpc.query({ + model: 'pos.payment.method', + method: 'stripe_payment_intent', + args: [[payment_method.id], amount], + }, { + silent: true, + }); + if (data.error) { + throw data.error; + } return data.client_secret; - }); + } catch (error) { + this._showError(error.message); + return false; + }; }, send_payment_request: async function (cid) {