Skip to content

Commit

Permalink
Set 'notificationType' to string in AppStore subscription status noti…
Browse files Browse the repository at this point in the history
…fication to support handling of new types
  • Loading branch information
mhuta committed Oct 6, 2022
1 parent 98b6916 commit fee5472
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.io.Serializable

data class StatusUpdateNotification(
@get:JsonProperty("environment") val environment: String?,
@get:JsonProperty("notification_type") val notificationType: AppStoreNotificationType,
@get:JsonProperty("notification_type") val notificationType: String?,
@get:JsonProperty("latest_receipt") val latestReceipt: String?,
@get:JsonProperty("latest_receipt_info") val latestReceiptInfo: LatestReceiptInfo,
@get:JsonProperty("expiration_intent") val expirationIntent: String?,
Expand Down Expand Up @@ -80,7 +80,34 @@ enum class AppStoreNotificationType(private val code: Int) {
/**
* User has entered a price increase flow
*/
PRICE_INCREASE_CONSENT(8);
PRICE_INCREASE_CONSENT(8),

/**
* Indicates that the customer initiated a refund request for a consumable in-app purchase,
* and the App Store is requesting that you provide consumption data
*/
CONSUMPTION_REQUEST(9),

/**
* Indicates that a customer’s subscription has successfully auto-renewed for a new transaction period.
* Provide the customer with access to the subscription’s content or service.
*/
DID_RENEW(10),

/**
* Indicates that the App Store successfully refunded a transaction for a consumable in-app purchase,
* a non-consumable in-app purchase, or a non-renewing subscription. The cancellation_date_ms contains
* the timestamp of the refunded transaction. The original_transaction_id and product_id identify
* the original transaction and product. The cancellation_reason contains the reason.
*/
REFUND(11),

/**
* Indicates that an in-app purchase the user was entitled to through Family Sharing is no longer
* available through sharing. StoreKit sends this notification when a purchaser disabled Family Sharing
* for a product, the purchaser (or family member) left the family group, or the purchaser asked for and received a refund.
*/
REVOKE(12);

companion object {
private val codes = values().associateBy(AppStoreNotificationType::code)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class AppStoreSubscriptionService(private val userAppClient: UserAppClient, priv
var notificationType = NotificationType.SUBSCRIPTION_PURCHASED
val latestReceiptInfo = statusUpdateNotification.latestReceiptInfo

when (statusUpdateNotification.notificationType) {
when (val appStoreNotificationType = parseAppStoreNotificationTypeEnum(statusUpdateNotification.notificationType)) {

// A subscription is first purchased
AppStoreNotificationType.INITIAL_BUY -> {
Expand All @@ -119,14 +119,14 @@ class AppStoreSubscriptionService(private val userAppClient: UserAppClient, priv
}

// a customer downgrades
AppStoreNotificationType.DID_CHANGE_RENEWAL_PREF -> {
AppStoreNotificationType.DID_CHANGE_RENEWAL_PREF, AppStoreNotificationType.DID_CHANGE_RENEWAL_STATUS -> {
// auto_renewal_product_id - product customer will auto renew at

// skipping it
// latest_receipt_info.original_transaction_id
}

// customer support issues a refund
AppStoreNotificationType.CANCEL -> {
AppStoreNotificationType.CANCEL, AppStoreNotificationType.REVOKE, AppStoreNotificationType.REFUND -> {
// suspend service with a cancellation date?

notificationType = NotificationType.SUBSCRIPTION_CANCELED
Expand Down Expand Up @@ -158,12 +158,20 @@ class AppStoreSubscriptionService(private val userAppClient: UserAppClient, priv
// latest_receipt_info.expires_date_ms - date when the subscription will expire
}

AppStoreNotificationType.DID_CHANGE_RENEWAL_STATUS -> {
// skipping it
AppStoreNotificationType.DID_RENEW -> {
// restore service for a renewed subscription
// update customer's subscription to active / subscribe

notificationType = NotificationType.SUBSCRIPTION_RENEWED;
}

AppStoreNotificationType.PRICE_INCREASE_CONSENT -> {
// skipping it
null -> {
throw IllegalStateException("Missing or not recognised notification type.")
}

else -> {
logger.warn { "Notification type $appStoreNotificationType is not supported." }
return null
}
}

Expand All @@ -186,6 +194,9 @@ class AppStoreSubscriptionService(private val userAppClient: UserAppClient, priv
return userAppClient.sendSubscriptionNotification(notification)
}

private fun parseAppStoreNotificationTypeEnum(appStoreNotificationValue: String?): AppStoreNotificationType? =
AppStoreNotificationType.values().find { it.name.equals(appStoreNotificationValue, ignoreCase = true) }

fun verifyReceipt(tenant: String?, receiptRequest: ReceiptRequest) = appStoreClient(tenant).verifyReceipt(receiptRequest)

private fun appStoreClient(tenant: String?) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal class SubscriptionControllerTest : SupportController() {


private val testStatusUpdateNotification: StatusUpdateNotification = StatusUpdateNotification(
"sandbox", AppStoreNotificationType.CANCEL, "cancellationDate", latestReceiptInfo, "",
"sandbox", "CANCEL", "cancellationDate", latestReceiptInfo, "",
"latestExpiredReceipt", true, "", "autoRenewProductId",
"autoRenewStatusChangeDate", 12323230, unifiedReceipt)

Expand Down

0 comments on commit fee5472

Please sign in to comment.