set billingCycleAnchor in play billing responses

This commit is contained in:
Ravi Khadiwala 2024-09-05 18:07:56 -05:00 committed by ravi-signal
parent 3e51366921
commit 9fb4e2d272
2 changed files with 16 additions and 5 deletions

View File

@ -527,7 +527,7 @@ public class SubscriptionController {
long level,
@Schema(
description = "If present, UNIX Epoch Timestamp in seconds, can be used to calculate next billing date. May be absent for IAP subscriptions",
description = "If present, UNIX Epoch Timestamp in seconds, can be used to calculate next billing date.",
externalDocs = @ExternalDocumentation(description = "Calculate next billing date", url = "https://stripe.com/docs/billing/subscriptions/billing-cycle"))
Instant billingCycleAnchor,

View File

@ -230,6 +230,7 @@ public class GooglePlayBillingManager implements SubscriptionPaymentProcessor {
return subscriptionFuture.thenCombineAsync(priceFuture, (subscription, price) -> {
final SubscriptionPurchaseLineItem lineItem = getLineItem(subscription);
final Optional<Instant> billingCycleAnchor = getStartTime(subscription);
final Optional<Instant> expiration = getExpiration(lineItem);
final SubscriptionStatus status = switch (SubscriptionState
@ -246,7 +247,8 @@ public class GooglePlayBillingManager implements SubscriptionPaymentProcessor {
return new SubscriptionInformation(
price,
productIdToLevel(lineItem.getProductId()),
null, expiration.orElse(null),
billingCycleAnchor.orElse(null),
expiration.orElse(null),
expiration.map(clock.instant()::isBefore).orElse(false),
lineItem.getAutoRenewingPlan() != null && lineItem.getAutoRenewingPlan().getAutoRenewEnabled(),
status,
@ -385,18 +387,27 @@ public class GooglePlayBillingManager implements SubscriptionPaymentProcessor {
"acknowledgementState", subscription.getAcknowledgementState());
}
private Optional<Instant> getStartTime(final SubscriptionPurchaseV2 subscription) {
return parseTimestamp(subscription.getStartTime());
}
private Optional<Instant> getExpiration(final SubscriptionPurchaseLineItem purchaseLineItem) {
if (StringUtils.isBlank(purchaseLineItem.getExpiryTime())) {
return parseTimestamp(purchaseLineItem.getExpiryTime());
}
private Optional<Instant> parseTimestamp(final String timestamp) {
if (StringUtils.isBlank(timestamp)) {
return Optional.empty();
}
try {
return Optional.of(Instant.parse(purchaseLineItem.getExpiryTime()));
return Optional.of(Instant.parse(timestamp));
} catch (DateTimeParseException e) {
logger.warn("received an expiry time with an invalid format: {}", purchaseLineItem.getExpiryTime());
logger.warn("received a timestamp with an invalid format: {}", timestamp);
return Optional.empty();
}
}
// https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptionsv2#SubscriptionState
@VisibleForTesting
enum SubscriptionState {