def post(self, request, *args, **kwargs): self.request = request for p in self.provider_forms: if p['provider'].identifier == request.POST.get('payment', ''): request.session['payment'] = p['provider'].identifier request.session['payment_change_{}'.format(self.order.pk)] = '1' with transaction.atomic(): old_fee, new_fee, fee, newpayment = change_payment_provider(self.order, p['provider'], None) resp = p['provider'].payment_prepare(request, newpayment) if isinstance(resp, str): return redirect(resp) elif resp is True: return redirect(self.get_confirm_url(newpayment)) else: return self.get(request, *args, **kwargs) messages.error(self.request, _("Please select a payment method.")) return self.get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): self.request = request oldtotal = self.order.total for p in self.provider_forms: if p['provider'].identifier == request.POST.get('payment', ''): request.session['payment'] = p['provider'].identifier request.session['payment_change_{}'.format( self.order.pk)] = '1' with transaction.atomic(): old_fee, new_fee, fee = change_payment_provider( self.order, p['provider'], None) newpayment = self.order.payments.create( state=OrderPayment.PAYMENT_STATE_CREATED, provider=p['provider'].identifier, amount=self.order.pending_sum, fee=fee) self.order.log_action( 'pretix.event.order.payment.changed' if self.open_payment else 'pretix.event.order.payment.started', { 'fee': new_fee, 'old_fee': old_fee, 'provider': newpayment.provider, 'payment': newpayment.pk, 'local_id': newpayment.local_id, }) i = self.order.invoices.filter( is_cancellation=False).last() if i and self.order.total != oldtotal: generate_cancellation(i) generate_invoice(self.order) resp = p['provider'].payment_prepare(request, newpayment) if isinstance(resp, str): return redirect(resp) elif resp is True: return redirect(self.get_confirm_url(newpayment)) else: return self.get(request, *args, **kwargs) messages.error(self.request, _("Please select a payment method.")) return self.get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): self.request = request oldtotal = self.order.total for p in self.provider_forms: if p['provider'].identifier == request.POST.get('payment', ''): request.session['payment'] = p['provider'].identifier request.session['payment_change_{}'.format(self.order.pk)] = '1' with transaction.atomic(): old_fee, new_fee, fee = change_payment_provider(self.order, p['provider'], None) newpayment = self.order.payments.create( state=OrderPayment.PAYMENT_STATE_CREATED, provider=p['provider'].identifier, amount=self.order.pending_sum, fee=fee ) self.order.log_action( 'pretix.event.order.payment.changed' if self.open_payment else 'pretix.event.order.payment.started', { 'fee': new_fee, 'old_fee': old_fee, 'provider': newpayment.provider, 'payment': newpayment.pk, 'local_id': newpayment.local_id, } ) i = self.order.invoices.filter(is_cancellation=False).last() if i and self.order.total != oldtotal: generate_cancellation(i) generate_invoice(self.order) resp = p['provider'].payment_prepare(request, newpayment) if isinstance(resp, str): return redirect(resp) elif resp is True: return redirect(self.get_confirm_url(newpayment)) else: return self.get(request, *args, **kwargs) messages.error(self.request, _("Please select a payment method.")) return self.get(request, *args, **kwargs)
def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = None, organizer: Organizer = None): orders = [] if event: for slug, code in matches: order = _find_order_for_code(event.orders, code) if order and order.code not in {o.code for o in orders}: orders.append(order) else: qs = Order.objects.filter(event__organizer=organizer) for slug, code in matches: order = _find_order_for_code(qs.filter(event__slug__iexact=slug), code) if order and order.code not in {o.code for o in orders}: orders.append(order) if not orders: # No match trans.state = BankTransaction.STATE_NOMATCH trans.save() return else: trans.order = orders[0] for o in orders: if o.status == Order.STATUS_PAID and o.pending_sum <= Decimal('0.00'): trans.state = BankTransaction.STATE_DUPLICATE trans.save() return elif o.status == Order.STATUS_CANCELED: trans.state = BankTransaction.STATE_ERROR trans.message = gettext_noop( 'The order has already been canceled.') trans.save() return if len(orders) > 1: # Multi-match! Can we split this automatically? order_pending_sum = sum(o.pending_sum for o in orders) if order_pending_sum != trans.amount: # we can't :( this needs to be dealt with by a human trans.state = BankTransaction.STATE_NOMATCH trans.message = gettext_noop( 'Automatic split to multiple orders not possible.') trans.save() return # we can! splits = [(o, o.pending_sum) for o in orders] else: splits = [(orders[0], trans.amount)] trans.state = BankTransaction.STATE_VALID for order, amount in splits: try: p, created = order.payments.get_or_create( amount=amount, provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), defaults={ 'state': OrderPayment.PAYMENT_STATE_CREATED, }) except OrderPayment.MultipleObjectsReturned: created = False p = order.payments.filter( amount=amount, provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).last() p.info_data = { 'reference': trans.reference, 'date': trans.date_parsed.isoformat() if trans.date_parsed else trans.date, 'payer': trans.payer, 'iban': trans.iban, 'bic': trans.bic, 'full_amount': str(trans.amount), 'trans_id': trans.pk } if created: # We're perform a payment method switching on-demand here old_fee, new_fee, fee, p = change_payment_provider( order, p.payment_provider, p.amount, new_payment=p, create_log=False) # noqa if fee: p.fee = fee p.save(update_fields=['fee']) try: p.confirm() except Quota.QuotaExceededException: # payment confirmed but order status could not be set, no longer problem of this plugin cancel_old_payments(order) except SendMailException: # payment confirmed but order status could not be set, no longer problem of this plugin cancel_old_payments(order) else: cancel_old_payments(order) order.refresh_from_db() if order.pending_sum > Decimal( '0.00') and order.status == Order.STATUS_PENDING: notify_incomplete_payment(order) trans.save()
def _handle_transaction(trans: BankTransaction, code: str, event: Event=None, organizer: Organizer=None, slug: str=None): if event: try: trans.order = event.orders.get(code=code) except Order.DoesNotExist: normalized_code = Order.normalize_code(code) try: trans.order = event.orders.get(code=normalized_code) except Order.DoesNotExist: trans.state = BankTransaction.STATE_NOMATCH trans.save() return else: qs = Order.objects.filter(event__organizer=organizer) if slug: qs = qs.filter(event__slug__iexact=slug) try: trans.order = qs.get(code=code) except Order.DoesNotExist: normalized_code = Order.normalize_code(code) try: trans.order = qs.get(code=normalized_code) except Order.DoesNotExist: trans.state = BankTransaction.STATE_NOMATCH trans.save() return if trans.order.status == Order.STATUS_PAID and trans.order.pending_sum <= Decimal('0.00'): trans.state = BankTransaction.STATE_DUPLICATE elif trans.order.status == Order.STATUS_CANCELED: trans.state = BankTransaction.STATE_ERROR trans.message = ugettext_noop('The order has already been canceled.') else: try: p, created = trans.order.payments.get_or_create( amount=trans.amount, provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), defaults={ 'state': OrderPayment.PAYMENT_STATE_CREATED, } ) except OrderPayment.MultipleObjectsReturned: created = False p = trans.order.payments.filter( amount=trans.amount, provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).last() p.info_data = { 'reference': trans.reference, 'date': trans.date, 'payer': trans.payer, 'trans_id': trans.pk } if created: # We're perform a payment method switchign on-demand here old_fee, new_fee, fee = change_payment_provider(trans.order, p.payment_provider, p.amount, new_payment=p) # noqa if fee: p.fee = fee p.save(update_fields=['fee']) try: p.confirm() except Quota.QuotaExceededException: trans.state = BankTransaction.STATE_VALID trans.order.payments.filter( provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).update(state=OrderPayment.PAYMENT_STATE_CANCELED) except SendMailException: trans.state = BankTransaction.STATE_VALID trans.order.payments.filter( provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).update(state=OrderPayment.PAYMENT_STATE_CANCELED) else: trans.state = BankTransaction.STATE_VALID trans.order.payments.filter( provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).update(state=OrderPayment.PAYMENT_STATE_CANCELED) o = trans.order o.refresh_from_db() if o.pending_sum > Decimal('0.00') and o.status == Order.STATUS_PENDING: notify_incomplete_payment(o) trans.save()
def _handle_transaction(trans: BankTransaction, code: str, event: Event=None, organizer: Organizer=None, slug: str=None): if event: try: trans.order = event.orders.get(code=code) except Order.DoesNotExist: normalized_code = Order.normalize_code(code) try: trans.order = event.orders.get(code=normalized_code) except Order.DoesNotExist: trans.state = BankTransaction.STATE_NOMATCH trans.save() return else: qs = Order.objects.filter(event__organizer=organizer) if slug: qs = qs.filter(event__slug__iexact=slug) try: trans.order = qs.get(code=code) except Order.DoesNotExist: normalized_code = Order.normalize_code(code) try: trans.order = qs.get(code=normalized_code) except Order.DoesNotExist: trans.state = BankTransaction.STATE_NOMATCH trans.save() return if trans.order.status == Order.STATUS_PAID and trans.order.pending_sum <= Decimal('0.00'): trans.state = BankTransaction.STATE_DUPLICATE elif trans.order.status == Order.STATUS_CANCELED: trans.state = BankTransaction.STATE_ERROR trans.message = ugettext_noop('The order has already been canceled.') else: try: p, created = trans.order.payments.get_or_create( amount=trans.amount, provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), defaults={ 'state': OrderPayment.PAYMENT_STATE_CREATED, } ) except OrderPayment.MultipleObjectsReturned: created = False p = trans.order.payments.filter( amount=trans.amount, provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).last() p.info_data = { 'reference': trans.reference, 'date': trans.date, 'payer': trans.payer, 'trans_id': trans.pk } if created: # We're perform a payment method switchign on-demand here old_fee, new_fee, fee = change_payment_provider(trans.order, p.payment_provider, p.amount, new_payment=p) # noqa if fee: p.fee = fee p.save(update_fields=['fee']) try: p.confirm() except Quota.QuotaExceededException: trans.state = BankTransaction.STATE_VALID trans.order.payments.filter( provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).update(state=OrderPayment.PAYMENT_STATE_CANCELED) except SendMailException: trans.state = BankTransaction.STATE_VALID trans.order.payments.filter( provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).update(state=OrderPayment.PAYMENT_STATE_CANCELED) else: trans.state = BankTransaction.STATE_VALID trans.order.payments.filter( provider='banktransfer', state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING), ).update(state=OrderPayment.PAYMENT_STATE_CANCELED) o = trans.order o.refresh_from_db() if o.pending_sum > Decimal('0.00') and o.status == Order.STATUS_PENDING: notify_incomplete_payment(o) trans.save()