On roblox studio how do you make a script only activate after purchasing a developer product? - roblox

On roblox studio how do you make a script only activate after purchasing a developer product?

The MarketplaceService.ProcessReceipt callback is called whenever a developer product purchase is completed. You should complete all the necessary steps to properly grant the product in the function set to this callback.
For example:
local MarketplaceService = game:GetService("MarketplaceService")
local function processPurchase(purchaseInfo)
-- Logic to handle purchase goes inside this function
-- Return Enum.ProductPurchaseDecision.PurchaseGranted upon successful purchase
end
MarketplaceService.ProcessReceipt = processPurchase
Besides granting the product, you could also perform other actions or make other function calls inside the callback function.

Related

PayPal Subscriptions: validating success on a server

I apologize in advance for this question, as its probably rather silly, but I really can not find any answers elsewhere.
My current goal is to integrate a subscription to my website, that allows for a user to have access to certain parts of the site.
I've watched a few videos on it, but it leaves me open ended with some questions.
PayPal allows you to manually create a subscription plan at https://www.paypal.com/billing/plans. When you create a plan here, it gives you the code you need to get the pay pal sub buttons to display on the page. Users can then use them to create the subscription. This is great. However, I have found now way to validate the results of the transaction. My goal would be that if the user was successful, I would be able to retrieve data via the API, that says it was successful, and I could then store than information in my database, and grant them access. Does anyone know how to get the data from the manually created facebook plans?
I did watch a video that had you do everything from your website (you create it all within your own code), the end result however sent everything through $_GET variables in the url. I feel like having this data exposed could result in the manipulation of the subscription, and grant it to users who were unsuccessful in creating a subscription.
I have no problem doing all of the coding to make this work, but I really want to make sure I do it the best possible way.
There is a few way to do it. By setting up a webhook and listen to paypal success notification and react to it. By using the Paypal Subscription API. Or a combination of both.
As you are using the paypal button you will have the onApprove function which will trigger upon user confirming the subscription. You can query the subscription data with:
onApprove={async (data: any, actions: any) => {
const detailedSubscriptionData = await actions.subscription.get()
// activate subscription on your side by sending it to your backend
...
// etc.
}}
Inside the data you have queried above, there will be a paypal transaction id (I-....) that is unique for each transaction, as well as your product id (plan_id). You can now do the following for verification on your backend:
Check if there is already a subscription (from another customer) on your side with that paypal transaction id
Check for the plan_id
Queried the API Subscription Details with the paypal transaction id and check for status, etc. as well as matching of plan_id
Keep in mind that for using the API you will have to queried for an access-token which in turn required you to have Developer App Setup following these steps.

askForPermission not working on Actions on Google simulator

I am trying to get the current location of the user and I am using the Api.AI web tool to create my actions/intent.
Deployed using -
firebase --only functions
API.AI Action -
Simulator -
Full index.js - link
But when my action is triggered I get this message -
Sorry, this action is not available in simulation
Can't we ask for permission on a simulation ? Also how do I test my app on a real device ?
EDIT:
The permission function is stuck in a loop -
Your problem is in this block of code:
//Action business logic
function welcomeMessage(app){
app.tell('Welcome !, Do you want to book a ride ?'); // Todo: Insert proper messages.
}
The app.tell() method sends the message and then closes the conversation. If you want to send the message to the user and keep the conversation going (ie - you're expecting a response) you need to use app.ask().
This is what is causing the "Sorry" message when you reply "Yeah" - your Action is no longer listening.
You can ask for permission in the simulation.
Once you have run it once in the simulator, you should be able to access it on any device that is linked to the same account you used to develop the Action, or to other accounts you've permitted (once they have run the simulator).

AWS APIGateway & Lambda - How to call function right before iOS App terminates?

I have been working with AWS for a little while now and I am starting to get the hang of APIGateway and Lambda. I have just made a Lambda function that receives the username entered by a user and then uses the AdminDeleteUser function to delete that user from the user pool, and it works fine. I even have it set up with APIGateway to be used in XCode and it works fine with that as well.
Problem
My problem is, is that I am trying to have the Lambda function run right as the user terminates the iOS app. I am using a NotificationCenter observer to watch when the App terminates, that all works well except the fact that I believe the Lambda function's call is cancelled once the app fully terminates, meaning it can't complete the full request. My lambda function essentially checks if the username that is being received is a user who is unconfirmed, and if they are unconfirmed then they are deleted from the user pool. I am doing this on the screen where the user has to confirm a confirmation code that was sent via SMS
Question
So I guess the questions I have are,
Is it possible to call a Lambda function while the App is terminating?
If not, is it possible to delete the current user from the user pool if they are not confirmed, before the App exits?
Thank you in advanced.
It sounds like what is happening is exactly what you have described above. The app is exiting before the connection can be made to the service.
A better design might be to have a process run at X interval (using a Lambda scheduled event) to automatically remove any unconfirmed users from your data store.
Edit:
When searching for unconfirmed users, you should be able to use the UserCreateDate field to check if the user has registered within your specified amount of time. If 'createDate' falls within that time, ignore that user.
ListUsers API

MKStoreKit -isSubscriptionActive always return False

I am Using MKStoreKit for autorenewable subscription.
On Button's TouchUpInside method I am using following code..
if([[MKStoreManager sharedManager] isSubscriptionActive:kSubscriptionMonthlyIdentifier]){
//access to subscription feature
}else{
//ask user to buy
}
It always returns me false. And ask user to buy.
When I tried to buy again it shows me that You are already subscribed.
Is there something that I am doing wrong?
Is there any other method to check if subscription is active or not.
How should I know that subscription is renewed?
Any help would be appreciated.
Thanks in Advance.
1) You should initialize MKStoreKit by adding [MKStoreManager sharedManager]; in your applicationDidFinishLaunching.
2) You should check, that you correctly fill MKStoreKitConfigs.plist:
you must add your subscriptions in-app ids to Subscriptions dictionary (in format: "subs id" - "subs duration").
In apple documentation you could find info about auto-renewable subs:
every renewal of the auto-renewable subscription new transaction would be generated and send to your application. In theory, MKStoreKit must take care about all this stuff, and isSubscriptionActive should work.
Also, you could add button for restoring previous purchases. So, in your case, when user press buy button before calling -isSubscriptionActive call -restorePreviousTransactions, or you can add this button, so user can restore previous transaction^ if he already has bought subscription.
You could add observers for this notifications:
#define kSubscriptionsPurchasedNotification #"MKStoreKitSubscriptionsPurchased"
#define kSubscriptionsInvalidNotification #"MKStoreKitSubscriptionsInvalid"
First notification MKStoreKit generate, when Subscription was renewed (or purchased), second one - when renewing failed.
There is an open issue on the MKStoreKit GitHub that might be related to what you are experiencing. The people in that thread claim that after the app is initialized MKStoreKit always returns NO for isSubscriptionActive. It seems they were able to successfully use a previous release of MKStoreKit, though. You might want to try that.

Clearing purchases from iOS in-app purchase sandbox for a test user

Does anyone have any ideas on how to reset and/or clear the iOS in-app purchase sandbox?
I have an app that I'm testing with the sandbox, and I'd like to test new purchases without having to create a new test user every time I purchase something.
If I don't do this, then I (of course) always get a message that the in-app purchase item has already been purchased when I click on my app's buy button.
IMO there are 3 things you can do to make testing non-consumables bearable:
You can have many test accounts associated to one email. Gmail for example lets you add a "plus" string to the email to create aliases for an address: so tester+01#gmail.com and tester+02#gmail.com both really just go to tester#gmail.com. Probably other email hosts do the same. When you create a test account you need to introduce: first name, last name, email address, password, secret question, secret answer, date of birth, and iTunes store country. You can put exactly the same data (including password) for tester+01#gmail.com and tester+02#gmail.com and you will have two test accounts. Finally, in your tester#gmail.com inbox you will receive two verification emails from Apple to confirm both test accounts.
Say that you have a non-consumable with product ID #"Extra_Levels". Instead of writing #"Extra_Levels" in all methods (requestProduct, purchaseProduct, ...), just write PRODUCT_ID1 and at some header file put #define PRODUCT_ID1 #"Extra_Levels" (with no semicolon!), then the preprocessor will search PRODUCT_ID1 and substitute it for #"Extra_Levels". Then creating a new non-consumable called #"Extra_Levels_01" and changing the #define will be as good as resetting the purchases for all your test users.
As appsmatics pointed out, you can test the correct behavior of your code when you buy a non-consumable IAP by first using a consumable IAP (so that test user can make as many purchases as needed) to get rid of some bugs. Of course, you should also test the code with the real non-consumable IAP after that.
You can't do this, as far as I know. The sandbox backend works like a real account-- once it's purchased, it's purchased (and thus you can test restore). You should do most of your development with the store stuff shimmed out, and then when you get to testing it for real, just expect to create several test accounts.
You can clear the purchase history for a tester so that you can continue to use the same sandbox Apple ID for ongoing testing. Clearing purchase history will delete all past auto-renewable subscriptions and non-consumables purchased by the selected testers in the sandbox environment. In-app purchases made by customers on the App Store are not affected.
To clear tester purchase history:
From Users and Access, under Sandbox, click Testers.
Click Edit.
Select the checkbox for each tester you want to modify and click Clear Purchase History.
Click Clear Purchase History in the dialog that appears.
Sandbox Apple IDs with a high number of purchases may take longer to clear. This action cannot be reversed.
I have 2 in app purchase items.
1 for production.
and the other for testing. when I need to "clear" I delete the in app item and create new one (15 seconds in itunes connect and 1 second to change the product id in code)
if i dont need to test "new user", i use the production in app item.
Deleting your app and reinstalling works also for sandbox testing. Depends on the app obviously, but I'm testing a subscription based app that only purchases during sign up at the moment so it's been the easiest solution.
Well, technically you don't need that.
If you get SKPaymentTransactionStateRestored, it is 100% equivalent to the app store verifying the user and granting him the purchase. I have a switch like:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for( SKPaymentTransaction *purch in transactions )
{
switch( purch.transactionState )
{
case SKPaymentTransactionStateRestored:
info( "PURCHASE RESTORE" ) ;
// fall thru
case SKPaymentTransactionStatePurchased:
[[SKPaymentQueue defaultQueue] finishTransaction:purch];
// Do regular changes to app state for this purchase,
// register in keychain, etc.
break ;
//.. other cases
}
}
}
The question of having your app logic / take back the purchase is simple: if you're caching purchases in keychain, delete your keychain. If you're doing it some other how, just change your local app state to pretend like the user never purchased it before. The request to purchase dialog is still exactly the same, the only difference is when you punch YES, it gives you SKPaymentTransactionStateRestored instead of SKPaymentTransactionStatePurchased.
You can clear the purchase history for a sandbox Apple ID in App Store Connect.
To clear tester purchase history:
From Users and Access, under Sandbox, click Testers.
Click Edit.
Select the checkbox for each tester you want to modify and click Clear Purchase History.
Click Clear Purchase History in the dialog that appears.
see Documentation https://help.apple.com/app-store-connect/#/dev7e89e149d
Check out SimStoreKit. It's a "simulated version of the iPhone's StoreKit, for testing store UIs on the iPhone Simulator, or even on device without having to set up IAP in Connect."
SimStoreKit stores purchases in the user defaults under the key ILSimSKTransactions. So to clear all purchases you can do:
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"ILSimSKTransactions"]
On the simulator, you can simply remove your app and install it again.
I've successfully used SimStoreKit to debug my app's store front before testing with the sandbox. The beauty of this library is that it can be set-up to use the same class names as the real StoreKit framework (by doing #define ILSimReplaceRealStoreKit 1 before doing #include <ILSimStoreKit.h>).
In source files where I need to access StoreKit, I include this header file:
#import <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR
#define kILSimAllowSimulatedStoreKit 1
#define ILSimReplaceRealStoreKit 1
#import <ILSimStoreKit.h>
#else
#import <StoreKit/StoreKit.h>
#endif
This has the effect of using SimStoreKit when I run on the simulator and the real StoreKit when I run on the device.
This is now possible for subscriptions purchases through Reset Eligibility
On the test iOS device, open Settings > Apple ID > Media & Purchases (or iTunes &/or App Store for iOS 13 and earlier). Under the Sandbox Account section, tap your highlighted Sandbox Apple ID then tap Manage to open the sandbox Subscription Management page.
If the subscription has expired, tap one of the options to resubscribe.
Once you resubscribe or when you have a subscription going on, you can use the Reset Eligibility button to reset and redeem another introductory offer (trial or discounted price).
Just keep using the same test account, restoring purchases as opposed to completing new ones. After all, whether you start a new purchase or restore an old one, YOUR APP will do the same thing (at least initially, maybe the user interface will update differently upon completion). Apple are the folks handling things differently in those different situations - don't worry about it.
Place your delivery logic in the SKPaymentTransactionStateRestored case within this method's implementation for testing:
- (void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray *)transactions;
Then be sure to put that delivery logic into the SKPaymentTransactionStatePurchased case.
At the end, because most of us are obsessive-compulsive to varying degrees, do a final test with a fresh account (not a big deal to make a second one for absolute certainty).
The final thing to note: consider apple's position. If there was a problem with developers having to waste time creating tens or hundreds of accounts to test IAP thoroughly, they would have solved the problem. There is no problem.
alternatively to create multiple test user solution you can create multiple test in app purchases in iTunes connect then you don't need to change a user account.