Iphone Phonegap in-app purchase not working - iphone

I have a phonegap project using which i have submitted my application at iPhone app store.
I m using cordova-2.2.0.js. Now I want to implement in-app purchase plugin to provide in-app purchase in my application.
I am trying to do it by adding in-app plugin from the link below:
https://github.com/phonegap/phonegap-plugins/tree/master/iPhone/InAppPurchaseManager
I then added InAppPurchase plugin to cordova.plist file.
When I write below mentioned code
(a) in my javascript, the control goes to InAppPurchaseManager.js plugin and code
(b) is executed.
(a)
window.plugins.inAppPurchaseManager.requestProductData(
"org.xxx.abcd.pqr",
function(productId, title, description, price) {
alert("data retrieved");
//window.plugins.inAppPurchaseManager.makePurchase(productId, 1);
},
function(id) {
alert("Invalid product id: " + id);
}
);
(b)
InAppPurchaseManager.prototype.requestProductData = function(productId, successCallback, failCallback) {
var key = 'f' + this.callbackIdx++;
window.plugins.inAppPurchaseManager.callbackMap[key] = {
success: function(productId, title, description, price ) {
if (productId == '__DONE') {
delete window.plugins.inAppPurchaseManager.callbackMap[key]
return;
}
successCallback(productId, title, description, price);
},
fail: failCallback
}
alert("product id: " + productId + "key: " + key);
var callback = 'window.plugins.inAppPurchaseManager.callbackMap.' + key;
cordova.exec('InAppPurchaseManager.requestProductData', productId, callback + ' .success', callback + '.fail');
}
In code (b), everything works fine, till the line below:
cordova.exec('InAppPurchaseManager.requestProductData', productId, callback + '.success', callback + '.fail');
The question is: Why the app get stop at the above mentioned line. Also the alert box is displayed in code (b) which belongs to InAppPurchaseManager.js.
I have added an in-app item at itunesconnect and it is in "ready to submit" mode.

Problem solved.
In phonegap 1.8.1, we have to remove the prefix cdvjk_ from cdvjk_JSONRepresentation and all other variables from InAppPurchaseManager.m file.
I was able to perform in-app successfully..

Got it working somehow..
There was some problem in sandboxing the application. I also moved to Xcode 4.3 from 4.2.
Now I am able to fetch product details and get the log as below:
- Getting product data..
- Got iap product response..
- Sending js for "abc.pqr.xyz.productid" (product id)
followed by the exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI cdvjk_JSONRepresentation]: unrecognized selector sent to instance 0x9156f40'
Googled it but didn't find much.. I am using cordova-1.8.1.
Any solutions??

Related

OneSignal - Swift - Receiving push notification in different languages

I am using the sdk from OneSignal. Let's assume, I have following use case:
User A use my app in German language. He triggers an action within the app e. g. a like on an image of User B. User B gets a push notification about the like. But User B uses the app in English language. How can I achieve that?
I mean, I can send the notification message in a particular language but if User B decides to change the language of the mobile device to Turkish, then I have to be flexibel.
Is there any way, I can access the incoming push notification on the target device?
Currently, my code for sending the notification from the source device looks like this:
public func notifyAboutSubscription(userObject:User, receiverArray:[String]) {
var receiverArray = removeChallengeCreatorTokenFromArray(receiverArray: receiverArray)
notificationTypeService.clearReceiverListForNotificationType(completionHandler: { (clearedReceiverArray) in
receiverArray = clearedReceiverArray
let source = self.determineUserType(userObject: userObject)
// actual message is source + FOLLOW_MESSAGE
OneSignal.postNotification(["contents": ["en": source
+ FOLLOW_MESSAGE], "include_player_ids": receiverArray])
}, receiverList: receiverArray, notificationType: NotificationType.follow)
}
Alright. I just found out the solution. Here is the modified code from above:
public func notifyAboutSubscription(userObject:User, receiverArray:[String]) {
var receiverArray = removeChallengeCreatorTokenFromArray(receiverArray: receiverArray)
notificationTypeService.clearReceiverListForNotificationType(completionHandler: { (clearedReceiverArray) in
receiverArray = clearedReceiverArray
let source = self.determineUserType(userObject: userObject)
OneSignal.postNotification(["contents": ["en": source +
" started following you", "de": source + " folgt dir jetzt", "tr": source + " seni takip ediyor"], "include_player_ids": receiverArray])
}, receiverList: receiverArray, notificationType: NotificationType.follow)
}
You basically add for each language, the respective key. Depending on the device language, the correct message is shown.

Check subscription validity using Flutters in-app-purchase plugin?

I'm trying to implement in-app purchases using the official Flutter In-App-Purchase plugin. I've got things working, except I can't figure out how to tell if a users subscription is still active or if it expired. Even after I canceled my test subscription, the values I get after connecting and doing queryPastPurchases() are the same as when the subscription was active:
productId: test_subscription_1
transactiondate: 1565682346568
status: null
verificationData
source: IAPSource.GooglePlay
localVerificationData: {
"orderId":"GPA.1234-1234-1234-12345",
"packageName":"com.example.myapp",
"productId":"test_subscription_1",
"purchaseTime":1565682346568,
"purchaseState":0,
"purchaseToken":"<long string>",
"autoRenewing":false
}
serverVerificationData: "<long string>"
Am I supposed to simply hard code my subscription period and compare the current time to purchaseTime + the subscription period? Will that even work across auto-renewals? What if the user changes the date on his phone to a year ago? It seems like there should be some value that should either give me the expiration time or at least a boolean true/false to indicate if the subscription is still valid?
The official in-app purchase plugin handles making the purchase but doesn't supply all of the backend infrastructure you need to handle auto-renewing subscriptions specifically.
The short answer to your question is send this purchase info up to your server and manage subscription status there. Alternatively you can look into a managed solution like purchases_flutter: https://pub.dev/packages/purchases_flutter/
I have used ‘purchases_flutter‘ and the process is straightforward. You can check the status of the subscription by calling the methods which comes with the plugin. Check out this article which includes an example https://medium.com/flutter-community/in-app-purchases-with-flutter-a-comprehensive-step-by-step-tutorial-b96065d79a21
For anyone still having issues, there's a simple solution to validate the receipt on iOS
Here's a simple js snippet that you can use to fetch the actual receipt from Apple and use it to validate the subscription
Note
You will need to generate app specific password for the app from with apple developer account
Further help
https://developer.apple.com/documentation/appstorereceipts/expiration_intent
const axios = require('axios');
const iosValidateReceipt = async (transactionReceipt, isTest = true) =>
new Promise(async (resolve, reject) => {
const url = isTest ? 'https://sandbox.itunes.apple.com/verifyReceipt' : 'https://buy.itunes.apple.com/verifyReceipt';
const data = {
'receipt-data': transactionReceipt,
password: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
};
console.log('iosValidateReceipt - input - ', { url, data });
try {
const response = await axios.post(url, data);
console.log('iosValidateReceipt - success - ', JSON.stringify(response.data, null, 2));
resolve(response.data);
} catch (err) {
console.log('iosValidateReceipt - error -', err);
reject(err);
}
});

Not able to get data using MessengerExtensions.requestPaymentCredentials

Has anyone tried MessengerExtensions.requestPaymentCredentials using the facebook messenger extension sdk (refer documentation) ?
I am trying to call this in my client side javascript code and I am not getting any data. Below code doesn't alert me neither with email nor with error.
Here is my client side javascript code :
window.extAsyncInit = function() {
MessengerExtensions.requestPaymentCredentials(function success(name, email, cardType, cardLastFourDigits, shippingAddress) {
alert("Email" +email);
}, function error(err) {
alert("Messenger Extension error in getting payment credentials" + err);
});
};
Note : I am able to get user profile data using MessengerExtensions.getUserID by similar code.

Storekit requestProducts returns empty products array, nothing returned invalid

I am trying to get IAP working with Appcelerator Titanium 3.1. I have all the signing/certificates/provisioning profiles/contracts working. I was getting an invalid product ID, and fixed that issue. Now, the product array is simply returned empty when calling requestProducts().
When I requestProducts('valid_product')
Response: {"type":"callback","products":[{}],"source":{},"success":true}
When I requestProducts('invalid_product')
Response: {"products":[],"type":"callback","source":{},"invalid":["invalid_product"],"success":true}
Note that I do not get an invalid product returned when I request a valid product (setup in itunesconnect under IAP for this app), I simply get an empty string for the product array.
Why could this be happening? I have tried this for IAP products in the "Waiting for Review" status, as well as "Ready to Submit" status. I have not yet submitted the binary for review.
Any help would be immensely appreciated.
Regards,
Daniel
EDIT, code posted below
function requestProduct(identifier, success) {
showLoading();
Storekit.requestProducts([identifier], function (evt) {
hideLoading();
Ti.API.info('ReqProduct:' + JSON.stringify(evt));
if (!evt.success) {
alert('ERROR: We failed to talk to Apple!');
}
else if (evt.invalid) {
alert('ERROR: We requested an invalid product!');
}
else {
alert('success. product: ' + JSON.stringify(evt.products[0]));
success(evt.products[0]);
}
});
}
calling the above function as follows:
var product;
requestProduct('22credits', function(data) {
Ti.API.info(JSON.stringify(data));
product = data;
});

Store kit module error in titanium

Hi I am using store kit module in titanium.The code is working fine until i add the line of purchasing the product
My code is as follows
var Storekit = require('ti.storekit');
Storekit.requestProducts([ 'com.example.qld.inapp' ], function (evt) {
if (!evt.success) {
alert('ERROR: We were not able to get the product!');
}
else if (evt.invalid) {
alert('ERROR: We requested an invalid product!');
}
else {
alert(evt.products[0]);
Storekit.purchase(evt);
}
});
and when i add the purchase line it gives the following error
[ERROR] Exception in event callback: {
line = 14;
message = "*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]";
sourceId = 173081376;
sourceURL = "file://localhost/Users/aadilf/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/C7C55347-5965-4C58-9624-8A41837459D4/QLD%20Best%20Bets.app/home.js";
}
as i have not done objective c before i am unable to resolve this error
You're not specifying the object you want to purchase. You're purchasing the event itself (which contains a status, and zero, one, or multiple products).
Storekit.purchase(evt.products[0]);