j3k0 / cordova-plugin-purchase Goto Github PK
View Code? Open in Web Editor NEWIn-App Purchase for Cordova on iOS, Android and Windows
Home Page: https://purchase.cordova.fovea.cc
In-App Purchase for Cordova on iOS, Android and Windows
Home Page: https://purchase.cordova.fovea.cc
For tracking purposes we need to know the price & currency for the products.
I've made some changes so that storekit.load
returns these values alongside the preformatted price. We tested it with different countries and so far it worked fine.
I'm not submitting a pull request as the current implementation would break existing code. In our code price
is used for returning an unformatted number and the new localizedPrice
is the formatted price as it was before.
See the changes for yourself here: https://github.com/platogo/PhoneGap-InAppPurchase-iOS/commit/0e8e842a246a0f2ab92d65932cffa49dd892568e
It would be great if price & currency code would find their way into the plugin.
Also, thanks for providing this plugin!
Hi, Thanks for very useful plugin.
there is a problem IAP.onRestore not firing
please guide me
Look for callbackContext.error in "InAppBilling.java".
The IabResult
object already provides an integer status code, that just isn't passed to javascript error callback. Maybe to keep things backward compatible, it could be passed as an optional second argument to the error callbacks.
Hi!
I am trying your plugin in a phonegap 3.0 hello world project to keep things simple. When I call the purchase function:
window.storekit.purchase("com.example.app.inappid1", 1);
I am getting in the console:
2013-10-08 16:19:54.062 InAppTest[2934:60b] InAppPurchase[objc]: About to do IAP
2013-10-08 16:19:54.064 InAppTest[2934:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid product identifier: (null)'
*** First throw call stack:
(0x31303f53 0x3b6da6af 0x31303e95 0x33a0690f 0x105897 0xfe3e1 0xfdd11 0xfd8e9 0xfda93 0xfd9b1 0x31ce703b 0x312cf18b 0x312ce65b 0x312cce4f 0x31237ce7 0x31237acb 0x35f58283 0x33ad9a41 0x103f67 0x103f28)
libc++abi.dylib: terminating with uncaught exception of type NSException
The "null" is very weird. I am getting the same issue in my real app with the real app id. Any ideas of what could be wrong?
Thanks a lot for your help!
poiuytrez
PS: My real app is using Phonegap 1.9 with the old inappplugin (I even contributed to it). I am upgrading it to Phonegap 3.0
Hi there,
In my test setup (Phonegap app running on iPad Mini with iOS 7), running the storekit.restore() command causes the 'restore' event handler to fire for every restored purchase, but the restoreCompleted handler never runs.
Your docs are not 100% clear to me on this issue, but I expected the 'restore' handler to be fired for every individual restored purchase and the 'restoreCompleted' to be fired when all purchases were restored.
If I check your .js and .m files, I see that this is not how it works. In the file inAppPurchase.m, the handlers "restoreCompletedTransactionsFailedWithError" and "restoreCompletedTransactionsFinished" only do one line of debugging, the rest of the code is commented out.
I noticed that both of these commented-out bits refer to javascript handlers with a slightly different name, including an unused "on" prefix:
onRestoreCompletedTransactionsFailed (in the .m file)
restoreCompletedTransactionsFailed (in the js file)
Could it be that this caused errors, and you commented out the code to prevent bigger problems?
Regards,
Wytze
This may already be possible, if it is please let me know.
It would be really useful in some cases to be able to manually call finishTransaction rather than have it done automatically. Consider an auto-renewing subscription where subscriptions need to be tracked on the app server to authorize certain content.
Currently, my understanding is that the app will still call finishTransaction. Desired behavior would be to wait for a response from the app server and a) retry if it failed or display some error message to the user or b) manually call finishTransaction if it succeeded.
Add a way to specify the payload used in "InAppBillingPlugin.java".
Shouldn't be empty in production.
Sadly, I not able to reproduce it using the Apple sandbox env but few of our customers can't restore subscriptions on different device, looking at the server log it seems that the transaction id is not passed.
It seems to happen with IOS7 (but not 100% confirmed). Does anyone had the same issue? Also does the restore process is different on IOS 7, for purchase we have to use receipts.appStoreReceipt
, is it the same for restore?
Thanks
Hello there,
thank you for do this beautiful plugin. I have a problem when i call purchase. Debug of xcode answer Cannot finish transaction, and i don't have recepit. Can you help me?
This is debug:
2014-06-08 16:58:54.027 Tis[571:60b] InAppPurchase[objc]: About to do IAP
2014-06-08 16:58:54.028 Tis[571:60b] InAppPurchase[objc]: Payment transaction updated ((null)):
2014-06-08 16:58:54.030 Tis[571:60b] InAppPurchase[objc]: Purchasing...
2014-06-08 16:58:58.684 Tis[571:60b] InAppPurchase[objc]: Payment transaction updated ((null)):
2014-06-08 16:58:58.685 Tis[571:60b] InAppPurchase[objc]: State: PaymentTransactionStatePurchased
2014-06-08 16:58:58.689 Tis[571:60b] InAppPurchase[objc]: Cannot finish transaction 1000000113327529.
Unfortunately this is my first experience with Cordova development.
When I call storekit.init() absolutely nothing happens. I don't get past it, I don't trigger ready(), I don't see any details in the console.
Do I need to include a license key anywhere?
Is there any known issues with iOS 8 yet?
The plugin is working like charm but I recommend to add function to clear the old transactions Queue.
thanks.
in "Advanced use/Receipts" section:
...
receipts.appStoreReceipt(); // null or base64 encoded receipt (iOS >= 7)
...
receipts.appStoreReceipt is not a function, I think it's should be:
...
receipts.appStoreReceipt; // null or base64 encoded receipt (iOS >= 7)
...
it's kinda a little problem, but fixing it will save people time to debug code like me: I submit my app 2 days ago without testing IAP on iOS7 until I found this problem.
Hi,
i'm new to all this stuff and can now successfully validate purchases made from ios7+ devices via php. Thanks for that!
But i'm really struggling with validating receipts for ios6.
What should i do with the receipts.forTransaction(transactionId) to validate it?
When i send it untouched to the sandbox i get the
[status] => 21002
[exception] => java.lang.IllegalArgumentException
result.
The same when i try to base64 encode it with php or replace blanks with + etc.
I noticed a space around the 10. character and no == at the of the receipt. So i assume it's not properly encoded by the client or is it another validation progress than in 7?
Type is consumable
The callback for a successful restore isn't firing.
Running Phonegap 3.1. Could that be the reason?
This is not really an issue as this plugin is for in-app purchases, but my question is related to this.
How to know what a user purchased ? Do you know if its possible ? do you know a plugin for it ?
Thank you and sorry for opening an issue.
Hi there,
First of all, thank you for doing this. I had been trying to do this on my own, and it was not working at all, so your plugin has filled in a lot of the blanks I had.
Right now, I'm just trying to initialize, then display the items in an alert, to try it out. Here's some of my code:
initialize: function() {
console.log('IOS STORE INITIALIZING');
var me = this;
var readyCallback = function successCallback(result) {
console.log( 'STORE INITIALIZED' )
me.getDetails();
};
storekit.init({
debug: true, // Enable IAP messages on the console
ready: readyCallback,
purchase: function() { alert('coming soon') },
restore: function() { alert('coming soon') },
error: function() { alert('error') }
});
},
getDetails: function() {
var skuList = [/* An array of my SKUs */];
var successCallback = function() {
var strResult = "";
if(typeof result === 'object') {
strResult = JSON.stringify(result);
} else {
strResult = result;
}
alert("SUCCESS: \r\n" + strResult );
}
storekit.load( skuList, successCallback );
}
Now, the alert pops up with the details of my products, but then the app immediately crashes. Here's where it crashes:
- (void)evalJsHelper2:(NSString*)js
{
CDV_EXEC_LOG(@"Exec: evalling: %@", [js substringToIndex:MIN([js length], 160)]);
NSString* commandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString:js];
if ([commandsJSON length] > 0) {
CDV_EXEC_LOG(@"Exec: Retrieved new exec messages by chaining.");
}
[_commandQueue enqueueCommandBatch:commandsJSON];
[_commandQueue executePending];
}
It fails trying to set commandsJSON
. The value of js
is a string:
cordova.require('cordova/exec').nativeCallback('InAppPurchase662531270',1,
[
[
{
"title" : "Video 5",
"id" : "sku1",
"price" : "$0.99",
"description" : "Product description goes here."
},
{
"title" : "Video 6",
"id" : "sku2",
"price" : "$0.99",
"description" : "Product description goes here."
}
],
[
]
]
,0)
Any idea what I'm doing wrong?
There's a bug in the Javascript where the plugin won't maintain which product IDs have been previously loaded in a load() call, and therefore won't allow you to purchase a product that has previously been loaded.
If I call storekit.load("A"), then call storekit.load("B"), the InAppPurchase.js overwrites the array of productIDs with "B" only.
This happens on line 196 of InAppPurchase.js:
InAppPurchase._productIds = productIds;
Our use case for this is a paginated list of products from our server. Rather than loading up hundreds of products from our server on app start, we paginate them, loading them from the app store as we get the products from our server.
Add android support to the plugin. Turn it into a multi-platform In-App-Purchase solution.
The idea would be to provide as much abstraction of the platform as possible, yet giving access to platform specific APIs.
It could be implemented as a layered architecture:
It probably won't be possible to abstract everything, I think about things like receipts validation for instance... (except if we also provide server-side code, but lets keep this for later).
This is just a starting point of reflection. Please tell me what you think, share your remarks and ideas.
One of the problems with Cordova is the ability to call Javascript functions from the web inspector.
As such I want to send the receipt of the purchase to our server along with the request to validate serverSide that the purchase has been made.
However, it seems that the receipt parameter in the onPurchase callback is always undefined.
If user purchased more than one items in the past, then he restores on a new device now, then storekit.restore event is fired multiple times for every item. It's expectable behavior, except we don't know in advance how many times this event will be fired. So if for example we show an alert (to say thank you) in the event handler, it will be displayed more than one time, and it surely annoys user.
Hey,
So I've double checked and triple checked to make sure everything is set up correctly, but in deviceready, when I alert window.storekit, it says it is undefined. We're using Cordova 2.9 and xCode 5, deploying to iOS 5 using the iOS 7 SDK.
Any help would be appreciated. Thanks.
If user is in a purchase transaction, error event is fired whenever user tap Cancel button.
Nothing is fired when user tap Cancel button (in various alert boxes) during a restore transaction (restore failed/completed are not fired too).
Regards,
Hi
There seems to be a problem with the in app purchases plugin and iOS 7 on iPads. It works perfectly on an iphone, but on an ipad the IAP information is not shown and neither is the purchase button. Only the restore all button appears.
Any ideas.
My app gets rejected from the itunes.connect store due to this issue.
ask
is unnecessary as the same behaviour can be achieved with once("product loaded")
.
I´m having a problem using the plugin below to manage in-app purchases. i think i have installed it correctly because it was working correctly yesterday but today the window.storekit object is undefined
When buying on the app store you get a transaction receipt from Apple, which should be used to verify that the purchase is real. This is quite important when unlocking content on a server, because it is the only way to actually secure your content from being stolen.
I see that you have commented it out InAppPurchase.m.
What are the reasons to not pass back to JS?
Cordova: 3.0
Installation method: CLI
Everything is running smooth until I call the "restore()" method.
Console simply returns (as this is the JS method for restoreFailed()):
Restore Failed: 0
Then, seconds later, the console is updated with the (correctly) purchased items.
Payment transaction updated:
2013-11-27 18:22:35.768 MyApp[593:60b] InAppPurchase[objc]: State: PaymentTransactionStatePurchased
2013-11-27 18:22:35.769 MyApp[593:60b] InAppPurchase[objc]: js: window.storekit.updatedTransactionCallback.apply(window.storekit, [
"PaymentTransactionStatePurchased",
0,
"",
"1000000094876393",
"com.my.product.id"
])
Is there something I'm doing wrong? What does error code 0 mean?
@maxmoore14 : do you remember if it necessary to call StoreKit's finish on a failed transaction?
https://github.com/j3k0/PhoneGap-InAppPurchase-iOS/blob/master/src/ios/InAppPurchase.m#L403-L407
Anyway, I don't think user side's finish()
callback should be called in that case, or maybe with a error code as a parameter. The behavior is especially weird when storekit.purchase()
is called again by the user on a product with non-finished transaction in progress: this results in a failed transaction and user code's finish()
callback called directly... Could be mind-bugging ;)
Any thoughts?
Heya,
Any idea would this work out of the box or do I need some configuring? For what its worth, I read something about using the SKDownload class to download the content.
You can read more about it in the In-app-purchase guide provided by Apple.
Thank you already for the plugin :)
Hey guys,
Any chance of getting full iOS 7 support in the near future? Specifically, the transactionReceipt property is deprecated in iOS 7, and we need to use the appStoreReceiptUrl property of the mainBundle object to be able to get the transaction receipt. Without this, it is impossible to verify purchases on iOS 7. I'd do this myself, but obj-c is beyond me at this point.
Thanks.
I see the Indigogo campain here: https://www.indiegogo.com/projects/phonegap-cordova-in-app-purchase-ios-and-android
Are you still working on the Android solution?
If user used other store (e.g. France) last time, then when IAP popups a dialog for entering iTunes account and he enters account for US store, he will see an alert for store redirection (from current France to US, default store of being entered account). The app doesn't know this case and just gets an error. Worse, App Store also shows below error in a blank page:
Your request produced an error.
[new NullResponse]
Hey,
I have tried to implement this IAP plugin, however whenever I try to run my code I consistently get the same error message in Xcode:
2014-05-06 16:41:57.281 Airborne[80261:70b] CDVPlugin class InAppPurchase (pluginName: InAppPurchase) does not exist.
2014-05-06 16:41:57.281 Airborne[80261:70b] ERROR: Plugin 'InAppPurchase' not found, or is not a CDVPlugin. Check your plugin mapping in config.xml.
2014-05-06 16:41:57.282 Airborne[80261:70b] -[CDVCommandQueue executePending] [Line 158] FAILED pluginJSON = [
"InAppPurchase466332499",
"InAppPurchase",
"setup",
[
]
]
I have absolutely no idea why this is happening, as it seems that all the files are there and registered in the proper confix.xml and cordova_plugins.json files. I am currently compiling with cordova version 3.4.1-0.1.0
Any help would be really appreciated
I'd like to have this plugin published to the cordova plugin registry, so that other published plugins can declare it as a dependency. com.google.payments
would use this immediately, if it were made available there.
I'm willing to do the work of getting it published, and assigning ownership to you if necessary; just let me know.
When I call window.storekit.restore(), first it naturally asks for itunes login, then when I call it again, it restores all my IAP items, even the ones not bought and even without itunes login...
Hi. I saw your cross-platform IAP campaign. IAP code seems to be difficult to implement even without considering Cordova usage.
Edit: I see you are working on it. Great. :-)
Hi Jean-Christophe!
I currently trying to integrate a monthly subscription into my Cordova App - but unfortunately I do not have any clue how and I've opened an issue over at the ngStorekit repo from Alex:
https://github.com/AlexDisler/ng-storekit/issues/2#issuecomment-51860226
Seems like there's a serious need for this, so the question came up if it's even possible by using your current plugin?
Would be absolutely great if we can put something together (if it does not exist already and I'm just missing it?!) which can be used for the subscription payments!
Reads:
phonegap local add git://github.com/j3k0/PhoneGap-InAppPurchase-iOS.git
I had to run:
phonegap local plugin add git://github.com/j3k0/PhoneGap-InAppPurchase-iOS.git
Hi!
I am trying your plugin in a phonegap 3.0 hello world project to keep things simple. When I call the purchase function:
window.storekit.purchase("com.example.app.inappid1", 1);
I am getting in the console:
2013-10-08 16:19:54.062 InAppTest[2934:60b] InAppPurchase[objc]: About to do IAP
2013-10-08 16:19:54.064 InAppTest[2934:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid product identifier: (null)'
*** First throw call stack:
(0x31303f53 0x3b6da6af 0x31303e95 0x33a0690f 0x105897 0xfe3e1 0xfdd11 0xfd8e9 0xfda93 0xfd9b1 0x31ce703b 0x312cf18b 0x312ce65b 0x312cce4f 0x31237ce7 0x31237acb 0x35f58283 0x33ad9a41 0x103f67 0x103f28)
libc++abi.dylib: terminating with uncaught exception of type NSException
The "null" is very weird. I am getting the same issue in my real app with the real app id. Any ideas of what could be wrong?
Thanks a lot for your help!
poiuytrez
PS: My real app is using Phonegap 1.9 with the old inappplugin (I even contributed to it). I am upgrading it to Phonegap 3.0
Can we do non renewing subscription using the current version of the plugin?
Apparently there's something wrong when we try to purchase on 7.1.1
I will do more debugging and will try to get back asap but I just got one of my apps rejected :)
(My bad, I didn't upgrade my testing device).
Will be posting back soon.
Anybody else having this issue?
I assume this happens possibly because my app is still very young and I haven't signed my application with my developer license, but it would be nice if this didn't crash my app because of an unhandled exception. Here's the logs with relevant stack trace:
2014-01-08 20:58:25.066 XXX[52022:70b] InAppPurchase[objc]: About to do IAP
2014-01-08 20:58:25.075 XXX[52022:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid product identifier: (null)'
*** First throw call stack:
(
0 CoreFoundation 0x000f05e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01e088b6 objc_exception_throw + 44
2 CoreFoundation 0x000f03bb +[NSException raise:format:] + 139
3 StoreKit 0x019ae74f -[SKPaymentQueue addPayment:] + 659
4 XXX 0x00033098 -[InAppPurchase purchase:] + 440
Hello, I use cordova 3.4.1 my app crashes after purchasing an item.
2014-05-11 21:12:30.598 appname[10564:60b] InAppPurchase[objc]: State: PaymentTransactionStateFailed
2014-05-11 21:12:40.786 appname10564:60b] InAppPurchase[objc]: About to do IAP
2014-05-11 21:12:40.787 appname[10564:60b] InAppPurchase[objc]: Payment transaction updated ((null)):
2014-05-11 21:12:40.789 appname[10564:60b] InAppPurchase[objc]: Purchasing...
2014-05-11 21:12:57.449 appname[10564:60b] InAppPurchase[objc]: Payment transaction updated (3):
2014-05-11 21:12:57.451 appname[10564:60b] InAppPurchase[objc]: State: PaymentTransactionStatePurchased
2014-05-11 21:12:57.472 appname[10564:60b] InAppPurchase[objc]: Transaction 1000000110332005 finished.
appname(10564,0x3d36f18c) malloc: *** error for object 0x1722b000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Process 10564 stopped
__pthread_kill + 8, queue = 'com.apple.main-thread', stop reason = signal SIGABRT frame #0: 0x3b3ca1f0 libsystem_kernel.dylib
__pthread_kill + 8Anyone an idea?
SKPaymentTransactionStateFailed produces error callback with transaction error code
errorCode = transaction.error.code;
and thanks to that it doesnt follow InAppPurchase.ERR_*
codes stategy.
Hi,
Is it possible to add a custom callback function on purchase besides the one we need to give the init function?
I'd like to be able to run some code after a purchase is successfull, but in a different part of the code...
Thank you.
Hello!
Just curious about this project status given the warning in the readme:
WARNING: I'M CURRENLTY REWRITING PART OF THIS PLUGING. IT'S NOT YET USABLE!
Now that cordova 3.0 is out it's unclear whether this will work or not, or whether it is still in active development.
Screenshot
http://screencast.com/t/geNYmcvadJ
Ignore this... there was a bug in my js... sorry for raising alarm... =\
I've got a problem with the callback function when doing a purchase, In the console of Xcode, it gives me an ok on the purchase, the product gets purchased and I get an succes.
When I look at the InAppPurchase.prototype.purchase function, it never gets into the purchaseOk or purchaseFailed function, which should be called by the exec purchase command.
Any ideas where this can go wrong?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.