Example #1
0
    def execute_refund(self, refund: OrderRefund, retry=True):
        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:
            req = requests.post(
                'https://api.mollie.com/v2/payments/{}/refunds'.format(
                    payment),
                json=body,
                headers=self.request_headers)
            req.raise_for_status()
            refund.info_data = req.json()
        except HTTPError:
            logger.exception('Mollie error: %s' % req.text)
            try:
                refund.info_data = req.json()

                if payment.info_data.get('status') == 401 and retry:
                    # Token might be expired, let's retry!
                    if refresh_mollie_token(self.event, False):
                        return self.execute_refund(refund, retry=False)
            except:
                refund.info_data = {'error': True, 'detail': req.text}
            raise PaymentException(
                _('Mollie reported an error: {}').format(
                    refund.info_data.get('detail')))
        else:
            refund.done()
Example #2
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
Example #3
0
def handle_payment(payment, mollie_id, retry=True):
    pprov = payment.payment_provider
    if pprov.settings.connect_client_id and payment.info_data and payment.info_data.get(
            'mode', 'live') == 'test':
        qp = 'testmode=true'
    elif pprov.settings.connect_client_id and pprov.settings.access_token and pprov.settings.endpoint == "test":
        qp = 'testmode=true'
    else:
        qp = ''
    try:
        resp = requests.get('https://api.mollie.com/v2/payments/' + mollie_id +
                            '?' + qp,
                            headers=pprov.request_headers)
        resp.raise_for_status()
        data = resp.json()

        if data.get('amountRefunded') and data.get('status') == 'paid':
            refundsresp = requests.get('https://api.mollie.com/v2/payments/' +
                                       mollie_id + '/refunds?' + qp,
                                       headers=pprov.request_headers)
            refundsresp.raise_for_status()
            refunds = refundsresp.json()['_embedded']['refunds']
        else:
            refunds = []

        if data.get('status') == 'paid':
            chargebacksresp = requests.get(
                'https://api.mollie.com/v2/payments/' + mollie_id +
                '/chargebacks?' + qp,
                headers=pprov.request_headers)
            chargebacksresp.raise_for_status()
            chargebacks = chargebacksresp.json()['_embedded']['chargebacks']
        else:
            chargebacks = []

        payment.info = json.dumps(data)
        payment.save()

        if data.get('status') == 'paid' and payment.state in (
                OrderPayment.PAYMENT_STATE_PENDING,
                OrderPayment.PAYMENT_STATE_CREATED,
                OrderPayment.PAYMENT_STATE_CANCELED,
                OrderPayment.PAYMENT_STATE_FAILED):
            payment.order.log_action('pretix_mollie.event.paid')
            payment.confirm()
        elif data.get('status') == 'canceled' and payment.state in (
                OrderPayment.PAYMENT_STATE_CREATED,
                OrderPayment.PAYMENT_STATE_PENDING):
            payment.state = OrderPayment.PAYMENT_STATE_CANCELED
            payment.save()
            payment.order.log_action('pretix_mollie.event.canceled')
        elif data.get(
                'status'
        ) == 'pending' and payment.state == OrderPayment.PAYMENT_STATE_CREATED:
            payment.state = OrderPayment.PAYMENT_STATE_PENDING
            payment.save()
        elif data.get('status') in ('expired', 'failed') and payment.state in (
                OrderPayment.PAYMENT_STATE_CREATED,
                OrderPayment.PAYMENT_STATE_PENDING):
            payment.state = OrderPayment.PAYMENT_STATE_CANCELED
            payment.save()
            payment.order.log_action('pretix_mollie.event.' +
                                     data.get('status'))
        elif payment.state == OrderPayment.PAYMENT_STATE_CONFIRMED:
            known_refunds = [
                r.info_data.get('id') for r in payment.refunds.all()
            ]
            for r in refunds:
                if r.get('status') != 'failed' and r.get(
                        'id') not in known_refunds:
                    payment.create_external_refund(amount=Decimal(
                        r['amount']['value']),
                                                   info=json.dumps(r))
            for r in chargebacks:
                if r.get('id') not in known_refunds:
                    payment.create_external_refund(amount=Decimal(
                        r['amount']['value']),
                                                   info=json.dumps(r))
        else:
            payment.order.log_action('pretix_mollie.event.unknown', data)
    except HTTPError:
        if resp.status_code == 401 and retry:
            # Token might be expired, let's retry!
            if refresh_mollie_token(payment.order.event, False):
                return handle_payment(payment, mollie_id, retry=False)
        raise PaymentException(
            _('We had trouble communicating with Mollie. Please try again and get in touch '
              'with us if this problem persists.'))