Use last subscription created at time as a subscription generation number
This commit is contained in:
parent
c0837104cd
commit
8b8c6237be
|
@ -305,11 +305,12 @@ public class SubscriptionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record.subscriptionId == null) {
|
if (record.subscriptionId == null) {
|
||||||
|
long lastSubscriptionCreatedAt = record.subscriptionCreatedAt != null ? record.subscriptionCreatedAt.getEpochSecond() : 0;
|
||||||
// we don't have one yet so create it and then record the subscription id
|
// we don't have one yet so create it and then record the subscription id
|
||||||
//
|
//
|
||||||
// this relies on stripe's idempotency key to avoid creating more than one subscription if the client
|
// this relies on stripe's idempotency key to avoid creating more than one subscription if the client
|
||||||
// retries this request
|
// retries this request
|
||||||
return stripeManager.createSubscription(record.customerId, priceConfiguration.getId(), level)
|
return stripeManager.createSubscription(record.customerId, priceConfiguration.getId(), level, lastSubscriptionCreatedAt)
|
||||||
.thenCompose(subscription -> subscriptionManager.subscriptionCreated(
|
.thenCompose(subscription -> subscriptionManager.subscriptionCreated(
|
||||||
requestData.subscriberUser, subscription.getId(), requestData.now, level)
|
requestData.subscriberUser, subscription.getId(), requestData.now, level)
|
||||||
.thenApply(unused -> subscription));
|
.thenApply(unused -> subscription));
|
||||||
|
|
|
@ -50,6 +50,7 @@ import javax.annotation.Nullable;
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.whispersystems.textsecuregcm.util.Conversions;
|
||||||
|
|
||||||
public class StripeManager {
|
public class StripeManager {
|
||||||
|
|
||||||
|
@ -139,7 +140,7 @@ public class StripeManager {
|
||||||
}, executor);
|
}, executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Subscription> createSubscription(String customerId, String priceId, long level) {
|
public CompletableFuture<Subscription> createSubscription(String customerId, String priceId, long level, long lastSubscriptionCreatedAt) {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
SubscriptionCreateParams params = SubscriptionCreateParams.builder()
|
SubscriptionCreateParams params = SubscriptionCreateParams.builder()
|
||||||
.setCustomer(customerId)
|
.setCustomer(customerId)
|
||||||
|
@ -152,9 +153,9 @@ public class StripeManager {
|
||||||
// the idempotency key intentionally excludes priceId
|
// the idempotency key intentionally excludes priceId
|
||||||
//
|
//
|
||||||
// If the client tells the server several times in a row before the initial creation of a subscription to
|
// If the client tells the server several times in a row before the initial creation of a subscription to
|
||||||
// create a subscription, we want to ensure only one gets created. If the prices are different each time,
|
// create a subscription, we want to ensure only one gets created.
|
||||||
// whichever one gets to stripe first will win (depending on how idempotent the idempotency keys are...)
|
return Subscription.create(params, commonOptions(generateIdempotencyKeyForCreateSubscription(
|
||||||
return Subscription.create(params, commonOptions(generateIdempotencyKeyForCustomerId(customerId)));
|
customerId, lastSubscriptionCreatedAt)));
|
||||||
} catch (StripeException e) {
|
} catch (StripeException e) {
|
||||||
throw new CompletionException(e);
|
throw new CompletionException(e);
|
||||||
}
|
}
|
||||||
|
@ -332,8 +333,11 @@ public class StripeManager {
|
||||||
return generateIdempotencyKey("subscriberUser", mac -> mac.update(subscriberUser));
|
return generateIdempotencyKey("subscriberUser", mac -> mac.update(subscriberUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateIdempotencyKeyForCustomerId(String customerId) {
|
private String generateIdempotencyKeyForCreateSubscription(String customerId, long lastSubscriptionCreatedAt) {
|
||||||
return generateIdempotencyKey("customerId", mac -> mac.update(customerId.getBytes(StandardCharsets.UTF_8)));
|
return generateIdempotencyKey("customerId", mac -> {
|
||||||
|
mac.update(customerId.getBytes(StandardCharsets.UTF_8));
|
||||||
|
mac.update(Conversions.longToByteArray(lastSubscriptionCreatedAt));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateIdempotencyKey(String type, Consumer<Mac> byteConsumer) {
|
private String generateIdempotencyKey(String type, Consumer<Mac> byteConsumer) {
|
||||||
|
|
Loading…
Reference in New Issue