Skip to content

Commit ee83b59

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

File tree

2 files changed

+294
-0
lines changed

2 files changed

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

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)