mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 12:08:05 +01:00
Support changing just the currency of an existing subscription
This commit is contained in:
@@ -358,11 +358,13 @@ public class BraintreeManager implements SubscriptionProcessorManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Long> getLevelForSubscription(Object subscriptionObj) {
|
||||
public CompletableFuture<LevelAndCurrency> getLevelAndCurrencyForSubscription(Object subscriptionObj) {
|
||||
final Subscription subscription = getSubscription(subscriptionObj);
|
||||
|
||||
return findPlan(subscription.getPlanId())
|
||||
.thenApply(this::getLevelForPlan);
|
||||
.thenApply(
|
||||
plan -> new LevelAndCurrency(getLevelForPlan(plan), plan.getCurrencyIsoCode().toLowerCase(Locale.ROOT)));
|
||||
|
||||
}
|
||||
|
||||
private CompletableFuture<Plan> findPlan(String planId) {
|
||||
|
||||
@@ -246,37 +246,37 @@ public class StripeManager implements SubscriptionProcessorManager {
|
||||
@Override
|
||||
public CompletableFuture<SubscriptionId> createSubscription(String customerId, String priceId, long level,
|
||||
long lastSubscriptionCreatedAt) {
|
||||
// this relies on Stripe's idempotency key to avoid creating more than one subscription if the client
|
||||
// retries this request
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
SubscriptionCreateParams params = SubscriptionCreateParams.builder()
|
||||
.setCustomer(customerId)
|
||||
.setOffSession(true)
|
||||
.setPaymentBehavior(SubscriptionCreateParams.PaymentBehavior.ERROR_IF_INCOMPLETE)
|
||||
.addItem(SubscriptionCreateParams.Item.builder()
|
||||
.setPrice(priceId)
|
||||
.build())
|
||||
.putMetadata(METADATA_KEY_LEVEL, Long.toString(level))
|
||||
.build();
|
||||
try {
|
||||
// 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
|
||||
// create a subscription, we want to ensure only one gets created.
|
||||
return Subscription.create(params, commonOptions(generateIdempotencyKeyForCreateSubscription(
|
||||
customerId, lastSubscriptionCreatedAt)));
|
||||
} catch (StripeException e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}, executor)
|
||||
.thenApply(subscription -> new SubscriptionId(subscription.getId()));
|
||||
.setPrice(priceId)
|
||||
.build())
|
||||
.putMetadata(METADATA_KEY_LEVEL, Long.toString(level))
|
||||
.build();
|
||||
try {
|
||||
// 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
|
||||
// create a subscription, we want to ensure only one gets created.
|
||||
return Subscription.create(params, commonOptions(generateIdempotencyKeyForCreateSubscription(
|
||||
customerId, lastSubscriptionCreatedAt)));
|
||||
} catch (StripeException e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}, executor)
|
||||
.thenApply(subscription -> new SubscriptionId(subscription.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<SubscriptionId> updateSubscription(
|
||||
Object subscriptionObj, String priceId, long level, String idempotencyKey) {
|
||||
|
||||
if (!(subscriptionObj instanceof final Subscription subscription)) {
|
||||
throw new IllegalArgumentException("invalid subscription object: " + subscriptionObj.getClass().getName());
|
||||
}
|
||||
final Subscription subscription = getSubscription(subscriptionObj);
|
||||
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
List<SubscriptionUpdateParams.Item> items = new ArrayList<>();
|
||||
@@ -400,12 +400,12 @@ public class StripeManager implements SubscriptionProcessorManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Long> getLevelForSubscription(Object subscriptionObj) {
|
||||
if (!(subscriptionObj instanceof final Subscription subscription)) {
|
||||
public CompletableFuture<LevelAndCurrency> getLevelAndCurrencyForSubscription(Object subscriptionObj) {
|
||||
final Subscription subscription = getSubscription(subscriptionObj);
|
||||
|
||||
throw new IllegalArgumentException("Invalid subscription object: " + subscriptionObj.getClass().getName());
|
||||
}
|
||||
return getProductForSubscription(subscription).thenApply(this::getLevelForProduct);
|
||||
return getProductForSubscription(subscription).thenApply(
|
||||
product -> new LevelAndCurrency(getLevelForProduct(product), subscription.getCurrency().toLowerCase(
|
||||
Locale.ROOT)));
|
||||
}
|
||||
|
||||
public CompletableFuture<Long> getLevelForPrice(Price price) {
|
||||
|
||||
@@ -42,12 +42,16 @@ public interface SubscriptionProcessorManager {
|
||||
CompletableFuture<Object> getSubscription(String subscriptionId);
|
||||
|
||||
CompletableFuture<SubscriptionId> createSubscription(String customerId, String templateId, long level,
|
||||
long lastSubscriptionCreatedAt);
|
||||
long lastSubscriptionCreatedAt);
|
||||
|
||||
CompletableFuture<SubscriptionId> updateSubscription(
|
||||
Object subscription, String templateId, long level, String idempotencyKey);
|
||||
|
||||
CompletableFuture<Long> getLevelForSubscription(Object subscription);
|
||||
/**
|
||||
* @param subscription
|
||||
* @return the subscription’s current level and lower-case currency code
|
||||
*/
|
||||
CompletableFuture<LevelAndCurrency> getLevelAndCurrencyForSubscription(Object subscription);
|
||||
|
||||
CompletableFuture<Void> cancelAllActiveSubscriptions(String customerId);
|
||||
|
||||
@@ -160,4 +164,8 @@ public interface SubscriptionProcessorManager {
|
||||
|
||||
}
|
||||
|
||||
record LevelAndCurrency(long level, String currency) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user