示例#1
0
 def arbitrary_charge(self,
                      session,
                      id,
                      amount,
                      description,
                      email,
                      return_to='arbitrary_charge_form'):
     charge = Charge(amount=100 * int(amount),
                     description=description,
                     receipt_email=email)
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent,
                                           string_types) else ''
     if message:
         return {'error': message}
     else:
         session.add(
             ArbitraryCharge(
                 amount=charge.dollar_amount,
                 what=charge.description,
                 reg_station=cherrypy.session.get('reg_station')))
         return {
             'stripe_intent':
             stripe_intent,
             'success_url':
             '{}?message={}'.format(return_to,
                                    'Charge successfully processed'),
             'cancel_url':
             'cancel_arbitrary_charge'
         }
示例#2
0
 def purchases_charge(self, session, id, amount, receipt_id):
     receipt = session.art_show_receipt(receipt_id)
     attendee = session.attendee(id)
     charge = Charge(
         attendee,
         amount=amount,
         description='{}ayment for {}\'s art show purchases'.format(
             'P' if int(amount) == receipt.total else 'Partial p',
             attendee.full_name))
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent,
                                           string_types) else ''
     if message:
         return {'error': message}
     else:
         session.add(
             ArtShowPayment(
                 receipt=receipt,
                 amount=charge.amount,
                 type=c.STRIPE,
             ))
         session.commit()
         return {
             'stripe_intent':
             stripe_intent,
             'success_url':
             'pieces_bought?id={}&message={}'.format(
                 attendee.id, 'Charge successfully processed')
         }
示例#3
0
 def process_art_show_payment(self, session, id):
     attendee = session.attendee(id)
     charge = Charge(attendee, description="Art show application payment")
     
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent, string_types) else ''
     if message:
         return {'error': message}
     else:
         for app in attendee.art_show_applications:
             app.status = c.PAID  # This needs to accommodate payment cancellations
             send_email.delay(
                 c.ADMIN_EMAIL,
                 c.ART_SHOW_EMAIL,
                 'Art Show Payment Received',
                 render('emails/art_show/payment_notification.txt',
                     {'app': app}, encoding=None),
                 model=app.to_dict('id'))
             send_email.delay(
                 c.ART_SHOW_EMAIL,
                 app.email,
                 'Art Show Payment Received',
                 render('emails/art_show/payment_confirmation.txt',
                     {'app': app}, encoding=None),
                 model=app.to_dict('id'))
         if attendee.paid == c.NOT_PAID:
             attendee.paid = c.HAS_PAID
         session.add(session.create_receipt_item(attendee, charge.amount, "Art show payment", charge.stripe_transaction))
         session.add(attendee)
         session.commit()
         
         return {'stripe_intent': stripe_intent,
                 'success_url': 'edit?id={}&message={}'.format(attendee.art_show_applications[0].id,
                                                               'Your payment has been accepted')}
示例#4
0
    def stripe_webhook_handler(request=None):
        if not request or not request.body:
            return "Request required"
        sig_header = cherrypy.request.headers['HTTP_STRIPE_SIGNATURE']
        payload = request.body
        event = None

        try:
            event = stripe.Webhook.construct_event(
                payload, sig_header, c.STRIPE_ENDPOINT_SECRET
            )
        except ValueError as e:
            # Invalid payload
            cherrypy.response.status = 400
        except stripe.error.SignatureVerificationError as e:
            # Invalid signature
            return HttpResponse(status=400)

        if event['type'] == 'payment_intent.succeeded':
            payment_intent = event.data.object
            Charge.mark_paid_from_stripe(payment_intent)
        else:
            cherrypy.response.status = 400

        cherrypy.response.status = 200

        return "Success!"
示例#5
0
    def take_payment(self, session, id):
        attendee = session.attendee(id)
        charge = Charge(attendee, amount=attendee.amount_unpaid * 100)
        stripe_intent = charge.create_stripe_intent(session)
        message = stripe_intent if isinstance(stripe_intent,
                                              string_types) else ''

        if message:
            return {'error': message}
        else:
            db_attendee = session.query(Attendee).filter_by(
                id=attendee.id).first()
            if db_attendee:
                attendee = db_attendee
            session.add(
                session.create_receipt_item(attendee, charge.amount,
                                            "At-door kiosk payment",
                                            charge.stripe_transaction))
            session.add(attendee)
            session.commit()
            return {
                'stripe_intent': stripe_intent,
                'success_url':
                'register?message={}'.format(c.AT_DOOR_PREPAID_MSG)
            }
示例#6
0
 def test_charge_log_transaction(self, monkeypatch):
     attendee = Attendee()
     monkeypatch.setattr(Attendee, 'amount_unpaid', 10)
     charge = Charge(targets=[attendee], amount=1000, description="Test charge")
     charge.response = stripe.Charge(id=10)
     result = charge.stripe_transaction_from_charge()
     assert result.stripe_id == 10
     assert result.amount == 1000
     assert result.desc == "Test charge"
     assert result.type == c.PAYMENT
     assert result.who == 'non-admin'
示例#7
0
    def process_marketplace_payment(self, session, id):
        attendee = session.attendee(id)
        charge = Charge(
            attendee,
            description="Marketplace application payment for {}".format(
                attendee.full_name))

        stripe_intent = charge.create_stripe_intent(session)
        message = stripe_intent if isinstance(stripe_intent,
                                              string_types) else ''
        if message:
            return {'error': message}
        else:
            if attendee.marketplace_cost:
                for app in attendee.marketplace_applications:
                    cancel_amt = app.amount_unpaid
                    app.amount_paid += app.amount_unpaid
                    send_email.delay(
                        c.ADMIN_EMAIL,
                        c.MARKETPLACE_APP_EMAIL,
                        'Marketplace Payment Received',
                        render('emails/marketplace/payment_notification.txt',
                               {'app': app},
                               encoding=None),
                        model=app.to_dict('id'))
                    send_email.delay(
                        c.MARKETPLACE_APP_EMAIL,
                        app.email_to_address,
                        'Marketplace Payment Received',
                        render('emails/marketplace/payment_confirmation.txt',
                               {'app': app},
                               encoding=None),
                        model=app.to_dict('id'))

            if attendee.paid == c.NOT_PAID:
                attendee.paid = c.HAS_PAID
            session.add(
                session.create_receipt_item(attendee, charge.amount,
                                            "Marketplace payment",
                                            charge.stripe_transaction))
        session.add(attendee)
        session.commit()

        return {
            'stripe_intent':
            stripe_intent,
            'success_url':
            'edit?id={}&message={}'.format(
                attendee.marketplace_applications[0].id,
                'Your payment has been accepted'),
            'cancel_url':
            '../preregistration/cancel_payment?model_id={}&cancel_amt={}'.
            format(attendee.marketplace_applications[0].id, cancel_amt)
        }
示例#8
0
 def test_charge_log_transaction_no_unpaid(self, monkeypatch):
     group = Group()
     monkeypatch.setattr(Group, 'amount_unpaid', 0)
     charge = Charge(targets=[group], amount=1000,
                     description="Test charge")
     charge.response = stripe.Charge(id=10)
     txn = charge.stripe_transaction_from_charge()
     result = charge.stripe_transaction_for_model(group, txn)
     assert result.group_id == group.id
     assert result.txn_id == txn.id
     assert result.share == 1000
示例#9
0
 def test_charge_log_transaction_attendee(self, monkeypatch):
     attendee = Attendee()
     monkeypatch.setattr(Attendee, 'amount_unpaid', 10)
     charge = Charge(targets=[attendee],
                     description="Test charge")
     charge.response = stripe.Charge(id=10)
     txn = charge.stripe_transaction_from_charge()
     result = charge.stripe_transaction_for_model(attendee, txn)
     assert result.attendee_id == attendee.id
     assert result.txn_id == txn.id
     assert result.share == 1000
示例#10
0
 def test_charge_log_transaction(self):
     attendee = Attendee()
     charge = Charge(targets=[attendee], amount=1000, description="Test charge")
     charge.response = stripe.Charge(id=10)
     result = charge.stripe_transaction_from_charge()
     assert result.stripe_id == 10
     assert result.amount == 1000
     assert result.desc == "Test charge"
     assert result.type == c.PAYMENT
     assert result.who == 'non-admin'
     assert result.fk_id == attendee.id
     assert result.fk_model == attendee.__class__.__name__
示例#11
0
    def hotel(self, session, message='', id=None, edit_id=None, requested_hotel_info=False):
        id = edit_id or id
        if not id:
            raise HTTPRedirect('form')

        if not c.PREREG_REQUEST_HOTEL_INFO_OPEN:
            if cherrypy.request.method == 'POST':
                raise HTTPRedirect('index?message={}', 'Requests for hotel booking info have already been closed')
            else:
                raise HTTPRedirect('form?edit_id={}', id)

        attendee = self._get_unsaved(
            id, if_not_found=HTTPRedirect('form?message={}', 'Could not find the given preregistration'))

        is_group_leader = not attendee.is_unassigned and attendee.promo_code_groups > 0

        if cherrypy.request.method == 'POST':
            attendee.requested_hotel_info = requested_hotel_info
            target = attendee
            track_type = c.EDITED_PREREG if target.id in Charge.unpaid_preregs else c.UNPAID_PREREG
            Charge.unpaid_preregs[target.id] = Charge.to_sessionized(attendee)
            Tracking.track(track_type, attendee)
            raise HTTPRedirect('index')
        return {
            'message': message,
            'id': id,
            'edit_id': edit_id,
            'is_group_leader': is_group_leader,
            'requested_hotel_info': attendee.requested_hotel_info if edit_id else True
        }
示例#12
0
    def stripe_webhook_handler(self):
        if not cherrypy.request or not cherrypy.request.body:
            cherrypy.response.status = 400
            return "Request required"
        sig_header = cherrypy.request.headers.get('Stripe-Signature', '')
        payload = cherrypy.request.body.read()
        event = None

        try:
            event = stripe.Webhook.construct_event(payload, sig_header,
                                                   c.STRIPE_ENDPOINT_SECRET)
        except ValueError as e:
            cherrypy.response.status = 400
            return "Invalid payload: " + payload
        except stripe.error.SignatureVerificationError as e:
            cherrypy.response.status = 400
            return "Invalid signature: " + sig_header

        if not event:
            cherrypy.response.status = 400
            return "No event"

        if event and event['type'] == 'payment_intent.succeeded':
            payment_intent = event['data']['object']
            matching_txns = Charge.mark_paid_from_stripe_id(
                payment_intent['id'])
            if not matching_txns:
                cherrypy.response.status = 400
                return "No matching Stripe transaction"
            cherrypy.response.status = 200
            return "Payment marked complete for payment intent ID " + payment_intent[
                'id']
示例#13
0
    def hotel(self, session, message='', id=None, edit_id=None, requested_hotel_info=False):
        id = edit_id or id
        if not id:
            raise HTTPRedirect('form')

        if not c.PREREG_REQUEST_HOTEL_INFO_OPEN:
            if cherrypy.request.method == 'POST':
                raise HTTPRedirect('index?message={}', 'Requests for hotel booking info have already been closed')
            else:
                raise HTTPRedirect('form?edit_id={}', id)

        attendee = self._get_unsaved(
            id, if_not_found=HTTPRedirect('form?message={}', 'Could not find the given preregistration'))

        is_group_leader = not attendee.is_unassigned and attendee.promo_code_groups > 0

        if cherrypy.request.method == 'POST':
            attendee.requested_hotel_info = requested_hotel_info
            target = attendee
            track_type = c.EDITED_PREREG if target.id in Charge.unpaid_preregs else c.UNPAID_PREREG
            Charge.unpaid_preregs[target.id] = Charge.to_sessionized(attendee)
            Tracking.track(track_type, attendee)
            raise HTTPRedirect('index')
        return {
            'message': message,
            'id': id,
            'edit_id': edit_id,
            'is_group_leader': is_group_leader,
            'requested_hotel_info': attendee.requested_hotel_info if edit_id else True
        }
示例#14
0
    def pay_for_extra_members(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [group] = charge.groups
        group_badge_price = c.DEALER_BADGE_PRICE if group.tables else c.GROUP_PRICE
        badges_to_add = charge.dollar_amount // group_badge_price
        if charge.dollar_amount % group_badge_price:
            message = 'Our preregistration price has gone up since you tried to add the badges; please try again'
        else:
            message = charge.charge_cc(session, stripeToken)

        if message:
            raise HTTPRedirect('group_members?id={}&message={}', group.id, message)
        else:
            session.assign_badges(group, group.badges + badges_to_add)
            group.amount_paid += charge.dollar_amount
            session.merge(group)
            if group.is_dealer:
                send_email.delay(
                    c.MARKETPLACE_EMAIL,
                    c.MARKETPLACE_EMAIL,
                    'Dealer Paid for Extra Members',
                    render('emails/dealers/payment_notification.txt', {'group': group}, encoding=None),
                    model=group.to_dict('id'))
            raise HTTPRedirect(
                'group_members?id={}&message={}',
                group.id,
                'You payment has been accepted and the badges have been added to your group')
示例#15
0
 def manual_reg_charge(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     [attendee] = charge.attendees
     message = charge.charge_cc(session, stripeToken)
     if message:
         return {
             'success': False,
             'message': 'Error processing card: {}'.format(message)
         }
     else:
         attendee.paid = c.HAS_PAID
         attendee.payment_method = c.MANUAL
         session.add(
             session.create_receipt_item(attendee,
                                         attendee.total_cost * 100,
                                         "At-door desk payment",
                                         charge.stripe_transaction))
         attendee.amount_paid_override = attendee.total_cost
         session.merge(attendee)
         session.commit()
         return {
             'success': True,
             'message': 'Payment accepted.',
             'id': attendee.id
         }
 def process_art_show_payment(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     [attendee] = charge.attendees
     attendee = session.merge(attendee)
     apps = attendee.art_show_applications
     for app in apps:
         message = charge.charge_cc(session, stripeToken)
         if message:
             raise HTTPRedirect('edit?id={}&message={}', app.id, message)
         else:
             attendee.amount_paid += charge.dollar_amount
             app.status = c.PAID
             if attendee.paid == c.NOT_PAID:
                 attendee.paid = c.HAS_PAID
         session.add(attendee)
         send_email.delay(c.ADMIN_EMAIL,
                          c.ART_SHOW_EMAIL,
                          'Art Show Payment Received',
                          render('emails/art_show/payment_notification.txt',
                                 {'app': app},
                                 encoding=None),
                          model=app.to_dict('id'))
         send_email.delay(c.ART_SHOW_EMAIL,
                          app.email,
                          'Art Show Payment Received',
                          render('emails/art_show/payment_confirmation.txt',
                                 {'app': app},
                                 encoding=None),
                          model=app.to_dict('id'))
         raise HTTPRedirect('edit?id={}&message={}', app.id,
                            'Your payment has been accepted!')
示例#17
0
    def pay_for_extra_codes(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [attendee] = charge.attendees
        attendee = session.attendee(attendee.id)
        group = attendee.promo_code_groups[0]
        badges_to_add = charge.dollar_amount // c.GROUP_PRICE
        if charge.dollar_amount % c.GROUP_PRICE:
            message = 'Our preregistration price has gone up since you tried to add more codes; please try again'
        else:
            message = charge.charge_cc(session, stripeToken)

        if message:
            raise HTTPRedirect('group_promo_codes?id={}&message={}', group.id, message)
        else:
            session.add(session.create_receipt_item(
                attendee, charge.amount,
                "Adding {} badge{} to promo code group {} (${} each)".format(
                    badges_to_add,
                    "s" if badges_to_add > 1 else "",
                    group.name, c.GROUP_PRICE), charge.stripe_transaction, c.PROMO_CODE),
            )

            session.add_codes_to_pc_group(group, badges_to_add)
            attendee.amount_paid_override += charge.dollar_amount

            raise HTTPRedirect(
                'group_promo_codes?id={}&message={}',
                group.id,
                'You payment has been accepted and the codes have been added to your group')
示例#18
0
    def pay_for_extra_members(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [group] = charge.groups
        group_badge_price = c.DEALER_BADGE_PRICE if group.tables else c.GROUP_PRICE
        badges_to_add = charge.dollar_amount // group_badge_price
        if charge.dollar_amount % group_badge_price:
            message = 'Our preregistration price has gone up since you tried to add the badges; please try again'
        else:
            message = charge.charge_cc(session, stripeToken)

        if message:
            raise HTTPRedirect('group_members?id={}&message={}', group.id, message)
        else:
            session.assign_badges(group, group.badges + badges_to_add)
            group.amount_paid_override += charge.dollar_amount
            session.add(session.create_receipt_item(
                group, charge.amount,
                "{} badge{} (${} each)".format(
                    badges_to_add,
                    "s" if badges_to_add > 1 else "",
                    group.new_badge_cost), charge.stripe_transaction, c.BADGE),
            )
            session.merge(group)
            if group.is_dealer:
                send_email.delay(
                    c.MARKETPLACE_EMAIL,
                    c.MARKETPLACE_EMAIL,
                    '{} Paid for Extra Members'.format(c.DEALER_TERM.title()),
                    render('emails/dealers/payment_notification.txt', {'group': group}, encoding=None),
                    model=group.to_dict('id'))
            raise HTTPRedirect(
                'group_members?id={}&message={}',
                group.id,
                'You payment has been accepted and the badges have been added to your group')
示例#19
0
    def process_marketplace_payment(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [attendee] = charge.attendees
        attendee = session.merge(attendee)
        apps = attendee.marketplace_applications

        message = charge.charge_cc(session, stripeToken)
        if message:
            raise HTTPRedirect('edit?id={}&message={}', apps[0].id, message)
        else:
            attendee_payment = charge.dollar_amount
            if attendee.marketplace_cost:
                for app in attendee.marketplace_applications:
                    attendee_payment -= app.amount_unpaid
                    app.amount_paid += app.amount_unpaid
            attendee.amount_paid += attendee_payment
            if attendee.paid == c.NOT_PAID:
                attendee.paid = c.HAS_PAID
        session.add(attendee)
        send_email.delay(c.ADMIN_EMAIL,
                         c.MARKETPLACE_APP_EMAIL,
                         'Marketplace Payment Received',
                         render('emails/marketplace/payment_notification.txt',
                                {'app': app},
                                encoding=None),
                         model=app.to_dict('id'))
        send_email.delay(c.MARKETPLACE_APP_EMAIL,
                         app.email,
                         'Marketplace Payment Received',
                         render('emails/marketplace/payment_confirmation.txt',
                                {'app': app},
                                encoding=None),
                         model=app.to_dict('id'))
        raise HTTPRedirect('edit?id={}&message={}', app.id,
                           'Your payment has been accepted!')
示例#20
0
    def process_group_payment(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [group] = charge.groups
        message = charge.charge_cc(session, stripeToken)
        if message:
            raise HTTPRedirect('group_members?id={}&message={}', group.id,
                               message)
        else:
            group.amount_paid += charge.dollar_amount

            session.merge(group)
            if group.is_dealer:
                try:
                    send_email.delay(
                        c.MARKETPLACE_EMAIL,
                        c.MARKETPLACE_EMAIL,
                        'Dealer Payment Completed',
                        render('emails/dealers/payment_notification.txt',
                               {'group': group},
                               encoding=None),
                        model=group.to_dict('id'))
                except Exception:
                    log.error(
                        'unable to send dealer payment confirmation email',
                        exc_info=True)
            raise HTTPRedirect('group_members?id={}&message={}', group.id,
                               'Your payment has been accepted!')
示例#21
0
    def pay_for_extra_members(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [group] = charge.groups
        badges_to_add = charge.dollar_amount // c.GROUP_PRICE
        if charge.dollar_amount % c.GROUP_PRICE:
            message = 'Our preregistration price has gone up since you tried to add the badges; please try again'
        else:
            message = charge.charge_cc(session, stripeToken)

        if message:
            raise HTTPRedirect('group_members?id={}&message={}', group.id,
                               message)
        else:
            session.assign_badges(group, group.badges + badges_to_add)
            group.amount_paid += charge.dollar_amount
            session.merge(group)
            if group.is_dealer:
                send_email.delay(
                    c.MARKETPLACE_EMAIL,
                    c.MARKETPLACE_EMAIL,
                    'Dealer Paid for Extra Members',
                    render('emails/dealers/payment_notification.txt',
                           {'group': group},
                           encoding=None),
                    model=group.to_dict('id'))
            raise HTTPRedirect(
                'group_members?id={}&message={}', group.id,
                'You payment has been accepted and the badges have been added to your group'
            )
示例#22
0
 def index(self, message=''):
     if not Charge.unpaid_preregs:
         raise HTTPRedirect('form?message={}',
                            message) if message else HTTPRedirect('form')
     else:
         return {
             'message': message,
             'charge': Charge(listify(Charge.unpaid_preregs.values()))
         }
示例#23
0
 def _get_unsaved(self, id, if_not_found=None):
     """
     if_not_found:  pass in an HTTPRedirect() class to raise if the unsaved attendee is not found.
                    by default we will redirect to the index page
     """
     if id in Charge.unpaid_preregs:
         return Charge.from_sessionized(Charge.unpaid_preregs[id])
     else:
         raise HTTPRedirect('index') if if_not_found is None else if_not_found
示例#24
0
 def _get_unsaved(self, id, if_not_found=None):
     """
     if_not_found:  pass in an HTTPRedirect() class to raise if the unsaved attendee is not found.
                    by default we will redirect to the index page
     """
     if id in Charge.unpaid_preregs:
         return Charge.from_sessionized(Charge.unpaid_preregs[id])
     else:
         raise HTTPRedirect('index') if if_not_found is None else if_not_found
示例#25
0
    def manual_reg_charge(self, session, id):
        attendee = session.attendee(id)
        charge = Charge(attendee, amount=attendee.amount_unpaid * 100)
        stripe_intent = charge.create_stripe_intent(session)
        message = stripe_intent if isinstance(stripe_intent,
                                              string_types) else ''

        if message:
            return {'error': message}
        else:
            attendee.payment_method = c.MANUAL
            session.add(
                session.create_receipt_item(attendee, charge.amount,
                                            "At-door desk payment",
                                            charge.stripe_transaction))

            session.merge(attendee)
            session.commit()
            return {'stripe_intent': stripe_intent, 'success_url': ''}
示例#26
0
 def pay(self, session, id, message=''):
     attendee = session.attendee(id)
     if attendee.paid != c.NOT_PAID:
         raise HTTPRedirect('register?message={}', c.AT_DOOR_NOPAY_MSG)
     else:
         return {
             'message': message,
             'attendee': attendee,
             'charge': Charge(attendee, description=attendee.full_name)
         }
示例#27
0
 def repurchase(self, session, id, **params):
     if 'csrf_token' in params:
         old_attendee = session.attendee(id).to_dict(c.UNTRANSFERABLE_ATTRS)
         del old_attendee['id']
         new_attendee = Attendee(**old_attendee)
         Charge.unpaid_preregs[new_attendee.id] = Charge.to_sessionized(
             new_attendee)
         Tracking.track(c.UNPAID_PREREG, new_attendee)
         raise HTTPRedirect("form?edit_id={}", new_attendee.id)
     return {'id': id}
示例#28
0
 def sales_charge(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     message = charge.charge_cc(session, stripeToken)
     if message:
         raise HTTPRedirect('sales_charge_form?message={}', message)
     else:
         session.add(
             ArbitraryCharge(amount=charge.dollar_amount,
                             what=charge.description))
         raise HTTPRedirect('sales_charge_form?message={}',
                            'Charge successfully processed')
示例#29
0
 def index(self, session, message=''):
     if not Charge.unpaid_preregs:
         raise HTTPRedirect('form?message={}',
                            message) if message else HTTPRedirect('form')
     else:
         charge = Charge(listify(Charge.unpaid_preregs.values()))
         for attendee in charge.attendees:
             if attendee.promo_code and attendee.promo_code.group:
                 attendee.group_name = session.query(PromoCode).filter_by(
                     code=attendee.promo_code.code).first().group.name
         return {'message': message, 'charge': charge}
示例#30
0
 def repurchase(self, session, id, **params):
     if 'csrf_token' in params:
         old_attendee = session.attendee(id).to_dict(c.UNTRANSFERABLE_ATTRS)
         del old_attendee['id']
         new_attendee = Attendee(**old_attendee)
         Charge.unpaid_preregs[new_attendee.id] = Charge.to_sessionized(new_attendee)
         Tracking.track(c.UNPAID_PREREG, new_attendee)
         raise HTTPRedirect("form?edit_id={}", new_attendee.id)
     return {
         'id': id
     }
示例#31
0
def check_missed_stripe_payments():
    pending_ids = []
    with Session() as session:
        pending_payments = session.query(StripeTransaction).filter_by(
            type=c.PENDING)
        for payment in pending_payments:
            pending_ids.append(payment.stripe_id)

    events = stripe.Event.list(
        type='payment_intent.succeeded',
        created={
            # Check for events created in the last hour.
            'gte': int(time.time() - 60 * 60),
        })

    for event in events.auto_paging_iter():
        payment_intent = event.data.object
        log.debug('Processing Payment Intent ID {}', payment_intent.id)
        if payment_intent.id in pending_ids:
            log.debug('Charge is pending, intent ID is {}', payment_intent.id)
            Charge.mark_paid_from_stripe_id(payment_intent.id)
示例#32
0
 def arbitrary_charge(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     message = charge.charge_cc(session, stripeToken)
     if message:
         raise HTTPRedirect('arbitrary_charge_form?message={}', message)
     else:
         session.add(ArbitraryCharge(
             amount=charge.dollar_amount,
             what=charge.description,
             reg_station=cherrypy.session.get('reg_station')
         ))
         raise HTTPRedirect('{}?message={}', return_to, 'Charge successfully processed')
示例#33
0
    def prereg_payment(self, session, payment_id=None, stripeToken=None):
        if not payment_id or not stripeToken or c.HTTP_METHOD != 'POST':
            message = 'The payment was interrupted. Please check below to ensure you received your badge.'
            raise HTTPRedirect('paid_preregistrations?message={}', message)

        charge = Charge.get(payment_id)
        if not charge.total_cost:
            message = 'Your total cost was $0. Your credit card has not been charged.'
        elif charge.amount != charge.total_cost:
            message = 'Our preregistration price has gone up; ' \
                'please fill out the payment form again at the higher price'
        else:
            message = charge.charge_cc(session, stripeToken)

        if message:
            raise HTTPRedirect('index?message={}', message)

        # from this point on, the credit card has actually been charged but we haven't marked anything as charged yet.
        # be ultra-careful until the attendees/groups are marked paid and written to the DB or we could end up in a
        # situation where we took the payment, but didn't mark the cards charged

        for attendee in charge.attendees:
            attendee.paid = c.HAS_PAID
            attendee.amount_paid = attendee.total_cost
            attendee_name = 'PLACEHOLDER' if attendee.is_unassigned else attendee.full_name
            log.info("PAYMENT: marked attendee id={} ({}) as paid",
                     attendee.id, attendee_name)
            session.add(attendee)

        for group in charge.groups:
            group.amount_paid = group.default_cost
            log.info("PAYMENT: marked group id={} ({}) as paid", group.id,
                     group.name)

            for attendee in group.attendees:
                attendee.amount_paid = attendee.total_cost - attendee.badge_cost
                attendee_name = 'UNASSIGNED PLACEHOLDER' if attendee.is_unassigned else attendee.full_name
                log.info("PAYMENT: marked group member id={} ({}) as paid",
                         attendee.id, attendee_name)
            session.add(group)

        session.commit(
        )  # paranoia: really make sure we lock in marking taking payments in the database

        Charge.unpaid_preregs.clear()
        Charge.paid_preregs.extend(charge.targets)

        log.debug(
            'PAYMENT: prereg payment actual charging process FINISHED for stripeToken={}',
            stripeToken)
        raise HTTPRedirect('paid_preregistrations?payment_received={}',
                           charge.dollar_amount)
示例#34
0
 def sales_charge(self, session, id, amount, description):
     charge = Charge(amount=100 * float(amount), description=description)
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent,
                                           string_types) else ''
     if message:
         return {'error': message}
     else:
         session.add(
             ArbitraryCharge(
                 amount=charge.dollar_amount,
                 what=charge.description,
             ))
         return {
             'stripe_intent':
             stripe_intent,
             'success_url':
             'sales_charge_form?message={}'.format(
                 'Charge successfully processed'),
             'cancel_url':
             '../merch_admin/cancel_arbitrary_charge'
         }
示例#35
0
 def manual_reg_charge(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     [attendee] = charge.attendees
     message = charge.charge_cc(session, stripeToken)
     if message:
         return {'success': False, 'message': 'Error processing card: {}'.format(message)}
     else:
         attendee.paid = c.HAS_PAID
         attendee.payment_method = c.MANUAL
         attendee.amount_paid = attendee.total_cost
         session.merge(attendee)
         session.commit()
         return {'success': True, 'message': 'Payment accepted.', 'id': attendee.id}
示例#36
0
 def manual_reg_charge(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     [attendee] = charge.attendees
     message = charge.charge_cc(session, stripeToken)
     if message:
         return {'success': False, 'message': 'Error processing card: {}'.format(message)}
     else:
         attendee.paid = c.HAS_PAID
         attendee.payment_method = c.MANUAL
         attendee.amount_paid = attendee.total_cost
         session.merge(attendee)
         session.commit()
         return {'success': True, 'message': 'Payment accepted.', 'id': attendee.id}
示例#37
0
 def paid_preregistrations(self, session, payment_received=None, message=''):
     if not Charge.paid_preregs:
         raise HTTPRedirect('index')
     else:
         preregs = [session.merge(Charge.from_sessionized(d)) for d in Charge.paid_preregs]
         for prereg in preregs:
             try:
                 session.refresh(prereg)
             except Exception:
                 pass  # this badge must have subsequently been transferred or deleted
         return {
             'preregs': preregs,
             'total_cost': payment_received,
             'message': message
         }
示例#38
0
 def take_payment(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     [attendee] = charge.attendees
     message = charge.charge_cc(session, stripeToken)
     if message:
         raise HTTPRedirect('pay?id={}&message={}', attendee.id, message)
     else:
         db_attendee = session.query(Attendee).filter_by(id=attendee.id).first()
         if db_attendee:
             attendee = db_attendee
         attendee.paid = c.HAS_PAID
         attendee.amount_paid = attendee.total_cost
         session.add(attendee)
         raise HTTPRedirect(
             'register?message={}', c.AT_DOOR_PREPAID_MSG)
示例#39
0
 def process_attendee_donation(self, session, payment_id, stripeToken):
     charge = Charge.get(payment_id)
     [attendee] = charge.attendees
     message = charge.charge_cc(session, stripeToken)
     if message:
         raise HTTPRedirect('attendee_donation_form?id=' + attendee.id + '&message={}', message)
     else:
         # It's safe to assume the attendee exists in the database already.
         # The only path to reach this method requires the attendee to have
         # already paid for their registration, thus the attendee has been
         # saved to the database.
         attendee = session.query(Attendee).get(attendee.id)
         attendee.amount_paid += charge.dollar_amount
         if attendee.paid == c.NOT_PAID and attendee.amount_paid == attendee.total_cost:
             attendee.paid = c.HAS_PAID
         raise HTTPRedirect('badge_updated?id={}&message={}', attendee.id, 'Your payment has been accepted')
示例#40
0
    def pay_for_extra_codes(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [attendee] = charge.attendees
        group = session.attendee(attendee.id).promo_code_groups[0]
        badges_to_add = charge.dollar_amount // c.GROUP_PRICE
        if charge.dollar_amount % c.GROUP_PRICE:
            message = 'Our preregistration price has gone up since you tried to add more codes; please try again'
        else:
            message = charge.charge_cc(session, stripeToken)

        if message:
            raise HTTPRedirect('group_promo_codes?id={}&message={}', group.id, message)
        else:
            session.add_codes_to_pc_group(group, badges_to_add)
            attendee.amount_paid += charge.dollar_amount
            session.merge(attendee)

            raise HTTPRedirect(
                'group_promo_codes?id={}&message={}',
                group.id,
                'You payment has been accepted and the codes have been added to your group')
示例#41
0
    def process_group_payment(self, session, payment_id, stripeToken):
        charge = Charge.get(payment_id)
        [group] = charge.groups
        message = charge.charge_cc(session, stripeToken)
        if message:
            raise HTTPRedirect('group_members?id={}&message={}', group.id, message)
        else:
            group.amount_paid += charge.dollar_amount

            session.merge(group)
            if group.is_dealer:
                try:
                    send_email.delay(
                        c.MARKETPLACE_EMAIL,
                        c.MARKETPLACE_EMAIL,
                        'Dealer Payment Completed',
                        render('emails/dealers/payment_notification.txt', {'group': group}, encoding=None),
                        model=group.to_dict('id'))
                except Exception:
                    log.error('unable to send dealer payment confirmation email', exc_info=True)
            raise HTTPRedirect('group_members?id={}&message={}', group.id, 'Your payment has been accepted!')
示例#42
0
    def prereg_payment(self, session, payment_id=None, stripeToken=None):
        if not payment_id or not stripeToken or c.HTTP_METHOD != 'POST':
            message = 'The payment was interrupted. Please check below to ensure you received your badge.'
            raise HTTPRedirect('paid_preregistrations?message={}', message)

        charge = Charge.get(payment_id)
        if not charge.total_cost:
            message = 'Your total cost was $0. Your credit card has not been charged.'
        elif charge.amount != charge.total_cost:
            message = 'Our preregistration price has gone up; ' \
                'please fill out the payment form again at the higher price'
        else:
            message = charge.charge_cc(session, stripeToken)

        if message:
            raise HTTPRedirect('index?message={}', message)

        # from this point on, the credit card has actually been charged but we haven't marked anything as charged yet.
        # be ultra-careful until the attendees/groups are marked paid and written to the DB or we could end up in a
        # situation where we took the payment, but didn't mark the cards charged

        for attendee in charge.attendees:
            attendee.paid = c.HAS_PAID
            attendee_name = 'PLACEHOLDER' if attendee.is_unassigned else attendee.full_name
            log.info("PAYMENT: marked attendee id={} ({}) as paid", attendee.id, attendee_name)
            session.add(attendee)

            if attendee.badges:
                pc_group = session.create_promo_code_group(attendee, attendee.name, int(attendee.badges) - 1)
                session.add(pc_group)
                session.commit()
            attendee.amount_paid = attendee.total_cost

        session.commit()  # paranoia: really make sure we lock in marking taking payments in the database

        Charge.unpaid_preregs.clear()
        Charge.paid_preregs.extend(charge.targets)

        log.debug('PAYMENT: prereg payment actual charging process FINISHED for stripeToken={}', stripeToken)
        raise HTTPRedirect('paid_preregistrations?payment_received={}', charge.dollar_amount)
示例#43
0
 def test_charge_log_transaction_no_model(self):
     stripe.Charge.create = Mock(return_value=1)
     Charge.stripe_transaction_from_charge = Mock()
     charge = Charge(amount=1000, description="Test charge")
     Charge.charge_cc(charge, Mock(), 1)
     assert not Charge.stripe_transaction_from_charge.called
示例#44
0
    def form(self, session, message='', edit_id=None, **params):
        """
        Our production NGINX config caches the page at /preregistration/form.
        Since it's cached, we CAN'T return a session cookie with the page. We
        must POST to a different URL in order to bypass the cache and get a
        valid session cookie. Thus, this page is also exposed as "post_form".
        """
        params['id'] = 'None'   # security!
        group = Group()

        if edit_id is not None:
            attendee = self._get_unsaved(
                edit_id,
                if_not_found=HTTPRedirect('form?message={}', 'That preregistration has already been finalized'))
            attendee.apply(params, restricted=True)
            params.setdefault('pii_consent', True)
        else:
            attendee = session.attendee(params, ignore_csrf=True, restricted=True)

            if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                if not c.DEALER_REG_OPEN:
                    return render('static_views/dealer_reg_closed.html') if c.AFTER_DEALER_REG_START \
                        else render('static_views/dealer_reg_not_open.html')

                # Both the Attendee class and Group class have identically named
                # address fields. In order to distinguish the two sets of address
                # fields in the params, the Group fields are prefixed with "group_"
                # when the form is submitted. To prevent instantiating the Group object
                # with the Attendee's address fields, we must clone the params and
                # rename all the "group_" fields.
                group_params = dict(params)
                for field_name in ['country', 'region', 'zip_code', 'address1', 'address2', 'city']:
                    group_params[field_name] = params.get('group_{}'.format(field_name), '')
                    if params.get('copy_address'):
                        params[field_name] = group_params[field_name]

                group = session.group(group_params, ignore_csrf=True, restricted=True)

        if c.PAGE == 'post_dealer':
            attendee.badge_type = c.PSEUDO_DEALER_BADGE
        elif not attendee.badge_type:
            attendee.badge_type = c.ATTENDEE_BADGE

        if cherrypy.request.method == 'POST' or edit_id is not None:
            message = check_pii_consent(params, attendee) or message
            if not message and attendee.badge_type not in c.PREREG_BADGE_TYPES:
                message = 'Invalid badge type!'
            if not message and c.BADGE_PROMO_CODES_ENABLED and params.get('promo_code'):
                message = session.add_promo_code_to_attendee(attendee, params.get('promo_code'))

        if message:
            return {
                'message':    message,
                'attendee':   attendee,
                'group':      group,
                'edit_id':    edit_id,
                'affiliates': session.affiliates(),
                'cart_not_empty': Charge.unpaid_preregs,
                'copy_address': params.get('copy_address'),
                'promo_code': params.get('promo_code', ''),
                'pii_consent': params.get('pii_consent'),
            }

        if 'first_name' in params:
            message = check(attendee, prereg=True)
            if not message and attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                message = check(group, prereg=True)

            if attendee.badge_type in [c.PSEUDO_GROUP_BADGE, c.PSEUDO_DEALER_BADGE]:
                message = "Please enter a group name" if not params.get('name') else ''
            else:
                params['badges'] = 0
                params['name'] = ''

            if not message:
                if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                    attendee.paid = c.PAID_BY_GROUP
                    group.attendees = [attendee]
                    session.assign_badges(group, params['badges'])
                    group.status = c.WAITLISTED if c.DEALER_REG_SOFT_CLOSED else c.UNAPPROVED
                    attendee.ribbon = add_opt(attendee.ribbon_ints, c.DEALER_RIBBON)
                    attendee.badge_type = c.ATTENDEE_BADGE

                    session.add_all([attendee, group])
                    session.commit()
                    try:
                        send_email.delay(
                            c.MARKETPLACE_EMAIL,
                            c.MARKETPLACE_EMAIL,
                            'Dealer Application Received',
                            render('emails/dealers/reg_notification.txt', {'group': group}, encoding=None),
                            model=group.to_dict('id'))
                        send_email.delay(
                            c.MARKETPLACE_EMAIL,
                            attendee.email,
                            'Dealer Application Received',
                            render('emails/dealers/application.html', {'group': group}, encoding=None),
                            'html',
                            model=group.to_dict('id'))
                    except Exception:
                        log.error('unable to send marketplace application confirmation email', exc_info=True)
                    raise HTTPRedirect('dealer_confirmation?id={}', group.id)
                else:
                    track_type = c.UNPAID_PREREG
                    if attendee.id in Charge.unpaid_preregs:
                        track_type = c.EDITED_PREREG
                        # Clear out any previously cached targets, in case the unpaid badge
                        # has been edited and changed from a single to a group or vice versa.
                        del Charge.unpaid_preregs[attendee.id]

                    Charge.unpaid_preregs[attendee.id] = Charge.to_sessionized(attendee,
                                                                               params.get('name'),
                                                                               params.get('badges'))
                    Tracking.track(track_type, attendee)

                if session.attendees_with_badges().filter_by(
                        first_name=attendee.first_name, last_name=attendee.last_name, email=attendee.email).count():

                    raise HTTPRedirect('duplicate?id={}', group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)

                if attendee.banned:
                    raise HTTPRedirect('banned?id={}', group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)

                if c.PREREG_REQUEST_HOTEL_INFO_OPEN:
                    hotel_page = 'hotel?edit_id={}' if edit_id else 'hotel?id={}'
                    raise HTTPRedirect(hotel_page, group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)
                else:
                    raise HTTPRedirect('index')

        else:
            if edit_id is None:
                if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                    # All new dealer signups should default to receiving the
                    # hotel info email, even if the deadline has passed.
                    # There's a good chance some dealers will apply for a table
                    # AFTER the hotel booking deadline, but BEFORE the hotel
                    # booking is sent out. This ensures they'll still receive
                    # the email, as requested by the Marketplace Department.
                    attendee.requested_hotel_info = True

            if attendee.badge_type == c.PSEUDO_DEALER_BADGE and c.DEALER_REG_SOFT_CLOSED:
                message = 'Dealer registration is closed, but you can ' \
                    'fill out this form to add yourself to our waitlist'

        promo_code_group = None
        if attendee.promo_code:
            promo_code_group = session.query(PromoCode).filter_by(code=attendee.promo_code.code).first().group

        return {
            'message':    message,
            'attendee':   attendee,
            'group':      group,
            'promo_code_group': promo_code_group,
            'edit_id':    edit_id,
            'affiliates': session.affiliates(),
            'cart_not_empty': Charge.unpaid_preregs,
            'copy_address': params.get('copy_address'),
            'promo_code': params.get('promo_code', ''),
            'pii_consent': params.get('pii_consent'),
        }