예제 #1
0
 def _process(self):
     self._verify_business()
     verify_params = list(chain(IPN_VERIFY_EXTRA_PARAMS, request.form.iteritems()))
     result = requests.post(current_plugin.settings.get('url'), data=verify_params).text
     if result != 'VERIFIED':
         current_plugin.logger.warning("Paypal IPN string %s did not validate (%s)", verify_params, result)
         return
     if self._is_transaction_duplicated():
         current_plugin.logger.info("Payment not recorded because transaction was duplicated\nData received: %s",
                                    request.form)
         return
     payment_status = request.form.get('payment_status')
     if payment_status == 'Failed':
         current_plugin.logger.info("Payment failed (status: %s)\nData received: %s", payment_status, request.form)
         return
     if payment_status == 'Refunded' or float(request.form.get('mc_gross')) <= 0:
         current_plugin.logger.warning("Payment refunded (status: %s)\nData received: %s",
                                       payment_status, request.form)
         return
     if payment_status not in paypal_transaction_action_mapping:
         current_plugin.logger.warning("Payment status '%s' not recognized\nData received: %s",
                                       payment_status, request.form)
         return
     self._verify_amount()
     register_transaction(registration=self.registration,
                          amount=float(request.form['mc_gross']),
                          currency=request.form['mc_currency'],
                          action=paypal_transaction_action_mapping[payment_status],
                          provider='paypal',
                          data=request.form)
예제 #2
0
    def _process(self):
        payment_intent_id = self.session.payment_intent
        payment_intent = stripe.PaymentIntent.retrieve(payment_intent_id)
        if len(payment_intent.charges.data) != 1:
            raise BadRequest("Charges data doesn't contain only 1 item.")
        charge = payment_intent.charges.data[0]

        transaction_data = {}
        transaction_data['charge_id'] = charge['id']
        register_transaction(registration=self.registration,
                             amount=conv_from_stripe_amount(
                                 charge['amount'], charge['currency']),
                             currency=charge['currency'],
                             action=TransactionAction.complete,
                             provider='stripe',
                             data=transaction_data)

        receipt_url = charge['receipt_url']
        flash_msg = Markup(
            _('Your payment request has been processed.'
              ' See the receipt <a href="' + receipt_url + '">here</a>.'))
        flash(flash_msg, 'success')
        reg_url = url_for('event_registration.display_regform',
                          self.registration.locator.registrant)
        return redirect(reg_url)
예제 #3
0
 def _process(self):
     self._verify_business()
     verify_params = list(chain(IPN_VERIFY_EXTRA_PARAMS, request.form.iteritems()))
     result = requests.post(current_plugin.settings.get('url'), data=verify_params).text
     if result != 'VERIFIED':
         current_plugin.logger.warning("Paypal IPN string %s did not validate (%s)", verify_params, result)
         return
     if self._is_transaction_duplicated():
         current_plugin.logger.info("Payment not recorded because transaction was duplicated\nData received: %s",
                                    request.form)
         return
     payment_status = request.form.get('payment_status')
     if payment_status == 'Failed':
         current_plugin.logger.info("Payment failed (status: %s)\nData received: %s", payment_status, request.form)
         return
     if payment_status == 'Refunded' or float(request.form.get('mc_gross')) <= 0:
         current_plugin.logger.warning("Payment refunded (status: %s)\nData received: %s",
                                       payment_status, request.form)
         return
     if payment_status not in touchnet_transaction_action_mapping:
         current_plugin.logger.warning("Payment status '%s' not recognized\nData received: %s",
                                       payment_status, request.form)
         return
     self._verify_amount()
     register_transaction(registration=self.registration,
                          amount=float(request.form['mc_gross']),
                          currency=request.form['mc_currency'],
                          action=touchnet_transaction_action_mapping[payment_status],
                          provider='paypal',
                          data=request.form)
예제 #4
0
 def _register_payment(self, assert_data):
     """Register the transaction as paid."""
     register_transaction(self.registration,
                          self.registration.transaction.amount,
                          self.registration.transaction.currency,
                          TransactionAction.complete,
                          PROVIDER_SIXPAY,
                          data={'Transaction': assert_data['Transaction']})
예제 #5
0
 def _process(self):
     register_transaction(
         self.registration,
         self.registration.transaction.amount,
         self.registration.transaction.currency,
         TransactionAction.reject,
         provider=PROVIDER_SIXPAY,
     )
     flash(_('Your payment has failed.'), 'info')
     return redirect(
         url_for('event_registration.display_regform',
                 self.registration.locator.registrant))
예제 #6
0
 def _register_transaction(self, transaction_data):
     """Register the transaction persistently within Indico"""
     register_transaction(
         registration=self.registration,
         # SixPay uses SMALLEST currency, Indico expects LARGEST currency
         amount=to_large_currency(float(transaction_data['AMOUNT']),
                                  transaction_data['CURRENCY']),
         currency=transaction_data['CURRENCY'],
         action=TransactionAction.complete,
         provider='sixpay',
         data=transaction_data,
     )
예제 #7
0
파일: reglists.py 프로젝트: manikm/indico2
 def _process(self):
     pay = request.form.get('pay') == '1'
     if pay != self.registration.is_paid:
         currency = self.registration.currency if pay else self.registration.transaction.currency
         amount = self.registration.price if pay else self.registration.transaction.amount
         action = TransactionAction.complete if pay else TransactionAction.cancel
         register_transaction(registration=self.registration,
                              amount=amount,
                              currency=currency,
                              action=action,
                              data={'changed_by_name': session.user.full_name,
                                    'changed_by_id': session.user.id})
     return jsonify_data(html=_render_registration_details(self.registration))
예제 #8
0
파일: reglists.py 프로젝트: oddlord/indico
 def _process(self):
     pay = request.form.get('pay') == '1'
     if pay != self.registration.is_paid:
         currency = self.registration.currency if pay else self.registration.transaction.currency
         amount = self.registration.price if pay else self.registration.transaction.amount
         action = TransactionAction.complete if pay else TransactionAction.cancel
         register_transaction(registration=self.registration,
                              amount=amount,
                              currency=currency,
                              action=action,
                              data={'changed_by_name': session.user.full_name,
                                    'changed_by_id': session.user.id})
     return jsonify_data(html=_render_registration_details(self.registration))
예제 #9
0
 def _process(self):
     register_transaction(
         self.registration,
         self.registration.transaction.amount,
         self.registration.transaction.currency,
         # XXX: this is indeed reject and not cancel (cancel is "mark as unpaid" and
         # only used for manual transactions)
         TransactionAction.reject,
         provider=PROVIDER_SIXPAY,
     )
     flash(_('You cancelled the payment.'), 'info')
     return redirect(
         url_for('event_registration.display_regform',
                 self.registration.locator.registrant))
예제 #10
0
 def _create_transaction(self):
     amount = float(request.values['amount'])
     currency = request.values['currency']
     request_data = request.values.to_dict()
     transaction = self.registration.transaction
     if transaction and transaction.data == request_data:
         # Same request, e.g. because of the client-side and server-side success notification
         return
     register_transaction(registration=self.registration,
                          amount=amount,
                          currency=currency,
                          action=TransactionAction.complete,
                          provider='cern',
                          data=request_data)
예제 #11
0
def test_register_transaction(mocker, new, status):
    mocker.patch('indico.modules.events.payment.util.db')
    mocker.patch('indico.modules.events.payment.util.notify_registration_state_update')
    cn = mocker.patch.object(PaymentTransaction, 'create_next')
    registration = MagicMock()
    db_transaction = MagicMock(status=status) if new else None
    cn.return_value = db_transaction
    transaction = register_transaction(registration, None, None, None)
    if new:
        assert transaction is db_transaction
    else:
        assert transaction is None
예제 #12
0
def test_register_transaction(mocker, new, status):
    mocker.patch('indico.modules.events.payment.util.db')
    mocker.patch('indico.modules.events.payment.util.notify_registration_state_update')
    cn = mocker.patch.object(PaymentTransaction, 'create_next')
    registration = MagicMock()
    db_transaction = MagicMock(status=status) if new else None
    cn.return_value = db_transaction
    transaction = register_transaction(registration, None, None, None)
    if new:
        assert transaction is db_transaction
    else:
        assert transaction is None
예제 #13
0
def test_register_transaction(mocker, new, double, status):
    mocker.patch("indico.modules.events.payment.util.db")
    mocker.patch("indico.modules.events.payment.util.notify_registration_state_update")
    ndp = mocker.patch("indico.modules.events.payment.util.notify_double_payment")
    cn = mocker.patch.object(PaymentTransaction, "create_next")
    registration = MagicMock()
    db_transaction = MagicMock(status=status) if new else None
    cn.return_value = db_transaction, double
    transaction = register_transaction(registration, None, None, None)
    if new:
        assert transaction is db_transaction
        assert ndp.called == double
    else:
        assert transaction is None
        assert not ndp.called
예제 #14
0
    def _process(self):
        transaction_params = self._get_transaction_parameters()
        init_response = self._init_payment_page(transaction_params)
        payment_url = init_response['RedirectUrl']

        # create pending transaction and store Saferpay transaction token
        new_indico_txn = register_transaction(
            self.registration, self.registration.price,
            self.registration.currency, TransactionAction.pending,
            PROVIDER_SIXPAY, {'Init_PP_response': init_response})
        if not new_indico_txn:
            # set it on the current transaction if we could not create a next one
            # this happens if we already have a pending transaction and it's incredibly
            # ugly...
            self.registration.transaction.data = {
                'Init_PP_response': init_response
            }
        return redirect(payment_url)
예제 #15
0
    def _process(self):

        description = self._get_event_settings('description')
        use_event_api_keys = self._get_event_settings('use_event_api_keys')
        sec_key = (self._get_event_settings('sec_key') if use_event_api_keys
                   else current_plugin.settings.get('sec_key'))

        # Several redirect possibilities:
        # To registration form:
        #   1. Successful payment.
        #   2. Possibly successful payment, manual review required.
        reg_url = url_for('event_registration.display_regform',
                          self.registration.locator.registrant)
        # To checkout page:
        #   1. Fail.
        chk_url = url_for(
            'payment.event_payment',
            self.registration.locator.registrant,
        )

        try:
            charge = stripe.Charge.create(
                api_key=sec_key,
                amount=conv_to_stripe_amount(self.registration.price,
                                             self.registration.currency),
                currency=self.registration.currency.lower(),
                # TODO: Use proper conference name.
                description=description,
                source=self.stripe_token,
            )

        except err.APIConnectionError as e:
            current_plugin.logger.exception(e)
            flash(
                _('There was a problem connecting to Stripe.'
                  ' Please try again.'), 'error')
            return redirect(chk_url)

        except err.CardError as e:
            current_plugin.logger.exception(e)
            flash(_('Your payment was declined. Please try again.'), 'error')
            return redirect(chk_url)

        except Exception as e:
            current_plugin.logger.exception(e)
            flash(_('Your payment can not be made. Please try again.'),
                  'error')
            return redirect(chk_url)

        outcome = charge['outcome']
        outc_type = outcome['type']
        seller_message = outcome.get('seller_message')
        flash_msg = None
        flash_type = None
        receipt_url = None

        # See: https://stripe.com/docs/declines
        if outc_type == 'issuer_declined':
            flash_msg = _(
                'Your payment failed because your card was declined.')
            flash_type = 'error'
            current_plugin.logger.error(seller_message)
            flash(flash_msg, flash_type)
            return redirect(reg_url)

        elif outc_type == 'blocked':
            flash_msg = _(
                'Your payment failed because it was classified as high risk.')
            flash_type = 'error'
            current_plugin.logger.error(seller_message)
            flash(flash_msg, flash_type)
            return redirect(reg_url)

        elif outc_type == 'manual_review':
            receipt_url = charge['receipt_url']
            flash_msg = Markup(
                _('Your payment request has been processed and will be reviewed'
                  ' soon. See the receipt <a href="' + receipt_url +
                  '">here</a>.'))
            flash_type = 'info'

        elif outc_type == 'authorized':
            receipt_url = charge['receipt_url']
            flash_msg = Markup(
                _('Your payment request has been processed.'
                  ' See the receipt <a href="' + receipt_url + '">here</a>.'))
            flash_type = 'success'

        else:
            # This is actually the 'invalid' outcome type, which indicates
            # our API call is wrong.
            flash_msg = _(
                'Payment failed because something went wrong on our end.'
                ' Please notify the event contact person.')
            flash_type = 'error'
            flash(flash_msg, flash_type)
            return redirect(reg_url)

        transaction_data = request.form.to_dict()
        transaction_data['charge_id'] = charge['id']
        register_transaction(registration=self.registration,
                             amount=conv_from_stripe_amount(
                                 charge['amount'], charge['currency']),
                             currency=charge['currency'],
                             action=STRIPE_TRX_ACTION_MAP[charge['status']],
                             provider='stripe',
                             data=transaction_data)

        flash(flash_msg, flash_type)
        return redirect(reg_url)