aporat / store-receipt-validator

PHP receipt validator for Apple iTunes, Google Play and Amazon App Store
Apache License 2.0
633 stars 153 forks source link

Active when no expiration intent? #151

Closed bopoda closed 3 years ago

bopoda commented 3 years ago

https://github.com/aporat/store-receipt-validator/blob/master/src/iTunes/PendingRenewalInfo.php#L237-L238

public function getStatus(): ?string
{
    // Active when no expiration intent
    if (null === $this->expiration_intent) {
        return $this::STATUS_ACTIVE;
    }

Hi,

I wonder if we should consider all the iTunes responses with subscription without field "expiration_intent" in "pending_renewal_info" section as "active"?

1. For example, that's from iTunes response (Sandbox env):

"pending_renewal_info": [
        {
            “auto_renew_product_id": “dpm.1month_7dt",
            “is_in_billing_retry_period": “1",
            “product_id": “dpm.1month_7dt",
            “original_transaction_id": “1000000838121962",
            “auto_renew_status": “1"
        }

2. That's part of response (Production env):

"latest_receipt_info”: [
    {
        "quantity”: "1”,
        "product_id”: "groove.1year”,
        "transaction_id”: "XXXXXXXX”,
        "original_transaction_id”: "XXXXXXXX”,
        "purchase_date”: "2020-04-30 13:33:06 Etc/GMT”,
        "purchase_date_ms”: "1588253586000”,
        "purchase_date_pst”: "2020-04-30 06:33:06 America/Los_Angeles”,
        "original_purchase_date”: "2020-04-30 13:33:09 Etc/GMT”,
        "original_purchase_date_ms”: "1588253589000”,
        "original_purchase_date_pst”: "2020-04-30 06:33:09 America/Los_Angeles”,
        "expires_date”: "2021-04-30 13:33:06 Etc/GMT”,          #It looks like as it's expired for 2.5 months!
        "expires_date_ms”: "1619789586000”,
        "expires_date_pst”: "2021-04-30 06:33:06 America/Los_Angeles”,
        "web_order_line_item_id”: "530000211809273”,
        "is_trial_period”: "false”,
        "is_in_intro_offer_period”: "false”,
        "in_app_ownership_type”: "PURCHASED”,
        "subscription_group_identifier”: "XXXXXX”
    }
]
...
"pending_renewal_info": [
        {
            “auto_renew_product_id": “groove.1year",
            “is_in_billing_retry_period": “1",
            “product_id": “groove.1year",
            “original_transaction_id": “530000571876958",
            “auto_renew_status": “1"
        }
]

I should say that's is very rare case for Production when pending_renewal_info does not contain expiration_intent but contains is_in_billing_retry_period:"1".

In the example above, on the one hand, it looks like the subscription expired 2.5 months ago. On the other hand, it doesn't contain expiration_intent.

In your opinion, is it correct if we consider the second response as active subscription from the server validation perspective?

Stafox commented 3 years ago

It depends what you are going call "active subscription". In your case the subscription in billing retry period. It means subscription expired, but in case when user will refill the balance (or bank issue will be fixed) Apple will charge him and you will get new transaction.

bopoda commented 3 years ago

@Stafox thank you for your reply.

My main concern is if user should have access to premium features in app or not in such a case?

In your case the subscription in billing retry period. It means subscription expired

So, using the getStatus method, I receive "active" and consider the user should have access to premium features like he has an active subscription.

Stafox commented 3 years ago

No, in general, user should not have access to premium in that case.

bopoda commented 3 years ago

@Stafox, thanks. I will close issue