appleSubscription static method
Parses getAllSubscriptionStatuses.
Looks at every subscription group, preferring the entries whose
originalTransactionId matches originalTransactionId; if none match,
considers all of the customer's subscriptions. Among the candidates, the
best status wins (active > grace period > billing retry > expired >
revoked), then the latest expiration.
Implementation
static VerificationResult appleSubscription(
StatusResponse response,
String originalTransactionId,
) {
final isSandbox = _isAppleSandbox(response.environment);
final all = [for (final group in response.data) ...group.lastTransactions];
if (all.isEmpty) {
return VerificationResult.notFound(
StorePlatform.apple,
isSandbox: isSandbox,
);
}
final matching = all
.where((item) => item.originalTransactionId == originalTransactionId)
.toList();
final candidates = matching.isNotEmpty ? matching : all;
final decoded = [
for (final item in candidates)
(item: item, tx: item.transactionInfo, renewal: _renewalOf(item)),
];
decoded.sort((a, b) {
final byRank = (_appleStatusRank[b.item.status] ?? 0).compareTo(
_appleStatusRank[a.item.status] ?? 0,
);
if (byRank != 0) return byRank;
return (b.tx.expiresDate ?? 0).compareTo(a.tx.expiresDate ?? 0);
});
final best = decoded.first;
final willAutoRenew = best.renewal == null
? null
: best.renewal!.autoRenewStatus == 1;
final VerificationState state;
switch (best.item.status) {
case _appleActive:
state = willAutoRenew == false
? VerificationState.canceled
: VerificationState.active;
case _appleGracePeriod:
state = VerificationState.gracePeriod;
case _appleBillingRetry:
state = VerificationState.billingRetry;
case _appleExpired:
state = VerificationState.expired;
case _appleRevoked:
state = VerificationState.revoked;
default:
state = VerificationState.unknown;
}
return VerificationResult(
isValid:
best.item.status == _appleActive ||
best.item.status == _appleGracePeriod,
state: state,
platform: StorePlatform.apple,
productId: best.tx.productId,
expiresAt: _fromMillis(best.tx.expiresDate),
willAutoRenew: willAutoRenew,
isSandbox: isSandbox,
raw: {
'status': best.item.status,
'transaction': best.tx.toJson(),
if (best.renewal != null) 'renewalInfo': best.renewal!.toJson(),
},
);
}