Esempio n. 1
0
 def get(self, request, *args, **kwargs):
     context = {}
     if 'specs' not in request.session or 'user' not in request.session:
         return HttpResponseRedirect(reverse('datacenterlight:index'))
     if 'token' in self.request.session:
         token = self.request.session['token']
         stripe_utils = StripeUtils()
         card_details = stripe_utils.get_cards_details_from_token(
             token
         )
         if not card_details.get('response_object'):
             return HttpResponseRedirect(reverse('hosting:payment'))
         card_details_response = card_details['response_object']
         context['cc_last4'] = card_details_response['last4']
         context['cc_brand'] = card_details_response['brand']
     else:
         card_id = self.request.session.get('card_id')
         card_detail = UserCardDetail.objects.get(id=card_id)
         context['cc_last4'] = card_detail.last4
         context['cc_brand'] = card_detail.brand
     context.update({
         'site_url': reverse('datacenterlight:index'),
         'vm': request.session.get('specs'),
         'page_header_text': _('Confirm Order'),
         'billing_address_data': (
             request.session.get('billing_address_data')
         ),
         'cms_integration': get_cms_integration('default'),
     })
     return render(request, self.template_name, context)
Esempio n. 2
0
    def post(self, request, *args, **kwargs):
        user = request.session.get('user')
        stripe_api_cus_id = request.session.get('customer')
        stripe_utils = StripeUtils()

        if 'token' in request.session:
            card_details = stripe_utils.get_cards_details_from_token(
                request.session.get('token'))
            if not card_details.get('response_object'):
                msg = card_details.get('error')
                messages.add_message(self.request,
                                     messages.ERROR,
                                     msg,
                                     extra_tags='failed_payment')
                response = {
                    'status':
                    False,
                    'redirect':
                    "{url}#{section}".format(
                        url=(reverse(
                            'show_product',
                            kwargs={
                                'product_slug':
                                request.session['generic_payment_details']
                                ['product_slug']
                            }) if 'generic_payment_details' in request.session
                             else reverse('datacenterlight:payment')),
                        section='payment_error'),
                    'msg_title':
                    str(_('Error.')),
                    'msg_body':
                    str(
                        _('There was a payment related error.'
                          ' On close of this popup, you will be'
                          ' redirected back to the payment page.'))
                }
                return JsonResponse(response)
            card_details_response = card_details['response_object']
            card_details_dict = {
                'last4': card_details_response['last4'],
                'brand': card_details_response['brand'],
                'card_id': card_details_response['card_id']
            }
            stripe_customer_obj = StripeCustomer.objects.filter(
                stripe_id=stripe_api_cus_id).first()
            if stripe_customer_obj:
                ucd = UserCardDetail.get_user_card_details(
                    stripe_customer_obj, card_details_response)
                if not ucd:
                    acc_result = stripe_utils.associate_customer_card(
                        stripe_api_cus_id,
                        request.session['token'],
                        set_as_default=True)
                    if acc_result['response_object'] is None:
                        msg = _('An error occurred while associating the card.'
                                ' Details: {details}'.format(
                                    details=acc_result['error']))
                        messages.add_message(self.request,
                                             messages.ERROR,
                                             msg,
                                             extra_tags='failed_payment')
                        response = {
                            'status':
                            False,
                            'redirect':
                            "{url}#{section}".
                            format(url=(reverse(
                                'show_product',
                                kwargs={
                                    'product_slug':
                                    request.session['generic_payment_details']
                                    ['product_slug']
                                }) if 'generic_payment_details'
                                        in request.session else
                                        reverse('datacenterlight:payment')),
                                   section='payment_error'),
                            'msg_title':
                            str(_('Error.')),
                            'msg_body':
                            str(
                                _('There was a payment related error.'
                                  ' On close of this popup, you will be redirected'
                                  ' back to the payment page.'))
                        }
                        return JsonResponse(response)
        elif 'card_id' in request.session:
            card_id = request.session.get('card_id')
            user_card_detail = UserCardDetail.objects.get(id=card_id)
            card_details_dict = {
                'last4': user_card_detail.last4,
                'brand': user_card_detail.brand,
                'card_id': user_card_detail.card_id
            }
        else:
            response = {
                'status':
                False,
                'redirect':
                "{url}#{section}".format(
                    url=reverse('datacenterlight:payment'),
                    section='payment_error'),
                'msg_title':
                str(_('Error.')),
                'msg_body':
                str(
                    _('There was a payment related error.'
                      ' On close of this popup, you will be redirected back to'
                      ' the payment page.'))
            }
            return JsonResponse(response)

        if ('generic_payment_type' in request.session
                and self.request.session['generic_payment_type'] == 'generic'):
            gp_details = self.request.session['generic_payment_details']
            if gp_details['recurring']:
                # generic recurring payment
                logger.debug("Commencing a generic recurring payment")
            else:
                # generic one time payment
                logger.debug("Commencing a one time payment")
                charge_response = stripe_utils.make_charge(
                    amount=gp_details['amount'], customer=stripe_api_cus_id)
                stripe_onetime_charge = charge_response.get('response_object')

                # Check if the payment was approved
                if not stripe_onetime_charge:
                    msg = charge_response.get('error')
                    messages.add_message(self.request,
                                         messages.ERROR,
                                         msg,
                                         extra_tags='failed_payment')
                    response = {
                        'status':
                        False,
                        'redirect':
                        "{url}#{section}".format(
                            url=(reverse('show_product',
                                         kwargs={
                                             'product_slug':
                                             gp_details['product_slug']
                                         }) if 'generic_payment_details'
                                 in request.session else
                                 reverse('datacenterlight:payment')),
                            section='payment_error'),
                        'msg_title':
                        str(_('Error.')),
                        'msg_body':
                        str(
                            _('There was a payment related error.'
                              ' On close of this popup, you will be redirected'
                              ' back to the payment page.'))
                    }
                    return JsonResponse(response)

        if ('generic_payment_type' not in request.session
                or (request.session['generic_payment_details']['recurring'])):
            if 'generic_payment_details' in request.session:
                amount_to_be_charged = (round(
                    request.session['generic_payment_details']['amount'], 2))
                plan_name = "generic-{0}-{1:.2f}".format(
                    request.session['generic_payment_details']['product_id'],
                    amount_to_be_charged)
                stripe_plan_id = plan_name
            else:
                template = request.session.get('template')
                specs = request.session.get('specs')
                vm_template_id = template.get('id', 1)

                cpu = specs.get('cpu')
                memory = specs.get('memory')
                disk_size = specs.get('disk_size')
                amount_to_be_charged = specs.get('total_price')
                plan_name = StripeUtils.get_stripe_plan_name(
                    cpu=cpu,
                    memory=memory,
                    disk_size=disk_size,
                    price=amount_to_be_charged)
                stripe_plan_id = StripeUtils.get_stripe_plan_id(
                    cpu=cpu,
                    ram=memory,
                    ssd=disk_size,
                    version=1,
                    app='dcl',
                    price=amount_to_be_charged)
            stripe_plan = stripe_utils.get_or_create_stripe_plan(
                amount=amount_to_be_charged,
                name=plan_name,
                stripe_plan_id=stripe_plan_id)
            subscription_result = stripe_utils.subscribe_customer_to_plan(
                stripe_api_cus_id,
                [{
                    "plan": stripe_plan.get('response_object').stripe_plan_id
                }])
            stripe_subscription_obj = subscription_result.get(
                'response_object')
            # Check if the subscription was approved and is active
            if (stripe_subscription_obj is None
                    or stripe_subscription_obj.status != 'active'):
                # At this point, we have created a Stripe API card and
                # associated it with the customer; but the transaction failed
                # due to some reason. So, we would want to dissociate this card
                # here.
                # ...

                msg = subscription_result.get('error')
                messages.add_message(self.request,
                                     messages.ERROR,
                                     msg,
                                     extra_tags='failed_payment')
                response = {
                    'status':
                    False,
                    'redirect':
                    "{url}#{section}".format(
                        url=(reverse(
                            'show_product',
                            kwargs={
                                'product_slug':
                                request.session['generic_payment_details']
                                ['product_slug']
                            }) if 'generic_payment_details' in request.session
                             else reverse('datacenterlight:payment')),
                        section='payment_error'),
                    'msg_title':
                    str(_('Error.')),
                    'msg_body':
                    str(
                        _('There was a payment related error.'
                          ' On close of this popup, you will be redirected back to'
                          ' the payment page.'))
                }
                return JsonResponse(response)

        # Create user if the user is not logged in and if he is not already
        # registered
        if not request.user.is_authenticated():
            try:
                custom_user = CustomUser.objects.get(email=user.get('email'))
                stripe_customer = StripeCustomer.objects.filter(
                    user_id=custom_user.id).first()
                if stripe_customer is None:
                    stripe_customer = StripeCustomer.objects.create(
                        user=custom_user, stripe_id=stripe_api_cus_id)
                stripe_customer_id = stripe_customer.id
            except CustomUser.DoesNotExist:
                logger.debug("Customer {} does not exist.".format(
                    user.get('email')))
                password = CustomUser.get_random_password()
                base_url = "{0}://{1}".format(self.request.scheme,
                                              self.request.get_host())
                custom_user = CustomUser.register(user.get('name'),
                                                  password,
                                                  user.get('email'),
                                                  app='dcl',
                                                  base_url=base_url,
                                                  send_email=True,
                                                  account_details=password)
                logger.debug("Created user {}.".format(user.get('email')))
                stripe_customer = StripeCustomer.objects. \
                    create(user=custom_user, stripe_id=stripe_api_cus_id)
                stripe_customer_id = stripe_customer.id
                new_user = authenticate(username=custom_user.email,
                                        password=password)
                login(request, new_user)
        else:
            # We assume that if the user is here, his/her StripeCustomer
            # object already exists
            stripe_customer_id = request.user.stripecustomer.id
            custom_user = request.user

        if 'token' in request.session:
            ucd = UserCardDetail.get_or_create_user_card_detail(
                stripe_customer=self.request.user.stripecustomer,
                card_details=card_details_response)
            UserCardDetail.save_default_card_local(
                self.request.user.stripecustomer.stripe_id, ucd.card_id)
        else:
            card_id = request.session.get('card_id')
            user_card_detail = UserCardDetail.objects.get(id=card_id)
            card_details_dict = {
                'last4': user_card_detail.last4,
                'brand': user_card_detail.brand,
                'card_id': user_card_detail.card_id
            }
            if not user_card_detail.preferred:
                UserCardDetail.set_default_card(
                    stripe_api_cus_id=stripe_api_cus_id,
                    stripe_source_id=user_card_detail.card_id)

        # Save billing address
        billing_address_data = request.session.get('billing_address_data')
        logger.debug('billing_address_data is {}'.format(billing_address_data))
        billing_address_data.update({'user': custom_user.id})

        if 'generic_payment_type' in request.session:
            stripe_cus = StripeCustomer.objects.filter(
                stripe_id=stripe_api_cus_id).first()
            billing_address = BillingAddress(
                cardholder_name=billing_address_data['cardholder_name'],
                street_address=billing_address_data['street_address'],
                city=billing_address_data['city'],
                postal_code=billing_address_data['postal_code'],
                country=billing_address_data['country'])
            billing_address.save()

            order = HostingOrder.create(
                price=self.request.session['generic_payment_details']
                ['amount'],
                customer=stripe_cus,
                billing_address=billing_address,
                vm_pricing=VMPricing.get_default_pricing())

            # Create a Hosting Bill
            HostingBill.create(customer=stripe_cus,
                               billing_address=billing_address)

            # Create Billing Address for User if he does not have one
            if not stripe_cus.user.billing_addresses.count():
                billing_address_data.update({'user': stripe_cus.user.id})
                billing_address_user_form = UserBillingAddressForm(
                    billing_address_data)
                billing_address_user_form.is_valid()
                billing_address_user_form.save()

            if self.request.session['generic_payment_details']['recurring']:
                # Associate the given stripe subscription with the order
                order.set_subscription_id(stripe_subscription_obj.id,
                                          card_details_dict)
            else:
                # Associate the given stripe charge id with the order
                order.set_stripe_charge(stripe_onetime_charge)

            # Set order status approved
            order.set_approved()
            order.generic_payment_description = gp_details["description"]
            order.generic_product_id = gp_details["product_id"]
            order.save()
            # send emails
            context = {
                'name': user.get('name'),
                'email': user.get('email'),
                'amount': gp_details['amount'],
                'description': gp_details['description'],
                'recurring': gp_details['recurring'],
                'product_name': gp_details['product_name'],
                'product_id': gp_details['product_id'],
                'order_id': order.id
            }

            email_data = {
                'subject': (settings.DCL_TEXT +
                            " Payment received from %s" % context['email']),
                'from_email':
                settings.DCL_SUPPORT_FROM_ADDRESS,
                'to': ['*****@*****.**'],
                'body':
                "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]),
                'reply_to': [context['email']],
            }
            send_plain_email_task.delay(email_data)

            email_data = {
                'subject':
                _("Confirmation of your payment"),
                'from_email':
                settings.DCL_SUPPORT_FROM_ADDRESS,
                'to': [user.get('email')],
                'body':
                _("Hi {name},\n\n"
                  "thank you for your order!\n"
                  "We have just received a payment of CHF {amount:.2f}"
                  " from you.{recurring}\n\n"
                  "Cheers,\nYour Data Center Light team".format(
                      name=user.get('name'),
                      amount=gp_details['amount'],
                      recurring=(_(' This is a monthly recurring plan.')
                                 if gp_details['recurring'] else ''))),
                'reply_to': ['*****@*****.**'],
            }
            send_plain_email_task.delay(email_data)

            response = {
                'status':
                True,
                'redirect':
                (reverse('hosting:orders') if request.user.is_authenticated()
                 else reverse('datacenterlight:index')),
                'msg_title':
                str(_('Thank you for the payment.')),
                'msg_body':
                str(
                    _('You will soon receive a confirmation email of the '
                      'payment. You can always contact us at '
                      '[email protected] for any question that you may have.'))
            }
            clear_all_session_vars(request)

            return JsonResponse(response)

        user = {
            'name': custom_user.name,
            'email': custom_user.email,
            'pass': custom_user.password,
            'request_scheme': request.scheme,
            'request_host': request.get_host(),
            'language': get_language(),
        }

        create_vm(billing_address_data, stripe_customer_id, specs,
                  stripe_subscription_obj, card_details_dict, request,
                  vm_template_id, template, user)

        response = {
            'status':
            True,
            'redirect': (reverse('hosting:virtual_machines')
                         if request.user.is_authenticated() else
                         reverse('datacenterlight:index')),
            'msg_title':
            str(_('Thank you for the order.')),
            'msg_body':
            str(
                _('Your VM will be up and running in a few moments.'
                  ' We will send you a confirmation email as soon as'
                  ' it is ready.'))
        }

        return JsonResponse(response)
Esempio n. 3
0
    def post(self, request, *args, **kwargs):
        template = request.session.get('template')
        specs = request.session.get('specs')
        user = request.session.get('user')
        stripe_api_cus_id = request.session.get('customer')
        vm_template_id = template.get('id', 1)
        stripe_utils = StripeUtils()

        if 'token' in request.session:
            card_details = stripe_utils.get_cards_details_from_token(
                request.session.get('token')
            )
            if not card_details.get('response_object'):
                msg = card_details.get('error')
                messages.add_message(self.request, messages.ERROR, msg,
                                     extra_tags='failed_payment')
                response = {
                    'status': False,
                    'redirect': "{url}#{section}".format(
                        url=reverse('datacenterlight:payment'),
                        section='payment_error'),
                    'msg_title': str(_('Error.')),
                    'msg_body': str(
                        _('There was a payment related error.'
                          ' On close of this popup, you will be'
                          ' redirected back to the payment page.')
                    )
                }
                return JsonResponse(response)
            card_details_response = card_details['response_object']
            card_details_dict = {
                'last4': card_details_response['last4'],
                'brand': card_details_response['brand'],
                'card_id': card_details_response['card_id']
            }
            stripe_customer_obj = StripeCustomer.objects.filter(stripe_id=stripe_api_cus_id).first()
            if stripe_customer_obj:
                ucd = UserCardDetail.get_user_card_details(
                    stripe_customer_obj, card_details_response
                )
                if not ucd:
                    acc_result = stripe_utils.associate_customer_card(
                        stripe_api_cus_id, request.session['token'],
                        set_as_default=True
                    )
                    if acc_result['response_object'] is None:
                        msg = _(
                            'An error occurred while associating the card.'
                            ' Details: {details}'.format(
                                details=acc_result['error']
                            )
                        )
                        messages.add_message(self.request, messages.ERROR, msg,
                                             extra_tags='failed_payment')
                        response = {
                            'status': False,
                            'redirect': "{url}#{section}".format(
                                url=reverse('hosting:payment'),
                                section='payment_error'),
                            'msg_title': str(_('Error.')),
                            'msg_body': str(
                                _('There was a payment related error.'
                                  ' On close of this popup, you will be redirected'
                                  ' back to the payment page.')
                            )
                        }
                        return JsonResponse(response)
        elif 'card_id' in request.session:
            card_id = request.session.get('card_id')
            user_card_detail = UserCardDetail.objects.get(id=card_id)
            card_details_dict = {
                'last4': user_card_detail.last4,
                'brand': user_card_detail.brand,
                'card_id': user_card_detail.card_id
            }
        else:
            response = {
                'status': False,
                'redirect': "{url}#{section}".format(
                    url=reverse('datacenterlight:payment'),
                    section='payment_error'),
                'msg_title': str(_('Error.')),
                'msg_body': str(
                    _('There was a payment related error.'
                      ' On close of this popup, you will be redirected back to'
                      ' the payment page.'))
            }
            return JsonResponse(response)

        cpu = specs.get('cpu')
        memory = specs.get('memory')
        disk_size = specs.get('disk_size')
        amount_to_be_charged = specs.get('total_price')
        plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu,
                                                     memory=memory,
                                                     disk_size=disk_size)
        stripe_plan_id = StripeUtils.get_stripe_plan_id(cpu=cpu,
                                                        ram=memory,
                                                        ssd=disk_size,
                                                        version=1,
                                                        app='dcl')
        stripe_plan = stripe_utils.get_or_create_stripe_plan(
            amount=amount_to_be_charged,
            name=plan_name,
            stripe_plan_id=stripe_plan_id)
        subscription_result = stripe_utils.subscribe_customer_to_plan(
            stripe_api_cus_id,
            [{"plan": stripe_plan.get(
                'response_object').stripe_plan_id}])
        stripe_subscription_obj = subscription_result.get('response_object')
        # Check if the subscription was approved and is active
        if (stripe_subscription_obj is None
                or stripe_subscription_obj.status != 'active'):
            # At this point, we have created a Stripe API card and
            # associated it with the customer; but the transaction failed
            # due to some reason. So, we would want to dissociate this card
            # here.
            # ...

            msg = subscription_result.get('error')
            messages.add_message(self.request, messages.ERROR, msg,
                                 extra_tags='failed_payment')
            response = {
                'status': False,
                'redirect': "{url}#{section}".format(
                    url=reverse('datacenterlight:payment'),
                    section='payment_error'),
                'msg_title': str(_('Error.')),
                'msg_body': str(
                    _('There was a payment related error.'
                      ' On close of this popup, you will be redirected back to'
                      ' the payment page.'))
            }
            return JsonResponse(response)

        # Create user if the user is not logged in and if he is not already
        # registered
        if not request.user.is_authenticated():
            try:
                custom_user = CustomUser.objects.get(
                    email=user.get('email'))
                stripe_customer = StripeCustomer.objects.filter(
                    user_id=custom_user.id).first()
                if stripe_customer is None:
                    stripe_customer = StripeCustomer.objects.create(
                        user=custom_user, stripe_id=stripe_api_cus_id
                    )
                stripe_customer_id = stripe_customer.id
            except CustomUser.DoesNotExist:
                logger.debug(
                    "Customer {} does not exist.".format(user.get('email')))
                password = CustomUser.get_random_password()
                base_url = "{0}://{1}".format(self.request.scheme,
                                              self.request.get_host())
                custom_user = CustomUser.register(
                    user.get('name'), password,
                    user.get('email'),
                    app='dcl', base_url=base_url, send_email=True,
                    account_details=password
                )
                logger.debug("Created user {}.".format(user.get('email')))
                stripe_customer = StripeCustomer.objects. \
                    create(user=custom_user, stripe_id=stripe_api_cus_id)
                stripe_customer_id = stripe_customer.id
                new_user = authenticate(username=custom_user.email,
                                        password=password)
                login(request, new_user)
        else:
            # We assume that if the user is here, his/her StripeCustomer
            # object already exists
            stripe_customer_id = request.user.stripecustomer.id
            custom_user = request.user

        if 'token' in request.session:
            ucd = UserCardDetail.get_or_create_user_card_detail(
                stripe_customer=self.request.user.stripecustomer,
                card_details=card_details_response
            )
            UserCardDetail.save_default_card_local(
                self.request.user.stripecustomer.stripe_id,
                ucd.card_id
            )
        else:
            card_id = request.session.get('card_id')
            user_card_detail = UserCardDetail.objects.get(id=card_id)
            card_details_dict = {
                'last4': user_card_detail.last4,
                'brand': user_card_detail.brand,
                'card_id': user_card_detail.card_id
            }
            if not user_card_detail.preferred:
                UserCardDetail.set_default_card(
                    stripe_api_cus_id=stripe_api_cus_id,
                    stripe_source_id=user_card_detail.card_id
                )

        # Save billing address
        billing_address_data = request.session.get('billing_address_data')
        logger.debug('billing_address_data is {}'.format(billing_address_data))
        billing_address_data.update({
            'user': custom_user.id
        })

        user = {
            'name': custom_user.name,
            'email': custom_user.email,
            'pass': custom_user.password,
            'request_scheme': request.scheme,
            'request_host': request.get_host(),
            'language': get_language(),
        }

        create_vm(
            billing_address_data, stripe_customer_id, specs,
            stripe_subscription_obj, card_details_dict, request,
            vm_template_id, template, user
        )

        response = {
            'status': True,
            'redirect': (
                reverse('hosting:virtual_machines')
                if request.user.is_authenticated()
                else reverse('datacenterlight:index')
            ),
            'msg_title': str(_('Thank you for the order.')),
            'msg_body': str(
                _('Your VM will be up and running in a few moments.'
                  ' We will send you a confirmation email as soon as'
                  ' it is ready.'))
        }

        return JsonResponse(response)