示例#1
0
    def _confirm_payment_intent(self, request, payment):
        self._init_api()

        try:
            payment_info = json.loads(payment.info)

            intent = stripe.PaymentIntent.confirm(
                payment_info['id'],
                return_url=build_absolute_uri(self.event, 'plugins:stripe:sca.return', kwargs={
                    'order': payment.order.code,
                    'payment': payment.pk,
                    'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(),
                }),
                **self.api_kwargs
            )

            payment.info = str(intent)
            payment.save()

            self._handle_payment_intent(request, payment)
        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))
            payment.info_data = {
                'error': True,
                'message': err['message'],
            }
            payment.state = OrderPayment.PAYMENT_STATE_FAILED
            payment.save()
            payment.order.log_action('pretix.event.order.payment.failed', {
                'local_id': payment.local_id,
                'provider': payment.provider,
                'message': err['message']
            })
            raise PaymentException(_('Stripe reported an error with your card: %s') % err['message'])
        except stripe.error.InvalidRequestError 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))
            payment.info_data = {
                'error': True,
                'message': err['message'],
            }
            payment.state = OrderPayment.PAYMENT_STATE_FAILED
            payment.save()
            payment.order.log_action('pretix.event.order.payment.failed', {
                'local_id': payment.local_id,
                'provider': payment.provider,
                'message': err['message']
            })
            raise PaymentException(_('We had trouble communicating with Stripe. Please try again and get in touch '
                                     'with us if this problem persists.'))
示例#2
0
    def payment_perform(self, request, order) -> str:
        """
        Will be called if the user submitted his order successfully to initiate the
        payment process.

        It should return a custom redirct URL, if you need special behavior, or None to
        continue with default behavior.

        On errors, it should use Django's message framework to display an error message
        to the user (or the normal form validation error messages).

        :param order: The order object
        """
        if (request.session.get('payment_paypal_id', '') == ''
                or request.session.get('payment_paypal_payer', '') == ''):
            raise PaymentException(
                _('We were unable to process your payment. See below for details on how to '
                  'proceed.'))

        self.init_api()
        payment = paypalrestsdk.Payment.find(
            request.session.get('payment_paypal_id'))
        ReferencedPayPalObject.objects.get_or_create(order=order,
                                                     reference=payment.id)
        if str(payment.transactions[0].amount.total) != str(order.total) or payment.transactions[0].amount.currency != \
                self.event.currency:
            logger.error('Value mismatch: Order %s vs payment %s' %
                         (order.id, str(payment)))
            raise PaymentException(
                _('We were unable to process your payment. See below for details on how to '
                  'proceed.'))

        return self._execute_payment(payment, request, order)
示例#3
0
    def process_callback(request, log=True):
        # @see https://tech.dibspayment.com/D2/Hosted/Output_parameters/Return_pages
        # @see https://tech.dibspayment.com/D2/Hosted/Output_parameters/Return_parameters
        parameters = request.POST if request.method == 'POST' else request.GET

        order_id = parameters.get('orderid')
        payment = DIBS.get_order_payment(order_id)

        if payment.provider != DIBS.identifier or payment.order.event != request.event:
            return False

        info = json.loads(json.dumps(parameters))
        info['currency_code'] = info['currency']
        info['currency'] = pycountry.currencies.get(
            numeric=info['currency']).alpha_3
        info['statuscode'] = int(info['statuscode'])
        status_code = info['statuscode']

        payment.order.log_action('pretix_paymentdibs.callback', data=info)

        if status_code in {
                DIBS.STATUS_CODE_AUTHORIZATION_APPROVED,
                DIBS.STATUS_CODE_CAPTURE_COMPLETED
        }:
            payment_provider = payment.payment_provider
            if payment_provider.validate_transaction(payment, parameters):
                try:
                    payment.info_data = info
                    payment.confirm()
                except Quota.QuotaExceededException as e:
                    raise PaymentException(str(e))
                except SendMailException:
                    raise PaymentException(
                        _('There was an error sending the confirmation mail.'))
示例#4
0
文件: payment.py 项目: obutuz/pretix
    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()
示例#5
0
    def execute_refund(self, refund):
        info = refund.payment.info_data
        merchant = self.settings.get('merchant_id')
        transact = info['transact']
        currency = info['currency']
        orderid = info['orderid']

        payload = {
            'merchant': merchant,
            'transact': transact,
            'amount': DIBS.get_amount(refund.amount),
            'currency': currency,
            'orderid': orderid,
            'textreply': 'true',
            # 'fullreply': 'true'
        }

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

        # 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=' + DIBS.get_amount(
            refund.amount)
        md5key = DIBS.md5(key2 + DIBS.md5(key1 + parameters))
        payload['md5key'] = md5key

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

        # 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
        refund.info_data = data

        if result == DIBS.REFUND_ACCEPTED:
            refund.done()
        else:
            refund.state = OrderRefund.REFUND_STATE_FAILED
            refund.execution_date = now()
            refund.save()
            raise PaymentException(
                _('Error refunding in DIBS ({status}; {result}; {message})'.
                  format(status=status, result=result,
                         message=message.strip())))
示例#6
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        try:
            # Get the correct endpoint to consume
            x_endpoint = self.get_settings_key('x_endpoint')
            if x_endpoint == 'live':
                url = 'https://payments.qpaypro.com/checkout/api_v1'
            else:
                url = 'https://sandbox.qpaypro.com/payment/api_v1'

            # Get the message body
            payment_body = self._get_payment_body(request, payment)

            # # To save the information befor send
            # # TO DO: to delete this action because of security issues
            # payment.order.log_action('pretix.event.order.payment.started', {
            #     'local_id': payment.local_id,
            #     'provider': payment.provider,
            #     'data': payment_body
            # })

            # Perform the call to the endpoint
            req = requests.post(
                url,
                json=payment_body,
            )
            req.raise_for_status()

            # Load the response to be read
            data = req.json()

            # The result is evaluated to determine the next step
            if not (data['result'] == 1 and data['responseCode'] == 100):
                raise PaymentException(data['responseText'])

            # To save the result
            payment.info = req.json()
            payment.confirm()
        except (HTTPError, PaymentException, Quota.QuotaExceededException):
            logger.exception('QPayPro error: %s' % req.text)
            try:
                payment.info_data = req.json()
            except Exception:
                payment.info_data = {'error': True, 'detail': req.text}
            payment.state = OrderPayment.PAYMENT_STATE_FAILED
            payment.save()
            payment.order.log_action(
                'pretix.event.order.payment.failed', {
                    'local_id': payment.local_id,
                    'provider': payment.provider,
                    'data': payment.info_data
                })
            raise PaymentException(
                _('We had trouble communicating with QPayPro. Please try again and get in touch '
                  'with us if this problem persists.'))

        return None
示例#7
0
 def execute_payment(self, request: HttpRequest, payment: OrderPayment):
     request.session['sofort_order_secret'] = payment.order.secret
     shash = hashlib.sha1(payment.order.secret.lower().encode()).hexdigest()
     r = sofort.MultiPay(
         project_id=self.settings.get('project_id'),
         amount=payment.amount,
         currency_code=self.event.currency,
         reasons=[payment.order.full_code, '-TRANSACTION-'],
         user_variables=[payment.order.full_code],
         success_url=build_absolute_uri(self.event,
                                        'plugins:pretix_sofort:return',
                                        kwargs={
                                            'order': payment.order.code,
                                            'hash': shash,
                                        }) +
         '?state=success&transaction=-TRANSACTION-',
         abort_url=build_absolute_uri(self.event,
                                      'plugins:pretix_sofort:return',
                                      kwargs={
                                          'order': payment.order.code,
                                          'hash': shash,
                                      }) +
         '?state=abort&transaction=-TRANSACTION-',
         timeout_url=build_absolute_uri(self.event,
                                        'plugins:pretix_sofort:return',
                                        kwargs={
                                            'order': payment.order.code,
                                            'hash': shash,
                                        }) +
         '?state=timeout&transaction=-TRANSACTION-',
         notification_urls=[
             build_absolute_uri(self.event, 'plugins:pretix_sofort:webhook')
         ],
     )
     try:
         trans = sofort.NewTransaction.from_xml(self._api_call(r.to_xml()))
     except sofort.SofortError as e:
         logger.exception('Failure during sofort payment: {}'.format(
             e.message))
         raise PaymentException(
             _('Sofort reported an error: {}').format(e.message))
     except IOError:
         logger.exception('Failure during sofort payment.')
         raise PaymentException(
             _('We had trouble communicating with Sofort. Please try again and get in touch '
               'with us if this problem persists.'))
     ReferencedSofortTransaction.objects.get_or_create(
         order=payment.order, reference=trans.transaction, payment=payment)
     payment.info_data = {
         'transaction': trans.transaction,
         'status': 'initiated'
     }
     payment.save(update_fields=['info'])
     return self.redirect(request, trans.payment_url)
示例#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()
示例#9
0
 def execute_payment(self, request: HttpRequest, payment: OrderPayment):
     payment.info_data = {
         'sender_address': request.session['payment_ethereum_fm_address'],
         'currency': request.session['payment_ethereum_fm_currency'],
         'time': request.session['payment_ethereum_time'],
         'amount': request.session['payment_ethereum_amount'],
     }
     payment.save(update_fields=['info'])
     try:
         if request.session['payment_ethereum_fm_currency'] == 'ETH':
             response = requests.get(
                 f'https://api.ethplorer.io/getAddressTransactions/{self.settings.ETH}?apiKey=freekey'  # noqa: E501
             )
             deca = response.json()
             if len(deca) > 0:
                 for decc in deca:
                     if decc['success'] == True and decc[
                             'from'] == request.session[
                                 'payment_ethereum_fm_address']:  # noqa: E501
                         if decc['timestamp'] > request.session[
                                 'payment_ethereum_time'] and decc[
                                     'value'] >= request.session[
                                         'payment_ethereum_amount']:  # noqa: E501
                             try:
                                 payment.confirm()
                             except Quota.QuotaExceededException as e:
                                 raise PaymentException(str(e))
         else:
             dec = requests.get(
                 'https://blockscout.com/poa/dai/api?module=account&action=txlist&address='
                 + self.settings.DAI)  # noqa: E501
             deca = dec.json()
             for decc in deca['result']:
                 if decc['txreceipt_status'] == '1' and decc[
                         'from'] == request.session[
                             'payment_ethereum_fm_address']:  # noqa: E501
                     #           if (decc['timestamp'] > request.session['payment_ethereum_time'] and decc[  # noqa: E501
                     # 'value'] >= request.session['payment_ethereum_amount']):
                     try:
                         payment.confirm()
                     except Quota.QuotaExceededException as e:
                         raise PaymentException(str(e))
     except NameError:
         pass
     except TypeError:
         pass
     except AttributeError:
         pass
     return None
示例#10
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        if (request.session.get('payment_paypal_id', '') == '' or request.session.get('payment_paypal_payer', '') == ''):
            raise PaymentException(_('We were unable to process your payment. See below for details on how to '
                                     'proceed.'))

        self.init_api()
        pp_payment = paypalrestsdk.Payment.find(request.session.get('payment_paypal_id'))
        ReferencedPayPalObject.objects.get_or_create(order=payment.order, payment=payment, reference=pp_payment.id)
        if str(pp_payment.transactions[0].amount.total) != str(payment.amount) or pp_payment.transactions[0].amount.currency \
                != self.event.currency:
            logger.error('Value mismatch: Payment %s vs paypal trans %s' % (payment.id, str(pp_payment)))
            raise PaymentException(_('We were unable to process your payment. See below for details on how to '
                                     'proceed.'))

        return self._execute_payment(pp_payment, request, payment)
示例#11
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        txn_hash = request.session['payment_ethereum_txn_hash']
        txn_hash_bytes = to_bytes(hexstr=txn_hash)
        currency_type = request.session['payment_ethereum_currency_type']
        payment_timestamp = request.session['payment_ethereum_time']
        payment_amount = request.session['payment_ethereum_amount']

        if Transaction.objects.filter(txn_hash=txn_hash_bytes).exists():
            raise PaymentException(
                f'Transaction with hash {txn_hash} already used for payment')

        payment.info_data = {
            'txn_hash': txn_hash,
            'currency_type': currency_type,
            'time': payment_timestamp,
            'amount': payment_amount,
        }
        payment.save(update_fields=['info'])

        if currency_type == 'ETH':
            transaction = self.transaction_provider.get_transaction(txn_hash)
            is_valid_payment = all((
                transaction.success,
                transaction.to == self.settings.ETH,
                transaction.value >= payment_amount,
                transaction.timestamp >= payment_timestamp,
            ))
        elif currency_type == 'DAI':
            transfer = self.token_provider.get_ERC20_transfer(txn_hash)
            is_valid_payment = all((
                transfer.success,
                transfer.to == self.settings.DAI,
                transfer.value >= payment_amount,
                transfer.timestamp >= payment_timestamp,
            ))
        else:
            # unkown currency
            raise ImproperlyConfigured(f"Unknown currency: {currency_type}")

        if is_valid_payment:
            with db_transaction.atomic():
                try:
                    payment.confirm()
                except Quota.QuotaExceededException as e:
                    raise PaymentException(str(e))
                else:
                    Transaction.objects.create(txn_hash=txn_hash_bytes,
                                               order_payment=payment)
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        try:
            req = self._post('Payment/v1/PaymentPage/Initialize',
                             json=self._get_payment_page_init_body(payment))
            req.raise_for_status()
        except HTTPError:
            logger.exception('Saferpay error: %s' % req.text)
            try:
                payment.info_data = req.json()
            except:
                payment.info_data = {'error': True, 'detail': req.text}
            payment.state = OrderPayment.PAYMENT_STATE_FAILED
            payment.save()
            payment.order.log_action(
                'pretix.event.order.payment.failed', {
                    'local_id': payment.local_id,
                    'provider': payment.provider,
                    'data': payment.info_data
                })
            raise PaymentException(
                _('We had trouble communicating with Saferpay. Please try again and get in touch '
                  'with us if this problem persists.'))

        data = req.json()
        payment.info = json.dumps(data)
        payment.state = OrderPayment.PAYMENT_STATE_CREATED
        payment.save()
        request.session['payment_saferpay_order_secret'] = payment.order.secret
        return self.redirect(request, data.get('RedirectUrl'))
示例#13
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        request.session['payment_bitpay_order_secret'] = payment.order.secret

        try:
            inv = self.client.create_invoice({
                "price": float(payment.amount),
                "currency": self.event.currency,
                "orderId": payment.order.full_code,
                "transactionSpeed": "medium",
                "extendedNotifications": "true",
                "notificationURL": build_absolute_uri(self.event, "plugins:pretix_bitpay:webhook"),
                "redirectURL": build_absolute_uri(self.event, "plugins:pretix_bitpay:return", kwargs={
                    'order': payment.order.code,
                    'payment': payment.pk,
                    'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(),
                }),
                # "buyer": {"email": "*****@*****.**"},
                "token": self.settings.token
            })
        except (BitPayConnectionError, BitPayBitPayError, BitPayArgumentError) as e:
            logger.exception('Failure during bitpay payment.')
            raise PaymentException(_('We had trouble communicating with BitPay. Please try again and get in touch '
                                     'with us if this problem persists.'))
        ReferencedBitPayObject.objects.get_or_create(order=payment.order, payment=payment, reference=inv['id'])
        payment.info = json.dumps(inv)
        payment.save(update_fields=['info'])
        return self.redirect(request, inv['url'])
    def _get_rates_from_api(self, total, currency):
        try:
            if self.event.currency == 'USD':
                rate = requests.get('https://api.bitfinex.com/v1/pubticker/' +
                                    currency + 'usd')
                rate = rate.json()
                final_price = float(total) / float(rate['last_price'])
            else:
                url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
                parameters = {
                    'symbol': currency,
                    'convert': self.event.currency,
                }
                headers = {
                    'Accepts': 'application/json',
                    'X-CMC_PRO_API_KEY':
                    '7578555c-bf3e-4639-8651-11a20ddb30c6',
                }
                session = Session()
                session.headers.update(headers)

                response = session.get(url, params=parameters)
                data = json.loads(response.text)
                final_price = float(total) / float(
                    data['data'][currency]['quote'][
                        self.event.currency]['price'])
            return round(final_price, 2)
        except ConnectionError as e:
            logger.exception('Internal eror occured.')
            raise PaymentException(
                _('Please try again and get in touch '
                  'with us if this problem persists.'))
示例#15
0
文件: payment.py 项目: moser/pretix
    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()
示例#16
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        try:
            req = requests.post('https://api.mollie.com/v2/payments',
                                json=self._get_payment_body(payment),
                                headers=self.request_headers)
            req.raise_for_status()
        except HTTPError:
            logger.exception('Mollie error: %s' % req.text)
            try:
                payment.info_data = req.json()
            except:
                payment.info_data = {'error': True, 'detail': req.text}
            payment.state = OrderPayment.PAYMENT_STATE_FAILED
            payment.save()
            payment.order.log_action(
                'pretix.event.order.payment.failed', {
                    'local_id': payment.local_id,
                    'provider': payment.provider,
                    'data': payment.info_data
                })
            raise PaymentException(
                _('We had trouble communicating with Mollie. Please try again and get in touch '
                  'with us if this problem persists.'))

        data = req.json()
        payment.info = json.dumps(data)
        payment.state = OrderPayment.PAYMENT_STATE_CREATED
        payment.save()
        request.session['payment_mollie_order_secret'] = payment.order.secret
        return self.redirect(request,
                             data.get('_links').get('checkout').get('href'))
示例#17
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        self._init_api()
        try:
            source = self._create_source(request, payment)
        except stripe.error.StripeError as e:
            if e.json_body and 'err' 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))
            payment.info_data = {
                'error': True,
                'message': err['message'],
            }
            payment.state = OrderPayment.PAYMENT_STATE_FAILED
            payment.save()
            payment.order.log_action('pretix.event.order.payment.failed', {
                'local_id': payment.local_id,
                'provider': payment.provider,
                'message': err['message']
            })
            raise PaymentException(_('We had trouble communicating with Stripe. Please try again and get in touch '
                                     'with us if this problem persists.'))

        ReferencedStripeObject.objects.get_or_create(
            reference=source.id,
            defaults={'order': payment.order, 'payment': payment}
        )
        payment.info = str(source)
        payment.state = OrderPayment.PAYMENT_STATE_PENDING
        payment.save()
        request.session['payment_stripe_order_secret'] = payment.order.secret
        return self.redirect(request, source.redirect.url)
示例#18
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()
示例#19
0
文件: payment.py 项目: zippyy/pretix
    def payment_perform(self, request, order) -> str:
        self._init_api()
        try:
            source = self._create_source(request, order)
        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.'))

        ReferencedStripeObject.objects.get_or_create(order=order,
                                                     reference=source.id)
        order.payment_info = str(source)
        order.save(update_fields=['payment_info'])
        request.session['payment_stripe_order_secret'] = order.secret
        return self.redirect(request, source.redirect.url)
示例#20
0
文件: payment.py 项目: zippyy/pretix
    def payment_perform(self, request, order) -> str:
        self._init_api()

        if request.session['payment_stripe_token'].startswith('src_'):
            try:
                src = stripe.Source.retrieve(
                    request.session['payment_stripe_token'], **self.api_kwargs)
                if src.type == 'card' and src.card and self._use_3ds(src.card):
                    request.session[
                        'payment_stripe_order_secret'] = order.secret
                    source = stripe.Source.create(
                        type='three_d_secure',
                        amount=self._get_amount(order),
                        currency=self.event.currency.lower(),
                        three_d_secure={'card': src.id},
                        metadata={
                            'order': str(order.id),
                            'event': self.event.id,
                            'code': order.code
                        },
                        redirect={
                            'return_url':
                            build_absolute_uri(
                                self.event,
                                'plugins:stripe:return',
                                kwargs={
                                    'order':
                                    order.code,
                                    'hash':
                                    hashlib.sha1(order.secret.lower().encode()
                                                 ).hexdigest(),
                                })
                        },
                        **self.api_kwargs)
                    if source.status == "pending":
                        order.payment_info = str(source)
                        order.save(update_fields=['payment_info'])
                        return self.redirect(request, source.redirect.url)
            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.'))

        try:
            self._charge_source(request,
                                request.session['payment_stripe_token'], order)
        finally:
            del request.session['payment_stripe_token']
示例#21
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        pay_data = {
            "NotificationURL": build_absolute_uri(self.event, 'plugins:pretix_tinkoff:webhook', kwargs={
                'payment': payment.pk
            }),
            "SuccessURL": build_absolute_uri(self.event, 'plugins:pretix_tinkoff:return', kwargs={
                'order': payment.order.code,
                'payment': payment.pk,
                'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(),
                'action': 'success'
            }),
            "FailURL": build_absolute_uri(self.event, 'plugins:pretix_tinkoff:return', kwargs={
                'order': payment.order.code,
                'payment': payment.pk,
                'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(),
                'action': 'fail'
            }),
            'Amount': int(payment.amount * 100),
            'OrderId': "{}-{}".format(self.event.slug.upper(), payment.order.code),
            'Description': "Order {}-{}".format(self.event.slug.upper(), payment.order.code),
            'DATA': {
                'organizer': self.event.organizer.slug,
                'event': self.event.slug,
                'order': payment.order.code,
                'payment': payment.local_id,
                'order-full-code': payment.order.full_code
            },
            'PayType': "O"
        }
        try:
            req = self._init(pay_data)
        except HTTPError:
            logger.exception('Tinkoff error: %s' % req)
        
        if req['Success'] == False:
            logger.exception('Tinkoff error: %s' % req)

            payment.info_data = {
                'error': True,
                'detail': req
            }
            
            payment.state = OrderPayment.PAYMENT_STATE_FAILED
            payment.save()
            payment.order.log_action('pretix.event.order.payment.failed', {
                'local_id': payment.local_id,
                'provider': payment.provider,
                'data': payment.info_data
            })
            raise PaymentException(_('We had trouble communicating with Tinkoff. Please try again and get in touch '
                                     'with us if this problem persists. Detail: {}'.format(req['Details'])))
        ReferencedTinkoffTransaction.objects.get_or_create(order=payment.order, payment=payment, reference=req['PaymentId'])
        LogTransaction(paymentid=req['PaymentId'], order=payment.order, payment=payment, method='get', meta_info=json.dumps(req))
        payment.info = json.dumps(req)
        payment.state = OrderPayment.PAYMENT_STATE_CREATED
        logger.info('pay_request: {}'.format(pay_data))
        logger.info('pay_response: {}'.format(payment.info))
        payment.save(update_fields=['info'])
        return self.redirect(request, req['PaymentURL'])
示例#22
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()
示例#23
0
def capture(payment: OrderPayment):
    if payment.state == OrderPayment.PAYMENT_STATE_CONFIRMED:
        return

    pprov = payment.payment_provider
    try:
        if payment.info_data.get('Status') == 'CAPTURED':
            return

        if 'Token' in payment.info_data:
            req = pprov._post('Payment/v1/PaymentPage/Assert', json={
                "RequestHeader": {
                    "SpecVersion": "1.10",
                    "CustomerId": pprov.settings.customer_id,
                    "RequestId": str(uuid.uuid4()),
                    "RetryIndicator": 0
                },
                "Token": payment.info_data.get('Token')
            })
            req.raise_for_status()
            data = req.json()
            trans = data['Transaction']
            if 'PaymentMeans' in data:
                trans['PaymentMeans'] = data['PaymentMeans']

            payment.info = json.dumps(trans)
            payment.save(update_fields=['info'])
            handle_transaction_result(payment)
        elif payment.info_data.get('Status') == 'AUTHORIZED':
            handle_transaction_result(payment)
        else:
            raise PaymentException('Unknown payment state')

    except requests.exceptions.HTTPError as e:
        payment.order.log_action('pretix.event.order.payment.failed', {
            'local_id': payment.local_id,
            'provider': payment.provider,
            'data': e.response.text
        })
        raise PaymentException(_('We had trouble communicating with Saferpay. Please try again and get in touch '
                                 'with us if this problem persists.'))
示例#24
0
    def _refund(self, refund):
        from btcpay import crypto
        payload = json.dumps({
            'token':
            refund.payment.info_data.get('token'),
            'amount':
            refund.payment.info_data.get('price'),
            'currency':
            refund.payment.info_data.get('currency'),
            'refundEmail':
            refund.order.email
        })
        uri = self.client.host + "/invoices/" + refund.payment.info_data.get(
            'id') + "/refunds"
        xidentity = crypto.get_compressed_public_key_from_pem(self.client.pem)
        xsignature = crypto.sign(uri + payload, self.client.pem)
        headers = {
            "content-type": "application/json",
            'accept': 'application/json',
            'X-Identity': xidentity,
            'X-Signature': xsignature,
            'X-accept-version': '2.0.0'
        }
        try:
            response = requests.post(uri,
                                     data=payload,
                                     headers=headers,
                                     verify=self.client.verify)
        except Exception:
            logger.exception('Failure during bitpay refund.')
            raise PaymentException(
                _('We had trouble communicating with BitPay. Please try again and get in touch '
                  'with us if this problem persists.'))
        if not response.ok:
            try:
                e = response.json()['error']
            except JSONDecodeError:
                e = response

            logger.exception('Failure during bitpay refund: {}'.format(e))
            raise PaymentException(_('BitPay reported an error: {}').format(e))
示例#25
0
 def _refund(self, refund):
     r = sofort.Refunds(refunds=[
         sofort.Refund(transaction=refund.payment.info_data.get(
             'transaction'),
                       amount=refund.amount,
                       comment=refund.order.full_code,
                       reason_1=refund.order.full_code,
                       reason_2=refund.payment.info_data.get('transaction'))
     ])
     try:
         sofort.Refunds.from_xml(self._api_call(r.to_xml()))
     except sofort.SofortError as e:
         logger.exception('Failure during sofort payment: {}'.format(
             e.message))
         raise PaymentException(
             _('Sofort reported an error: {}').format(e.message))
     except IOError:
         logger.exception('Failure during sofort payment.')
         raise PaymentException(
             _('We had trouble communicating with Sofort. Please try again and get in touch '
               'with us if this problem persists.'))
示例#26
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()
示例#27
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()
示例#28
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']
示例#29
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
示例#30
0
 def execute_payment(self, request: HttpRequest, payment: OrderPayment):
     payment.refresh_from_db()
     try:
         if (request.session['fm_currency'] == 'ETH'):
             dec = requests.get(
                 'https://api.ethplorer.io/getAddressTransactions/' +
                 self.settings.ETH + '?apiKey=freekey')
             deca = dec.json()
             if len(deca) > 0:
                 for decc in deca:
                     if (decc['success'] == True and decc['from']
                             == request.session['fm_address']):
                         if (decc['timestamp'] > request.session['time']
                                 and decc['value'] >=
                                 request.session['amount']):
                             try:
                                 payment.confirm()
                             except Quota.QuotaExceededException:
                                 raise PaymentException(str(e))
         else:
             dec = requests.get(
                 'https://blockscout.com/poa/dai/api?module=account&action=txlist&address='
                 + self.settings.DAI)
             deca = dec.json()
             for decc in deca['result']:
                 if (decc['txreceipt_status'] == '1'
                         and decc['from'] == request.session['fm_address']):
                     #           if (decc['timestamp'] > request.session['time'] and decc['value'] >= request.session['amount']):
                     try:
                         payment.confirm()
                     except Quota.QuotaExceededException:
                         raise PaymentException(str(e))
     except NameError:
         pass
     except TypeError:
         pass
     except AttributeError:
         pass
     return None