What's the recommended way to manage features for a subscription plan?

I’d like to manage a list of features that are available for subscription plans to my SaaS service. Should I create a catalog item for each feature and link them to each plan variation? Curious how others are approaching this with Square.

:wave: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Catalog API
Square Developer
https://developer.squareup.com/docs/squarebridge/business-central/onboard

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

You can create a CatalogItem for each feature of your SaaS service and then create a CatalogItemVariation for each subscription plan that includes these features. This way, each CatalogItemVariation represents a specific combination of features (i.e., a specific plan).

For example, if you have a Basic plan and a Premium plan, you can create two CatalogItemVariation objects, one for each plan. Each CatalogItemVariation can then be linked to the CatalogItem objects that represent the features included in that plan.

This approach allows you to easily manage and track the features included in each plan, and it also allows you to leverage the Catalog API’s functionality for managing and organizing your product catalog.

This answer was reviewed by @Bryan-Square.

1 Like

So, along these lines?

def init(self):
        
        feature1_id = self.create_catalog_item("feature1")
        feature2_id = self.create_catalog_item("feature2")
        feature3_id = self.create_catalog_item("feature3")
        feature4_id = self.create_catalog_item("feature4")

        self.create_catalog_item_variations("Starter Feature", [feature1_id, feature2_id])
        self.create_catalog_item_variations("Premium Feature", [feature1_id, feature2_id, feature3_id])
        self.create_catalog_item_variations("Enterprise Feature", [feature1_id, feature2_id, feature3_id, feature4_id])
        
        starter_plan_id = self.create_subscription_plan("Starter")
        premium_plan_id = self.create_subscription_plan("Premium")
        enterprise_plan_id = self.create_subscription_plan("Enterprise")

        self.create_subscription_variation("Monthly", starter_plan_id, 14, "MONTHLY", 2000)
        self.create_subscription_variation("Annual", starter_plan_id, 14, "ANNUAL", 20000)
        
        self.create_subscription_variation("Monthly", premium_plan_id, 14, "MONTHLY", 10000)
        self.create_subscription_variation("Annual", premium_plan_id, 14, "ANNUAL", 10000)

        self.create_subscription_variation("Monthly", enterprise_plan_id, 14, "MONTHLY", 50000)
        self.create_subscription_variation("Annual", enterprise_plan_id, 14, "ANNUAL", 400000)

    def create_catalog_item(self, name: str):
        catalog_api : CatalogApi = self.client.catalog
        body = {
                    "idempotency_key": str(uuid4()),
                    "object": {
                        "id": "#item",
                        "type": "ITEM",
                        "item_data": {
                            "product_type": "DIGITAL",
                            "name": name,
                            "variations": [
                                {
                                    "id": "#var",
                                    "type": "ITEM_VARIATION",
                                    "item_variation_data": {
                                        "name": "Plan",
                                        "price_money": {
                                            "amount": 0,
                                            "currency": "USD"
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
        result = catalog_api.upsert_catalog_object(body)
        if result.is_error():
            errors = result.errors
        else:
            return result.body.get('catalog_object', {}).get('id', None)

    def create_catalog_item_variations(self, name: str, catalog_object_ids: list):
        catalog_api : CatalogApi = self.client.catalog
        for catalog_object_id in catalog_object_ids:
            body = {
                        "idempotency_key": str(uuid4()),
                        "object": {
                            "id": "#var",
                            "type": "ITEM_VARIATION",
                            "item_variation_data": 
                            {
                                "name": name,
                                "item_id": catalog_object_id,
                                "price_money": {
                                    "amount": 0,
                                    "currency": "USD"
                                }
                            }
                        }
                    }
            result = catalog_api.upsert_catalog_object(body)
            if result.is_error():
                errors = result.errors
            
    def create_subscription_plan(self, name: str):
        catalog_api : CatalogApi = self.client.catalog
        body = {
                "idempotency_key": str(uuid4()),
                "object": {
                    "type": "SUBSCRIPTION_PLAN",
                    "id": "#plan",
                    "subscription_plan_data": {
                        "name": name,
                        "all_items": False,
                    }
                }   
        }
        result = catalog_api.upsert_catalog_object(body)
        if result.is_error():
            errors = result.errors
        else:
            return result.body.get('catalog_object', {}).get('id', None)
        
    def create_subscription_variation(self, name: str, subscription_plan_id: str, trial_period: int, payment_cadence: str, payment_amount: int):
        catalog_api : CatalogApi = self.client.catalog
        body = {
                    "idempotency_key": str(uuid4()),
                    "object": {
                        "id": "#variation",
                        "type": "SUBSCRIPTION_PLAN_VARIATION",
                        "subscription_plan_variation_data": {
                            "name": name,
                            "subscription_plan_id": subscription_plan_id,
                            "phases": [{
                                    "cadence": "DAILY",
                                    "ordinal": 0,
                                    "periods": trial_period,
                                    "pricing": {
                                        "type": "STATIC",
                                        "price": {
                                            "amount": 0,
                                            "currency": "USD"
                                        }
                                    }
                                },
                                {
                                    "cadence": payment_cadence,
                                    "ordinal": 1,
                                    "pricing": {
                                        "type": "STATIC",
                                        "price": {
                                            "amount": payment_amount,
                                            "currency": "USD"
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
        result = catalog_api.upsert_catalog_object(body)
        if result.is_error():
            errors = result.errors
        else:
            return True