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()
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()
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()
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"])
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"])
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()
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, })
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.'))