Example #1
0
def create_update_data(customer) -> Dict[str, Any]:
    """
    Provide readable data for customer update to display
    :param customer:
    :return: return_data dict
    """
    payment_sources = customer["sources"]["data"]
    return_data: Dict[str, Any] = dict()
    return_data["subscriptions"] = []

    return_data["payment_type"] = ""
    return_data["last4"] = ""
    return_data["exp_month"] = ""
    return_data["exp_year"] = ""

    if len(payment_sources) > 0:
        first_payment_source = payment_sources[0]
        return_data["payment_type"] = first_payment_source.get("funding")
        return_data["last4"] = first_payment_source.get("last4")
        return_data["exp_month"] = first_payment_source.get("exp_month")
        return_data["exp_year"] = first_payment_source.get("exp_year")

    products = {}  # type: Dict
    for subscription in customer["subscriptions"]["data"]:
        try:
            product = products[subscription["plan"]["product"]]
        except KeyError:
            product = Product.retrieve(subscription["plan"]["product"])
            products[subscription["plan"]["product"]] = product

        plan_name = format_plan_nickname(
            product_name=product["name"], plan_interval=subscription["plan"]["interval"]
        )

        if subscription["status"] == "incomplete":
            invoice = Invoice.retrieve(subscription["latest_invoice"])
            if invoice["charge"]:
                intents = Charge.retrieve(invoice["charge"])
                return_data["subscriptions"].append(
                    {
                        "current_period_end": subscription["current_period_end"],
                        "current_period_start": subscription["current_period_start"],
                        "ended_at": subscription["ended_at"],
                        "plan_name": plan_name,
                        "plan_id": subscription["plan"]["id"],
                        "status": subscription["status"],
                        "cancel_at_period_end": subscription["cancel_at_period_end"],
                        "subscription_id": subscription["id"],
                        "failure_code": intents["failure_code"],
                        "failure_message": intents["failure_message"],
                    }
                )
                continue

        return_data["cancel_at_period_end"] = subscription["cancel_at_period_end"]
        return_data["subscriptions"].append(
            create_subscription_object_without_failure(subscription, plan_name)
        )

    return return_data
Example #2
0
def _get_all_plans() -> List[Dict[str, str]]:
    plans = Plan.list(limit=100)
    logger.info("number of plans", count=len(plans))
    stripe_plans = []
    products = {}  # type: Dict
    for plan in plans:
        try:
            product = products[plan["product"]]
        except KeyError:
            product = Product.retrieve(plan["product"])
            products[plan["product"]] = product

        plan_name = format_plan_nickname(
            product_name=product["name"], plan_interval=plan["interval"]
        )

        stripe_plans.append(
            {
                "plan_id": plan["id"],
                "product_id": plan["product"],
                "interval": plan["interval"],
                "amount": plan["amount"],
                "currency": plan["currency"],
                "plan_name": plan_name,
                "product_name": product["name"],
            }
        )
    return stripe_plans
Example #3
0
    def create_payload(self) -> Dict[str, Any]:
        """
        Create payload to be sent to external sources
        :return payload:
        :raises InvalidRequestError:
        """
        try:
            invoice_data = self.payload.data.object.lines.data
            product = Product.retrieve(invoice_data[0]["plan"]["product"])
            nickname = format_plan_nickname(
                product_name=product["name"],
                plan_interval=invoice_data[0]["plan"]["interval"],
            )
        except InvalidRequestError as e:
            logger.error("Unable to get plan nickname for payload", error=e)
            nickname = ""

        return self.create_data(
            customer_id=self.payload.data.object.customer,
            subscription_id=self.payload.data.object.subscription,
            currency=self.payload.data.object.currency,
            charge_id=self.payload.data.object.charge,
            amount_due=self.payload.data.object.amount_due,
            created=self.payload.data.object.created,
            nickname=nickname,
        )
Example #4
0
def _get_all_plans():
    plans = Plan.list(limit=100)
    logger.info("number of plans", count=len(plans))
    stripe_plans = []
    for plan in plans:
        product = Product.retrieve(plan["product"])
        stripe_plans.append({
            "plan_id": plan["id"],
            "product_id": plan["product"],
            "interval": plan["interval"],
            "amount": plan["amount"],
            "currency": plan["currency"],
            "plan_name": plan["nickname"],
            "product_name": product["name"],
        })
    return stripe_plans
Example #5
0
def create_return_data(subscriptions) -> JsonDict:
    """
    Create json object subscriptions object
    :param subscriptions:
    :return: JSON data to be consumed by client.
    """
    return_data: Dict[str, Any] = {}
    return_data["subscriptions"] = []

    products = {}  # type: Dict
    for subscription in subscriptions["data"]:
        try:
            product = products[subscription["plan"]["product"]]
        except KeyError:
            product = Product.retrieve(subscription["plan"]["product"])
            products[subscription["plan"]["product"]] = product

        plan_name = format_plan_nickname(
            product_name=product["name"], plan_interval=subscription["plan"]["interval"]
        )

        if subscription["status"] == "incomplete":
            invoice = Invoice.retrieve(subscription["latest_invoice"])
            if invoice["charge"]:
                intents = Charge.retrieve(invoice["charge"])
                logger.debug("intents", intents=intents)

                return_data["subscriptions"].append(
                    {
                        "current_period_end": subscription["current_period_end"],
                        "current_period_start": subscription["current_period_start"],
                        "ended_at": subscription["ended_at"],
                        "plan_name": plan_name,
                        "plan_id": subscription["plan"]["id"],
                        "status": subscription["status"],
                        "subscription_id": subscription["id"],
                        "cancel_at_period_end": subscription["cancel_at_period_end"],
                        "failure_code": intents["failure_code"],
                        "failure_message": intents["failure_message"],
                    }
                )
                continue

        return_data["subscriptions"].append(
            create_subscription_object_without_failure(subscription, plan_name)
        )
    return return_data
Example #6
0
 def run(self):
     product = Product.retrieve(self.payload.data.plan.product)
     nickname = format_plan_nickname(
         product_name=product["name"],
         plan_interval=self.payload.data.plan.interval)
     data = self.create_data(
         customer_id=self.payload.data.object.id,
         subscription_created=self.payload.data.items.data[0].created,
         current_period_start=self.payload.data.current_period_start,
         current_period_end=self.payload.data.current_period_end,
         plan_amount=self.payload.data.plan.amount,
         plan_currency=self.payload.data.plan.currency,
         plan_name=nickname,
         created=self.payload.data.object.created,
     )
     logger.info("subscription created", data=data)
     routes = [StaticRoutes.SALESFORCE_ROUTE]
     self.send_to_routes(routes, json.dumps(data))
Example #7
0
def retrieve_stripe_product(product_id: str) -> Product:
    """
    Retrieve Stripe Product
    :param product_id:
    :return: Product
    """
    try:
        product = Product.retrieve(product_id)
        return product
    except (
            InvalidRequestError,
            APIConnectionError,
            APIError,
            RateLimitError,
            IdempotencyError,
            StripeErrorWithParamCode,
    ) as e:
        logger.error("retrieve product error", error=str(e))
        raise e
Example #8
0
def list_all_plans() -> FlaskListResponse:
    """
    List all available plans for a user to purchase.
    :return:
    """
    plans = Plan.list(limit=100)
    logger.info("number of plans", count=len(plans))
    stripe_plans = []
    for plan in plans:
        product = Product.retrieve(plan["product"])
        stripe_plans.append({
            "plan_id": plan["id"],
            "product_id": plan["product"],
            "interval": plan["interval"],
            "amount": plan["amount"],
            "currency": plan["currency"],
            "plan_name": plan["nickname"],
            "product_name": product["name"],
        })
    return stripe_plans, 200
Example #9
0
    def run(self) -> None:
        try:
            invoice_data = self.payload.data.object.lines.data

            product = Product.retrieve(invoice_data[0]["plan"]["product"])
            nickname = format_plan_nickname(
                product_name=product["name"],
                plan_interval=invoice_data[0]["plan"]["interval"],
            )
        except InvalidRequestError as e:
            nickname = ""
            logger.error("payment failed error", error=e)
        data = self.create_data(
            customer_id=self.payload.data.object.customer,
            subscription_id=self.payload.data.object.subscription,
            currency=self.payload.data.object.currency,
            charge_id=self.payload.data.object.charge,
            amount_due=self.payload.data.object.amount_due,
            created=self.payload.data.object.created,
            nickname=nickname,
        )
        logger.info("invoice payment failed", data=data)
        routes = [StaticRoutes.SALESFORCE_ROUTE]
        self.send_to_routes(routes, json.dumps(data))
Example #10
0
def delete_customer(uid: str) -> FlaskResponse:
    """
    Delete an existing customer, cancel active subscriptions
    and delete from payment provider
    :param uid:
    :return: Success of failure message for the deletion
    """
    logger.info("delete customer", uid=uid)
    subscription_user = g.subhub_account.get_user(uid)
    logger.info("delete customer", subscription_user=subscription_user)
    if subscription_user is not None:
        origin = subscription_user.origin_system
        logger.info("delete origin", origin=origin)
        if not subscription_user:
            return dict(message="Customer does not exist."), 404
        subscribed_customer = vendor.retrieve_stripe_customer(
            subscription_user.cust_id)
        subscribed_customer = subscribed_customer.to_dict()
        subscription_info: List = []
        logger.info(
            "subscribed customer",
            subscribed_customer=subscribed_customer,
            data_type=type(subscribed_customer),
        )

        products = {}  # type: Dict
        for subs in subscribed_customer["subscriptions"]["data"]:
            try:
                product = products[subs.plan.product]
            except KeyError:
                product = Product.retrieve(subs.plan.product)
                products[subs.plan.product] = product
            plan_id = subs.plan.product

            sub = dict(
                plan_amount=subs.plan.amount,
                nickname=format_plan_nickname(subs.plan.nickname,
                                              subs.plan.interval),
                productId=plan_id,
                current_period_end=subs.current_period_end,
                current_period_start=subs.current_period_start,
                subscription_id=subs.id,
            )
            subscription_info.append(sub)
            vendor.cancel_stripe_subscription_immediately(
                subs.id, utils.get_indempotency_key())
            data = dict(
                uid=subscribed_customer["metadata"]["userid"],
                active=False,
                subscriptionId=subs.id,
                productId=plan_id,
                eventId=utils.get_indempotency_key(),
                eventCreatedAt=int(time.time()),
                messageCreatedAt=int(time.time()),
            )
            sns_message = Message(json.dumps(data)).route()
            logger.info("delete message", sns_message=sns_message)
        else:
            deleted_payment_customer = vendor.delete_stripe_customer(
                subscription_user.cust_id)
            if deleted_payment_customer:
                deleted_customer = delete_user(
                    user_id=subscribed_customer["metadata"]["userid"],
                    cust_id=subscribed_customer["id"],
                    origin_system=origin,
                    subscription_info=subscription_info,
                )
                user = g.subhub_account.get_user(uid)
                if deleted_customer and user is None:
                    return dict(message="Customer deleted successfully"), 200
    return dict(message="Customer not available"), 400