diff --git a/modules/account_payment_stripe/payment.py b/modules/account_payment_stripe/payment.py index dc9ef7d76d..fbff2fa4ec 100644 --- a/modules/account_payment_stripe/payment.py +++ b/modules/account_payment_stripe/payment.py @@ -1078,16 +1078,16 @@ class Account(ModelSQL, ModelView): account.save() Transaction().commit() - def webhook(self, payload): + def webhook(self, event): """This method handles stripe webhook callbacks The return values are: - - None if the method could not handle payload['type'] - - True if the payload has been handled + - None if the method could not handle event.type + - True if the event has been handled - False if the webhook should be retried by Stripe """ - data = payload['data'] - type_ = payload['type'] + data = event.data + type_ = event.type if type_ == 'charge.succeeded': return self.webhook_charge_succeeded(data) if type_ == 'charge.captured': @@ -1131,7 +1131,7 @@ class Account(ModelSQL, ModelView): ('stripe_charge_id', '=', charge['id']), ]) if not payments: - payment_intent_id = charge.get('payment_intent') + payment_intent_id = getattr(charge, 'payment_intent', None) if payment_intent_id: found = Payment.search([ ('stripe_payment_intent_id', '=', payment_intent_id), @@ -1204,7 +1204,7 @@ class Account(ModelSQL, ModelView): ('stripe_charge_id', '=', charge['id']), ]) if not payments: - payment_intent_id = charge.get('payment_intent') + payment_intent_id = getattr(charge, 'payment_intent', None) if payment_intent_id: found = Payment.search([ ('stripe_payment_intent_id', '=', payment_intent_id), diff --git a/modules/account_payment_stripe/routes.py b/modules/account_payment_stripe/routes.py index 55824a3f91..09dbfdf8de 100644 --- a/modules/account_payment_stripe/routes.py +++ b/modules/account_payment_stripe/routes.py @@ -66,7 +66,7 @@ def webhooks_endpoint(request, pool, account): if account.webhook_signing_secret: sig_header = request.headers['STRIPE_SIGNATURE'] try: - stripe.Webhook.construct_event( + event = stripe.Webhook.construct_event( request_body, sig_header, account.webhook_signing_secret) except ValueError: # Invalid payload abort(http.client.BAD_REQUEST) @@ -74,11 +74,15 @@ def webhooks_endpoint(request, pool, account): abort(http.client.BAD_REQUEST) else: logger.warn("Stripe signature ignored") + try: + event = stripe.Event.construct_from( + json.loads(request_body), account.secret_key) + except ValueError: + abort(HTTPStatus.BAD_REQUEST) - payload = json.loads(request_body) - result = account.webhook(payload) + result = account.webhook(event) if result is None: - logger.info("No callback for payload type '%s'", payload['type']) + logger.info("No callback for event type '%s'", event['type']) elif not result: return Response(status=http.client.NOT_FOUND) return Response(status=http.client.NO_CONTENT) diff --git a/modules/account_payment_stripe/tests/scenario_account_payment_stripe_dispute.rst b/modules/account_payment_stripe/tests/scenario_account_payment_stripe_dispute.rst index aa62acd850..140d04bf03 100644 --- a/modules/account_payment_stripe/tests/scenario_account_payment_stripe_dispute.rst +++ b/modules/account_payment_stripe/tests/scenario_account_payment_stripe_dispute.rst @@ -117,7 +117,7 @@ Create fully disputed payment:: Simulate charge.dispute.created event:: - >>> StripeAccount.webhook([stripe_account], { + >>> StripeAccount.webhook([stripe_account], stripe.Event.construct_from({ ... 'type': 'charge.dispute.created', ... 'data': { ... 'object': { @@ -129,7 +129,7 @@ Simulate charge.dispute.created event:: ... 'status': 'needs_response', ... }, ... }, - ... }, {}) + ... }, stripe_account.secret_key), {}) [True] >>> payment.reload() >>> payment.state @@ -141,7 +141,7 @@ Simulate charge.dispute.created event:: Simulate charge.dispute.closed event:: - >>> StripeAccount.webhook([stripe_account], { + >>> StripeAccount.webhook([stripe_account], stripe.Event.construct_from({ ... 'type': 'charge.dispute.closed', ... 'data': { ... 'object': { @@ -153,7 +153,7 @@ Simulate charge.dispute.closed event:: ... 'status': 'lost', ... }, ... }, - ... }, {}) + ... }, stripe_account.secret_key), {}) [True] >>> payment.reload() >>> payment.state @@ -213,7 +213,7 @@ Create partial disputed payment:: Simulate charge.dispute.closed event:: - >>> StripeAccount.webhook([stripe_account], { + >>> StripeAccount.webhook([stripe_account], stripe.Event.construct_from({ ... 'type': 'charge.dispute.closed', ... 'data': { ... 'object': { @@ -225,7 +225,7 @@ Simulate charge.dispute.closed event:: ... 'status': 'lost', ... }, ... }, - ... }, {}) + ... }, stripe_account.secret_key), {}) [True] >>> payment.reload() >>> payment.state