예제 #1
0
파일: order.py 프로젝트: bsod85/pretix
    def create(self, request, *args, **kwargs):
        if 'mark_refunded' in request.data:
            mark_refunded = request.data.pop('mark_refunded', False)
        else:
            mark_refunded = request.data.pop('mark_canceled', False)
        serializer = OrderRefundCreateSerializer(
            data=request.data, context=self.get_serializer_context())
        serializer.is_valid(raise_exception=True)
        with transaction.atomic():
            self.perform_create(serializer)
            r = serializer.instance
            serializer = OrderRefundSerializer(r, context=serializer.context)

            r.order.log_action(
                'pretix.event.order.refund.created', {
                    'local_id': r.local_id,
                    'provider': r.provider,
                },
                user=request.user if request.user.is_authenticated else None,
                auth=request.auth)
            if mark_refunded:
                mark_order_refunded(
                    r.order,
                    user=request.user
                    if request.user.is_authenticated else None,
                    auth=(request.auth if request.auth else None),
                )

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)
예제 #2
0
    def refund(self, request, **kwargs):
        payment = self.get_object()
        amount = serializers.DecimalField(max_digits=10, decimal_places=2).to_internal_value(
            request.data.get('amount', str(payment.amount))
        )
        mark_refunded = request.data.get('mark_refunded', False)

        if payment.state != OrderPayment.PAYMENT_STATE_CONFIRMED:
            return Response({'detail': 'Invalid state of payment.'}, status=status.HTTP_400_BAD_REQUEST)

        full_refund_possible = payment.payment_provider.payment_refund_supported(payment)
        partial_refund_possible = payment.payment_provider.payment_partial_refund_supported(payment)
        available_amount = payment.amount - payment.refunded_amount

        if amount <= 0:
            return Response({'amount': ['Invalid refund amount.']}, status=status.HTTP_400_BAD_REQUEST)
        if amount > available_amount:
            return Response(
                {'amount': ['Invalid refund amount, only {} are available to refund.'.format(available_amount)]},
                status=status.HTTP_400_BAD_REQUEST)
        if amount != payment.amount and not partial_refund_possible:
            return Response({'amount': ['Partial refund not available for this payment method.']},
                            status=status.HTTP_400_BAD_REQUEST)
        if amount == payment.amount and not full_refund_possible:
            return Response({'amount': ['Full refund not available for this payment method.']},
                            status=status.HTTP_400_BAD_REQUEST)
        r = payment.order.refunds.create(
            payment=payment,
            source=OrderRefund.REFUND_SOURCE_ADMIN,
            state=OrderRefund.REFUND_STATE_CREATED,
            amount=amount,
            provider=payment.provider
        )

        try:
            r.payment_provider.execute_refund(r)
        except PaymentException as e:
            r.state = OrderRefund.REFUND_STATE_FAILED
            r.save()
            return Response({'detail': 'External error: {}'.format(str(e))},
                            status=status.HTTP_400_BAD_REQUEST)
        else:
            payment.order.log_action('pretix.event.order.refund.created', {
                'local_id': r.local_id,
                'provider': r.provider,
            }, user=self.request.user if self.request.user.is_authenticated else None, auth=self.request.auth)
            if payment.order.pending_sum > 0:
                if mark_refunded:
                    mark_order_refunded(payment.order,
                                        user=self.request.user if self.request.user.is_authenticated else None,
                                        auth=self.request.auth)
                else:
                    payment.order.status = Order.STATUS_PENDING
                    payment.order.set_expires(
                        now(),
                        payment.order.event.subevents.filter(
                            id__in=payment.order.positions.values_list('subevent_id', flat=True))
                    )
                    payment.order.save(update_fields=['status', 'expires'])
            return Response(OrderRefundSerializer(r).data, status=status.HTTP_200_OK)
예제 #3
0
    def order_control_refund_perform(self, request: HttpRequest,
                                     order: Order) -> Union[bool, str]:
        """
        Will be called if the event administrator confirms the refund.

        This should transfer the money back (if possible). You can return the URL the
        user should be redirected to if you need special behaviour or None to continue
        with default behaviour.

        On failure, you should use Django's message framework to display an error message
        to the user.

        The default implementation sets the Order's state to refunded and shows a success
        message.

        :param request: The HTTP request
        :param order: The order object
        """
        from pretix.base.services.orders import mark_order_refunded

        mark_order_refunded(order, user=request.user)
        messages.success(
            request,
            _('The order has been marked as refunded. Please transfer the money '
              'back to the buyer manually.'))
예제 #4
0
파일: views.py 프로젝트: reynoldsjk1/pretix
def refund(request, **kwargs):
    with transaction.atomic():
        action = get_object_or_404(RequiredAction,
                                   event=request.event,
                                   pk=kwargs.get('id'),
                                   action_type='pretix.plugins.stripe.refund',
                                   done=False)
        data = json.loads(action.data)
        action.done = True
        action.user = request.user
        action.save()
        order = get_object_or_404(Order,
                                  event=request.event,
                                  code=data['order'])
        if order.status != Order.STATUS_PAID:
            messages.error(
                request,
                _('The order cannot be marked as refunded as it is not marked as paid!'
                  ))
        else:
            mark_order_refunded(order, user=request.user)
            messages.success(
                request,
                _('The order has been marked as refunded and the issue has been marked as resolved!'
                  ))

    return redirect(
        reverse('control:event.order',
                kwargs={
                    'organizer': request.event.organizer.slug,
                    'event': request.event.slug,
                    'code': data['order']
                }))
예제 #5
0
파일: payment.py 프로젝트: annp89/pretix
    def order_control_refund_perform(self, request, order) -> "bool|str":
        self._init_api()

        if order.payment_info:
            payment_info = json.loads(order.payment_info)
        else:
            payment_info = None

        if not payment_info:
            mark_order_refunded(order, user=request.user)
            messages.warning(request, _('We were unable to transfer the money back automatically. '
                                        'Please get in touch with the customer and transfer it back manually.'))
            return

        try:
            ch = stripe.Charge.retrieve(payment_info['id'])
            ch.refunds.create()
            ch.refresh()
        except stripe.error.InvalidRequestError or stripe.error.AuthenticationError or stripe.error.APIConnectionError \
                as e:
            err = e.json_body['error']
            messages.error(request, _('We had trouble communicating with Stripe. Please try again and contact '
                                      'support if the problem persists.'))
            logger.error('Stripe error: %s' % str(err))
        except stripe.error.StripeError:
            mark_order_refunded(order)
            messages.warning(request, _('We were unable to transfer the money back automatically. '
                                        'Please get in touch with the customer and transfer it back manually.'))
        else:
            order = mark_order_refunded(order)
            order.payment_info = str(ch)
            order.save()
예제 #6
0
    def order_control_refund_perform(self, request, order) -> "bool|str":
        self.init_api()

        if order.payment_info:
            payment_info = json.loads(order.payment_info)
        else:
            payment_info = None

        if not payment_info:
            mark_order_refunded(order, user=request.user)
            messages.warning(request, _('We were unable to transfer the money back automatically. '
                                        'Please get in touch with the customer and transfer it back manually.'))
            return

        for res in payment_info['transactions'][0]['related_resources']:
            for k, v in res.items():
                if k == 'sale':
                    sale = paypalrestsdk.Sale.find(v['id'])
                    break

        refund = sale.refund({})
        if not refund.success():
            mark_order_refunded(order, user=request.user)
            messages.warning(request, _('We were unable to transfer the money back automatically. '
                                        'Please get in touch with the customer and transfer it back manually.'))
        else:
            sale = paypalrestsdk.Payment.find(payment_info['id'])
            order = mark_order_refunded(order, user=request.user)
            order.payment_info = json.dumps(sale.to_dict())
            order.save()
예제 #7
0
파일: payment.py 프로젝트: cherti/pretix
    def order_control_refund_perform(self, request, order) -> "bool|str":
        self.init_api()

        if order.payment_info:
            payment_info = json.loads(order.payment_info)
        else:
            payment_info = None

        if not payment_info:
            mark_order_refunded(order)
            messages.warning(request, _('We were unable to transfer the money back automatically. '
                                        'Please get in touch with the customer and transfer it back manually.'))
            return

        for res in payment_info['transactions'][0]['related_resources']:
            for k, v in res.items():
                if k == 'sale':
                    sale = paypalrestsdk.Sale.find(v['id'])
                    break

        refund = sale.refund({})
        if not refund.success():
            mark_order_refunded(order, user=request.user)
            messages.warning(request, _('We were unable to transfer the money back automatically. '
                                        'Please get in touch with the customer and transfer it back manually.'))
        else:
            sale = paypalrestsdk.Payment.find(payment_info['id'])
            order = mark_order_refunded(order)
            order.payment_info = json.dumps(sale.to_dict())
            order.save()
예제 #8
0
파일: order.py 프로젝트: bsod85/pretix
    def process(self, request, **kwargs):
        refund = self.get_object()

        if refund.state != OrderRefund.REFUND_STATE_EXTERNAL:
            return Response({'detail': 'Invalid state of refund'},
                            status=status.HTTP_400_BAD_REQUEST)

        refund.done(user=self.request.user
                    if self.request.user.is_authenticated else None,
                    auth=self.request.auth)
        if 'mark_refunded' in request.data:
            mark_refunded = request.data.get('mark_refunded', False)
        else:
            mark_refunded = request.data.get('mark_canceled', False)
        if mark_refunded:
            mark_order_refunded(refund.order,
                                user=self.request.user if
                                self.request.user.is_authenticated else None,
                                auth=self.request.auth)
        elif not (refund.order.status == Order.STATUS_PAID
                  and refund.order.pending_sum <= 0):
            refund.order.status = Order.STATUS_PENDING
            refund.order.set_expires(
                now(),
                refund.order.event.subevents.filter(
                    id__in=refund.order.positions.values_list('subevent_id',
                                                              flat=True)))
            refund.order.save(update_fields=['status', 'expires'])
        return self.retrieve(request, [], **kwargs)
예제 #9
0
    def create(self, request, *args, **kwargs):
        if 'mark_refunded' in request.data:
            mark_refunded = request.data.pop('mark_refunded', False)
        else:
            mark_refunded = request.data.pop('mark_canceled', False)
        serializer = OrderRefundCreateSerializer(data=request.data, context=self.get_serializer_context())
        serializer.is_valid(raise_exception=True)
        with transaction.atomic():
            self.perform_create(serializer)
            r = serializer.instance
            serializer = OrderRefundSerializer(r, context=serializer.context)

            r.order.log_action(
                'pretix.event.order.refund.created', {
                    'local_id': r.local_id,
                    'provider': r.provider,
                },
                user=request.user if request.user.is_authenticated else None,
                auth=request.auth
            )
            if mark_refunded:
                mark_order_refunded(
                    r.order,
                    user=request.user if request.user.is_authenticated else None,
                    auth=(request.auth if request.auth else None),
                )

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
예제 #10
0
    def order_control_refund_perform(self, request, order):
        info = json.loads(order.payment_info)
        merchant = self.settings.get('merchant_id')
        transact = info['transact']
        amount = info['amount']
        currency = info['currency']
        orderid = info['orderid']

        payload = {
            'merchant': merchant,
            'transact': transact,
            'amount': amount,
            'currency': currency,
            'orderid': orderid,
            'textreply': 'true',
            # 'fullreply': 'true'
        }

        if self.settings.get('test_mode'):
            payload['test'] = 1

        if self.settings.get('use_md5key'):
            # https://tech.dibspayment.com/D2/API/MD5
            key1 = self.settings.get('md5_key1')
            key2 = self.settings.get('md5_key2')

            parameters = 'merchant=' + merchant + '&orderid=' + orderid + '&transact=' + transact + '&amount=' + amount
            md5key = DIBS.md5(key2 + DIBS.md5(key1 + parameters))
            payload['md5key'] = md5key

        (username, password) = self.get_api_authorization(merchant)
        if username is None or password is None:
            messages.error(request, _('Missing DIBS api username and password for merchant {merchant}.'
                                      ' Order cannot be refunded in DIBS.').format(merchant=merchant))
            return None

        # https://tech.dibspayment.com/D2/API/Payment_functions/refundcgi
        url = 'https://{}:{}@payment.architrade.com/cgi-adm/refund.cgi'.format(username, password)

        r = requests.post(url, data=payload)

        data = parse_qs(r.text)
        status = data['status'][0] if 'status' in data else None
        result = int(data['result'][0]) if 'result' in data else -1
        message = data['message'][0] if 'message' in data else None

        if result == DIBS.REFUND_ACCEPTED:
            from pretix.base.services.orders import mark_order_refunded

            mark_order_refunded(order, user=request.user)
            messages.success(request, _('The order has been marked as refunded and the money have been refunded in DIBS.'))
        else:
            messages.error(request, _('Error refunding in DIBS ({status}; {result}; {message})'.format(status=status, result=result, message=message)))
            logger.error(['order_control_refund_perform', r.text, r.status_code, info])

        return None
예제 #11
0
파일: order.py 프로젝트: obutuz/pretix
    def mark_refunded(self, request, **kwargs):
        order = self.get_object()

        if order.status != Order.STATUS_PAID:
            return Response({'detail': 'The order is not paid.'},
                            status=status.HTTP_400_BAD_REQUEST)

        mark_order_refunded(
            order,
            user=request.user if request.user.is_authenticated else None,
            api_token=(request.auth
                       if isinstance(request.auth, TeamAPIToken) else None),
        )
        return self.retrieve(request, [], **kwargs)
예제 #12
0
    def mark_refunded(self, request, **kwargs):
        order = self.get_object()

        if order.status != Order.STATUS_PAID:
            return Response(
                {'detail': 'The order is not paid.'},
                status=status.HTTP_400_BAD_REQUEST
            )

        mark_order_refunded(
            order,
            user=request.user if request.user.is_authenticated else None,
            auth=(request.auth if isinstance(request.auth, (TeamAPIToken, OAuthAccessToken, Device)) else None),
        )
        return self.retrieve(request, [], **kwargs)
예제 #13
0
    def order_control_refund_perform(self, request, order) -> "bool|str":
        self._init_api()

        if order.payment_info:
            payment_info = json.loads(order.payment_info)
        else:
            payment_info = None

        if not payment_info or 'id' not in payment_info:
            mark_order_refunded(order, user=request.user)
            messages.warning(
                request,
                _('We were unable to transfer the money back automatically. '
                  'Please get in touch with the customer and transfer it back manually.'
                  ))
            return

        try:
            transaction = braintree.Transaction.find(payment_info['id'])
            if transaction.status in ("authorized",
                                      "submitted_for_settlement"):
                result = braintree.Transaction.void(payment_info['id'])
            elif transaction.status in ("settled", "settling"):
                result = braintree.Transaction.refund(payment_info['id'])
            else:
                mark_order_refunded(order, user=request.user)
                logger.warning(
                    'Braintree refund of invalid state requested: %s' %
                    transaction.status)
                messages.warning(
                    request,
                    _('We were unable to transfer the money back automatically. '
                      'Please get in touch with the customer and transfer it back manually.'
                      ))
                return

            if result.is_success:
                transaction = braintree.Transaction.find(payment_info['id'])
                order = mark_order_refunded(order, user=request.user)
                order.payment_info = json.dumps(self._serialize(transaction))
                order.save()
            else:
                order = mark_order_refunded(order, user=request.user)
                logger.warning('Braintree refund/void failed: %s' %
                               result.message)
                messages.warning(
                    request,
                    _('We were unable to transfer the money back automatically. '
                      'Please get in touch with the customer and transfer it back manually.'
                      ))
        except BraintreeError as e:
            logger.exception('Braintree error: %s' % str(e))
            mark_order_refunded(order, user=request.user)
            messages.warning(
                request,
                _('We were unable to transfer the money back automatically. '
                  'Please get in touch with the customer and transfer it back manually.'
                  ))
예제 #14
0
    def order_control_refund_perform(self, request, order) -> "bool|str":
        self._init_api()

        if order.payment_info:
            payment_info = json.loads(order.payment_info)
        else:
            payment_info = None

        if not payment_info:
            mark_order_refunded(order, user=request.user)
            messages.warning(
                request,
                _('We were unable to transfer the money back automatically. '
                  'Please get in touch with the customer and transfer it back manually.'
                  ))
            return

        try:
            ch = stripe.Charge.retrieve(payment_info['id'])
            ch.refunds.create()
            ch.refresh()
        except (stripe.error.InvalidRequestError, stripe.error.AuthenticationError, stripe.error.APIConnectionError) \
                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 contact '
                  'support if the problem persists.'))
            logger.error('Stripe error: %s' % str(err))
        except stripe.error.StripeError:
            mark_order_refunded(order, user=request.user)
            messages.warning(
                request,
                _('We were unable to transfer the money back automatically. '
                  'Please get in touch with the customer and transfer it back manually.'
                  ))
        else:
            order = mark_order_refunded(order, user=request.user)
            order.payment_info = str(ch)
            order.save()
예제 #15
0
파일: views.py 프로젝트: chotee/pretix
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)
예제 #16
0
    def process(self, request, **kwargs):
        refund = self.get_object()

        if refund.state != OrderRefund.REFUND_STATE_EXTERNAL:
            return Response({'detail': 'Invalid state of refund'}, status=status.HTTP_400_BAD_REQUEST)

        refund.done(user=self.request.user if self.request.user.is_authenticated else None, auth=self.request.auth)
        if request.data.get('mark_refunded', False):
            mark_order_refunded(refund.order, user=self.request.user if self.request.user.is_authenticated else None,
                                auth=self.request.auth)
        else:
            refund.order.status = Order.STATUS_PENDING
            refund.order.set_expires(
                now(),
                refund.order.event.subevents.filter(
                    id__in=refund.order.positions.values_list('subevent_id', flat=True))
            )
            refund.order.save(update_fields=['status', 'expires'])
        return self.retrieve(request, [], **kwargs)
예제 #17
0
def webhook(request):
    event_json = json.loads(request.body.decode('utf-8'))
    event_type = event_json['type']
    if event_type != 'charge.refunded':
        # Not interested
        return HttpResponse('Event is not a refund', status=200)

    charge = event_json['data']['object']
    if charge['object'] != 'charge':
        return HttpResponse('Object is not a charge', status=200)

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

    try:
        event = Event.objects.get(id=metadata['event'])
    except Event.DoesNotExist:
        return HttpResponse('Event not found', status=200)

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

    prov = Stripe(event)
    prov._init_api()

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

    try:
        charge = stripe.Charge.retrieve(charge['id'])
    except stripe.error.StripeError as err:
        logger.error('Stripe error on webhook: %s Event data: %s' %
                     (str(err), str(event_json)))
        return HttpResponse('StripeError', status=500)

    if charge['refunds'][
            'total_count'] > 0 and order.status == Order.STATUS_PAID:
        mark_order_refunded(order)

    return HttpResponse(status=200)
예제 #18
0
파일: views.py 프로젝트: rixx/pretix
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)

    if order.status == Order.STATUS_PAID and (charge['refunds']['total_count'] or charge['dispute']):
        mark_order_refunded(order, user=None)

    return HttpResponse(status=200)
예제 #19
0
    def order_control_refund_perform(self, request: HttpRequest, order: Order) -> "bool|str":
        """
        Will be called if the event administrator confirms the refund.

        This should transfer the money back (if possible). You can return the URL the
        user should be redirected to if you need special behaviour or None to continue
        with default behaviour.

        On failure, you should use Django's message framework to display an error message
        to the user.

        The default implementation sets the Order's state to refunded and shows a success
        message.

        :param request: The HTTP request
        :param order: The order object
        """
        from pretix.base.services.orders import mark_order_refunded

        mark_order_refunded(order, user=request.user)
        messages.success(request, _('The order has been marked as refunded.'))
예제 #20
0
def webhook(request):
    event_json = json.loads(request.body.decode('utf-8'))
    event_type = event_json['type']
    if event_type != 'charge.refunded':
        # Not interested
        return HttpResponse('Event is not a refund', status=200)

    charge = event_json['data']['object']
    if charge['object'] != 'charge':
        return HttpResponse('Object is not a charge', status=200)

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

    try:
        event = Event.objects.get(id=metadata['event'])
    except Event.DoesNotExist:
        return HttpResponse('Event not found', status=200)

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

    prov = Stripe(event)
    prov._init_api()

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

    try:
        charge = stripe.Charge.retrieve(charge['id'])
    except stripe.error.StripeError as err:
        logger.error('Stripe error on webhook: %s Event data: %s' % (str(err), str(event_json)))
        return HttpResponse('StripeError', status=500)

    if charge['refunds']['total_count'] > 0 and order.status == Order.STATUS_PAID:
        mark_order_refunded(order)

    return HttpResponse(status=200)
예제 #21
0
    def order_control_refund_perform(self, request, order) -> "bool|str":
        if order.payment_info:
            payment_info = json.loads(order.payment_info)
        else:
            payment_info = None

        if not payment_info or not self.refund_available:
            mark_order_refunded(order, user=request.user)
            messages.warning(
                request,
                _('We were unable to transfer the money back automatically. '
                  'Please get in touch with the customer and transfer it back manually.'
                  ))
            return

        f = self._refund_form(request)
        if not f.is_valid():
            messages.error(request,
                           _('Your input was invalid, please try again.'))
            return
        elif f.cleaned_data.get('auto_refund') == 'manual':
            order = mark_order_refunded(order, user=request.user)
            order.payment_manual = True
            order.save()
            return

        try:
            self._refund(payment_info['orderNumber'], order.total,
                         self.event.currency, order.locale[:2])
        except PaymentException as e:
            messages.error(request, str(e))
        except requests.exceptions.RequestException as e:
            logger.exception('Wirecard error: %s' % str(e))
            messages.error(
                request,
                _('We had trouble communicating with Wirecard. Please try again and contact '
                  'support if the problem persists.'))
        else:
            mark_order_refunded(order, user=request.user)
예제 #22
0
    def order_control_refund_perform(self, request: HttpRequest,
                                     order: Order) -> Union[bool, str]:
        from pretix.base.services.orders import mark_order_refunded

        mark_order_refunded(order, user=request.user)
        messages.success(request, _('The order has been marked as refunded.'))