-
Notifications
You must be signed in to change notification settings - Fork 184
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
Listen for purchase events + optional promise support + other updates #128
base: master
Are you sure you want to change the base?
Listen for purchase events + optional promise support + other updates #128
Conversation
@superandrew213 I tested on the device for In-App purchases using the |
awesome! i will find some time over the weekend for this. |
@superandrew213 and @chirag04 I discovered an issue. My app has a Keyboard Extension target that bundles and runs the RN app. The extension crashes with this updated code in place. I have more discovery to do but wanted to let you know. I do not use this package in the code running inside of the extension, that is not allowed anyway, but having it linked and available is causing it to crash. |
@jeremyhicks what is the error output? |
@superandrew213 I wasn't getting any in the console. I need to explore further. When opening the Keyboard Extension it would crash. Debugging that is not easy. |
@superandrew213 @chirag04 I have found the source of the issue when this library is included in a project that gets bundled in an iOS extension. The libInAppUtils.a library still needs to be included even though the extension itself doesn't support IAP. I've updated my apps to use this branch and it is working good, no crashes. |
@chirag04 will you have some time soon to take this in soon? I've had it in a production app for over 3 weeks now and have had no issues. |
@superandrew213 sorry i haven't had a chance to look at it yet. i'm still planning to review and merge this soon. |
@chirag04 sure no problem! |
Hi! Any changes here? |
@superandrew213 I started test your solution, but this link don't work for me itms-services://?action=purchaseIntent&bundleId=com.example.app&productIdentifier=product_name (with my bundleId and productIdentifier, for purchase testing). I use your branch and subscribe on events as written in your readme. |
@merryejik what happens when you press the link? Does it open your app? |
No... |
Hmm there must be something wrong with your bundleId. Paste this in your safari browser on your phone and make sure you have the right
|
Safari wants to open this link in iTunes and opens nothing after that. I will investigate SKPaymentTransactionObserver more carefully. Maybe there is need to be some changes in Info.plist or in AppDelegate? |
would love to see this merged |
…se-event # Conflicts: # InAppUtils/InAppUtils.m
index.js
Outdated
? InAppUtils.loadProducts(products, cb) | ||
: promisify(InAppUtils.loadProducts)(products), | ||
|
||
canMakePayments: cb => cb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@superandrew213 - If canMakePayments
returns true, your promisfy
function will reject the promise. You can create a special function just for canMakePayments
like this one:
const promisifyBool = fn => (...args) => new Promise((resolve, reject) => {
fn(...args, res => res === true || false ? resolve(res) : reject(res))
})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this:
const promisify = fn => (...args) => new Promise((resolve, reject) => {
fn(...args, (err, res) => {
if (err !== undefined && err instanceof Error) reject(err);
// If only one argument is given and it's not an error
if (err !== undefined && res === undefined) resolve(err);
resolve(res);
});
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Thanks for catching that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@superandrew213 just realized that err
is not always of type Error
. When calling restorePurchases
if the user cancels, err
comes back as a string "restore_failed". Seems the rejection types are bit inconsistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm ... it would be best if we enforce an error type. We can use callback(@[RCTMakeError(@"restore_failed", nil, nil)]);
where restore_failed
would be the error message. This will be a breaking change though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we have to do a breaking change, lets keep it simple and just change canMakePayments
to canMakePayments(err, res)
. @chirag04 what do you think? It would also be good to use error objects too.
Now handles callbacks with one argument & no error
This reverts commit ffa363f.
@superandrew213 Those latest additions are fantastic. Is there a way to get unfinished purchases, e.g. on start or resume, so I can unlock stuff server-side, and then call Since this package is on life support, have you considered publishing and maintaining your fork as your own package on NPM, e.g. as |
@Dexwell that's plan. Just haven't had any time. So it has been easier & faster to just use github fork for now. Have you tried Or do you mean for purchases that are still in purchasing state? |
Yeah |
@superandrew213 This PR is looking great! I won't have the time review it further or merge. Would you be interested in managing this library? |
@chirag04 I just don't have the time to maintain it. I am just adding the features that I need. It might not be best to merge this since it is a breaking change. If we will be doing a breaking change then we should consider using events (while still supporting callbacks if possible). This PR is heading towards that direction. I will continue working on it. When it is ready, then we can release it as v7. |
With these changes I am able to catch auto renewable subscriptions on application startup just fine by listening for the purchaseCompleted event. However, this event is also emitted for regular purchases (as in, purchases that are user initiated through purchaseProduct). @superandrew213 Is there some way of distinguishing the automatic events from the user initiated ones? |
@pennersr you can track the purchases that have been processed by using the Otherwise you could remove the listener as soon as you have caught the subscription purchase initiated from the AppStore. You could also set a timeout incase there are no purchases. |
@superandrew213 I am not sure how you would use |
@pennersr the callback will be triggered first. |
Hey @superandrew213, thank you for all your work. I'm wondering, what's left on this PR to get it merged? and if this is not going to be merged and stay here, how would someone use it (since you mention there are breaking changes)? |
@Eyesonly88 you can install it like this:
The docs on my fork tell you how to use it. I have kept them updated. The only breaking changes are related to how errors are handled. My fork returns error objects instead of just a string. |
Just came across this, @superandrew213 so while we are waiting for v7. How about changing your default branch in your repo from |
@thanakij done 🙂 |
In-app purchase, after the product has been purchased and paid for. I didn't call finishTransaction to end the transaction. Why can't I get the pending transaction the next time I come in and print an empty array |
` // to purchase product
// in app componentDidMount use |
Updates:
canMakePurchase
returns error arg too now *shouldFinishTransactions
,finishCurrentTransaction
andclearCompletedTransactions
. See readme for more info.addTransactionObserver
after js code initialises ** breaking change
To install and test:
To trigger purchase initiated from App Store, open this link in safari. Replace
bundleId
andproductIdentifier
with your own.