Exemplo n.º 1
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'])
Exemplo n.º 2
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:
                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)
    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'))
Exemplo n.º 4
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)
Exemplo n.º 5
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'))
Exemplo n.º 6
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'])
Exemplo n.º 7
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
    def shred_payment_info(self, obj: OrderPayment):
        if not obj.info:
            return
        d = json.loads(obj.info)
        if 'details' in d:
            d['details'] = {k: '█' for k in d['details'].keys()}

        d['_shredded'] = True
        obj.info = json.dumps(d)
        obj.save(update_fields=['info'])
Exemplo n.º 9
0
    def execute_payment(self,
                        request: HttpRequest,
                        payment: OrderPayment,
                        retry=True):
        try:
            if '_links' in payment.info_data:
                if request:
                    return self.redirect(
                        request,
                        payment.info_data.get('_links').get('checkout').get(
                            'href'))
                else:
                    return
        except:
            pass
        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:
                d = req.json()

                if d.get('status') == 401 and retry:
                    # Token might be expired, let's retry!
                    if refresh_mollie_token(self.event, False):
                        return self.execute_payment(request,
                                                    payment,
                                                    retry=False)
            except:
                d = {'error': True, 'detail': req.text}
            payment.fail(info=d)
            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()
        if request:
            request.session[
                'payment_mollie_order_secret'] = payment.order.secret
            return self.redirect(
                request,
                data.get('_links').get('checkout').get('href'))
        else:
            return
Exemplo n.º 10
0
 def execute_payment(self, request: HttpRequest, payment: OrderPayment):
     charge = self.client.charge.create(
         name=payment.order.event.name,
         description=payment.order.event.name,
         local_price={
             "amount": payment.amount,
             "currency": payment.order.event.currency,
         },
         pricing_type="fixed_price",
         metadata={"paymentId": payment.id},
     )
     payment.info = json.dumps(charge)
     payment.save(update_fields=["info"])
     return charge.data.hosted_url
Exemplo n.º 11
0
    def shred_payment_info(self, obj: OrderPayment):
        if not obj.info:
            return
        d = json.loads(obj.info)
        new = {}
        if 'source' in d:
            new['source'] = {
                'id': d['source'].get('id'),
                'type': d['source'].get('type'),
                'brand': d['source'].get('brand'),
                'last4': d['source'].get('last4'),
                'bank_name': d['source'].get('bank_name'),
                'bank': d['source'].get('bank'),
                'bic': d['source'].get('bic'),
                'card': {
                    'brand': d['source'].get('card', {}).get('brand'),
                    'country': d['source'].get('card', {}).get('cuntry'),
                    'last4': d['source'].get('card', {}).get('last4'),
                }
            }
        if 'amount' in d:
            new['amount'] = d['amount']
        if 'currency' in d:
            new['currency'] = d['currency']
        if 'status' in d:
            new['status'] = d['status']
        if 'id' in d:
            new['id'] = d['id']

        new['_shredded'] = True
        obj.info = json.dumps(new)
        obj.save(update_fields=['info'])

        for le in obj.order.all_logentries().filter(
                action_type="pretix.plugins.stripe.event").exclude(
                    data="", shredded=True):
            d = le.parsed_data
            if 'data' in d:
                for k, v in list(d['data']['object'].items()):
                    if v not in ('reason', 'status', 'failure_message',
                                 'object', 'id'):
                        d['data']['object'][k] = '█'
                le.data = json.dumps(d)
                le.shredded = True
                le.save(update_fields=['data', 'shredded'])
Exemplo n.º 12
0
    def shred_payment_info(self, obj: OrderPayment):
        if not obj.info:
            return
        d = json.loads(obj.info)
        new = {}
        if 'source' in d:
            new['source'] = {
                'id': d['source'].get('id'),
                'type': d['source'].get('type'),
                'brand': d['source'].get('brand'),
                'last4': d['source'].get('last4'),
                'bank_name': d['source'].get('bank_name'),
                'bank': d['source'].get('bank'),
                'bic': d['source'].get('bic'),
                'card': {
                    'brand': d['source'].get('card', {}).get('brand'),
                    'country': d['source'].get('card', {}).get('cuntry'),
                    'last4': d['source'].get('card', {}).get('last4'),
                }
            }
        if 'amount' in d:
            new['amount'] = d['amount']
        if 'currency' in d:
            new['currency'] = d['currency']
        if 'status' in d:
            new['status'] = d['status']
        if 'id' in d:
            new['id'] = d['id']

        new['_shredded'] = True
        obj.info = json.dumps(new)
        obj.save(update_fields=['info'])

        for le in obj.order.all_logentries().filter(
                action_type="pretix.plugins.stripe.event"
        ).exclude(data="", shredded=True):
            d = le.parsed_data
            if 'data' in d:
                for k, v in list(d['data']['object'].items()):
                    if v not in ('reason', 'status', 'failure_message', 'object', 'id'):
                        d['data']['object'][k] = '█'
                le.data = json.dumps(d)
                le.shredded = True
                le.save(update_fields=['data', 'shredded'])
Exemplo n.º 13
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.'))
Exemplo n.º 14
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        self._init_api()
        try:
            payment_method_data = json.loads(request.session['{}-{}'.format(
                'payment_adyen_paymentMethodData', self.method)])

            rqdata = {
                'amount': {
                    'value': self._get_amount(payment),
                    'currency': self.event.currency,
                },
                'merchantOrderReference':
                '{event}-{code}'.format(event=self.event.slug.upper(),
                                        code=payment.order.code),
                'reference':
                '{event}-{code}-P-{payment}'.format(
                    event=self.event.slug.upper(),
                    code=payment.order.code,
                    payment=payment.local_id),
                'shopperStatement':
                self.statement_descriptor(payment),
                'paymentMethod':
                payment_method_data['paymentMethod'],
                'returnUrl':
                build_absolute_uri(
                    self.event,
                    'plugins:pretix_adyen:return',
                    kwargs={
                        'order':
                        payment.order.code,
                        'payment':
                        payment.pk,
                        'hash':
                        hashlib.sha1(
                            payment.order.secret.lower().encode()).hexdigest(),
                    }),
                'channel':
                'Web',
                'origin':
                settings.SITE_URL,
                'captureDelayHours':
                0,
                'shopperInteraction':
                'Ecommerce',
                **self.api_kwargs
            }

            if self.method == "scheme":
                rqdata['additionalData'] = {'allow3DS2': 'true'}
                rqdata['browserInfo'] = payment_method_data['browserInfo']
                # Since we do not have the IP-address of the customer, we cannot pass rqdata['shopperIP'].

            try:
                result = self.adyen.checkout.payments(rqdata)
            except AdyenError as e:
                logger.exception('Adyen error: %s' % str(e))
                payment.state = OrderPayment.PAYMENT_STATE_FAILED
                payment.info = json.dumps({
                    'refusalReason':
                    json.loads(e.raw_response or {}).get('message', '')
                })
                payment.save()
                payment.order.log_action(
                    'pretix.event.order.payment.failed', {
                        'local_id':
                        payment.local_id,
                        'provider':
                        payment.provider,
                        'message':
                        json.loads(e.raw_response or {}).get('message', '')
                    })
                raise PaymentException(
                    _('We had trouble communicating with Adyen. Please try again and get in touch '
                      'with us if this problem persists.'))

            if 'action' in result.message:
                payment.info = json.dumps(result.message)
                payment.state = OrderPayment.PAYMENT_STATE_CREATED
                payment.save()
                payment.order.log_action('pretix.event.order.payment.started',
                                         {
                                             'local_id': payment.local_id,
                                             'provider': payment.provider
                                         })
                return build_absolute_uri(
                    self.event,
                    'plugins:pretix_adyen:sca',
                    kwargs={
                        'order':
                        payment.order.code,
                        'payment':
                        payment.pk,
                        'hash':
                        hashlib.sha1(
                            payment.order.secret.lower().encode()).hexdigest(),
                    })

            else:
                payment.info = json.dumps(result.message)
                payment.save()
                self._handle_resultcode(payment)
        finally:
            del request.session['{}-{}'.format(
                'payment_adyen_paymentMethodData', self.method)]
Exemplo n.º 15
0
    def _handle_action(self,
                       request: HttpRequest,
                       payment: OrderPayment,
                       statedata=None,
                       payload=None,
                       md=None,
                       pares=None):
        self._init_api()

        payment_info = json.loads(payment.info)

        try:
            if statedata:
                result = self.adyen.checkout.payments_details(
                    json.loads(statedata))
            elif payload:
                result = self.adyen.checkout.payments_details({
                    'paymentData':
                    payment_info['paymentData'],
                    'details': {
                        'payload': payload,
                    },
                })
            elif md and pares:
                result = self.adyen.checkout.payments_details({
                    'paymentData':
                    payment_info['paymentData'],
                    'details': {
                        'MD': md,
                        'PaRes': pares,
                    },
                })
            else:
                messages.error(
                    request,
                    _('Sorry, there was an error in the payment process.'))
                return eventreverse(self.event,
                                    'presale:event.order',
                                    kwargs={
                                        'order': payment.order.code,
                                        'secret': payment.order.secret
                                    })
        except AdyenError as e:
            logger.exception('AdyenError: %s' % str(e))
            messages.error(
                request,
                _('Sorry, there was an error in the payment process.'))
            return eventreverse(self.event,
                                'presale:event.order',
                                kwargs={
                                    'order': payment.order.code,
                                    'secret': payment.order.secret
                                })

        payment.info = json.dumps(result.message)
        payment.save(update_fields=['info'])

        if 'action' in result.message:
            return build_absolute_uri(
                self.event,
                'plugins:pretix_adyen:sca',
                kwargs={
                    'order':
                    payment.order.code,
                    'payment':
                    payment.pk,
                    'hash':
                    hashlib.sha1(
                        payment.order.secret.lower().encode()).hexdigest(),
                })
        else:
            state = self._handle_resultcode(payment)
            return eventreverse(self.event,
                                'presale:event.order',
                                kwargs={
                                    'order': payment.order.code,
                                    'secret': payment.order.secret
                                }) + ('?paid=yes' if state in [
                                    OrderPayment.PAYMENT_STATE_CONFIRMED,
                                    OrderPayment.PAYMENT_STATE_PENDING
                                ] else '')
Exemplo n.º 16
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        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'] = payment.order.secret
                    source = stripe.Source.create(
                        type='three_d_secure',
                        amount=self._get_amount(payment),
                        currency=self.event.currency.lower(),
                        three_d_secure={
                            'card': src.id
                        },
                        statement_descriptor=ugettext('{event}-{code}').format(
                            event=self.event.slug.upper(),
                            code=payment.order.code
                        )[:22],
                        metadata={
                            'order': str(payment.order.id),
                            'event': self.event.id,
                            'code': payment.order.code
                        },
                        redirect={
                            'return_url': build_absolute_uri(self.event, 'plugins:stripe:return', kwargs={
                                'order': payment.order.code,
                                'payment': payment.pk,
                                'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(),
                            })
                        },
                        **self.api_kwargs
                    )
                    ReferencedStripeObject.objects.get_or_create(
                        reference=source.id,
                        defaults={'order': payment.order, 'payment': payment}
                    )
                    if source.status == "pending":
                        payment.info = str(source)
                        payment.state = OrderPayment.PAYMENT_STATE_PENDING
                        payment.save()
                        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))
                payment.info_data = {
                    'error': True,
                    'message': err['message'],
                }
                payment.state = OrderPayment.PAYMENT_STATE_FAILED
                payment.save()
                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'], payment)
        finally:
            del request.session['payment_stripe_token']
Exemplo n.º 17
0
    def execute_payment(self, request: HttpRequest, payment_obj: OrderPayment):
        try:
            # After the user has confirmed their purchase,
            # this method will be called to complete the payment process.
            mp = self.init_api()
            order = payment_obj.order
            meta_info = json.loads(order.meta_info)
            form_data = meta_info.get('contact_form_data', {})

            address = {}
            company = ''
            name = ''
            if hasattr(Order, 'invoice_address'):
                address = {
                    "zip_code": order.invoice_address.zipcode,
                    "street_name": order.invoice_address.street
                }
                company = order.invoice_address.company
                name = str(order.invoice_address.name_parts)

            identification_type = form_data.get('invoicing_type_tax_id', '')

            if identification_type == 'PASS':
                identification_number = form_data.get('invoicing_tax_id_pass',
                                                      '')
            elif identification_type == 'VAT':
                identification_number = form_data.get('invoicing_tax_id_vat',
                                                      '')
            else:
                identification_number = form_data.get('invoicing_tax_id_dni',
                                                      '')

            price = float(payment_obj.amount)
            if self.settings.get('currency') is not order.event.currency:
                price = price * float(self.settings.get('exchange_rate'))
            price = round(price, 2)

            order_url = build_absolute_uri(request.event,
                                           'presale:event.order',
                                           kwargs={
                                               'order': order.code,
                                               'secret': order.secret
                                           })

            preference = {
                "items": [{
                    "title":
                    __('Order {slug}-{code}').format(slug=self.event.slug,
                                                     code=order.code),
                    "quantity":
                    1,
                    "unit_price":
                    price,
                    "currency_id":
                    self.settings.get('currency')
                }],
                "auto_return":
                'all',
                "back_urls": {
                    "failure":
                    order_url,
                    "pending":
                    build_absolute_uri(request.event,
                                       'plugins:pretix_mercadopago:return'),
                    "success":
                    build_absolute_uri(request.event,
                                       'plugins:pretix_mercadopago:return')
                },
                "notification_url":
                build_absolute_uri(request.event,
                                   'plugins:pretix_mercadopago:return'),
                "statement_descriptor":
                __('Order {slug}-{code}').format(slug=self.event.slug,
                                                 code=order.code),
                "external_reference":
                str(payment_obj.id),
                #          "additional_info": json.dumps(order.invoice_address)[:600],
                "payer": {
                    "name": name,
                    "surname": company,
                    "email": form_data.get('email', ''),
                    "identification": {
                        "type": identification_type,
                        "number": identification_number
                    },
                    "address": address
                },
                "payment_methods": {
                    "installments": 1
                }
            }

            # Get the payment reported by the IPN.
            # Glossary of attributes response in https://developers.mercadopago.com
            #        paymentInfo = mp.get_payment(kwargs["id"])

            preferenceResult = mp.create_preference(preference)
            payment_obj.info = json.dumps(preferenceResult, indent=4)
            payment_obj.save()
            request.session['payment_mercadopago_preferece_id'] = str(
                preferenceResult['response']['id'])
            request.session['payment_mercadopago_collector_id'] = str(
                preferenceResult['response']['collector_id'])
            request.session['payment_mercadopago_order'] = order.pk
            request.session['payment_mercadopago_payment'] = payment_obj.pk

            try:
                if preferenceResult:
                    if preferenceResult["status"] not in (
                            200, 201
                    ):  # ate not in ('created', 'approved', 'pending'):
                        messages.error(
                            request,
                            _('We had trouble communicating with MercadoPago' +
                              str(preferenceResult["response"]["message"])))
                        logger.error('Invalid payment state: ' +
                                     str(preferenceResult["response"]))
                        return
                    request.session['payment_mercadopago_id'] = str(
                        preferenceResult["response"]["id"])
                    if (self.test_mode_message == None):
                        link = preferenceResult["response"]["init_point"]
                    else:
                        link = preferenceResult["response"][
                            "sandbox_init_point"]
                    return link
                else:
                    messages.error(
                        request,
                        _('We had trouble communicating with MercadoPago' +
                          str(preferenceResult["response"])))
                    logger.error('Error on creating payment: ' +
                                 str(preferenceResult["response"]))
            except Exception as e:
                messages.error(
                    request,
                    _('We had trouble communicating with ' + 'MercadoPago ' +
                      str(e) + str(preferenceResult["response"])))
                logger.exception('Error on creating payment: ' + str(e))

        except Exception as e:
            messages.error(
                request,
                _('We had trouble preparing the order for ' + 'MercadoPago ' +
                  str(e)))
            logger.exception('Error on creating payment: ' + str(e))
Exemplo n.º 18
0
    def execute_payment(self, request: HttpRequest, payment: OrderPayment):
        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'] = payment.order.secret
                    source = stripe.Source.create(
                        type='three_d_secure',
                        amount=self._get_amount(payment),
                        currency=self.event.currency.lower(),
                        three_d_secure={
                            'card': src.id
                        },
                        statement_descriptor=ugettext('{event}-{code}').format(
                            event=self.event.slug.upper(),
                            code=payment.order.code
                        )[:22],
                        metadata={
                            'order': str(payment.order.id),
                            'event': self.event.id,
                            'code': payment.order.code
                        },
                        redirect={
                            'return_url': build_absolute_uri(self.event, 'plugins:stripe:return', kwargs={
                                'order': payment.order.code,
                                'payment': payment.pk,
                                'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(),
                            })
                        },
                        **self.api_kwargs
                    )
                    ReferencedStripeObject.objects.get_or_create(
                        reference=source.id,
                        defaults={'order': payment.order, 'payment': payment}
                    )
                    if source.status == "pending":
                        payment.info = str(source)
                        payment.state = OrderPayment.PAYMENT_STATE_PENDING
                        payment.save()
                        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))
                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.'))

        try:
            self._charge_source(request, request.session['payment_stripe_token'], payment)
        finally:
            del request.session['payment_stripe_token']