Any example on how to implement the new VerificationController and the KNOWN_TRANSACTIONS_KEY constant? - iphone

I've been looking at implementing the new VerificationController to verify in-App-Purchases:
http://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/_index.html
And I wonder if there is some example anywhere en how to validate a transaction, since it seems that the - (BOOL)verifyPurchase:(SKPaymentTransaction *)transaction; is not enough and it has to be implemented internally to verify the purchase when the data form the server is received.
Another question is if anyone has a clue on what the KNOWN_TRANSACTIONS_KEY is and how to fill it, is it just the product id of the purchase?

In the file "VerificationController.m", check this function:
- (void)saveTransactionId:(NSString *)transactionId
we can see, KNOWN_TRANSACTIONS_KEY is a key to be wrote to NSUserDefaults. So we don't need to touch it.
login iTunes Connect > Manage Your Apps > (click your app) > Manage In-App Purchases > click the link View or generate a shared secret (at bottom-left of the page)
it'll show us:
A shared secret is a unique code that you should use when you make the
call to our servers for your In-App Purchase receipts.
Just click Generate.

You can find a complete implementation over here: https://github.com/evands/iap_validation

RayWenderlich.com Tutorial
This article, In-App Purchases in iOS 6 Tutorial: Consumables and Receipt Validation on the RayWenderlich.com site, offers a download of Apple's code but fleshed-out (including Base64 methods) and tweaked.

You need to perform the validation on a transaction when it changes to one of the completion states:
SKPaymentTransactionStatePurchased
SKPaymentTransactionStateRestored
call the function:
[[VerificationController sharedInstance] verifyPurchase:transaction];
As you say it is not enough to just look at the return value. The function is asynchronous. You need to add some code to VerificationController.m where it says:
#warning Validation succeeded. Unlock content here.
There are also a few other lines with #warning in VerificationController.m where you need to deal with errors.
As for base64 another library you might want to look at using is:
http://www.imthi.com/blog/programming/iphone-sdk-base64-encode-decode.php
When it comes to
KNOWN_TRANSACTIONS_KEY
and
ITC_CONTENT_PROVIDER_SHARED_SECRET
I too would like to know what they are for and why and when they are needed.

Related

Parse Signup Problems

So, I wanted to create a new social media app using Swift and Parse. When I go to the Parse site, and click on dashboard, it gives me a login screen. I don't have an account, so I click on the "I don't have a parse account" button. When I click on that, it just takes me back to the home page. I did manage to get the code and frameworks and stuff that I needed from the docs, but that didn't quite work. It gave me this for the initialize code:
let configuration = ParseClientConfiguration {
$0.applicationId = "YOUR_APP_ID"
$0.server = "http://YOUR_PARSE_SERVER:1337/parse"
}
In the tutorial I'm watching, rather than "YOUR_APP_ID" and "http://YOUR_PARSE_SERVER:1337/parse" it just had a bunch of letters and numbers, which I would assume are the app ID and Parse server. My guess is, that I need an account to get those. Would that be correct? And, does anyone know why I can't seem to get an account? Thanks.
Parse.com is shutting down, so that's why you are not allowed to create new accounts on the service. Check the blog post.
They open sourced a nodeJS implementation, which you should definitely check out at link, and here is an example to get you started. You can easily use the deploy buttons to host the server on services like Heroku, AWS, Azure, etc. You can also deploy a server locally, for testing purposes.
Although it's true that Parse is discontinuing early next year, you can still setup a new app if you want to use the service for a shorter term project. Replace your code with the following.
Parse.setApplicationId("YOUR-APP-ID", clientKey: "YOUR-CLIENT-ID")
You can find your App ID and Client ID in your app's settings > security & keys.
EDIT: You definitely need an account for this to work.

Encoding problems in PayPal Here callback URL?

I'm trying to get PayPal Here to issue a callback to a FileMaker Go database. It looks like the fmp:// protocol is being used correctly, but seems that there may be some kind of other problem with the callback URL.
Here's the URL that I'm using to call PayPal Here (note that I'm not stripping out the carriage returns from the base64-encoded invoice in my application; this is the actual URL my application sends to the OS, and the invoice appears to be fine in PPH):
paypalhere://takePayment?as=b64&accepted=card%2Cpaypal&returnUrl=fmp:%2F%2F$%2Ffmg_pphTest&step=choosePayment&invoice=eyJwYXltZW50VGVybXMiOiJEdWVPblJlY2VpcHQiLCJkaXNjb3VudFBlcmNlbnQiOjAsImN1cnJl
bmN5Q29kZSI6IlVTRCIsInBheWVyRW1haWwiOiJjcmlzdG9zK3Rlc3RAY3Jpc3Rvc2xjLmNvbSIs
Iml0ZW1MaXN0Ijp7DQogICAgIml0ZW0iOiBbDQogICAgICAgIHsibmFtZSI6IkRpbGl0aGl1bSBD
cnlzdGFsIiwiZGVzY3JpcHRpb24iOiJNYWtlcyBzaGlwIGdvIGZhc3QuIiwidW5pdFByaWNlIjow
LjEsInF1YW50aXR5IjoxMCwidGF4UmF0ZSI6MCwidGF4TmFtZSI6IlRheCJ9DQogICAgXQ0KfX0=
This is the URL that I want to fire (this is just for testing; later on, there will be additional parameters added on to send the payment status, etc., but I can't even get this basic version to work yet):
fmp://$/fmg_pphTest
However, the behavior I'm seeing looks like this is the URL PPH is actually sending:
fmp://
Testing is being done on an iPad 2 running iOS 8.3. Any thoughts/suggestions out there?
A kind soul on the FileMaker Community boards pointed me at a working example, https://github.com/Genecom/FileMakerSampleSolutions. After doing some comparisons, I discovered the issue is due to using base64-encoding of the JSON invoice object. When I changed it to use URL-encoding of the JSON invoice (like the Genecom example), I was able to get the callback URL to work successfully.
I opened an issue on the PayPal Here github project, please feel free to chime in there if you've also experienced this issue (or found countervailing evidence): https://github.com/paypal/here-sideloader-api-samples/issues/26

Payment Transaction State Failed

I am trying to make In-app purchase in my application using phonegap plugin which is https://github.com/phonegap/phonegap-plugins/tree/master/iPhone/InAppPurchaseManager
but in sandbox testing i'm getting following error
plugins.inAppPurchaseManager.updatedTransactionCallback.apply(plugins.inAppPurchaseManager, ["PaymentTransactionStateFailed",0,"Cannot connect to iTunes Store","","",""])
and then the application gets struck...can anyone help me out with this??
Take a look inside of InAppPurchaseManager.js, and you'll see the first call of InAppPurchaseManager.prototype.updatedTransactionCallback is:
alert(state);
Replace that with PhoneGap's preferred:
navigator.notification.alert(state);
And it should clear up fine.

CurrentAppSimulator.RequestProductPurchaseAsync purchasing simulation

I am trying to implement in-app purchase for my Windows Store App (Metro App). I was referring to the code samples here, but when I triggered the RequestProductPurchaseAsync method nothing happens.
When I say nothing happens, it means literally nothing. No return results (the result was supposed to be a receipt since I passed in true for includeReceipt). Also, when I re-checked the ProductLicences[string].IsActive flag it will always return me false.
How do I test this out properly? Thanks a lot!
Make sure the app LicenseInformation.IsTrial is false, otherwise it won't work. In-app product purchases require that the app not be in trial. In a published app, the user would see an error stating that you can't do in-app product purchases under trial license. The simulator doesn't show this warning in the in-app purchase simulation dialog during testing.
You can either modify the initial state of the simulation (see the samples for how to do that) or call RequestAppPurchaseAsync(false) during the simulation run to get a full license for the app, then try the product purchase.
We experienced and solved a similar problem.
Using CurrentAppSimulator worked fine, but bringing up the real purchasing UI with CurrentApp did not.
In a production setting await CurrentApp.RequestProductPurchaseAsync(string,bool) seemed to never return (more specifically, it only returns once after the user has logged in -- subsequent calls did not return).
Additionally, after we tried to bring up the purchasing UI in our app, other applications using the purchasing UI had the same problem -- UI never shows.
Here is the problem code:
private async void CommandInvokedHandler(IUICommand command)
{
switch (command.Label)
{
case "Continue":
licenseInformation = CurrentApp.LicenseInformation;
if (!licenseInformation.ProductLicenses[Notes.ProductName].IsActive)
{
try
{
await CurrentApp.RequestProductPurchaseAsync(Notes.ProductName, false);
// The code never steps over
}
The somewhat-obvious problem with the code above is that the request to bring up the in-app purchase UI is made from within a modal dialog box command handler. The request hangs -- never returns. The not-so-obvious part is that it also blocks all subsequent requests from our application and every other application (until the user's session is restarted).
Upon moving the "try" block out of the command handler, and ensuring that there are no modal UI calls contesting the purchase request, purchasing worked without issue.
EDIT: You should restart (or re-login) to test this. Once the purchasing UI breaks, it will not show until you restart or re-login.
There is a small nuance to follow: to be able to purchase anything using CurrentAppSimulator one needs to call CurrentAppSimulator.RequestAppPurchaseAsync before making any purchase requests. After the operation returned by the call is done, you can successfully call CurrentAppSimulator.RequestProductPurchaseAsync (unless the IsTrial value in LicenseInformation element is set to false in the xml).

How to use FB.Event.Subscribe securely to call webservice

I'm looking at using the FB.event.subscribe method to get a notification whenever someone leaves a comment in the FB comment plugin.
However, I want to use Ajax to call a webservice I've exposed on my server to keep track of (a) What was commented on (b) who left the comment.
I have the following questions and was hoping to get some help:
Does the what information does the FB.event.subscribe give me to my function? The FB documentation is totally anemic and doesn't give enough detail. For example, I want to know WHO left the comment.
If I call a webservice, say to insert a row in my DB to keep track of comments, such as what the comment is and what datetime it was left. If I use Ajax to just call a web service, how do I do it securely? Since it's ajax, anyone can view source and see the endpoint I'm calling. I can't use a token since that's exposed.
Answer to question 1:
You can do below snippet to find out what you get from facebook api while firebug's console window is opening.
FB.Event.subscribe('comment.create', function(response) {
console.log(response);
});
Answer to question 2:
You might need to implement your own security mechanism to secure the webservice you have. It can be done by checking a token when it be called or whatever something else.