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

Does this support monthly subscriptions in any way? #25

Closed
sbefort opened this issue Jun 3, 2016 · 32 comments
Closed

Does this support monthly subscriptions in any way? #25

sbefort opened this issue Jun 3, 2016 · 32 comments

Comments

@sbefort
Copy link

sbefort commented Jun 3, 2016

Thanks!

@whitmanc
Copy link

whitmanc commented Jun 5, 2016

@chirag04 Wondering same thing here. Since subscriptions are technically products as well, does this library supports them? Specifically, auto-renewing subscription. I would imagine it should work since data such as subscription expiration, etc. is sent in the receipt..... Will follow up with findings if we figure it out before hearing back

Thank you!

@chirag04
Copy link
Owner

chirag04 commented Jun 6, 2016

subscriptions are not supported but i'm happy to accept a PR

@DClark5218
Copy link

Very interested in this. @whitmanc any need of help in collaborating on this?

@whitmanc
Copy link

whitmanc commented Jun 10, 2016

@DClark5218 We're deciding what route we're going to take... If we end up using this library as a base/forking it, I'll let you know
cc @motdotla

@chetstone
Copy link
Contributor

@whitmanc thanks for asking this question. I naively assumed it would support all purchase types.
Have you evaluated what it would take to support subscriptions--- what the issues are? Does it make a difference whether the subscriptions are autorenewable or not? (I had not decided yet on which one to use for my app --- obviously difficulty in implementing would be a factor).

@chirag04 , since there are so many different types of IAP's, I think it would be a very useful addition to the documentation to specify which types are supported.

@sibelius
Copy link
Contributor

👍

@sibelius sibelius mentioned this issue Jun 19, 2016
@sibelius
Copy link
Contributor

I'm following this blog post http://savvyapps.com/blog/how-setup-test-auto-renewable-subscription-ios-app to implement auto-renewable subscriptions

We can use InAppUtils.purchaseProduct to let the user purchase an Automatically Renewable Subscription

The only part missing is the receipt validation, I think we can implement it using only js based on receiptValidation of the blog post

@sibelius
Copy link
Contributor

So to handle auto-renewable subscriptions do this:

install this package https://github.com/sibelius/iap-receipt-validator

  1. load products
  2. get receipt data
  3. validate receipt data on App Store using iap-receipt-validator
InAppUtils.loadProducts(products, (error, products) => {
    InAppUtils.receiptData((error, receiptData)=> {
        this.validate(receiptData);
   });
});
import iapReceiptValidator from 'iap-receipt-validator';

const password = 'b212549818ff42ecb65aa45c'; // Shared Secret from iTunes connect
const production = false; // use sandbox or production url for validation
const validateReceipt = iapReceiptValidator(password, production);

async validate(receiptData) {
    try {
        const validationData = await validateReceipt(receiptData);

        // check if Auto-Renewable Subscription is still valid
        // validationData['latest_receipt_info'][0].expires_date > today
    } catch(err) {
        console.log(err.valid, err.error, err.message)
    }
}

@chetstone
Copy link
Contributor

Excellent! Thanks for sharing this..

On Mon, Jun 20, 2016 at 5:48 AM Sibelius Seraphini notifications@github.com
wrote:

So to handle auto-renewable subscriptions do this:

install this package https://github.com/sibelius/iap-receipt-validator

  1. load products
  2. get receipt data
  3. validate receipt data on App Store using iap-receipt-validator

InAppUtils.loadProducts(products, (error, products) => {
InAppUtils.receiptData((error, receiptData)=> {
this.validate(receiptData);
});
});

import iapReceiptValidator from 'iap-receipt-validator';
const password = 'b212549818ff42ecb65aa45c'; // Shared Secret from iTunes connectconst production = false; // use sandbox or production url for validationconst validateReceipt = iapReceiptValidator(password, production);
async validate(receiptData) {
try {
const validationData = await validateReceipt(receiptData);

    // check if Auto-Renewable Subscription is still valid
    // validationData['latest_receipt_info'][0].expires_date > today
} catch(err) {
    console.log(err.valid, err.error, err.message)
}

}


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#25 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AA7l152gx4O1zC6R7dY8XklhJCtOG-_Mks5qNn4jgaJpZM4It8xi
.

@chirag04
Copy link
Owner

@sibelius want to merge receipt-validator into in-app-utils?

@sibelius
Copy link
Contributor

@chirag04 great idea, I'll do that

I think we should also integrate the android version from https://github.com/satya164/react-native-in-app-purchase

@chirag04
Copy link
Owner

totally agree. looking forward to your pr for receipt validator.

react-native-in-app-purchase was originally created to be merged into in-app-utils so it makes sense to do that. din't get time to do that. Up for a pr?

@skilesare
Copy link

Question: When we get the recieptData back, is it already in a base64 string? That is what apple says it wants, but when I just send the string, or I send the base64 string by calling

receipt64 = (new Buffer(req.body.receiptData)).toString('base64');

I'm getting 21002 malformed either way.

@sibelius
Copy link
Contributor

the receiptData from this lib is already a base64 string

@skilesare
Copy link

Any reason the validation data that I'd be getting back from the validateReceipt function would just be my original receipt data?

the body looks good in case 7: but then it gets to the case 10: and it calls
return _context.abrupt('return', receipt); and sure enough all I get back is the receipt.

Shouldn't it be returning back body instead?

@skilesare
Copy link

I changed it to body and the code started working. I'll try to get a PR together but I have a few other things up in the air.

@victor-falcon
Copy link

Anything new on this? 😕

@chirag04
Copy link
Owner

Seems like people are using subscriptions with this lib. I haven't used it myself so can't confirm.

@skilesare
Copy link

Just use the above instructions...use the referenced library in concert
with this one.

On Wed, Aug 24, 2016 at 9:49 AM, Chirag notifications@github.com wrote:

Seems like people are using subscriptions with this lib. I haven't used it
myself so can't confirm.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#25 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAnROyaMbiPo0MIQ_BM7XVIiK5vvON7Pks5qjFn-gaJpZM4It8xi
.

Austin Fatheree
RIVVIR Consulting
http://www.rivvir.com
austin@rivvir.com
832-483-0741
twitter: @afat http://twitter.com/afat

@itinance
Copy link

In our company we initiate subscriptions with this library. But we are'nt able right now to indicate if a subscription is still kept alive and valid or was it cancelled by the customer

@sibelius
Copy link
Contributor

you should have a cron job to run every day to check everyday if the subscription is still valid.

u can use this package in ur server: https://github.com/sibelius/iap-receipt-validator

you need to store the receipt in ur server side to do this

@itinance
Copy link

A, thx @sibelius. What will ne the argument "recepitData" in the validate() function?

@sibelius
Copy link
Contributor

the result of: InAppUtils.receiptData

InAppUtils.loadProducts(products, (error, products) => {
    InAppUtils.receiptData((error, receiptData)=> {
        this.validate(receiptData);
   });
});

#25 (comment)

@EdmundMai
Copy link

@sibelius it doesn't look like validationData['latest_receipt_info'][0].expires_date > today works. validationData is still a base64 encoded string not a hash

@chirag04
Copy link
Owner

From the feedback here, it seems like it does work with subscriptions. I'm going to close this one for now.

@sibelius
Copy link
Contributor

I've just sent a PR to improve info on monthly subscriptions: #56

@booboothefool
Copy link

booboothefool commented Apr 17, 2017

I'm about to do my first subscription. Need some newbie advice. Also note that the app is iOS/Android.

@sibelius Could you elaborate more on:

This works on both react native and backend server, you should setup a cron job that run everyday to check if the receipt is still valid

I don't quite understand. Do you mean every day, this would check every receipt for every user? Doesn't that seem like a lot? What do I then do with the validation results? Do I save it to their account on the backend?

What about: user opens the app -> then check their sub by validating their receipt -> then use the results to save the effects on the the backend with their account -> then apply the effects ??

If I should save to the backend on their user account, should the metadata look something like this?

{
    premiumSubscription: 1523996684  // the expiration date in the future in unix time
}

Something like:

async validate(receiptData) {
    try {
        const validationData = await validateReceipt(receiptData);

        updateUser({ premiumSubscription: validationData['latest_receipt_info'][0].expires_date })

        // then the logic to actually apply the subscription effects would be handled elsewhere
    } catch(err) {
        console.log(err.valid, err.error, err.message)
    }
}

cause I have a bunch of other things I will need to keep track of and for both iOS/Android. if this was stored on the user account, makes it easier to deal with for iOS/Android compatibility.

{
    premiumSubscription: 1523996684,
    numberOfCoins: 111,
    numberOfGems: 42,
    oneTimePurchaseExpiration: 1023996684,
    someOtherExpiration: 1123996684
}

Thanks!

@itinance
Copy link

itinance commented May 7, 2017

Can someone tell me why the expires_date is in the past?
At least in sandbox mode (can't test the non-sandbox mode for iOS) the expires_date that was mentioned above returns the date from last purchase, not the one that i would expect when a subscription would expire without any further payment. Do i have to add the monthly-subscription-phase by myself to the expiration-date?

@jamesmsp89
Copy link

@itinance did you manage to find out the answer to your last question? I've noticed that expires_date is the same as the purchase date. Testing in sandbox mode where I purchased a subscription yesterday, and today I am verifying the receipt is still valid. I would expect expiry date to be 3 months after the purchase date (for a 3-month auto-renewable subscription) and not the same as the purchase date.

Has anyone gone through the lifecycle of an auto-renewable subscription to confirm that https://github.com/sibelius/iap-receipt-validator works as expected e.g. expiry adjusts correctly with a renewal & cancel?

@itinance
Copy link

itinance commented Jul 31, 2018 via email

@jamesmsp89
Copy link

jamesmsp89 commented Aug 1, 2018

Thanks @itinance. I now have a better understanding of what is going on and can share some observations:

  1. In sandbox mode, the subscription purchased will have an expiry a short time after purchase (for me, I found it to be 1 hour) but looking at a few other threads online, this may vary depending on your subscription interval.

  2. The test condition should use expires_date_ms to avoid any discrepancies with timezones e.g.
    if (validationData['latest_receipt_info'][0].expires_date_ms > today.getTime()) { //subscription has not expired }

@Natim
Copy link

Natim commented Jul 2, 2019

The important thing is not to mix validationData["receipt"]["expires_date_ms"] and validationData["latest_receipt_info"]["expires_date_ms"]

The former is the immutable receipt, while the later is the last renewed receipt.

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