PPv2: Revert ISU Return-Retry; Add access token cache invalidation on ISU return

This commit is contained in:
Martin Gross
2022-06-08 12:59:30 +02:00
parent 0d5f3697a1
commit fdee69cd69
2 changed files with 14 additions and 12 deletions

View File

@@ -29,12 +29,16 @@ from paypalcheckoutsdk.core import (
class PayPalHttpClient(VendorPayPalHttpClient): class PayPalHttpClient(VendorPayPalHttpClient):
def __call__(self, request): def __call__(self, request):
# First we get all the items that make up the current credentials and create a hash to detect changes # Cached access tokens are not updated by PayPal to include new Merchants that granted access rights since
# the access token was generated. Therefor we increment the cycle count and by that invalidate the cached
# token and pull a new one.
incr = cache.get('pretix_paypal_token_hash_cycle', default=0)
# Then we get all the items that make up the current credentials and create a hash to detect changes
checksum = hashlib.sha256(''.join([ checksum = hashlib.sha256(''.join([
self.environment.base_url, self.environment.client_id, self.environment.client_secret self.environment.base_url, self.environment.client_id, self.environment.client_secret
]).encode()).hexdigest() ]).encode()).hexdigest()
cache_key_hash = f'pretix_paypal_token_hash_{checksum}' cache_key_hash = f'pretix_paypal_token_hash_{checksum}_{incr}'
token_hash = cache.get(cache_key_hash) token_hash = cache.get(cache_key_hash)
if token_hash: if token_hash:

View File

@@ -38,6 +38,7 @@ from decimal import Decimal
from django.contrib import messages from django.contrib import messages
from django.core import signing from django.core import signing
from django.core.cache import cache
from django.db.models import Sum from django.db.models import Sum
from django.http import ( from django.http import (
Http404, HttpResponse, HttpResponseBadRequest, JsonResponse, Http404, HttpResponse, HttpResponseBadRequest, JsonResponse,
@@ -201,6 +202,11 @@ def isu_return(request, *args, **kwargs):
event = get_object_or_404(Event, pk=request.session['payment_paypal_isu_event']) event = get_object_or_404(Event, pk=request.session['payment_paypal_isu_event'])
# Cached access tokens are not updated by PayPal to include new Merchants that granted access rights since
# the access token was generated. Therefor we increment the cycle count and by that invalidate the cached
# token and pull a new one.
cache.incr('pretix_paypal_token_hash_cycle')
gs = GlobalSettingsObject() gs = GlobalSettingsObject()
prov = Paypal(event) prov = Paypal(event)
prov.init_api() prov.init_api()
@@ -212,16 +218,8 @@ def isu_return(request, *args, **kwargs):
) )
response = prov.client.execute(req) response = prov.client.execute(req)
except IOError as e: except IOError as e:
retry = request.GET.get('retry', 0) messages.error(request, _('An error occurred during connecting with PayPal, please try again.'))
retry = int(retry) logger.exception('PayPal PartnersMerchantIntegrationsGetRequest: {}'.format(str(e)))
if retry < 3:
params = request.GET.copy()
params['retry'] = retry + 1
logger.exception('PayPal PartnersMerchantIntegrationsGetRequest: {}; Retrying.'.format(str(e)))
return redirect('{}?{}'.format(request.path, params.urlencode()))
else:
messages.error(request, _('An error occurred during connecting with PayPal, please try again.'))
logger.exception('PayPal PartnersMerchantIntegrationsGetRequest: {}'.format(str(e)))
else: else:
params = ['merchant_id', 'tracking_id', 'payments_receivable', 'primary_email_confirmed'] params = ['merchant_id', 'tracking_id', 'payments_receivable', 'primary_email_confirmed']
if not any(k in response.result for k in params): if not any(k in response.result for k in params):