Exemplo n.º 1
0
def cancel_subscription(uid: str, sub_id: str) -> 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 dict(message="Customer does not exist."), 404

    for item in customer["subscriptions"]["data"]:
        if item["id"] == sub_id and item["status"] in [
                "active",
                "trialing",
                "incomplete",
        ]:
            vendor.cancel_stripe_subscription_period_end(
                sub_id, utils.get_indempotency_key())
            updated_customer = fetch_customer(g.subhub_account, uid)
            logger.info("updated customer", updated_customer=updated_customer)
            subs = retrieve_stripe_subscriptions(updated_customer)
            logger.info("subs", subs=subs, type=type(subs))
            for sub in subs:
                if sub["cancel_at_period_end"] and sub["id"] == sub_id:
                    return {
                        "message": "Subscription cancellation successful"
                    }, 201

    return dict(message="Subscription not available."), 400
Exemplo n.º 2
0
def subscribe_to_plan(uid: str, data: Dict[str, Any]) -> 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["origin_system"],
        display_name=data["display_name"],
    )
    existing_plan = has_existing_plan(customer, plan_id=data["plan_id"])
    if existing_plan:
        return dict(message="User already subscribed."), 409

    if not customer.get("deleted"):
        vendor.build_stripe_subscription(customer.id, data["plan_id"],
                                         utils.get_indempotency_key())
        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

    return dict(message=None), 400
Exemplo n.º 3
0
def customer_update(uid) -> tuple:
    """
    Provide latest data for a given user
    :param uid:
    :return: return_data dict with credit card info and subscriptions
    """
    customer = fetch_customer(g.subhub_account, uid)
    if not customer:
        response_message = dict(message="Customer does not exist.")
        logger.debug("customer update",
                     response_message=response_message,
                     response_code=404)
        return response_message, 404
    metadata = customer.get("metadata", None)
    if metadata:
        if metadata.get("userid", None) == uid:
            return_data = create_update_data(customer)
            logger.debug("customer update",
                         response_message=return_data,
                         response_code=200)
            return return_data, 200
    response_message = dict(message="Customer mismatch.")
    logger.debug("customer update",
                 response_message=response_message,
                 response_code=400)
    return response_message, 400
Exemplo n.º 4
0
    def test_fetch_customer_success(self):
        self.retrieve_stripe_customer_mock.return_value = self.customer1
        subhub_account = self.subhub_account_mock("table", "region")
        subhub_account.get_user.return_value = self.subhub_user

        customer = fetch_customer(subhub_account, "user_1")

        assert customer == self.customer1
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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 dict(message="Customer does not exist."), 404

        if customer["metadata"]["userid"] == uid:
            return_data = create_update_data(customer)
            return return_data, 200

        return dict(message="Customer mismatch."), 400
    except KeyError as e:
        logger.error("Customer does not exist", error=e)
        return dict(message=f"Customer does not exist: missing {e}"), 404
Exemplo n.º 7
0
def reactivate_subscription(uid: str, sub_id: str) -> FlaskResponse:
    """
    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:
        response_message = dict(message="Customer does not exist.")
        logger.debug("reactivate subscription",
                     response_message=response_message)
        return response_message, 404

    active_subscriptions = customer["subscriptions"]["data"]
    response_message = dict(message="Current subscription not found.")
    for subscription in active_subscriptions:
        if subscription["id"] == sub_id:
            response_message = dict(message="Subscription is already active.")
            if subscription["cancel_at_period_end"]:
                reactivate_stripe_subscription(sub_id,
                                               utils.get_indempotency_key())
                response_message = dict(
                    message="Subscription reactivation was successful.")
                logger.debug(
                    "reactivate subscription",
                    response_message=response_message,
                    response_code=200,
                )
                return response_message, 200
            logger.debug(
                "reactivate subscription",
                response_message=response_message,
                response_code=200,
            )
            return response_message, 200
    logger.debug("reactivate subscription",
                 response_message=response_message,
                 response_code=404)
    return response_message, 404
Exemplo n.º 8
0
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)
    logger.info("customer", customer=customer)
    if not customer:
        return dict(message="Customer does not exist."), 404

    metadata = customer.get("metadata")
    logger.info("metadata", metadata=metadata, customer=type(customer))
    if metadata:
        if metadata["userid"] == uid:
            Customer.modify(customer.id, source=data["pmt_token"])
            return {"message": "Payment method updated successfully."}, 201

    return dict(message="Customer mismatch."), 400
Exemplo n.º 9
0
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)
    logger.debug("customer", customer=customer)
    if not customer:
        response_message = dict(message="Customer does not exist.")
        logger.debug(
            "update payment method",
            response_message=response_message,
            response_code=404,
        )
        return response_message, 404

    metadata = customer.get("metadata")
    logger.debug("metadata", metadata=metadata, customer=type(customer))
    if metadata:
        if metadata.get("userid", None) == uid:
            modify_customer(
                customer_id=customer.id,
                source_token=data["pmt_token"],
                idempotency_key=utils.get_indempotency_key(),
            )
            response_message = dict(
                message="Payment method updated successfully.")
            logger.debug(
                "update payment method",
                response_message=response_message,
                response_code=201,
            )
            return response_message, 201
    response_message = dict(message="Customer mismatch.")
    logger.debug("update payment method",
                 response_message=response_message,
                 response_code=400)
    return response_message, 400
Exemplo n.º 10
0
def reactivate_subscription(uid: str, sub_id: str) -> FlaskResponse:
    """
    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 dict(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 dict(message="Subscription reactivation was successful."), 200
            return dict(message="Subscription is already active."), 200

    return dict(message="Current subscription not found."), 404
Exemplo n.º 11
0
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
Exemplo n.º 12
0
    def test_fetch_customer_failure(self):
        subhub_account = self.subhub_account_mock("table", "region")
        subhub_account.get_user.return_value = None

        customer = fetch_customer(subhub_account, "user_1")
        assert customer is None