forked from CGM_Public/pretix_original
Add payment provider specific details to the API
This commit is contained in:
@@ -297,12 +297,22 @@ class PaymentURLField(serializers.URLField):
|
||||
})
|
||||
|
||||
|
||||
class PaymentDetailsField(serializers.Field):
|
||||
def to_representation(self, value: OrderPayment):
|
||||
pp = value.payment_provider
|
||||
if not pp:
|
||||
return {}
|
||||
return pp.api_payment_details(value)
|
||||
|
||||
|
||||
class OrderPaymentSerializer(I18nAwareModelSerializer):
|
||||
payment_url = PaymentURLField(source='*', allow_null=True, read_only=True)
|
||||
details = PaymentDetailsField(source='*', allow_null=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = OrderPayment
|
||||
fields = ('local_id', 'state', 'amount', 'created', 'payment_date', 'provider', 'payment_url')
|
||||
fields = ('local_id', 'state', 'amount', 'created', 'payment_date', 'provider', 'payment_url',
|
||||
'details')
|
||||
|
||||
|
||||
class OrderRefundSerializer(I18nAwareModelSerializer):
|
||||
|
||||
@@ -608,22 +608,24 @@ class Event(EventMixin, LoggedModel):
|
||||
question_map=question_map
|
||||
)
|
||||
|
||||
def get_payment_providers(self) -> dict:
|
||||
def get_payment_providers(self, cached=False) -> dict:
|
||||
"""
|
||||
Returns a dictionary of initialized payment providers mapped by their identifiers.
|
||||
"""
|
||||
from ..signals import register_payment_providers
|
||||
|
||||
responses = register_payment_providers.send(self)
|
||||
providers = {}
|
||||
for receiver, response in responses:
|
||||
if not isinstance(response, list):
|
||||
response = [response]
|
||||
for p in response:
|
||||
pp = p(self)
|
||||
providers[pp.identifier] = pp
|
||||
if not cached or not hasattr(self, '_cached_payment_providers'):
|
||||
responses = register_payment_providers.send(self)
|
||||
providers = {}
|
||||
for receiver, response in responses:
|
||||
if not isinstance(response, list):
|
||||
response = [response]
|
||||
for p in response:
|
||||
pp = p(self)
|
||||
providers[pp.identifier] = pp
|
||||
|
||||
return OrderedDict(sorted(providers.items(), key=lambda v: str(v[1].verbose_name)))
|
||||
self._cached_payment_providers = OrderedDict(sorted(providers.items(), key=lambda v: str(v[1].verbose_name)))
|
||||
return self._cached_payment_providers
|
||||
|
||||
def get_html_mail_renderer(self):
|
||||
"""
|
||||
|
||||
@@ -1196,7 +1196,7 @@ class OrderPayment(models.Model):
|
||||
"""
|
||||
Cached access to an instance of the payment provider in use.
|
||||
"""
|
||||
return self.order.event.get_payment_providers().get(self.provider)
|
||||
return self.order.event.get_payment_providers(cached=True).get(self.provider)
|
||||
|
||||
def _mark_paid(self, force, count_waitinglist, user, auth, ignore_date=False, overpaid=False):
|
||||
from pretix.base.signals import order_paid
|
||||
|
||||
@@ -657,6 +657,15 @@ class BasePaymentProvider:
|
||||
obj.info = '{}'
|
||||
obj.save(update_fields=['info'])
|
||||
|
||||
def api_payment_details(self, payment: OrderPayment):
|
||||
"""
|
||||
Will be called to populate the ``details`` parameter of the payment in the REST API.
|
||||
|
||||
:param payment: The payment in question.
|
||||
:return: A serializable dictionary
|
||||
"""
|
||||
return {}
|
||||
|
||||
|
||||
class PaymentException(Exception):
|
||||
pass
|
||||
@@ -720,6 +729,12 @@ class BoxOfficeProvider(BasePaymentProvider):
|
||||
def order_change_allowed(self, order: Order) -> bool:
|
||||
return False
|
||||
|
||||
def api_payment_details(self, payment: OrderPayment):
|
||||
return {
|
||||
"pos_id": payment.info_data.get('pos_id', None),
|
||||
"receipt_id": payment.info_data.get('receipt_id', None),
|
||||
}
|
||||
|
||||
def payment_control_render(self, request, payment) -> str:
|
||||
if not payment.info:
|
||||
return
|
||||
@@ -864,6 +879,11 @@ class OffsettingProvider(BasePaymentProvider):
|
||||
def order_change_allowed(self, order: Order) -> bool:
|
||||
return False
|
||||
|
||||
def api_payment_details(self, payment: OrderPayment):
|
||||
return {
|
||||
"orders": payment.info_data.get('orders', []),
|
||||
}
|
||||
|
||||
def payment_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:
|
||||
return _('Balanced against orders: %s' % ', '.join(payment.info_data['orders']))
|
||||
|
||||
|
||||
@@ -395,6 +395,20 @@ class Paypal(BasePaymentProvider):
|
||||
'retry': retry, 'order': payment.order}
|
||||
return template.render(ctx)
|
||||
|
||||
def api_payment_details(self, payment: OrderPayment):
|
||||
sale_id = None
|
||||
for trans in payment.info_data.get('transactions', []):
|
||||
for res in trans.get('related_resources', []):
|
||||
if 'sale' in res and 'id' in res['sale']:
|
||||
sale_id = res['sale']['id']
|
||||
return {
|
||||
"payer_email": payment.info_data.get('payer', {}).get('payer_info', {}).get('email'),
|
||||
"payer_id": payment.info_data.get('payer', {}).get('payer_info', {}).get('payer_id'),
|
||||
"cart_id": payment.info_data.get('cart', None),
|
||||
"payment_id": payment.info_data.get('id', None),
|
||||
"sale_id": sale_id,
|
||||
}
|
||||
|
||||
def payment_control_render(self, request: HttpRequest, payment: OrderPayment):
|
||||
template = get_template('pretixplugins/paypal/control.html')
|
||||
ctx = {'request': request, 'event': self.event, 'settings': self.settings,
|
||||
|
||||
@@ -411,6 +411,12 @@ class StripeMethod(BasePaymentProvider):
|
||||
}
|
||||
return template.render(ctx)
|
||||
|
||||
def api_payment_details(self, payment: OrderPayment):
|
||||
return {
|
||||
"id": payment.info_data.get("id", None),
|
||||
"payment_method": payment.info_data.get("payment_method", None)
|
||||
}
|
||||
|
||||
def payment_control_render(self, request, payment) -> str:
|
||||
if payment.info:
|
||||
payment_info = json.loads(payment.info)
|
||||
|
||||
Reference in New Issue
Block a user