Esempio n. 1
0
 def execute_refund(self, refund: OrderRefund):
     payment = refund.payment.info_data.get('id')
     body = {
         'amount': {
             'currency': self.event.currency,
             'value': str(refund.amount)
         },
     }
     if self.settings.connect_client_id and self.settings.access_token:
         body['testmode'] = refund.payment.info_data.get('mode',
                                                         'live') == 'test'
     try:
         print(self.request_headers, body)
         req = requests.post(
             'https://api.mollie.com/v2/payments/{}/refunds'.format(
                 payment),
             json=body,
             headers=self.request_headers)
         req.raise_for_status()
         req.json()
     except HTTPError:
         logger.exception('Mollie error: %s' % req.text)
         try:
             refund.info_data = req.json()
         except:
             refund.info_data = {'error': True, 'detail': req.text}
         raise PaymentException(
             _('Mollie reported an error: {}').format(
                 refund.info_data.get('detail')))
     else:
         refund.done()
Esempio n. 2
0
    def execute_refund(self, refund: OrderRefund):
        self._init_api()

        payment_info = refund.payment.info_data

        if not payment_info:
            raise PaymentException(_('No payment information found.'))

        try:
            ch = stripe.Charge.retrieve(payment_info['id'], **self.api_kwargs)
            ch.refunds.create(
                amount=self._get_amount(refund),
            )
            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))
            raise PaymentException(_('We had trouble communicating with Stripe. Please try again and contact '
                                     'support if the problem persists.'))
        except stripe.error.StripeError as err:
            logger.error('Stripe error: %s' % str(err))
            raise PaymentException(_('Stripe returned an error'))
        else:
            refund.done()
Esempio n. 3
0
    def execute_refund(self, refund: OrderRefund):
        self.init_api()

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

        pp_refund = sale.refund({
            "amount": {
                "total": self.format_price(refund.amount),
                "currency": refund.order.event.currency
            }
        })
        if not pp_refund.success():
            raise PaymentException(
                _('Refunding the amount via PayPal failed: {}').format(
                    pp_refund.error))
        else:
            sale = paypalrestsdk.Payment.find(refund.payment.info_data['id'])
            refund.payment.info = json.dumps(sale.to_dict())
            refund.info = json.dumps(pp_refund.to_dict())
            refund.done()
Esempio n. 4
0
 def execute_refund(self, refund: OrderRefund):
     try:
         self._refund(refund)
     except requests.exceptions.RequestException as e:
         logger.exception('BitPay error: %s' % str(e))
         raise PaymentException(_('We had trouble communicating with BitPay. Please try again and contact '
                                  'support if the problem persists.'))
     else:
         refund.done()
Esempio n. 5
0
 def execute_refund(self, refund: OrderRefund):
     if refund.payment.sepaexportorder_set.exists():
         refund.info_data = {
             'payer': refund.payment.info_data[
                 'account'],  # Use payer to keep it compatible with the banktransfer-refunds
             'iban': self.norm(refund.payment.info_data['iban']),
             'bic': self.norm(refund.payment.info_data['bic']),
         }
         refund.save(update_fields=["info"])
     else:
         refund.done()
Esempio n. 6
0
 def execute_refund(self, refund: OrderRefund):
     from .models import GiftCard
     gc = GiftCard.objects.get(pk=refund.payment.info_data.get('gift_card'))
     trans = gc.transactions.create(value=refund.amount,
                                    order=refund.order,
                                    refund=refund)
     refund.info_data = {
         'gift_card': gc.pk,
         'transaction_id': trans.pk,
     }
     refund.done()
Esempio n. 7
0
 def execute_refund(self, refund: OrderRefund):
     try:
         self._refund(refund.payment.info_data['orderNumber'],
                      refund.amount, self.event.currency,
                      refund.order.locale[:2])
     except requests.exceptions.RequestException as e:
         logger.exception('Wirecard error: %s' % str(e))
         raise PaymentException(
             _('We had trouble communicating with Wirecard. Please try again and contact '
               'support if the problem persists.'))
     else:
         refund.done()
Esempio n. 8
0
    def execute_refund(self, refund: OrderRefund):
        self.init_api()

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

            if not sale:
                pp_payment = paypalrestsdk.Payment.find(
                    refund.payment.info_data['id'])
                for res in pp_payment.transactions[0].related_resources:
                    for k, v in res.to_dict().items():
                        if k == 'sale':
                            sale = paypalrestsdk.Sale.find(v['id'])
                            break

            pp_refund = sale.refund({
                "amount": {
                    "total": self.format_price(refund.amount),
                    "currency": refund.order.event.currency
                }
            })
        except paypalrestsdk.exceptions.ConnectionError as e:
            refund.order.log_action(
                'pretix.event.order.refund.failed', {
                    'local_id': refund.local_id,
                    'provider': refund.provider,
                    'error': str(e)
                })
            raise PaymentException(
                _('Refunding the amount via PayPal failed: {}').format(str(e)))
        if not pp_refund.success():
            refund.order.log_action(
                'pretix.event.order.refund.failed', {
                    'local_id': refund.local_id,
                    'provider': refund.provider,
                    'error': str(pp_refund.error)
                })
            raise PaymentException(
                _('Refunding the amount via PayPal failed: {}').format(
                    pp_refund.error))
        else:
            sale = paypalrestsdk.Payment.find(refund.payment.info_data['id'])
            refund.payment.info = json.dumps(sale.to_dict())
            refund.info = json.dumps(pp_refund.to_dict())
            refund.done()
Esempio n. 9
0
    def execute_refund(self, refund: OrderRefund):
        """
        We just keep a created refund object. It will be marked as done using the control view
        for bank transfer refunds.
        """
        if refund.payment is None:
            raise ValueError(
                _("Can only create a bank transfer refund from an existing payment."
                  ))

        refund.info_data = {
            'payer': refund.payment.info_data['payer'],
            'iban': self.norm(refund.payment.info_data['iban']),
            'bic': self.norm(refund.payment.info_data['bic']),
        }
        refund.save(update_fields=["info"])
Esempio n. 10
0
    def execute_refund(self, refund: OrderRefund):
        if refund.payment is None:
            raise Exception('Invariant: No payment associated with refund')

        wallet_queryset = WalletAddress.objects.filter(order_payment=refund.payment)

        if wallet_queryset.count() != 1:
            raise Exception('Invariant: There is not assigned wallet address to this payment')

        refund.info_data = {
            'currency_type': refund.payment.info_data['currency_type'],
            'amount': refund.payment.info_data['amount'],
            'wallet_address': wallet_queryset.first().hex_address,
        }

        refund.save(update_fields=["info"])
Esempio n. 11
0
    def execute_refund(self, refund: OrderRefund):
        payment_data = refund.payment.info_data
        data = {
            'PaymentId': payment_data['PaymentId'],
            'Amount':  int(refund.amount * 100)
        }

        logger.info('refund_request:{}'.format(data))
        req = self.cancel(data)
        refund.info_data = json.dumps(req)
        refund.save(update_fields=['info'])
        logger.info('refund_response:{}'.format(req))
        if req['Success'] == False:
            raise PaymentException(_('Refunding the amount via Tinkoff failed: {}'.format(req['Details'])))
        else:
            if req['Status'] == 'REFUNDED':
                refund.done()
Esempio n. 12
0
    def execute_refund(self, refund: OrderRefund):
        self._init_api()

        payment_info = refund.payment.info_data

        if not payment_info:
            raise PaymentException(_('No payment information found.'))

        try:
            ch = stripe.Charge.retrieve(payment_info['id'], **self.api_kwargs)
            r = ch.refunds.create(
                amount=self._get_amount(refund),
            )
            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))
            raise PaymentException(_('We had trouble communicating with Stripe. Please try again and contact '
                                     'support if the problem persists.'))
        except stripe.error.StripeError as err:
            logger.error('Stripe error: %s' % str(err))
            raise PaymentException(_('Stripe returned an error'))
        else:
            refund.info = str(r)
            if r.status in ('succeeded', 'pending'):
                refund.done()
            elif r.status in ('failed', 'canceled'):
                refund.state = OrderRefund.REFUND_STATE_FAILED
                refund.execution_date = now()
                refund.save()
Esempio n. 13
0
    def execute_refund(self, refund: OrderRefund):
        self._init_api()

        payment_info = refund.payment.info_data

        if not payment_info:
            raise PaymentException(_('No payment information found.'))

        rqdata = {
            'modificationAmount': {
                'value': self._get_amount(refund),
                'currency': self.event.currency,
            },
            'originalReference':
            payment_info['pspReference'],
            'merchantOrderReference':
            '{event}-{code}'.format(event=self.event.slug.upper(),
                                    code=refund.order.code),
            'reference':
            '{event}-{code}-R-{payment}'.format(event=self.event.slug.upper(),
                                                code=refund.order.code,
                                                payment=refund.local_id),
            'shopperStatement':
            self.statement_descriptor(refund),
            'captureDelayHours':
            0,
            **self.api_kwargs
        }

        try:
            result = self.adyen.payment.refund(rqdata)
        except AdyenError as e:
            logger.exception('AdyenError: %s' % str(e))
            return

        refund.info = json.dumps(result.message)
        refund.state = OrderRefund.REFUND_STATE_TRANSIT
        refund.save()
        refund.order.log_action('pretix.event.order.refund.created', {
            'local_id': refund.local_id,
            'provider': refund.provider,
        })
Esempio n. 14
0
    def execute_refund(self, refund: OrderRefund):
        self.init_api()

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

        pp_refund = sale.refund({
            "amount": {
                "total": self.format_price(refund.amount),
                "currency": refund.order.event.currency
            }
        })
        if not pp_refund.success():
            raise PaymentException(_('Refunding the amount via PayPal failed: {}').format(pp_refund.error))
        else:
            sale = paypalrestsdk.Payment.find(refund.payment.info_data['id'])
            refund.payment.info = json.dumps(sale.to_dict())
            refund.info = json.dumps(pp_refund.to_dict())
            refund.done()
Esempio n. 15
0
 def new_refund_control_form_process(self, request: HttpRequest,
                                     amount: Decimal,
                                     order: Order) -> OrderRefund:
     f = self.NewRefundForm(prefix="refund-banktransfer", data=request.POST)
     if not f.is_valid():
         raise ValidationError(
             _('Your input was invalid, please see below for details.'))
     d = {
         'payer': f.cleaned_data['payer'],
         'iban': self.norm(f.cleaned_data['iban']),
     }
     if f.cleaned_data.get('bic'):
         d['bic'] = f.cleaned_data['bic']
     return OrderRefund(order=order,
                        payment=None,
                        state=OrderRefund.REFUND_STATE_CREATED,
                        amount=amount,
                        provider=self.identifier,
                        info=json.dumps(d))
Esempio n. 16
0
    def execute_refund(self, refund: OrderRefund):
        self._init_api()

        payment_info = refund.payment.info_data

        if not payment_info:
            raise PaymentException(_('No payment information found.'))

        try:
            if payment_info['id'].startswith('pi_'):
                chargeid = payment_info['charges']['data'][0]['id']
            else:
                chargeid = payment_info['id']

            ch = stripe.Charge.retrieve(chargeid, **self.api_kwargs)
            r = ch.refunds.create(
                amount=self._get_amount(refund),
            )
            ch.refresh()
        except (stripe.error.InvalidRequestError, stripe.error.AuthenticationError, stripe.error.APIConnectionError) \
                as e:
            if e.json_body and 'error' in 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))
            raise PaymentException(_('We had trouble communicating with Stripe. Please try again and contact '
                                     'support if the problem persists.'))
        except stripe.error.StripeError as err:
            logger.error('Stripe error: %s' % str(err))
            raise PaymentException(_('Stripe returned an error'))
        else:
            refund.info = str(r)
            if r.status in ('succeeded', 'pending'):
                refund.done()
            elif r.status in ('failed', 'canceled'):
                refund.state = OrderRefund.REFUND_STATE_FAILED
                refund.execution_date = now()
                refund.save()
    def execute_refund(self, refund: OrderRefund):
        d = refund.payment.info_data

        try:
            if self.cancel_flow and refund.amount == refund.payment.amount:
                if 'Id' not in d:
                    raise PaymentException(
                        _('The payment has not been captured successfully and can therefore not be '
                          'refunded.'))

                req = self._post('Payment/v1/Transaction/Cancel',
                                 json={
                                     "RequestHeader": {
                                         "SpecVersion": "1.10",
                                         "CustomerId":
                                         self.settings.customer_id,
                                         "RequestId": str(uuid.uuid4()),
                                         "RetryIndicator": 0
                                     },
                                     "TransactionReference": {
                                         "TransactionId": d.get('Id')
                                     }
                                 })
                if req.status_code == 200:
                    refund.info = req.text
                    refund.save(update_fields=['info'])
                    refund.done()

                try:
                    err = req.json()
                except:
                    req.raise_for_status()
                else:
                    if err['ErrorName'] not in ('ACTION_NOT_SUPPORTED',
                                                'TRANSACTION_ALREADY_CAPTURED',
                                                'TRANSACTION_IN_WRONG_STATE'):
                        req.raise_for_status()

            if 'CaptureId' not in d:
                raise PaymentException(
                    _('The payment has not been captured successfully and can therefore not be '
                      'refunded.'))

            req = self._post(
                'Payment/v1/Transaction/Refund',
                json={
                    "RequestHeader": {
                        "SpecVersion": "1.10",
                        "CustomerId": self.settings.customer_id,
                        "RequestId": str(uuid.uuid4()),
                        "RetryIndicator": 0
                    },
                    "Refund": {
                        "Amount": {
                            "Value": str(self._decimal_to_int(refund.amount)),
                            "CurrencyCode": self.event.currency
                        },
                        "OrderId":
                        "{}-{}-R-{}".format(self.event.slug.upper(),
                                            refund.order.code,
                                            refund.local_id),
                        "Description":
                        "Order {}-{}".format(self.event.slug.upper(),
                                             refund.order.code),
                    },
                    "CaptureReference": {
                        "CaptureId": d.get('CaptureId')
                    }
                })
            req.raise_for_status()
            refund.info_data = req.json()
            refund.save(update_fields=['info'])

            if refund.info_data['Transaction'].get('Status') == 'AUTHORIZED':
                req = self._post(
                    'Payment/v1/Transaction/Capture',
                    json={
                        "RequestHeader": {
                            "SpecVersion": "1.10",
                            "CustomerId": self.settings.customer_id,
                            "RequestId": str(uuid.uuid4()),
                            "RetryIndicator": 0
                        },
                        "TransactionReference": {
                            "TransactionId":
                            refund.info_data['Transaction'].get('Id')
                        }
                    })
                req.raise_for_status()
                data = req.json()
                if data['Status'] == 'CAPTURED':
                    refund.order.log_action('pretix_saferpay.event.paid')
                    trans = refund.info_data
                    trans['Transaction']['Status'] = 'CAPTURED'
                    trans['Transaction']['CaptureId'] = data['CaptureId']
                    refund.info = json.dumps(trans)
                    refund.save(update_fields=['info'])
                    refund.done()

        except HTTPError:
            logger.exception('Saferpay error: %s' % req.text)
            try:
                refund.info_data = req.json()
            except:
                refund.info_data = {'error': True, 'detail': req.text}
            refund.state = OrderRefund.REFUND_STATE_FAILED
            refund.save()
            refund.order.log_action(
                'pretix.event.order.refund.failed', {
                    'local_id': refund.local_id,
                    'provider': refund.provider,
                    'data': refund.info_data
                })
            raise PaymentException(
                _('We had trouble communicating with Saferpay. Please try again and get in touch '
                  'with us if this problem persists.'))
Esempio n. 18
0
 def execute_refund(self, refund: OrderRefund):
     refund.done()