Skip to content

Commit 0e9e155

Browse files
committed
Add script to create 2025 plans
1 parent 2bb7dcf commit 0e9e155

File tree

2 files changed

+295
-0
lines changed

2 files changed

+295
-0
lines changed
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
package cmdpricing
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/spf13/cobra"
8+
"github.com/stripe/stripe-go/v72"
9+
"github.com/stripe/stripe-go/v72/client"
10+
11+
portalcmd "github.com/authgear/authgear-server/cmd/portal/cmd"
12+
portalconfig "github.com/authgear/authgear-server/pkg/portal/config"
13+
"github.com/authgear/authgear-server/pkg/util/cobrasentry"
14+
)
15+
16+
var Dollar int64 = 100
17+
var Cent int64 = 1
18+
19+
func createPlanProduct(api *client.API, logger Logger, planName string, planDisplayName string, price int64) error {
20+
params := &stripe.PriceParams{
21+
Currency: stripe.String(string(stripe.CurrencyUSD)),
22+
UnitAmount: stripe.Int64(price),
23+
TaxBehavior: stripe.String(string(stripe.PriceTaxBehaviorInclusive)),
24+
Recurring: &stripe.PriceRecurringParams{
25+
Interval: stripe.String(string(stripe.PriceRecurringIntervalMonth)),
26+
},
27+
ProductData: &stripe.PriceProductDataParams{
28+
Name: stripe.String(planDisplayName),
29+
Metadata: map[string]string{
30+
"plan_name": planName,
31+
"price_type": "fixed",
32+
"subscription_item_type": "plan",
33+
"version": "2025",
34+
},
35+
},
36+
}
37+
result, err := api.Prices.New(params)
38+
if err != nil {
39+
return err
40+
}
41+
42+
updateProductParams := &stripe.ProductParams{
43+
DefaultPrice: stripe.String(result.ID),
44+
}
45+
_, err = api.Products.Update(result.Product.ID, updateProductParams)
46+
if err != nil {
47+
return err
48+
}
49+
50+
logger.
51+
WithField("name", planDisplayName).
52+
WithField("product_id", result.Product.ID).
53+
Info("Created product")
54+
return nil
55+
}
56+
57+
func createSMSProduct(api *client.API, logger Logger, displayName, itemType string, smsRegion string, perUnitPrice int64) error {
58+
params := &stripe.PriceParams{
59+
Currency: stripe.String(string(stripe.CurrencyUSD)),
60+
TaxBehavior: stripe.String(string(stripe.PriceTaxBehaviorInclusive)),
61+
Recurring: &stripe.PriceRecurringParams{
62+
Interval: stripe.String(string(stripe.PriceRecurringIntervalMonth)),
63+
UsageType: stripe.String(string(stripe.PriceRecurringUsageTypeMetered)),
64+
AggregateUsage: stripe.String(string(stripe.PriceRecurringAggregateUsageSum)),
65+
},
66+
BillingScheme: stripe.String(string(stripe.PlanBillingSchemeTiered)),
67+
TiersMode: stripe.String(string(stripe.PlanTiersModeGraduated)),
68+
Tiers: []*stripe.PriceTierParams{
69+
{
70+
UnitAmount: stripe.Int64(perUnitPrice),
71+
UpToInf: stripe.Bool(true),
72+
},
73+
},
74+
ProductData: &stripe.PriceProductDataParams{
75+
Name: stripe.String(displayName),
76+
Metadata: map[string]string{
77+
"price_type": "usage",
78+
"subscription_item_type": itemType,
79+
"sms_region": smsRegion,
80+
"usage_type": "sms",
81+
"version": "2025",
82+
},
83+
},
84+
}
85+
result, err := api.Prices.New(params)
86+
if err != nil {
87+
return err
88+
}
89+
90+
updateProductParams := &stripe.ProductParams{
91+
DefaultPrice: stripe.String(result.ID),
92+
}
93+
_, err = api.Products.Update(result.Product.ID, updateProductParams)
94+
if err != nil {
95+
return err
96+
}
97+
98+
logger.
99+
WithField("name", displayName).
100+
WithField("product_id", result.Product.ID).
101+
Info("Created product")
102+
return nil
103+
}
104+
105+
func createWhatsappProduct(api *client.API, logger Logger, displayName, itemType string, whatsappRegion string, perUnitPrice int64) error {
106+
params := &stripe.PriceParams{
107+
Currency: stripe.String(string(stripe.CurrencyUSD)),
108+
TaxBehavior: stripe.String(string(stripe.PriceTaxBehaviorInclusive)),
109+
Recurring: &stripe.PriceRecurringParams{
110+
Interval: stripe.String(string(stripe.PriceRecurringIntervalMonth)),
111+
UsageType: stripe.String(string(stripe.PriceRecurringUsageTypeMetered)),
112+
AggregateUsage: stripe.String(string(stripe.PriceRecurringAggregateUsageSum)),
113+
},
114+
BillingScheme: stripe.String(string(stripe.PlanBillingSchemeTiered)),
115+
TiersMode: stripe.String(string(stripe.PlanTiersModeGraduated)),
116+
Tiers: []*stripe.PriceTierParams{
117+
{
118+
UnitAmount: stripe.Int64(perUnitPrice),
119+
UpToInf: stripe.Bool(true),
120+
},
121+
},
122+
ProductData: &stripe.PriceProductDataParams{
123+
Name: stripe.String(displayName),
124+
Metadata: map[string]string{
125+
"price_type": "usage",
126+
"subscription_item_type": itemType,
127+
"whatsapp_region": whatsappRegion,
128+
"usage_type": "whatsapp",
129+
"version": "2025",
130+
},
131+
},
132+
}
133+
result, err := api.Prices.New(params)
134+
if err != nil {
135+
return err
136+
}
137+
138+
updateProductParams := &stripe.ProductParams{
139+
DefaultPrice: stripe.String(result.ID),
140+
}
141+
_, err = api.Products.Update(result.Product.ID, updateProductParams)
142+
if err != nil {
143+
return err
144+
}
145+
146+
logger.
147+
WithField("name", displayName).
148+
WithField("product_id", result.Product.ID).
149+
Info("Created product")
150+
return nil
151+
}
152+
153+
func createMAUProduct(api *client.API, logger Logger, displayName, planName string, perGroupPrice, groupUnit, freeQuantity int64) error {
154+
params := &stripe.PriceParams{
155+
Params: stripe.Params{
156+
Metadata: map[string]string{
157+
"free_quantity": fmt.Sprint(freeQuantity),
158+
},
159+
},
160+
Currency: stripe.String(string(stripe.CurrencyUSD)),
161+
TaxBehavior: stripe.String(string(stripe.PriceTaxBehaviorInclusive)),
162+
Recurring: &stripe.PriceRecurringParams{
163+
Interval: stripe.String(string(stripe.PriceRecurringIntervalMonth)),
164+
UsageType: stripe.String(string(stripe.PriceRecurringUsageTypeMetered)),
165+
AggregateUsage: stripe.String(string(stripe.PriceRecurringAggregateUsageLastDuringPeriod)),
166+
},
167+
BillingScheme: stripe.String(string(stripe.PlanBillingSchemePerUnit)),
168+
UnitAmount: stripe.Int64(perGroupPrice),
169+
TransformQuantity: &stripe.PriceTransformQuantityParams{
170+
DivideBy: &groupUnit,
171+
Round: stripe.String(string(stripe.PriceTransformQuantityRoundUp)),
172+
},
173+
ProductData: &stripe.PriceProductDataParams{
174+
Name: stripe.String(displayName),
175+
Metadata: map[string]string{
176+
"plan_name": planName,
177+
"price_type": "usage",
178+
"subscription_item_type": "mau",
179+
"usage_type": "mau",
180+
"version": "2025",
181+
},
182+
},
183+
}
184+
result, err := api.Prices.New(params)
185+
if err != nil {
186+
return err
187+
}
188+
189+
updateProductParams := &stripe.ProductParams{
190+
DefaultPrice: stripe.String(result.ID),
191+
}
192+
_, err = api.Products.Update(result.Product.ID, updateProductParams)
193+
if err != nil {
194+
return err
195+
}
196+
197+
logger.
198+
WithField("name", displayName).
199+
WithField("product_id", result.Product.ID).
200+
Info("Created product")
201+
return nil
202+
}
203+
204+
var cmdPricingCreateStripePlans2025 = &cobra.Command{
205+
Use: "create-stripe-plans-2025",
206+
RunE: cobrasentry.RunEWrap(portalcmd.GetBinder, func(ctx context.Context, cmd *cobra.Command, args []string) (err error) {
207+
binder := portalcmd.GetBinder()
208+
209+
stripeSecretKey, err := binder.GetRequiredString(cmd, portalcmd.ArgStripeSecretKey)
210+
if err != nil {
211+
return
212+
}
213+
214+
stripeConfig := &portalconfig.StripeConfig{
215+
SecretKey: stripeSecretKey,
216+
}
217+
218+
hub := cobrasentry.GetHub(ctx)
219+
factory := cobrasentry.NewLoggerFactory(hub)
220+
logger := NewLogger(factory)
221+
222+
api := NewClientAPI(stripeConfig, logger)
223+
224+
err = createPlanProduct(api, logger,
225+
"developers2025", "Developers (2025)",
226+
50*Dollar,
227+
)
228+
if err != nil {
229+
return err
230+
}
231+
232+
err = createPlanProduct(api, logger,
233+
"business2025", "Business (2025)",
234+
500*Dollar,
235+
)
236+
if err != nil {
237+
return err
238+
}
239+
240+
err = createSMSProduct(api, logger,
241+
"SMS usage (North America) (2025)",
242+
"sms-north-america",
243+
"north-america",
244+
2*Cent,
245+
)
246+
if err != nil {
247+
return err
248+
}
249+
250+
err = createSMSProduct(api, logger,
251+
"SMS usage (Other regions) (2025)",
252+
"sms-other-region",
253+
"other-regions",
254+
10*Cent,
255+
)
256+
if err != nil {
257+
return err
258+
}
259+
260+
err = createWhatsappProduct(api, logger,
261+
"Whatsapp Usage (North America) (2025)",
262+
"whatsapp-north-america",
263+
"north-america",
264+
2*Cent,
265+
)
266+
if err != nil {
267+
return err
268+
}
269+
270+
err = createWhatsappProduct(api, logger,
271+
"Whatsapp Usage (Other regions) (2025)",
272+
"whatsapp-other-region",
273+
"other-regions",
274+
10*Cent,
275+
)
276+
if err != nil {
277+
return err
278+
}
279+
280+
err = createMAUProduct(api, logger,
281+
"Business Plan Additional MAU (2025)",
282+
"business2025",
283+
50*Dollar, 5000,
284+
25000,
285+
)
286+
if err != nil {
287+
return err
288+
}
289+
290+
return
291+
}),
292+
}

cmd/portal/cmd/cmdpricing/pricing.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ func init() {
5555
binder.BindString(cmdPricingAppUpdate.Flags(), portalcmd.ArgFeatureConfigFilePath)
5656
binder.BindString(cmdPricingAppUpdate.Flags(), portalcmd.ArgPlanNameForAppUpdate)
5757

58+
cmdPricing.AddCommand(cmdPricingCreateStripePlans2025)
59+
binder.BindString(cmdPricingCreateStripePlans2025.Flags(), portalcmd.ArgStripeSecretKey)
60+
5861
portalcmd.Root.AddCommand(cmdPricing)
5962
}
6063

0 commit comments

Comments
 (0)