def handle_put_post(http_server, database_manager, session, account): subscription_plan_template = SubscriptionPlan(database_manager) subscription_conditions = [{ "column": "is_active", "equivalence": "=", "value": 1 }] subscription_plans = database_manager.fetch_by(subscription_plan_template, subscription_conditions) billing_profiles = [] for available_subscription_plan in subscription_plans: billing_profiles.append({ "slug": available_subscription_plan.name, "name": available_subscription_plan.name.title(), "amount": available_subscription_plan.amount, "currency": available_subscription_plan.currency, "allowed_requests_per_month": available_subscription_plan.allowed_requests_per_month, "allowed_requests_per_month_printed": "{:,}".format( available_subscription_plan.allowed_requests_per_month), }) template = fetch_template("account/register.jinja.htm") keys = { "current_page": "register", "billing_profiles": billing_profiles, } errors = [] required_keys = [ "billing_id", "email", "password", "verify_password", "phone", #"g-recaptcha-response" ] post_params = http_server.get_post_parameters() if "billing_id" in post_params: if post_params["billing_id"] != "free": required_keys += ["stripe_token"] keys["response"] = post_params for required_key in required_keys: if required_key not in post_params or post_params[required_key] == "": errors.append(required_key) if len(errors) == 0: email = post_params["email"] password = post_params["password"] verify_password = post_params["verify_password"] phone = post_params["phone"] formatted_number = phone if password != verify_password: errors.append("verify_password") #try: phone_details = phonenumbers.parse(phone, "US") if phonenumbers.is_valid_number(phone_details) is False: errors.append("phone") else: formatted_number = "+{} {}".format( phone_details.country_code, phonenumbers.format_number( phone_details, phonenumbers.PhoneNumberFormat.NATIONAL)) client = Client(settings["twilio"]["account_sid"], settings["twilio"]["auth_token"]) twilio_phone_details = client.lookups.phone_numbers( formatted_number).fetch(type='carrier') if twilio_phone_details.carrier["error_code"] is not None: errors.append("phone") else: if twilio_phone_details.carrier["type"] == "voip": errors.append("phone_voip") #except: # errors.append("phone") if validate_email(email) is False: errors.append("email") else: subscription_plan_name = post_params["billing_id"] subscription_plan = SubscriptionPlan.fetch_by_name( database_manager, subscription_plan_name) if subscription_plan is None: errors.append("billing_id") keys["errors"] = errors for error in errors: keys["error_{}".format(error)] = True if len(errors) > 0: output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: is_captcha_valid = True ''' recaptcha_response = post_params['g-recaptcha-response'] captcha_data = { "secret": settings["google_recaptcha3"]["secret_key"], "response": recaptcha_response } recaptcha_response = requests.post( settings["google_recaptcha3"], data=captcha_data ) recapcha_json = recaptcha_response.json() is_captcha_valid = True if recapcha_json['success']: is_captcha_valid = True else: is_captcha_valid = False ''' if is_captcha_valid is False: keys["error_invalid_captcha"] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: is_marketing_ok = False if "subscribe" in post_params: if int(post_params["subscribe"]) == 1: is_marketing_ok = True keys["is_marketing_ok"] = True do_continue = True stripe_source_token = None stripe_customer_id = None stripe_subscription_id = None if subscription_plan.amount > 0: stripe.api_key = settings["stripe"]["secret_key"] discount_code = None stripe_coupon = None stripe_coupon_id = None if "discount_code" in post_params: discount_code = post_params["discount_code"] try: stripe_coupon = stripe.Coupon.retrieve(discount_code) do_continue = True stripe_coupon_id = stripe_coupon.id except Exception: errors += ["discount_code"] keys["errors"] = errors for error in errors: keys["error_{}".format(error)] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) if do_continue is True: stripe_plan = stripe.Plan.retrieve( subscription_plan.stripe_id) # How to acquire stripe tokens # https://stripe.com/docs/sources/cards # if "stripe_token" not in post_params: # raise ApiParamMissingStripeTokenError stripe_source_token = post_params["stripe_token"] stripe_customer_description = email try: customer = stripe.Customer.create( description=stripe_customer_description, source=stripe_source_token) stripe_customer_id = customer.id # will throw an exception if it fails. Must catch subscription = stripe.Subscription.create( customer=stripe_customer_id, items=[{ "plan": stripe_plan.id }], coupon=stripe_coupon_id) stripe_subscription_id = subscription.id except Exception: errors += ["duplicate_submission"] keys["errors"] = errors for error in errors: keys["error_{}".format(error)] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) do_continue = False if do_continue is True: # verify email doesn't already exist account = Account.fetch_by_email(database_manager, email) if account is not None: errors += ["email_taken"] keys["errors"] = errors for error in errors: keys["error_{}".format(error)] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: registration = AccountRegistration.fetch_by_email( database_manager, email) if registration is not None: errors += ["email_taken"] keys["errors"] = errors for error in errors: keys["error_{}".format(error)] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: registration_epoch = datetime.now() registration = AccountRegistration(database_manager) registration.email = post_params["email"] registration.password = post_params["password"] registration.phone = formatted_number registration.subscription_plan_id = subscription_plan.id registration.is_marketing_ok = is_marketing_ok registration.stripe_source_id = stripe_source_token registration.stripe_customer_id = stripe_customer_id registration.stripe_subscription_id = stripe_subscription_id registration.billing_interval = "monthly" registration.billing_year = registration_epoch.year registration.billing_month = registration_epoch.month registration.billing_day = registration_epoch.day confirmation_code = registration.generate_confirmation_code( ) # send confirmation email courier = Courier(settings["sendgrid"]) from_email = settings["email"]["from"]["email"] subject = "Confirm your account" template_id = "d-46d40e8316ba439095fdefb20b171a3e" substitutions = {"confirm_code": confirmation_code} response = courier.send_template_email( email, from_email, subject, template_id, substitutions) if response.status_code != 202: errors += ["email_delivery"] keys["errors"] = errors for error in errors: keys["error_{}".format(error)] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: registration.insert() template = fetch_template( "account/register-success.jinja.htm") keys["email"] = post_params["email"] http_server.set_status(200) http_server.print_headers() output = template.render(keys) print(output)
def handle_put_post(http_server, database_manager, session, account): if account.is_phone_verified != 1: redirect_to_phone_confirmation(http_server, database_manager, session, account) else: keys = {'current_page': "billing"} template = fetch_template("account/billing.jinja.htm") # http_server.print_headers() # print(dict(account)) subscription_plan_template = SubscriptionPlan(database_manager) subscription_conditions = [{ "column": "is_active", "equivalence": "=", "value": 1 }] subscription_plans = database_manager.fetch_by( subscription_plan_template, subscription_conditions) subscription_plan_name = None account_subscription_plan = None billing_profiles = [] for subscription_plan in subscription_plans: if subscription_plan.id == account.subscription_plan_id: subscription_plan_name = subscription_plan.name account_subscription_plan = subscription_plan billing_profiles.append({ "slug": subscription_plan.name, "name": subscription_plan.name.title(), "amount": subscription_plan.amount, "currency": subscription_plan.currency, "allowed_requests_per_month": subscription_plan.allowed_requests_per_month, "allowed_requests_per_month_printed": "{:,}".format(subscription_plan.allowed_requests_per_month), }) next_billing_date = account.get_next_billing_date() if account.stripe_subscription_id is not None and \ account.stripe_subscription_id != "": stripe.api_key = settings["stripe"]["secret_key"] stripe_subscription = stripe.Subscription.retrieve( account.stripe_subscription_id) next_billing_date = datetime.utcfromtimestamp( stripe_subscription.current_period_end) keys = { "current_page": "billing", "billing_profiles": billing_profiles, "current_plan_name": subscription_plan_name, "errors": [], "response": [], "billing_profile_name": account_subscription_plan.name.title(), "monthly_cost": "{:,.2f}".format(account_subscription_plan.amount), "currency": account_subscription_plan.currency, "billing_day": account.billing_day, "billing_day_ordinality": get_ordinality(account.billing_day), "next_billing_date": next_billing_date.strftime("%Y-%m-%d"), "max_api_calls": "{:,}".format( account_subscription_plan.allowed_requests_per_month), "selected_subscription_plan_name": account_subscription_plan.name } # new get post info errors = [] required_keys = [ "billing_id", ] post_params = http_server.get_post_parameters() if "billing_id" in post_params: if post_params["billing_id"] != "free": required_keys += ["stripe_token"] keys["response"] = post_params for required_key in required_keys: if required_key not in post_params or post_params[ required_key] == "": errors.append(required_key) if len(errors) == 0: subscription_plan_name = post_params["billing_id"] subscription_plan = SubscriptionPlan.fetch_by_name( database_manager, subscription_plan_name) if subscription_plan is None: errors.append("billing_id") keys["errors"] = errors for error in errors: keys["error_{}".format(error)] = True if len(errors) > 0: output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: if account.stripe_customer_id: stripe_subscription_id = account.stripe_subscription_id if account.stripe_subscription_id: try: subscription = stripe.Subscription.retrieve( account.stripe_subscription_id) subscription.delete() except: pass stripe_source_token = None stripe_subscription_id = None if subscription_plan.amount > 0: stripe.api_key = settings["stripe"]["secret_key"] stripe_plan = stripe.Plan.retrieve(subscription_plan.stripe_id) # How to acquire stripe tokens # https://stripe.com/docs/sources/cards stripe_source_token = post_params["stripe_token"] stripe_customer_description = account.email # will throw an exception if it fails. Must catch subscription = stripe.Subscription.create( customer=account.stripe_customer_id, items=[{ "plan": stripe_plan.id }]) stripe_subscription_id = subscription.id billing_epoch = datetime.now() account.subscription_plan_id = subscription_plan.id account.stripe_source_id = stripe_source_token account.stripe_subscription_id = stripe_subscription_id account.billing_interval = "monthly" account.billing_year = billing_epoch.year account.billing_month = billing_epoch.month account.billing_day = billing_epoch.day account.update() #keys["update_succeeded"] = True # retrieve updated subscription plan info subscription_plan_name = None account_subscription_plan = None billing_profiles = [] for subscription_plan in subscription_plans: if subscription_plan.id == account.subscription_plan_id: subscription_plan_name = subscription_plan.name account_subscription_plan = subscription_plan billing_profiles.append({ "slug": subscription_plan.name, "name": subscription_plan.name.title(), "amount": subscription_plan.amount, "currency": subscription_plan.currency, "allowed_requests_per_month": subscription_plan.allowed_requests_per_month, "allowed_requests_per_month_printed": "{:,}".format( subscription_plan.allowed_requests_per_month), }) next_billing_date = account.get_next_billing_date() if account.stripe_subscription_id is not None and \ account.stripe_subscription_id != "": stripe.api_key = settings["stripe"]["secret_key"] stripe_subscription = stripe.Subscription.retrieve( account.stripe_subscription_id) next_billing_date = datetime.utcfromtimestamp( stripe_subscription.current_period_end) keys = { 'current_page': "billing", "update_succeeded": True, "billing_profiles": billing_profiles, "current_plan_name": subscription_plan_name, "errors": [], "response": [], "billing_profile_name": account_subscription_plan.name.title(), "monthly_cost": "{:,.2f}".format(account_subscription_plan.amount), "currency": account_subscription_plan.currency, "billing_day": account.billing_day, "billing_day_ordinality": get_ordinality(account.billing_day), "next_billing_date": next_billing_date.strftime("%Y-%m-%d"), "max_api_calls": "{:,}".format( account_subscription_plan.allowed_requests_per_month), "selected_subscription_plan_name": account_subscription_plan.name } http_server.set_status(200) http_server.print_headers() output = template.render(keys) print(output)
def handle_get(http_server, database_manager, session, account): keys = { "current_page": "register" } template = fetch_template("account/confirm.jinja.htm") query_parameters = http_server.get_query_parameters() if "code" not in query_parameters: keys["no_code_provided"] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: code = query_parameters["code"] registration = AccountRegistration.fetch_by_confirmation_code( database_manager, code ) if registration is None: keys["invalid_code"] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: existing_account = Account.fetch_by_from_registration_id( database_manager, registration.id ) if existing_account is not None: keys["already_confirmed"] = True output = template.render(keys) # http_server.set_status(400) http_server.print_headers() print(output) else: account = Account.from_registration(registration) account.insert() if account.id is None or account.id < 1: account = Account.fetch_by_from_registration_id( database_manager, registration.id ) subscription = SubscriptionPlan.fetch_by_id( database_manager, account.subscription_plan_id ) if subscription is None: subscription = SubscriptionPlan.fetch_by_name( database_manager, "free" ) new_api_key = ApiKey(database_manager) new_api_key.generate_key() new_api_key.generate_secret() new_api_key.account_id = account.id new_api_key.update_plan(subscription) new_api_key.insert() # log in ip_string = http_server.get_remote_address() session = Session(database_manager) session.set_expiration_days_from_now( settings["confirm_page"]["session_timeout_days"] ) session_slug = session.generate_slug() session.account_id = account.id session.ip_address = ip_string session.slug = session_slug session.insert() http_server.set_cookie("session_id", session_slug) output = template.render(keys) http_server.print_headers() print(output)