Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to detect renewed or not reewed subscriptions on IOS #1622

Open
nvanhoeck opened this issue Dec 6, 2024 · 3 comments
Open

How to detect renewed or not reewed subscriptions on IOS #1622

nvanhoeck opened this issue Dec 6, 2024 · 3 comments

Comments

@nvanhoeck
Copy link

Observed behavior

So we have gone to production with this plugin for IOS and Android. Since IOS did not support the 5 minute renewal subscriptions on their testing track, like Android does, we could not test renewable subscriptions for that platform. We have been very defensive in our approach since almost all fields are optional in Transaction and VerifiedReceipts. After debugging we also see that a lot of necessary info is just undefined. And i'm speaking for Android now.

Now the first bugs are coming into our system after being a month online. We have started debugging to see what is going wrong.
We have logged the transactions on our screen in test and to my suprise there is little to no usefull info to know wether a subscription is being renewed. This is a json output of one of the transactions:
{"className": "Transaction", "transaction-Id":XXX, "state":"appproved", "products":[{...}], "platform":"ios-appstore", "originalTransactionId": XXXX, "purchaseDate": "2024-10-10T14:14:26.000Z"}

This is the info we need to deal with?! And suprise this is a subscription that has been cancelled. So there is no way for us to know wether a subscription has been cancelled or renewed. With Android it has been trying to find out as well, but we just use the renewIntent. And when the subscription is not sent by Android, we know it hasn't been renewed.

Expected behavior

We expect at least one usefull field, like expirationDate, renewalIntent or something like that. Not just purchaseDate and the plugin saying good luck with it, since you will not be able to know wether this is a cancelled subscription or not.

PS: Ios also spams hundreds of validation requests. This also has impacted the performance on our subscription screen.

@Dexus
Copy link
Collaborator

Dexus commented Dec 9, 2024

You should handle it on server side....

@nvanhoeck
Copy link
Author

nvanhoeck commented Dec 12, 2024

Ok, I tried that and it seemed to work a bit better (expect for product-id having an apple:XXX prefix, which is weird).
Now, there have already some users been registerred in our system without the iaptic backend. When we check the data coming in, there is no purchase-id, so we cannot manually register this user via the api. How do I register the user in Iaptic without an purchase-id? Is there a migration-plan pre-iaptic to iaptic?

@nvanhoeck
Copy link
Author

To be more specific, this is what we get from the plugin:

{
    "platform": "ios-appstore",
    "transactionId": "xxx",
    "purchaseDate": "2024-11-21T17:43:53.000Z",
    "productIds": [
        "xxx.xxx.xxx.xxx.50"
    ]
}

but we send the whole transaction object (see typescript type below). There is no purchase-id to use or no expiration-date.

export type VerifyTransactionDtoRequest = { productIds: string [] } & Pick<CdvPurchase.Transaction,
    'purchaseId' |
    'platform' |
    'transactionId' |
    'purchaseDate' |
    'lastRenewalDate' |
    'expirationDate' |
    'amountMicros'
>

The code for the mapping:

 verifyPurchase$(transaction: CdvPurchase.Transaction) {
        const transactionDto: VerifyTransactionDtoRequest = {
            purchaseId: transaction.purchaseId,
            platform: transaction.platform,
            transactionId: transaction.transactionId,
            purchaseDate: transaction.purchaseDate,
            lastRenewalDate: transaction.lastRenewalDate,
            expirationDate: transaction.expirationDate,
            amountMicros: transaction.amountMicros,
            productIds: transaction.products.map((product) => product.id)
        }

        return this.remoteSubscriptionService.verifyTransaction$(transactionDto)
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants