Google Play Subscription API:如何区分退款订阅与用户自行取消的订阅?
Hey there, I’ve dealt with this exact head-scratcher while building subscription management tools—total pain when those timestamps line up! Here are the most reliable ways to tell these two scenarios apart:
Check the explicit subscription/order state field
Most billing platforms (like Google Play Billing, Apple App Store Connect) include a dedicated state flag that directly distinguishes these cases. For example:- In Google Play's
SubscriptionPurchaseobject, look atpurchaseState: a value of2means the subscription was refunded. For user-initiated cancellations,purchaseStatestays0(active) butautoRenewingwill befalse, andcancelReasonwill map to user action. - Apple's receipt data includes a
cancellation_reasonfield:1indicates the user canceled their subscription, while0means the cancellation was due to a refund (initiated by you or the platform).
- In Google Play's
Look for refund-specific fields
Nearly all platforms add unique fields for refund events. For instance:- Some systems include a
refundDateMillisorrefundAmountfield—if either is populated, you’re dealing with a refunded subscription, not a user cancellation. - In Apple receipts, refunded transactions will have a
refund_date_msentry tied to the original transaction ID, which you can cross-reference.
- Some systems include a
Analyze event types from webhooks/logs
If your system uses webhooks to receive subscription updates, the event type itself is a dead giveaway. A user-initiated cancel will trigger something likesubscription.cancelledwith metadata noting user action, while a refund firessubscription.refunded(ortransaction.refunded). Even if the timestamps match, the event context removes all ambiguity.Use cancellation reason codes
Many platforms break down cancellation reasons into specific codes:- Google Play’s
cancelReason:0: User actively canceled the subscription3: Subscription was canceled due to a refund
- These codes eliminate confusion even when
expiryTimeMillisanduserCancellationTimeMillisoverlap.
- Google Play’s
Pro tip: If you’re handling subscriptions in your internal database, add a custom isRefunded boolean field when processing refund events. This acts as a failsafe for edge cases where third-party platform data might be ambiguous.
内容的提问来源于stack exchange,提问作者sadiq

