Skip to content

Commit 9a9ee1f

Browse files
committed
[installer][server] Make Stripe usage-based product price IDs configurable
1 parent 28f48ac commit 9a9ee1f

File tree

5 files changed

+53
-28
lines changed

5 files changed

+53
-28
lines changed

components/server/ee/src/user/stripe-service.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,15 @@ export class StripeService {
116116
}
117117

118118
async createSubscriptionForCustomer(customerId: string, currency: Currency): Promise<void> {
119-
// FIXME(janx): Use configmap.
120-
const prices = {
121-
EUR: "price_1LAE0AGadRXm50o3xjegX0Kd",
122-
USD: "price_1LAE0AGadRXm50o3rKoktPiJ",
123-
};
119+
const priceId = this.config?.stripeConfig?.usageProductPriceIds[currency];
120+
if (!priceId) {
121+
throw new Error(`No Stripe Price ID configured for currency '${currency}'`);
122+
}
124123
const startOfNextMonth = new Date(new Date().toISOString().slice(0, 7) + "-01"); // First day of this month (YYYY-MM-01)
125124
startOfNextMonth.setMonth(startOfNextMonth.getMonth() + 1); // Add one month
126125
await this.getStripe().subscriptions.create({
127126
customer: customerId,
128-
items: [{ price: prices[currency] }],
127+
items: [{ price: priceId }],
129128
billing_cycle_anchor: Math.round(startOfNextMonth.getTime() / 1000),
130129
});
131130
}

components/server/src/config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@ import { filePathTelepresenceAware } from "@gitpod/gitpod-protocol/lib/env";
2020
export const Config = Symbol("Config");
2121
export type Config = Omit<
2222
ConfigSerialized,
23-
"blockedRepositories" | "hostUrl" | "chargebeeProviderOptionsFile" | "stripeSecretsFile" | "licenseFile"
23+
| "blockedRepositories"
24+
| "hostUrl"
25+
| "chargebeeProviderOptionsFile"
26+
| "stripeSecretsFile"
27+
| "stripeConfig"
28+
| "licenseFile"
2429
> & {
2530
hostUrl: GitpodHostUrl;
2631
workspaceDefaults: WorkspaceDefaults;
2732
chargebeeProviderOptions?: ChargebeeProviderOptions;
2833
stripeSecrets?: { publishableKey: string; secretKey: string };
34+
stripeConfig?: { usageProductPriceIds: { EUR: string; USD: string } };
2935
builtinAuthProvidersConfigured: boolean;
3036
blockedRepositories: { urlRegExp: RegExp; blockUser: boolean }[];
3137
inactivityPeriodForRepos?: number;
@@ -152,6 +158,7 @@ export interface ConfigSerialized {
152158
*/
153159
chargebeeProviderOptionsFile?: string;
154160
stripeSecretsFile?: string;
161+
stripeConfig?: { usageProductPriceIds: { EUR: string; USD: string } };
155162
enablePayment?: boolean;
156163

157164
/**

install/installer/pkg/components/server/configmap.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
9999
return nil
100100
})
101101

102+
var stripeConfig StripeConfig
103+
_ = ctx.WithExperimental(func(cfg *experimental.Config) error {
104+
if cfg.WebApp != nil && cfg.WebApp.Server != nil {
105+
stripeConfig = cfg.WebApp.Server.StripeConfig
106+
}
107+
return nil
108+
})
109+
102110
disableWsGarbageCollection := false
103111
_ = ctx.WithExperimental(func(cfg *experimental.Config) error {
104112
if cfg.WebApp != nil && cfg.WebApp.Server != nil {
@@ -219,6 +227,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
219227
EnablePayment: chargebeeSecret != "" || stripeSecret != "",
220228
ChargebeeProviderOptionsFile: fmt.Sprintf("%s/providerOptions", chargebeeMountPath),
221229
StripeSecretsFile: fmt.Sprintf("%s/apikeys", stripeMountPath),
230+
StripeConfig: stripeConfig,
222231
InsecureNoDomain: false,
223232
PrebuildLimiter: map[string]int{
224233
// default limit for all cloneURLs

install/installer/pkg/components/server/types.go

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,28 @@ import (
1313

1414
// ConfigSerialized interface from components/server/src/config.ts
1515
type ConfigSerialized struct {
16-
Version string `json:"version"`
17-
HostURL string `json:"hostUrl"`
18-
InstallationShortname string `json:"installationShortname"`
19-
DevBranch string `json:"devBranch"`
20-
InsecureNoDomain bool `json:"insecureNoDomain"`
21-
License string `json:"license"`
22-
LicenseFile string `json:"licenseFile"`
23-
DefinitelyGpDisabled bool `json:"definitelyGpDisabled"`
24-
EnableLocalApp bool `json:"enableLocalApp"`
25-
DisableDynamicAuthProviderLogin bool `json:"disableDynamicAuthProviderLogin"`
26-
MaxEnvvarPerUserCount int32 `json:"maxEnvvarPerUserCount"`
27-
MaxConcurrentPrebuildsPerRef int32 `json:"maxConcurrentPrebuildsPerRef"`
28-
MakeNewUsersAdmin bool `json:"makeNewUsersAdmin"`
29-
DefaultBaseImageRegistryWhitelist []string `json:"defaultBaseImageRegistryWhitelist"`
30-
RunDbDeleter bool `json:"runDbDeleter"`
31-
ContentServiceAddr string `json:"contentServiceAddr"`
32-
ImageBuilderAddr string `json:"imageBuilderAddr"`
33-
VSXRegistryUrl string `json:"vsxRegistryUrl"`
34-
ChargebeeProviderOptionsFile string `json:"chargebeeProviderOptionsFile"`
35-
StripeSecretsFile string `json:"stripeSecretsFile"`
36-
EnablePayment bool `json:"enablePayment"`
16+
Version string `json:"version"`
17+
HostURL string `json:"hostUrl"`
18+
InstallationShortname string `json:"installationShortname"`
19+
DevBranch string `json:"devBranch"`
20+
InsecureNoDomain bool `json:"insecureNoDomain"`
21+
License string `json:"license"`
22+
LicenseFile string `json:"licenseFile"`
23+
DefinitelyGpDisabled bool `json:"definitelyGpDisabled"`
24+
EnableLocalApp bool `json:"enableLocalApp"`
25+
DisableDynamicAuthProviderLogin bool `json:"disableDynamicAuthProviderLogin"`
26+
MaxEnvvarPerUserCount int32 `json:"maxEnvvarPerUserCount"`
27+
MaxConcurrentPrebuildsPerRef int32 `json:"maxConcurrentPrebuildsPerRef"`
28+
MakeNewUsersAdmin bool `json:"makeNewUsersAdmin"`
29+
DefaultBaseImageRegistryWhitelist []string `json:"defaultBaseImageRegistryWhitelist"`
30+
RunDbDeleter bool `json:"runDbDeleter"`
31+
ContentServiceAddr string `json:"contentServiceAddr"`
32+
ImageBuilderAddr string `json:"imageBuilderAddr"`
33+
VSXRegistryUrl string `json:"vsxRegistryUrl"`
34+
ChargebeeProviderOptionsFile string `json:"chargebeeProviderOptionsFile"`
35+
StripeSecretsFile string `json:"stripeSecretsFile"`
36+
StripeConfig StripeConfig `json:"stripeConfig"`
37+
EnablePayment bool `json:"enablePayment"`
3738

3839
WorkspaceHeartbeat WorkspaceHeartbeat `json:"workspaceHeartbeat"`
3940
WorkspaceDefaults WorkspaceDefaults `json:"workspaceDefaults"`
@@ -119,6 +120,10 @@ type Session struct {
119120
Secret string `json:"secret"`
120121
}
121122

123+
type StripeConfig struct {
124+
UsageProductPriceIDs map[string]string `json:"usageProductPriceIds"`
125+
}
126+
122127
type WorkspaceHeartbeat struct {
123128
IntervalSeconds int32 `json:"intervalSeconds"`
124129
TimeoutSeconds int32 `json:"timeoutSeconds"`

install/installer/pkg/config/v1/experimental/experimental.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ type ServerConfig struct {
140140
GithubApp *GithubApp `json:"githubApp"`
141141
ChargebeeSecret string `json:"chargebeeSecret"`
142142
StripeSecret string `json:"stripeSecret"`
143+
StripeConfig StripeConfig `json:"stripeConfig"`
143144
DisableDynamicAuthProviderLogin bool `json:"disableDynamicAuthProviderLogin"`
144145
EnableLocalApp *bool `json:"enableLocalApp"`
145146
RunDbDeleter *bool `json:"runDbDeleter"`
@@ -177,6 +178,10 @@ type IDEProxyConfig struct {
177178
ServiceAnnotations map[string]string `json:"serviceAnnotations"`
178179
}
179180

181+
type StripeConfig struct {
182+
UsageProductPriceIDs map[string]string `json:"usageProductPriceIds"`
183+
}
184+
180185
type VSXProxyConfig struct {
181186
ServiceAnnotations map[string]string `json:"serviceAnnotations"`
182187
}

0 commit comments

Comments
 (0)