Example #1
0
def test_create_next_double_payment(caplog, creation_params):
    creation_params['registration'].transaction = MagicMock(
        status=TransactionStatus.successful)
    _, double_payment = PaymentTransaction.create_next(**creation_params)
    log = extract_logs(caplog, one=True, name='indico.payment').message
    assert 'already paid' in log
    assert double_payment
Example #2
0
def register_transaction(registration,
                         amount,
                         currency,
                         action,
                         provider=None,
                         data=None):
    """Create a new transaction for a certain transaction action.

    :param registration: the `Registration` associated to the transaction
    :param amount: the (strictly positive) amount of the transaction
    :param currency: the currency used for the transaction
    :param action: the `TransactionAction` of the transaction
    :param provider: the payment method name of the transaction,
                     or '_manual' if no payment method has been used
    :param data: arbitrary JSON-serializable data specific to the
                 transaction's provider
    """
    new_transaction = PaymentTransaction.create_next(registration=registration,
                                                     action=action,
                                                     amount=amount,
                                                     currency=currency,
                                                     provider=provider,
                                                     data=data)
    if new_transaction:
        db.session.flush()
        if new_transaction.status == TransactionStatus.successful:
            registration.update_state(paid=True)
        elif new_transaction.status == TransactionStatus.cancelled:
            registration.update_state(paid=False)
        notify_registration_state_update(registration)
        return new_transaction
Example #3
0
def register_transaction(registration, amount, currency, action, provider=None, data=None):
    """Creates a new transaction for a certain transaction action.

    :param registration: the `Registration` associated to the transaction
    :param amount: the (strictly positive) amount of the transaction
    :param currency: the currency used for the transaction
    :param action: the `TransactionAction` of the transaction
    :param provider: the payment method name of the transaction,
                     or '_manual' if no payment method has been used
    :param data: arbitrary JSON-serializable data specific to the
                 transaction's provider
    """
    new_transaction, double_payment = PaymentTransaction.create_next(
        registration=registration, action=action, amount=amount, currency=currency, provider=provider, data=data
    )
    if new_transaction:
        db.session.flush()
        if double_payment:
            notify_double_payment(registration)
        if new_transaction.status == TransactionStatus.successful:
            registration.update_state(paid=True)
        elif new_transaction.status == TransactionStatus.cancelled:
            registration.update_state(paid=False)
        notify_registration_state_update(registration)
        return new_transaction
Example #4
0
    def adjust_payment_form_data(self, data):
        """Prepare the payment form shown to registrants."""
        # indico does not seem to provide stacking of settings
        # we merge event on top of global settings, but remove defaults
        event_settings = data['event_settings']
        global_settings = data['settings']
        plugin_settings = {
            key: event_settings[key]
            if event_settings.get(key) is not None else global_settings[key]
            for key in (set(event_settings) | set(global_settings))
        }
        # parameters of the transaction - amount, currency, ...
        transaction = self._get_transaction_parameters(data, plugin_settings)
        init_response = self._init_payment_page(
            sixpay_url=plugin_settings['url'],
            transaction_data=transaction,
        )
        data['payment_url'] = init_response['RedirectUrl']

        # create pending transaction and store Saferpay transaction token
        if not PaymentTransaction.create_next(
                registration=data['registration'],
                amount=data['amount'],
                currency=data['currency'],
                action=TransactionAction.pending,
                provider=provider,
                data={'Init_PP_response': init_response}):
            data['registration'].transaction.data = {
                'Init_PP_response': init_response
            }
        return data
Example #5
0
def test_create_next_with_exception(caplog, mocker, creation_params, exception):
    mocker.patch.object(TransactionStatusTransition, 'next')
    TransactionStatusTransition.next.side_effect = exception('TEST_EXCEPTION')
    transaction = PaymentTransaction.create_next(**creation_params)
    log = extract_logs(caplog, one=True, name='indico.payment')
    assert transaction is None
    assert 'TEST_EXCEPTION' in log.message
    if log.exc_info:
        assert log.exc_info[0] == exception
Example #6
0
def test_create_next_with_exception(caplog, mocker, creation_params, exception):
    mocker.patch.object(TransactionStatusTransition, 'next')
    TransactionStatusTransition.next.side_effect = exception('TEST_EXCEPTION')
    transaction = PaymentTransaction.create_next(**creation_params)
    log = extract_logs(caplog, one=True, name='indico.payment')
    assert transaction is None
    assert 'TEST_EXCEPTION' in log.message
    if log.exc_info:
        assert log.exc_info[0] == exception
Example #7
0
def test_ipn_is_transaction_duplicated(txn_id, payment_status, expected):
    request.form = {'payment_status': 'Completed', 'txn_id': '12345'}
    rh = RHPaypalIPN()
    rh.registration = MagicMock()
    rh.registration.transaction = None
    assert not rh._is_transaction_duplicated()
    transaction = PaymentTransaction(provider='paypal',
                                     data={
                                         'payment_status': payment_status,
                                         'txn_id': txn_id
                                     })
    rh.registration.transaction = transaction
    assert rh._is_transaction_duplicated() == expected
Example #8
0
    def migrate_transactions(self):
        self.messages.append(cformat("%{magenta!} - Payment Transactions:"))
        print cformat("%{white!}migrating payment transactions")

        count = 0
        errors = 0
        warnings = 0

        for event, registrant, transaction in committing_iterator(self._iter_transactions()):
            try:
                data = self._get_transaction_data(transaction, event)
            except ValueError as e:
                print cformat("%{red!}{0} (evt: {1}, reg: {2})").format(e, event.id, registrant._id)
                errors += 1
                continue

            if data['provider'] == '_manual' and data['amount'] == 0.0:
                print cformat("%{yellow!}Skipping {0[provider]} transaction (evt: {1}, reg: {2}) "
                              "with zero amount: {0[amount]} {0[currency]}").format(data, event.id, registrant._id)
                warnings += 1
                continue

            elif data['amount'] < 0.0:
                print cformat("%{yellow!}Skipping {0[provider]} transaction (evt: {1}, reg: {2}) "
                              "with negative amount: {0[amount]} {0[currency]}").format(data, event.id, registrant._id)
                warnings += 1
                continue

            pt = PaymentTransaction(event_id=int(event.id), registrant_id=int(registrant._id),
                                    status=TransactionStatus.successful, **data)

            count += 1
            print cformat("%{cyan}{0}").format(pt)
            db.session.add(pt)

        if warnings:
            warning_msg = cformat("%{yellow!}There were {0} warnings during the migration "
                                  "of the payment transactions.").format(warnings)
            self.messages.append('    ' + warning_msg)
            print warning_msg

        if errors:
            msg = cformat("%{red!}There were some errors during the migration of the payment transactions.\n"
                          "{0} transactions were not migrated and will be lost.\n").format(errors)
        else:
            msg = cformat("%{green!}migration of {0} payment transactions successful\n").format(count)
        self.messages.append('    ' + '\n    '.join(msg.split('\n')))
        print msg
Example #9
0
 def _create_transaction(status, **params):
     params.setdefault('amount', 10)
     params.setdefault('currency', 'USD')
     params.setdefault('provider', '_manual')
     params.setdefault('data', {})
     return PaymentTransaction(status=status, **params)
Example #10
0
def test_create_next(creation_params):
    transaction, double_payment = PaymentTransaction.create_next(**creation_params)
    assert isinstance(transaction, PaymentTransaction)
    assert not double_payment
Example #11
0
def test_create_next(creation_params):
    transaction = PaymentTransaction.create_next(**creation_params)
    assert isinstance(transaction, PaymentTransaction)
Example #12
0
def test_create_next_double_payment(caplog, creation_params):
    creation_params['registration'].transaction = MagicMock(status=TransactionStatus.successful)
    _, double_payment = PaymentTransaction.create_next(**creation_params)
    log = extract_logs(caplog, one=True, name='indico.payment').message
    assert 'already paid' in log
    assert double_payment
Example #13
0
 def has_data(self):
     return bool(PaymentTransaction.find().count())
Example #14
0
 def has_data(self):
     return bool(PaymentTransaction.find().count())