def cancel_subscription(uid, sub_id) -> FlaskResponse: """ Cancel an existing subscription for a user. :param uid: :param sub_id: :return: Success or failure message for the cancellation. """ customer = fetch_customer(g.subhub_account, uid) if not customer: return {"message": "Customer does not exist."}, 404 for item in customer["subscriptions"]["data"]: if item["id"] == sub_id and item["status"] in [ "active", "trialing", "incomplete", ]: Subscription.modify(sub_id, cancel_at_period_end=True) updated_customer = fetch_customer(g.subhub_account, uid) subs = retrieve_stripe_subscriptions(updated_customer) for sub in subs: if sub["cancel_at_period_end"] and sub["id"] == sub_id: return { "message": "Subscription cancellation successful" }, 201 return {"message": "Subscription not available."}, 400
def test_fetch_customer_missing_stripe(monkeypatch): """ GIVEN a valid user_id that maps to an deleted customer account WHEN a user attempts to fetch a customer THEN None is returned """ subhub_account = MagicMock() get_user = MagicMock() user_id = PropertyMock(return_value="user123") cust_id = PropertyMock(return_value="cust123") type(get_user).user_id = user_id type(get_user).cust_id = cust_id remove_from_db = MagicMock(return_value=None) subhub_account.get_user = get_user subhub_account.remove_from_db = remove_from_db mock_customer = MagicMock(return_value={"id": "cust123", "deleted": True}) monkeypatch.setattr("stripe.Customer.retrieve", mock_customer) customer = fetch_customer(subhub_account, "user123") assert customer is None
def subscribe_to_plan(uid, data) -> FlaskResponse: """ Subscribe to a plan given a user id, payment token, email, orig_system :param uid: :param data: :return: current subscriptions for user. """ customer = existing_or_new_customer( g.subhub_account, user_id=uid, email=data["email"], source_token=data["pmt_token"], origin_system=data["orig_system"], display_name=data["display_name"], ) existing_plan = has_existing_plan(customer, plan_id=data["plan_id"]) if existing_plan: return {"message": "User already subscribed."}, 409 if not customer.get("deleted"): Subscription.create(customer=customer.id, items=[{ "plan": data["plan_id"] }]) updated_customer = fetch_customer(g.subhub_account, user_id=uid) newest_subscription = find_newest_subscription( updated_customer["subscriptions"]) return create_return_data(newest_subscription), 201 else: return dict(message=None), 400
def test_fetch_customer_no_account(monkeypatch): """ GIVEN an invalid user_id WHEN a user attempts to fetch a customer THEN None is returned """ subhub_account = MagicMock() get_user = MagicMock(return_value=None) subhub_account.get_user = get_user customer = fetch_customer(subhub_account, "user123") assert customer is None
def update_payment_method(uid, data) -> FlaskResponse: """ Given a user id and a payment token, update user's payment method :param uid: :param data: :return: Success or failure message. """ customer = fetch_customer(g.subhub_account, uid) if not customer: return {"message": "Customer does not exist."}, 404 if customer["metadata"]["userid"] == uid: customer.modify(customer.id, source=data["pmt_token"]) return {"message": "Payment method updated successfully."}, 201 else: return {"message": "Customer mismatch."}, 400
def customer_update(uid) -> tuple: """ Provide latest data for a given user :param uid: :return: return_data dict with credit card info and subscriptions """ try: customer = fetch_customer(g.subhub_account, uid) if not customer: return "Customer does not exist.", 404 if customer["metadata"]["userid"] == uid: return_data = create_update_data(customer) return return_data, 200 else: return "Customer mismatch.", 400 except KeyError as e: logger.error("Customer does not exist", error=e) return {"message": f"Customer does not exist: missing {e}"}, 404
def reactivate_subscription(uid, sub_id): """ Given a user's subscription that is flagged for cancellation, but is still active remove the cancellation flag to ensure the subscription remains active :param uid: User ID :param sub_id: Subscription ID :return: Success or failure message for the activation """ customer = fetch_customer(g.subhub_account, uid) if not customer: return {"message": "Customer does not exist."}, 404 active_subscriptions = customer["subscriptions"]["data"] for subscription in active_subscriptions: if subscription["id"] == sub_id: if subscription["cancel_at_period_end"]: Subscription.modify(sub_id, cancel_at_period_end=False) return { "message": "Subscription reactivation was successful." }, 200 return {"message": "Subscription is already active."}, 200 return {"message": "Current subscription not found."}, 404
def test_fetch_customer_success(monkeypatch): """ GIVEN a valid user_id that maps to a valid customer account WHEN a user attempts to fetch a customer THEN that customer is returned """ subhub_account = MagicMock() get_user = MagicMock() user_id = PropertyMock(return_value="user123") cust_id = PropertyMock(return_value="cust123") type(get_user).user_id = user_id type(get_user).cust_id = cust_id subhub_account.get_user = get_user mock_customer = MagicMock(return_value={"id": "cust123", "deleted": False}) monkeypatch.setattr("stripe.Customer.retrieve", mock_customer) customer = fetch_customer(subhub_account, "user123") assert customer is not None