Esempio n. 1
0
 def post(self, *args, **kwargs):
     to = self.request.POST.get('status', '')
     if self.order.status == 'n' and to == 'p':
         try:
             mark_order_paid(self.order, manual=True)
         except Quota.QuotaExceededException as e:
             messages.error(self.request, str(e))
         else:
             messages.success(self.request, _('The order has been marked as paid.'))
     elif self.order.status == 'n' and to == 'c':
         order = self.order.clone()
         order.status = Order.STATUS_CANCELLED
         order.save()
         messages.success(self.request, _('The order has been cancelled.'))
     elif self.order.status == 'p' and to == 'n':
         order = self.order.clone()
         order.status = Order.STATUS_PENDING
         order.payment_manual = True
         order.save()
         messages.success(self.request, _('The order has been marked as not paid.'))
     elif self.order.status == 'p' and to == 'r':
         ret = self.payment_provider.order_control_refund_perform(self.request, self.order)
         if ret:
             return redirect(ret)
     return redirect(self.get_order_url())
Esempio n. 2
0
    def _execute_payment(self, payment, request, order):
        payment.execute({"payer_id": request.session.get("payment_paypal_payer")})

        if payment.state == "pending":
            messages.warning(
                request,
                _("PayPal has not yet approved the payment. We will inform you as soon as the " "payment completed."),
            )
            order = order.clone()
            order.payment_info = json.dumps(payment.to_dict())
            order.save()
            return

        if payment.state != "approved":
            messages.error(
                request, _("We were unable to process your payment. See below for details on how to " "proceed.")
            )
            logger.error("Invalid state: %s" % str(payment))
            return

        try:
            mark_order_paid(order, "paypal", json.dumps(payment.to_dict()))
        except Quota.QuotaExceededException as e:
            messages.error(request, str(e))
        return None
Esempio n. 3
0
 def test_paid_expired_available(self):
     self.order.status = Order.STATUS_EXPIRED
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 4
0
 def post(self, *args, **kwargs):
     to = self.request.POST.get('status', '')
     if self.order.status in (Order.STATUS_PENDING, Order.STATUS_EXPIRED) and to == 'p':
         try:
             mark_order_paid(self.order, manual=True, user=self.request.user)
         except Quota.QuotaExceededException as e:
             messages.error(self.request, str(e))
         else:
             messages.success(self.request, _('The order has been marked as paid.'))
     elif self.order.status == Order.STATUS_PENDING and to == 'c':
         cancel_order(self.order, user=self.request.user)
         messages.success(self.request, _('The order has been cancelled.'))
     elif self.order.status == Order.STATUS_PAID and to == 'n':
         self.order.status = Order.STATUS_PENDING
         self.order.payment_manual = True
         self.order.save()
         self.order.log_action('pretix.event.order.unpaid', user=self.request.user)
         messages.success(self.request, _('The order has been marked as not paid.'))
     elif self.order.status == Order.STATUS_PENDING and to == 'e':
         self.order.status = Order.STATUS_EXPIRED
         self.order.save()
         self.order.log_action('pretix.event.order.expired', user=self.request.user)
         messages.success(self.request, _('The order has been marked as expired.'))
     elif self.order.status == Order.STATUS_PAID and to == 'r':
         ret = self.payment_provider.order_control_refund_perform(self.request, self.order)
         if ret:
             return redirect(ret)
     return redirect(self.get_order_url())
Esempio n. 5
0
 def test_paid_expired_unavailable_force(self):
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     self.quota.size = 0
     self.quota.save()
     mark_order_paid(self.order, force=True)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 6
0
    def payment_perform(self, request, order) -> str:
        self._init_api()
        try:
            charge = stripe.Charge.create(
                amount=int(order.total * 100),
                currency=self.event.currency.lower(),
                source=request.session['payment_stripe_token'],
                metadata={
                    'order': str(order.id),
                    'event': self.event.id,
                    'code': order.code
                },
                # TODO: Is this sufficient?
                idempotency_key=str(self.event.id) + order.code + request.session['payment_stripe_token']
            )
        except stripe.error.CardError as e:
            if e.json_body:
                err = e.json_body['error']
                logger.exception('Stripe error: %s' % str(err))
            else:
                err = {'message': str(e)}
                logger.exception('Stripe error: %s' % str(e))
            messages.error(request, _('Stripe reported an error with your card: %s' % err['message']))
            logger.info('Stripe card error: %s' % str(err))
            order.payment_info = json.dumps({
                'error': True,
                'message': err['message'],
            })
            order.save()
        except stripe.error.StripeError as e:
            if e.json_body:
                err = e.json_body['error']
                logger.exception('Stripe error: %s' % str(err))
            else:
                err = {'message': str(e)}
                logger.exception('Stripe error: %s' % str(e))
            messages.error(request, _('We had trouble communicating with Stripe. Please try again and get in touch '
                                      'with us if this problem persists.'))
            order.payment_info = json.dumps({
                'error': True,
                'message': err['message'],
            })
            order.save()
        else:
            if charge.status == 'succeeded' and charge.paid:
                try:
                    mark_order_paid(order, 'stripe', str(charge))
                except Quota.QuotaExceededException as e:
                    messages.error(request, str(e))
                except SendMailException:
                    messages.warning(request, _('There was an error sending the confirmation mail.'))

            else:
                messages.warning(request, _('Stripe reported an error: %s' % charge.failure_message))
                logger.info('Charge failed: %s' % str(charge))
                order.payment_info = str(charge)
                order.save()
        del request.session['payment_stripe_token']
Esempio n. 7
0
 def test_paid_expired_available(self):
     self.event.settings.payment_term_last = (
         now() + timedelta(days=2)).strftime('%Y-%m-%d')
     self.order.status = Order.STATUS_EXPIRED
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 8
0
def webhook(request, *args, **kwargs):
    event_body = request.body.decode('utf-8').strip()
    event_json = json.loads(event_body)

    prov = Paypal(request.event)
    prov.init_api()

    # We do not check the signature, we just use it as a trigger to look the charge up.
    if event_json['resource_type'] not in ('sale', 'refund'):
        return HttpResponse("Not interested in this resource type", status=200)

    try:
        if event_json['resource_type'] == 'sale':
            sale = paypalrestsdk.Sale.find(event_json['resource']['id'])
        else:
            sale = paypalrestsdk.Sale.find(event_json['resource']['sale_id'])
    except:
        logger.exception('PayPal error on webhook. Event data: %s' % str(event_json))
        return HttpResponse('Sale not found', status=500)

    orders = Order.objects.filter(event=request.event, payment_provider='paypal',
                                  payment_info__icontains=sale['id'])
    order = None
    for o in orders:
        payment_info = json.loads(o.payment_info)
        for res in payment_info['transactions'][0]['related_resources']:
            for k, v in res.items():
                if k == 'sale' and v['id'] == sale['id']:
                    order = o
                    break

    if not order:
        return HttpResponse('Order not found', status=200)

    order.log_action('pretix.plugins.paypal.event', data=event_json)

    if order.status == Order.STATUS_PAID and sale['state'] in ('partially_refunded', 'refunded'):
        RequiredAction.objects.create(
            event=request.event, action_type='pretix.plugins.paypal.refund', data=json.dumps({
                'order': order.code,
                'sale': sale['id']
            })
        )
    elif order.status in (Order.STATUS_PENDING, Order.STATUS_EXPIRED) and sale['state'] == 'completed':
        try:
            mark_order_paid(order, user=None)
        except Quota.QuotaExceededException:
            if not RequiredAction.objects.filter(event=request.event, action_type='pretix.plugins.paypal.overpaid',
                                                 data__icontains=order.code).exists():
                RequiredAction.objects.create(
                    event=request.event, action_type='pretix.plugins.paypal.overpaid', data=json.dumps({
                        'order': order.code,
                        'payment': sale['parent_payment']
                    })
                )

    return HttpResponse(status=200)
Esempio n. 9
0
 def test_paid_expired_late_not_allowed(self):
     self.event.settings.payment_term_accept_late = False
     self.order.status = Order.STATUS_EXPIRED
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     with self.assertRaises(Quota.QuotaExceededException):
         mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_EXPIRED)
Esempio n. 10
0
def charge_webhook(event, event_json, charge_id):
    prov = StripeCC(event)
    prov._init_api()
    try:
        charge = stripe.Charge.retrieve(charge_id)
    except stripe.error.StripeError:
        logger.exception('Stripe error on webhook. Event data: %s' %
                         str(event_json))
        return HttpResponse('Charge not found', status=500)

    metadata = charge['metadata']
    if 'event' not in metadata:
        return HttpResponse('Event not given in charge metadata', status=200)

    if int(metadata['event']) != event.pk:
        return HttpResponse('Not interested in this event', status=200)

    try:
        order = event.orders.get(id=metadata['order'],
                                 payment_provider__startswith='stripe')
    except Order.DoesNotExist:
        return HttpResponse('Order not found', status=200)

    if order.payment_provider != prov.identifier:
        prov = event.get_payment_providers()[order.payment_provider]
        prov._init_api()

    order.log_action('pretix.plugins.stripe.event', data=event_json)

    is_refund = charge['refunds']['total_count'] or charge['dispute']
    if order.status == Order.STATUS_PAID and is_refund:
        RequiredAction.objects.create(
            event=event,
            action_type='pretix.plugins.stripe.refund',
            data=json.dumps({
                'order': order.code,
                'charge': charge_id
            }))
    elif order.status in (
            Order.STATUS_PENDING, Order.STATUS_EXPIRED
    ) and charge['status'] == 'succeeded' and not is_refund:
        try:
            mark_order_paid(order, user=None)
        except Quota.QuotaExceededException:
            if not RequiredAction.objects.filter(
                    event=event,
                    action_type='pretix.plugins.stripe.overpaid',
                    data__icontains=order.code).exists():
                RequiredAction.objects.create(
                    event=event,
                    action_type='pretix.plugins.stripe.overpaid',
                    data=json.dumps({
                        'order': order.code,
                        'charge': charge.id
                    }))

    return HttpResponse(status=200)
Esempio n. 11
0
 def test_paid_expired_after_last_date(self):
     self.event.settings.payment_term_last = (now() - timedelta(days=2)).strftime('%Y-%m-%d')
     self.order.status = Order.STATUS_EXPIRED
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     with self.assertRaises(Quota.QuotaExceededException):
         mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_EXPIRED)
Esempio n. 12
0
 def payment_perform(self, request, order) -> str:
     self._init_api()
     try:
         charge = stripe.Charge.create(
             amount=int(order.total * 100),
             currency=request.event.currency.lower(),
             source=request.session['payment_stripe_token'],
             metadata={
                 'order': str(order.id),
                 'event': self.event.id,
                 'code': order.code
             },
             # TODO: Is this sufficient?
             idempotency_key=str(self.event.id) + order.code +
             request.session['payment_stripe_token'])
     except stripe.error.CardError as e:
         err = e.json_body['error']
         messages.error(
             request,
             _('Stripe reported an error with your card: %s' %
               err['message']))
         logger.info('Stripe card error: %s' % str(err))
         order.payment_info = json.dumps({
             'error': True,
             'message': err['message'],
         })
         order.save()
     except (stripe.error.InvalidRequestError,
             stripe.error.AuthenticationError,
             stripe.error.APIConnectionError,
             stripe.error.StripeError) as e:
         err = e.json_body['error']
         messages.error(
             request,
             _('We had trouble communicating with Stripe. Please try again and get in touch '
               'with us if this problem persists.'))
         logger.error('Stripe error: %s' % str(err))
         order.payment_info = json.dumps({
             'error': True,
             'message': err['message'],
         })
         order.save()
     else:
         if charge.status == 'succeeded' and charge.paid:
             try:
                 mark_order_paid(order, 'stripe', str(charge))
             except Quota.QuotaExceededException as e:
                 messages.error(request, str(e))
         else:
             messages.warning(
                 request,
                 _('Stripe reported an error: %s' % charge.failure_message))
             logger.info('Charge failed: %s' % str(charge))
             order.payment_info = str(charge)
             order.save()
     del request.session['payment_stripe_token']
Esempio n. 13
0
 def test_paid_expired_unavailable(self):
     self.order.expires = now() - timedelta(days=2)
     self.order.status = Order.STATUS_EXPIRED
     self.order.save()
     self.quota.size = 0
     self.quota.save()
     with self.assertRaises(Quota.QuotaExceededException):
         mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertIn(self.order.status, (Order.STATUS_PENDING, Order.STATUS_EXPIRED))
Esempio n. 14
0
 def test_paid_expired_unavailable_waiting_list_ignore(self):
     self.event.waitinglistentries.create(item=self.item1, email='*****@*****.**')
     self.order.expires = now() - timedelta(days=2)
     self.order.status = Order.STATUS_EXPIRED
     self.order.save()
     self.quota.size = 2
     self.quota.save()
     mark_order_paid(self.order, count_waitinglist=False)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 15
0
 def test_paid_expired_unavailable_force(self):
     self.event.settings.payment_term_accept_late = True
     self.order.expires = now() - timedelta(days=2)
     self.order.status = Order.STATUS_EXPIRED
     self.order.save()
     self.quota.size = 0
     self.quota.save()
     mark_order_paid(self.order, force=True)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 16
0
 def post(self, *args, **kwargs):
     to = self.request.POST.get('status', '')
     if self.order.status in (Order.STATUS_PENDING,
                              Order.STATUS_EXPIRED) and to == 'p':
         if not self.mark_paid_form.is_valid():
             return render(self.request, 'pretixcontrol/order/pay.html', {
                 'form': self.mark_paid_form,
                 'order': self.order,
             })
         try:
             mark_order_paid(self.order,
                             manual=True,
                             user=self.request.user,
                             count_waitinglist=False,
                             force=self.mark_paid_form.cleaned_data.get(
                                 'force', False))
         except Quota.QuotaExceededException as e:
             messages.error(self.request, str(e))
         except SendMailException:
             messages.warning(
                 self.request,
                 _('The order has been marked as paid, but we were unable to send a confirmation mail.'
                   ))
         else:
             messages.success(self.request,
                              _('The order has been marked as paid.'))
     elif self.order.cancel_allowed() and to == 'c':
         cancel_order(self.order,
                      user=self.request.user,
                      send_mail=self.request.POST.get("send_email") == "on")
         messages.success(self.request, _('The order has been canceled.'))
     elif self.order.status == Order.STATUS_PAID and to == 'n':
         self.order.status = Order.STATUS_PENDING
         self.order.payment_manual = True
         self.order.save()
         self.order.log_action('pretix.event.order.unpaid',
                               user=self.request.user)
         messages.success(self.request,
                          _('The order has been marked as not paid.'))
     elif self.order.status == Order.STATUS_PENDING and to == 'e':
         mark_order_expired(self.order, user=self.request.user)
         messages.success(self.request,
                          _('The order has been marked as expired.'))
     elif self.order.status == Order.STATUS_PAID and to == 'r':
         if not self.payment_provider:
             messages.error(
                 self.request,
                 _('This order is not assigned to a known payment provider.'
                   ))
         else:
             ret = self.payment_provider.order_control_refund_perform(
                 self.request, self.order)
             if ret:
                 return redirect(ret)
     return redirect(self.get_order_url())
Esempio n. 17
0
    def _execute_payment(self, payment, request, order):
        payment.replace([{
            "op": "replace",
            "path": "/transactions/0/item_list",
            "value": {
                "items": [{
                    "name":
                    __('Order {slug}-{code}').format(
                        slug=self.event.slug.upper(), code=order.code),
                    "quantity":
                    1,
                    "price":
                    str(order.total),
                    "currency":
                    order.event.currency
                }]
            }
        }, {
            "op":
            "replace",
            "path":
            "/transactions/0/description",
            "value":
            __('Order {order} for {event}').format(event=request.event.name,
                                                   order=order.code)
        }])
        payment.execute(
            {"payer_id": request.session.get('payment_paypal_payer')})

        if payment.state == 'pending':
            messages.warning(
                request,
                _('PayPal has not yet approved the payment. We will inform you as soon as the '
                  'payment completed.'))
            order.payment_info = json.dumps(payment.to_dict())
            order.save()
            return

        if payment.state != 'approved':
            messages.error(
                request,
                _('We were unable to process your payment. See below for details on how to '
                  'proceed.'))
            logger.error('Invalid state: %s' % str(payment))
            return

        try:
            mark_order_paid(order, 'paypal', json.dumps(payment.to_dict()))
        except Quota.QuotaExceededException as e:
            messages.error(request, str(e))
        except SendMailException:
            messages.warning(
                request,
                _('There was an error sending the confirmation mail.'))
        return None
Esempio n. 18
0
    def post(self, *args, **kwargs):
        if 'hbci_server' in self.request.POST:
            return self.process_hbci()

        if ('file' in self.request.FILES and 'csv' in self.request.FILES.get('file').name.lower()) \
                or 'amount' in self.request.POST:
            # Process CSV
            return self.process_csv()

        if 'file' in self.request.FILES and 'txt' in self.request.FILES.get(
                'file').name.lower():
            return self.process_mt940()

        if 'confirm' in self.request.POST:
            orders = Order.objects.current.filter(
                event=self.request.event,
                code__in=self.request.POST.getlist('mark_paid'))
            some_failed = False
            for order in orders:
                try:
                    mark_order_paid(
                        order,
                        provider='banktransfer',
                        info=json.dumps({
                            'reference':
                            self.request.POST.get('reference_%s' % order.code),
                            'date':
                            self.request.POST.get('date_%s' % order.code),
                            'payer':
                            self.request.POST.get('payer_%s' % order.code),
                            'import':
                            now().isoformat(),
                        }))
                except Quota.QuotaExceededException:
                    some_failed = True

            if some_failed:
                messages.warning(
                    self.request,
                    _('Not all of the selected orders could be marked as '
                      'paid as some of them have expired and the selected '
                      'items are sold out.'))
            else:
                messages.success(
                    self.request,
                    _('The selected orders have been marked as paid.'))
                # TODO: Display a list of them!
            return self.redirect_back()

        messages.error(
            self.request,
            _('We were unable to detect the file type of this import. Please '
              'contact support for help.'))
        return self.redirect_back()
Esempio n. 19
0
 def test_paid_expired_partial(self):
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     self.quota.size = 1
     self.quota.save()
     try:
         mark_order_paid(self.order)
         self.assertFalse(True, "This should have raised an exception.")
     except Quota.QuotaExceededException:
         pass
     self.order = Order.objects.get(id=self.order.id)
     self.assertIn(self.order.status, (Order.STATUS_PENDING, Order.STATUS_EXPIRED))
Esempio n. 20
0
def callback(request, *args, **kwargs):
    data = json.loads(request.body)
    logger.info("onepay cllback data {0}".format(request.body.decode('utf-8')))
    onepay=ReferencedOnepayObject.objects.get(reference=data["orderId"])
    if(data["status"]==1):
        mark_order_paid(onepay.order, 'onepay', data["transaction"])
    else:
        onepay.order.status = Order.STATUS_CANCELED
        onepay.order.save()
    onepay.transaction=data['transaction']
    onepay.save()
    return HttpResponse()
Esempio n. 21
0
 def test_paid_expired_unavailable(self):
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     self.quota.size = 0
     self.quota.save()
     try:
         mark_order_paid(self.order)
         self.assertFalse(True, 'This should have raised an exception.')
     except Quota.QuotaExceededException:
         pass
     self.order = Order.objects.current.get(identity=self.order.identity)
     self.assertIn(self.order.status, (Order.STATUS_PENDING, Order.STATUS_EXPIRED))
Esempio n. 22
0
 def test_paid_expired_unavailable_waiting_list(self):
     self.event.settings.payment_term_accept_late = True
     self.event.waitinglistentries.create(item=self.item1, email='*****@*****.**')
     self.order.expires = now() - timedelta(days=2)
     self.order.status = Order.STATUS_EXPIRED
     self.order.save()
     self.quota.size = 2
     self.quota.save()
     with self.assertRaises(Quota.QuotaExceededException):
         mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_EXPIRED)
Esempio n. 23
0
    def payment_perform(self, request, order) -> str:
        info = {'payment_date': datetime.now().strftime('%Y%m%dT%H%M%S')}

        try:
            mark_order_paid(order,
                            Cash.identifier,
                            send_mail=False,
                            info=json.dumps(info),
                            user=request.user)
        except Exception as e:
            raise PaymentException(_('Cash payment error: {}').format(e))

        return None
Esempio n. 24
0
 def test_paid_expired_unavailable(self):
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     self.quota.size = 0
     self.quota.save()
     try:
         mark_order_paid(self.order)
         self.assertFalse(True, 'This should have raised an exception.')
     except Quota.QuotaExceededException:
         pass
     self.order = Order.objects.get(id=self.order.id)
     self.assertIn(self.order.status,
                   (Order.STATUS_PENDING, Order.STATUS_EXPIRED))
Esempio n. 25
0
 def payment_perform(self, request, order) -> str:
     self._init_api()
     try:
         charge = stripe.Charge.create(
             amount=int(order.total * 100),
             currency=request.event.currency.lower(),
             source=request.session['payment_stripe_token'],
             metadata={
                 'order': order.identity,
                 'event': self.event.identity,
                 'code': order.code
             },
             # TODO: Is this sufficient?
             idempotency_key=self.event.identity + order.code + request.session['payment_stripe_token']
         )
     except stripe.error.CardError as e:
         err = e.json_body['error']
         messages.error(request, _('Stripe reported an error with your card: %s' % err['message']))
         logger.info('Stripe card error: %s' % str(err))
         order = order.clone()
         order.payment_info = json.dumps({
             'error': True,
             'message': err['message'],
         })
         order.save()
     except stripe.error.InvalidRequestError or stripe.error.AuthenticationError or stripe.error.APIConnectionError \
             or stripe.error.StripeError as e:
         err = e.json_body['error']
         messages.error(request, _('We had trouble communicating with Stripe. Please try again and get in touch '
                                   'with us if this problem persists.'))
         logger.error('Stripe error: %s' % str(err))
         order = order.clone()
         order.payment_info = json.dumps({
             'error': True,
             'message': err['message'],
         })
         order.save()
     else:
         if charge.status == 'succeeded' and charge.paid:
             try:
                 mark_order_paid(order, 'stripe', str(charge))
                 messages.success(request, _('We successfully received your payment. Thank you!'))
             except Quota.QuotaExceededException as e:
                 messages.error(request, str(e))
         else:
             messages.warning(request, _('Stripe reported an error: %s' % charge.failure_message))
             logger.info('Charge failed: %s' % str(charge))
             order = order.clone()
             order.payment_info = str(charge)
             order.save()
     del request.session['payment_stripe_token']
Esempio n. 26
0
def test_expiring_paid_invoice(event):
    o2 = Order.objects.create(
        code='FO2', event=event, email='*****@*****.**',
        status=Order.STATUS_PENDING, locale='en',
        datetime=now(), expires=now() - timedelta(days=10),
        total=12, payment_provider='banktransfer'
    )
    generate_invoice(o2)
    expire_orders(None)
    o2 = Order.objects.get(id=o2.id)
    assert o2.status == Order.STATUS_EXPIRED
    assert o2.invoices.count() == 2
    mark_order_paid(o2)
    assert o2.invoices.count() == 3
    assert o2.invoices.last().is_cancellation is False
Esempio n. 27
0
    def _accept_ignore_amount(self, trans):
        if trans.order.status == Order.STATUS_PAID:
            return JsonResponse({
                'status':
                'error',
                'message':
                _('The order is already marked as paid.')
            })
        elif trans.order.status == Order.STATUS_REFUNDED:
            return JsonResponse({
                'status':
                'error',
                'message':
                _('The order has already been refunded.')
            })
        elif trans.order.status == Order.STATUS_CANCELED:
            return JsonResponse({
                'status':
                'error',
                'message':
                _('The order has already been canceled.')
            })

        try:
            mark_order_paid(trans.order,
                            provider='banktransfer',
                            info=json.dumps({
                                'reference': trans.reference,
                                'date': trans.date,
                                'payer': trans.payer,
                                'trans_id': trans.pk
                            }),
                            count_waitinglist=False)
            trans.state = BankTransaction.STATE_VALID
            trans.save()
        except Quota.QuotaExceededException as e:
            return JsonResponse({'status': 'error', 'message': str(e)})
        except SendMailException:
            return JsonResponse({
                'status': 'error',
                'message': _('Problem sending email.')
            })
        else:
            trans.state = BankTransaction.STATE_VALID
            trans.save()
            return JsonResponse({'status': 'ok'})
Esempio n. 28
0
def callback(request, *args, **kwargs):
    if request.GET.get('key'):
        key = request.GET.get('key')
        logger.info("woopay callback data {0}" + key)
        woopay = ReferencedWoopayObject.objects.filter(key=key).first()
        if woopay:
            if (woopay.order.status != Order.STATUS_PAID):
                mark_order_paid(woopay.order, 'woopay', key)
            return HttpResponse('{"data":1}')
        else:
            response = HttpResponse()
            response.status_code = 404
            return response
    else:
        response = HttpResponse()
        response.status_code = 404
        return response
Esempio n. 29
0
 def post(self, *args, **kwargs):
     to = self.request.POST.get('status', '')
     if self.order.status in (Order.STATUS_PENDING,
                              Order.STATUS_EXPIRED) and to == 'p':
         try:
             mark_order_paid(self.order,
                             manual=True,
                             user=self.request.user,
                             count_waitinglist=False)
         except Quota.QuotaExceededException as e:
             messages.error(self.request, str(e))
         except SendMailException:
             messages.warning(
                 self.request,
                 _('The order has been marked as paid, but we were unable to send a confirmation mail.'
                   ))
         else:
             messages.success(self.request,
                              _('The order has been marked as paid.'))
     elif self.order.status == Order.STATUS_PENDING and to == 'c':
         cancel_order(self.order,
                      user=self.request.user,
                      send_mail=self.request.POST.get("send_email") == "on")
         messages.success(self.request, _('The order has been canceled.'))
     elif self.order.status == Order.STATUS_PAID and to == 'n':
         self.order.status = Order.STATUS_PENDING
         self.order.payment_manual = True
         self.order.save()
         self.order.log_action('pretix.event.order.unpaid',
                               user=self.request.user)
         messages.success(self.request,
                          _('The order has been marked as not paid.'))
     elif self.order.status == Order.STATUS_PENDING and to == 'e':
         self.order.status = Order.STATUS_EXPIRED
         self.order.save()
         self.order.log_action('pretix.event.order.expired',
                               user=self.request.user)
         messages.success(self.request,
                          _('The order has been marked as expired.'))
     elif self.order.status == Order.STATUS_PAID and to == 'r':
         ret = self.payment_provider.order_control_refund_perform(
             self.request, self.order)
         if ret:
             return redirect(ret)
     return redirect(self.get_order_url())
Esempio n. 30
0
def webhook(request, *args, **kwargs):
    event_json = json.loads(request.body.decode('utf-8'))

    # We do not check for the event type as we are not interested in the event it self,
    # we just use it as a trigger to look the charge up to be absolutely sure.
    # Another reason for this is that stripe events are not authenticated, so they could
    # come from anywhere.

    if event_json['data']['object']['object'] == "charge":
        charge_id = event_json['data']['object']['id']
    elif event_json['data']['object']['object'] == "dispute":
        charge_id = event_json['data']['object']['charge']
    else:
        return HttpResponse("Not interested in this data type", status=200)

    prov = Stripe(request.event)
    prov._init_api()
    try:
        charge = stripe.Charge.retrieve(charge_id)
    except stripe.error.StripeError:
        logger.exception('Stripe error on webhook. Event data: %s' % str(event_json))
        return HttpResponse('Charge not found', status=500)

    metadata = charge['metadata']
    if 'event' not in metadata:
        return HttpResponse('Event not given in charge metadata', status=200)

    if int(metadata['event']) != request.event.pk:
        return HttpResponse('Not interested in this event', status=200)

    try:
        order = request.event.orders.get(id=metadata['order'])
    except Order.DoesNotExist:
        return HttpResponse('Order not found', status=200)

    order.log_action('pretix.plugins.stripe.event', data=event_json)

    is_refund = charge['refunds']['total_count'] or charge['dispute']
    if order.status == Order.STATUS_PAID and is_refund:
        mark_order_refunded(order, user=None)
    elif order.status == Order.STATUS_PENDING and charge['status'] == 'succeeded' and not is_refund:
        mark_order_paid(order, user=None)

    return HttpResponse(status=200)
Esempio n. 31
0
def process_result(request, order, prov):
    order.payment_info = json.dumps(dict(request.POST.items()))
    order.save()
    if order.status in (Order.STATUS_PENDING, Order.STATUS_EXPIRED
                        ) and request.POST.get('paymentState') == 'SUCCESS':
        try:
            mark_order_paid(order, user=None, provider=prov.identifier)
        except Quota.QuotaExceededException:
            if not RequiredAction.objects.filter(
                    event=request.event,
                    action_type='pretix_wirecard.wirecard.overpaid',
                    data__icontains=order.code).exists():
                RequiredAction.objects.create(
                    event=request.event,
                    action_type='pretix_wirecard.wirecard.overpaid',
                    data=json.dumps({
                        'order': order.code,
                        'charge': request.POST.get('orderNumber')
                    }))
Esempio n. 32
0
File: views.py Progetto: rixx/pretix
    def _accept_ignore_amount(self, trans):
        if trans.order.status == Order.STATUS_PAID:
            return JsonResponse({
                'status': 'error',
                'message': _('The order is already marked as paid.')
            })
        elif trans.order.status == Order.STATUS_REFUNDED:
            return JsonResponse({
                'status': 'error',
                'message': _('The order has already been refunded.')
            })
        elif trans.order.status == Order.STATUS_CANCELED:
            return JsonResponse({
                'status': 'error',
                'message': _('The order has already been canceled.')
            })

        try:
            mark_order_paid(trans.order, provider='banktransfer', info=json.dumps({
                'reference': trans.reference,
                'date': trans.date,
                'payer': trans.payer,
                'trans_id': trans.pk
            }))
            trans.state = BankTransaction.STATE_VALID
            trans.save()
        except Quota.QuotaExceededException as e:
            return JsonResponse({
                'status': 'error',
                'message': str(e)
            })
        except SendMailException:
            return JsonResponse({
                'status': 'error',
                'message': _('Problem sending email.')
            })
        else:
            trans.state = BankTransaction.STATE_VALID
            trans.save()
            return JsonResponse({
                'status': 'ok'
            })
Esempio n. 33
0
def _handle_transaction(event: Event, trans: BankTransaction, code: str):
    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

    if trans.order.status == Order.STATUS_PAID:
        trans.state = BankTransaction.STATE_DUPLICATE
    elif trans.order.status == Order.STATUS_REFUNDED:
        trans.state = BankTransaction.STATE_ERROR
        trans.message = ugettext_noop('The order has already been refunded.')
    elif trans.order.status == Order.STATUS_CANCELED:
        trans.state = BankTransaction.STATE_ERROR
        trans.message = ugettext_noop('The order has already been canceled.')
    elif trans.amount != trans.order.total:
        trans.state = BankTransaction.STATE_INVALID
        trans.message = ugettext_noop('The transaction amount is incorrect.')
    else:
        try:
            mark_order_paid(trans.order,
                            provider='banktransfer',
                            info=json.dumps({
                                'reference': trans.reference,
                                'date': trans.date,
                                'payer': trans.payer,
                                'trans_id': trans.pk
                            }))
        except Quota.QuotaExceededException as e:
            trans.state = BankTransaction.STATE_ERROR
            trans.message = str(e)
        except SendMailException:
            trans.state = BankTransaction.STATE_ERROR
            trans.message = ugettext_noop('Problem sending email.')
        else:
            trans.state = BankTransaction.STATE_VALID
    trans.save()
Esempio n. 34
0
    def mark_paid(self, request, **kwargs):
        order = self.get_object()

        if order.status in (Order.STATUS_PENDING, Order.STATUS_EXPIRED):
            try:
                mark_order_paid(
                    order, manual=True,
                    user=request.user if request.user.is_authenticated else None,
                    api_token=(request.auth if isinstance(request.auth, TeamAPIToken) else None),
                )
            except Quota.QuotaExceededException as e:
                return Response({'detail': str(e)}, status=status.HTTP_400_BAD_REQUEST)
            except SendMailException:
                pass

            return self.retrieve(request, [], **kwargs)
        return Response(
            {'detail': 'The order is not pending or expired.'},
            status=status.HTTP_400_BAD_REQUEST
        )
Esempio n. 35
0
    def _execute_payment(self, payment, request, order):
        payment.execute({"payer_id": request.session.get('payment_paypal_payer')})

        if payment.state == 'pending':
            messages.warning(request, _('PayPal has not yet approved the payment. We will inform you as soon as the '
                                        'payment completed.'))
            order.payment_info = json.dumps(payment.to_dict())
            order.save()
            return

        if payment.state != 'approved':
            messages.error(request, _('We were unable to process your payment. See below for details on how to '
                                      'proceed.'))
            logger.error('Invalid state: %s' % str(payment))
            return

        try:
            mark_order_paid(order, 'paypal', json.dumps(payment.to_dict()))
        except Quota.QuotaExceededException as e:
            messages.error(request, str(e))
        return None
Esempio n. 36
0
    def payment_perform(self, request, order) -> str:
        self._init_api()
        result = braintree.Transaction.sale({
            "amount":
            str(order.total),
            "payment_method_nonce":
            request.session['payment_braintree_nonce'],
            "options": {
                "submit_for_settlement": True
            }
        })
        if result.is_success:
            try:
                mark_order_paid(
                    order, self.identifier,
                    json.dumps(self._serialize(result.transaction)))
            except Quota.QuotaExceededException as e:
                RequiredAction.objects.create(
                    event=request.event,
                    action_type='pretix_braintree.overpaid',
                    data=json.dumps({
                        'order': order.code,
                    }))
                raise PaymentException(str(e))

            except SendMailException:
                raise PaymentException(
                    _('There was an error sending the confirmation mail.'))
        else:
            if result.transaction:
                order.payment_info = json.dumps(
                    self._serialize(result.transaction))
            else:
                order.payment_info = json.dumps({'error': result.message})
            order.save()
            raise PaymentException(
                _('Your payment failed because Braintree reported the following error: %s'
                  ) % str(result.message))

        del request.session['payment_braintree_nonce']
Esempio n. 37
0
def _handle_transaction(event: Event, trans: BankTransaction, code: str):
    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

    if trans.order.status == Order.STATUS_PAID:
        trans.state = BankTransaction.STATE_DUPLICATE
    elif trans.order.status == Order.STATUS_REFUNDED:
        trans.state = BankTransaction.STATE_ERROR
        trans.message = ugettext_noop('The order has already been refunded.')
    elif trans.order.status == Order.STATUS_CANCELED:
        trans.state = BankTransaction.STATE_ERROR
        trans.message = ugettext_noop('The order has already been canceled.')
    elif trans.amount != trans.order.total:
        trans.state = BankTransaction.STATE_INVALID
        trans.message = ugettext_noop('The transaction amount is incorrect.')
    else:
        try:
            mark_order_paid(trans.order, provider='banktransfer', info=json.dumps({
                'reference': trans.reference,
                'date': trans.date,
                'payer': trans.payer,
                'trans_id': trans.pk
            }))
        except Quota.QuotaExceededException as e:
            trans.state = BankTransaction.STATE_ERROR
            trans.message = str(e)
        except SendMailException:
            trans.state = BankTransaction.STATE_ERROR
            trans.message = ugettext_noop('Problem sending email.')
        else:
            trans.state = BankTransaction.STATE_VALID
    trans.save()
Esempio n. 38
0
    def test_paid_expired_after_last_date_subevent_relative(self):
        self.event.has_subevents = True
        self.event.save()
        se1 = self.event.subevents.create(name="SE1", date_from=now() + timedelta(days=10))
        se2 = self.event.subevents.create(name="SE2", date_from=now() + timedelta(days=1))
        self.op1.subevent = se1
        self.op1.save()
        self.op2.subevent = se2
        self.op2.save()
        self.event.settings.set('payment_term_last', RelativeDateWrapper(
            RelativeDate(days_before=2, time=None, base_date_name='date_from')
        ))

        self.order.status = Order.STATUS_EXPIRED
        self.order.expires = now() - timedelta(days=2)
        self.order.save()
        with self.assertRaises(Quota.QuotaExceededException):
            mark_order_paid(self.order)
        self.order = Order.objects.get(id=self.order.id)
        self.assertEqual(self.order.status, Order.STATUS_EXPIRED)
        self.event.has_subevents = False
        self.event.save()
Esempio n. 39
0
    def post(self, *args, **kwargs):
        if 'hbci_server' in self.request.POST:
            return self.process_hbci()

        if ('file' in self.request.FILES and 'csv' in self.request.FILES.get('file').name.lower()) \
                or 'amount' in self.request.POST:
            # Process CSV
            return self.process_csv()

        if 'file' in self.request.FILES and 'txt' in self.request.FILES.get('file').name.lower():
            return self.process_mt940()

        if 'confirm' in self.request.POST:
            orders = Order.objects.current.filter(event=self.request.event,
                                                  code__in=self.request.POST.getlist('mark_paid'))
            some_failed = False
            for order in orders:
                try:
                    mark_order_paid(order, provider='banktransfer', info=json.dumps({
                        'reference': self.request.POST.get('reference_%s' % order.code),
                        'date': self.request.POST.get('date_%s' % order.code),
                        'payer': self.request.POST.get('payer_%s' % order.code),
                        'import': now().isoformat(),
                    }))
                except Quota.QuotaExceededException:
                    some_failed = True

            if some_failed:
                messages.warning(self.request, _('Not all of the selected orders could be marked as '
                                                 'paid as some of them have expired and the selected '
                                                 'items are sold out.'))
            else:
                messages.success(self.request, _('The selected orders have been marked as paid.'))
                # TODO: Display a list of them!
            return self.redirect_back()

        messages.error(self.request, _('We were unable to detect the file type of this import. Please '
                                       'contact support for help.'))
        return self.redirect_back()
Esempio n. 40
0
 def test_paid_in_time(self):
     self.quota.size = 0
     self.quota.save()
     mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 41
0
    def _charge_source(self, request, source, order):
        try:
            charge = stripe.Charge.create(
                amount=self._get_amount(order),
                currency=self.event.currency.lower(),
                source=source,
                metadata={
                    'order': str(order.id),
                    'event': self.event.id,
                    'code': order.code
                },
                # TODO: Is this sufficient?
                idempotency_key=str(self.event.id) + order.code + source,
                **self.api_kwargs)
        except stripe.error.CardError as e:
            if e.json_body:
                err = e.json_body['error']
                logger.exception('Stripe error: %s' % str(err))
            else:
                err = {'message': str(e)}
                logger.exception('Stripe error: %s' % str(e))
            logger.info('Stripe card error: %s' % str(err))
            order.payment_info = json.dumps({
                'error': True,
                'message': err['message'],
            })
            order.save(update_fields=['payment_info'])
            raise PaymentException(
                _('Stripe reported an error with your card: %s') %
                err['message'])

        except stripe.error.StripeError as e:
            if e.json_body:
                err = e.json_body['error']
                logger.exception('Stripe error: %s' % str(err))
            else:
                err = {'message': str(e)}
                logger.exception('Stripe error: %s' % str(e))
            order.payment_info = json.dumps({
                'error': True,
                'message': err['message'],
            })
            order.save(update_fields=['payment_info'])
            raise PaymentException(
                _('We had trouble communicating with Stripe. Please try again and get in touch '
                  'with us if this problem persists.'))
        else:
            ReferencedStripeObject.objects.get_or_create(order=order,
                                                         reference=charge.id)
            if charge.status == 'succeeded' and charge.paid:
                try:
                    mark_order_paid(order, self.identifier, str(charge))
                except Quota.QuotaExceededException as e:
                    RequiredAction.objects.create(
                        event=self.event,
                        action_type='pretix.plugins.stripe.overpaid',
                        data=json.dumps({
                            'order': order.code,
                            'charge': charge.id
                        }))
                    raise PaymentException(str(e))

                except SendMailException:
                    raise PaymentException(
                        _('There was an error sending the confirmation mail.'))
            elif charge.status == 'pending':
                if request:
                    messages.warning(
                        request,
                        _('Your payment is pending completion. We will inform you as soon as the '
                          'payment completed.'))
                order.payment_info = str(charge)
                order.save(update_fields=['payment_info'])
                return
            else:
                logger.info('Charge failed: %s' % str(charge))
                order.payment_info = str(charge)
                order.save(update_fields=['payment_info'])
                raise PaymentException(
                    _('Stripe reported an error: %s') % charge.failure_message)
Esempio n. 42
0
 def payment_perform(self, request: HttpRequest, order: Order):
     mark_order_paid(order, 'free')
Esempio n. 43
0
 def test_paid_after_deadline_but_not_expired(self):
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 44
0
 def payment_perform(self, request: HttpRequest, order: Order):
     from pretix.base.services.orders import mark_order_paid
     mark_order_paid(order, 'free')
Esempio n. 45
0
 def test_paid_in_time(self):
     self.quota.size = 0
     self.quota.save()
     mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 46
0
 def payment_perform(self, request: HttpRequest, order: Order):
     from pretix.base.services.orders import mark_order_paid
     try:
         mark_order_paid(order, 'free', send_mail=False)
     except Quota.QuotaExceededException as e:
         raise PaymentException(str(e))
Esempio n. 47
0
 def test_paid_expired_available(self):
     self.order.expires = now() - timedelta(days=2)
     self.order.save()
     mark_order_paid(self.order)
     self.order = Order.objects.get(id=self.order.id)
     self.assertEqual(self.order.status, Order.STATUS_PAID)
Esempio n. 48
0
 def payment_perform(self, request: HttpRequest, order: Order):
     from pretix.base.services.orders import mark_order_paid
     try:
         mark_order_paid(order, 'free', send_mail=False)
     except Quota.QuotaExceededException as e:
         messages.error(request, str(e))