diff --git a/pom.xml b/pom.xml
index e386469b5..1ddf8211a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,6 +36,7 @@
2.9.0
2.0.22
1.1.13
+ 2.8.8
30.1.1-jre
2.3.1
2.9.0
@@ -53,6 +54,7 @@
1.5.0
3.1.0
1.7.30
+ 20.79.0
UTF-8
@@ -241,6 +243,16 @@
9.2
test
+
+ com.stripe
+ stripe-java
+ ${stripe.version}
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+
diff --git a/service/config/sample.yml b/service/config/sample.yml
index 5fe26335b..96497bfd9 100644
--- a/service/config/sample.yml
+++ b/service/config/sample.yml
@@ -1,3 +1,21 @@
+stripe:
+ apiKey:
+ idempotencyKeyGenerator:
+
+dynamoDbClientConfiguration:
+ region: # AWS Region
+
+dynamoDbTables:
+ issuedReceipts:
+ tableName: # DDB Table Name
+ expiration: # Duration of time until rows expire
+ generator: # random binary sequence
+ redeemedReceipts:
+ tableName: # DDB Table Name
+ expiration: # Duration of time until rows expire
+ subscriptions:
+ tableName: # DDB Table Name
+
twilio: # Twilio gateway configuration
accountId:
accountToken:
@@ -249,7 +267,6 @@ asnTable:
donation:
uri: # value
- apiKey: # value
supportedCurrencies:
- # 1st supported currency
- # 2nd supported currency
diff --git a/service/pom.xml b/service/pom.xml
index 6ffa1ca23..306da335d 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -449,6 +449,11 @@
google-cloud-recaptchaenterprise
+
+ com.stripe
+ stripe-java
+
+
pl.pragmatists
JUnitParams
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java
index 9ae7a5dec..2e347b1c1 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java
@@ -26,7 +26,9 @@ import org.whispersystems.textsecuregcm.configuration.DatadogConfiguration;
import org.whispersystems.textsecuregcm.configuration.DeletedAccountsDynamoDbConfiguration;
import org.whispersystems.textsecuregcm.configuration.DirectoryConfiguration;
import org.whispersystems.textsecuregcm.configuration.DonationConfiguration;
+import org.whispersystems.textsecuregcm.configuration.DynamoDbClientConfiguration;
import org.whispersystems.textsecuregcm.configuration.DynamoDbConfiguration;
+import org.whispersystems.textsecuregcm.configuration.DynamoDbTables;
import org.whispersystems.textsecuregcm.configuration.GcmConfiguration;
import org.whispersystems.textsecuregcm.configuration.GcpAttachmentsConfiguration;
import org.whispersystems.textsecuregcm.configuration.MaxDeviceConfiguration;
@@ -38,12 +40,13 @@ import org.whispersystems.textsecuregcm.configuration.PushConfiguration;
import org.whispersystems.textsecuregcm.configuration.RateLimitsConfiguration;
import org.whispersystems.textsecuregcm.configuration.RecaptchaConfiguration;
import org.whispersystems.textsecuregcm.configuration.RecaptchaV2Configuration;
-import org.whispersystems.textsecuregcm.configuration.RedeemedReceiptsDynamoDbConfiguration;
import org.whispersystems.textsecuregcm.configuration.RedisClusterConfiguration;
import org.whispersystems.textsecuregcm.configuration.RedisConfiguration;
import org.whispersystems.textsecuregcm.configuration.RemoteConfigConfiguration;
import org.whispersystems.textsecuregcm.configuration.SecureBackupServiceConfiguration;
import org.whispersystems.textsecuregcm.configuration.SecureStorageServiceConfiguration;
+import org.whispersystems.textsecuregcm.configuration.StripeConfiguration;
+import org.whispersystems.textsecuregcm.configuration.SubscriptionConfiguration;
import org.whispersystems.textsecuregcm.configuration.TestDeviceConfiguration;
import org.whispersystems.textsecuregcm.configuration.TurnConfiguration;
import org.whispersystems.textsecuregcm.configuration.TwilioConfiguration;
@@ -55,6 +58,21 @@ import org.whispersystems.websocket.configuration.WebSocketConfiguration;
/** @noinspection MismatchedQueryAndUpdateOfCollection, WeakerAccess */
public class WhisperServerConfiguration extends Configuration {
+ @NotNull
+ @Valid
+ @JsonProperty
+ private StripeConfiguration stripe;
+
+ @NotNull
+ @Valid
+ @JsonProperty
+ private DynamoDbClientConfiguration dynamoDbClientConfiguration;
+
+ @NotNull
+ @Valid
+ @JsonProperty
+ private DynamoDbTables dynamoDbTables;
+
@NotNull
@Valid
@JsonProperty
@@ -155,11 +173,6 @@ public class WhisperServerConfiguration extends Configuration {
@JsonProperty
private DynamoDbConfiguration deletedAccountsLockDynamoDb;
- @Valid
- @NotNull
- @JsonProperty
- private RedeemedReceiptsDynamoDbConfiguration redeemedReceiptsDynamoDb;
-
@Valid
@NotNull
@JsonProperty
@@ -300,8 +313,25 @@ public class WhisperServerConfiguration extends Configuration {
@JsonProperty
private BadgesConfiguration badges;
+ @Valid
+ @JsonProperty
+ // TODO: Mark as @NotNull when enabled for production.
+ private SubscriptionConfiguration subscription;
+
private Map transparentDataIndex = new HashMap<>();
+ public StripeConfiguration getStripe() {
+ return stripe;
+ }
+
+ public DynamoDbClientConfiguration getDynamoDbClientConfiguration() {
+ return dynamoDbClientConfiguration;
+ }
+
+ public DynamoDbTables getDynamoDbTables() {
+ return dynamoDbTables;
+ }
+
public RecaptchaConfiguration getRecaptchaConfiguration() {
return recaptcha;
}
@@ -398,10 +428,6 @@ public class WhisperServerConfiguration extends Configuration {
return deletedAccountsLockDynamoDb;
}
- public RedeemedReceiptsDynamoDbConfiguration getRedeemedReceiptsDynamoDbConfiguration() {
- return redeemedReceiptsDynamoDb;
- }
-
public DatabaseConfiguration getAbuseDatabaseConfiguration() {
return abuseDatabase;
}
@@ -515,4 +541,8 @@ public class WhisperServerConfiguration extends Configuration {
public BadgesConfiguration getBadges() {
return badges;
}
+
+ public SubscriptionConfiguration getSubscription() {
+ return subscription;
+ }
}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
index 77014ed16..f1fb4bde3 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
@@ -17,6 +17,7 @@ import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
import io.dropwizard.Application;
import io.dropwizard.auth.AuthFilter;
import io.dropwizard.auth.PolymorphicAuthDynamicFeature;
@@ -91,6 +92,7 @@ import org.whispersystems.textsecuregcm.controllers.RemoteConfigController;
import org.whispersystems.textsecuregcm.controllers.SecureBackupController;
import org.whispersystems.textsecuregcm.controllers.SecureStorageController;
import org.whispersystems.textsecuregcm.controllers.StickerController;
+import org.whispersystems.textsecuregcm.controllers.SubscriptionController;
import org.whispersystems.textsecuregcm.controllers.VoiceVerificationController;
import org.whispersystems.textsecuregcm.currency.CurrencyConversionManager;
import org.whispersystems.textsecuregcm.currency.FixerClient;
@@ -167,6 +169,7 @@ import org.whispersystems.textsecuregcm.storage.DirectoryReconciler;
import org.whispersystems.textsecuregcm.storage.DirectoryReconciliationClient;
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
import org.whispersystems.textsecuregcm.storage.FaultTolerantDatabase;
+import org.whispersystems.textsecuregcm.storage.IssuedReceiptsManager;
import org.whispersystems.textsecuregcm.storage.KeysDynamoDb;
import org.whispersystems.textsecuregcm.storage.MessagePersister;
import org.whispersystems.textsecuregcm.storage.MessagesCache;
@@ -185,9 +188,11 @@ import org.whispersystems.textsecuregcm.storage.ReportMessageDynamoDb;
import org.whispersystems.textsecuregcm.storage.ReportMessageManager;
import org.whispersystems.textsecuregcm.storage.ReservedUsernames;
import org.whispersystems.textsecuregcm.storage.StoredVerificationCodeManager;
+import org.whispersystems.textsecuregcm.storage.SubscriptionManager;
import org.whispersystems.textsecuregcm.storage.Usernames;
import org.whispersystems.textsecuregcm.storage.UsernamesManager;
import org.whispersystems.textsecuregcm.storage.VerificationCodeStore;
+import org.whispersystems.textsecuregcm.stripe.StripeManager;
import org.whispersystems.textsecuregcm.util.AsnManager;
import org.whispersystems.textsecuregcm.util.Constants;
import org.whispersystems.textsecuregcm.util.DynamoDbFromConfig;
@@ -250,10 +255,9 @@ public class WhisperServerService extends Application commonControllers = List.of(
+ final List