My app keeps getting rejected for the silliest thing.
Using unity's In app p urchasing package 4.12.2
The sandbox store displays a screen as you initialize a purchase
comes from the call IStoreListener.InitializePurchase(Product product);
The screen says 'purchasing.. Native Android/iOS purchase window should be displayed'
because of this they wont allow my app to be approved. Ive spent countless hours trying to remedy this. mustilple appeals and submissions.
the developers at unity say theyve never run into this before.. Apple just keeps sending me the same text template and wont answer my questions.
someone please help.
In-App Purchase
RSS for tagOffer extra content, digital goods, and features directly within your app using in-app purchases.
Posts under In-App Purchase tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
The application has changed from paid purchase to free use. We need to obtain the previous player's purchase records to unlock the paid content.
//Here is the code for the client to obtain the player's payment information:
NSURL * receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptURL path]]){
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
NSString *receiptUrlString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSLog(@"requestAppStoreReceipt receiptUrlString = %@", receiptUrlString);
} else {
// 如果凭证为空,则再发一次凭证请求
SKReceiptRefreshRequest *refreshReceiptRequest = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:@{}];
refreshReceiptRequest.delegate = self;
[refreshReceiptRequest start];
NSLog(@"requestAppStoreReceipt 如果凭证为空,则再发一次凭证请求!");
}
//The following is the server-side parsing code:
Path filePath = Path.of("SubscriptionKey_ABCDEFGHIJ.p8");
String encodedKey = Files.readString(filePath);
Environment environment = Environment.SANDBOX;
AppStoreServerAPIClient client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment);
String appReceipt = "MIIcs...";
ReceiptUtility receiptUtil = new ReceiptUtility();
String transactionId = receiptUtil.extractTransactionIdFromTransactionReceipt(transactionReceipt);
System.out.println(transactionId);
if (transactionId != null) {
long now = System.currentTimeMillis();
TransactionHistoryRequest request = new TransactionHistoryRequest()
.sort(TransactionHistoryRequest.Order.DESCENDING)
.revoked(false)
.productTypes(List.of(TransactionHistoryRequest.ProductType.CONSUMABLE));
HistoryResponse response = null;
List<String> transactions = new LinkedList<>();
do {
String revision = response != null ? response.getRevision() : null;
response = client.getTransactionHistory(transactionId, revision, request, GetTransactionHistoryVersion.V2);
transactions.addAll(response.getSignedTransactions());
} while (response.getHasMore());
Set<InputStream> rootCAs = Set.of(
new FileInputStream("AppleComputerRootCertificate.cer"),
new FileInputStream("AppleIncRootCertificate.cer"),
new FileInputStream("AppleRootCA-G2.cer"),
new FileInputStream("AppleRootCA-G3.cer")
);
Long appAppleId = 1234567899L; // appAppleId must be provided for the Production environment
System.out.println(transactions.size());
SignedDataVerifier signedPayloadVerifier = new SignedDataVerifier(rootCAs, bundleId, appAppleId, environment, true);
for (String notificationPayload : transactions) {
try {
AppTransaction payload = signedPayloadVerifier.verifyAndDecodeAppTransaction(notificationPayload);
System.out.println(payload);
} catch (VerificationException e) {
e.printStackTrace();
}
}
}
//Return result analysis:
JWSTransactionDecodedPayload{originalTransactionId='2000000641683476', transactionId='2000000641683476', webOrderLineItemId='null', bundleId='', productId='', subscriptionGroupIdentifier='null', purchaseDate=1719566962000, originalPurchaseDate=1719566962000, expiresDate=null, quantity=1, type='Consumable', appAccountToken=null, inAppOwnershipType='PURCHASED', signedDate=1728885967093, revocationReason=null, revocationDate=null, isUpgraded=null, offerType=null, offerIdentifier='null', environment='Sandbox', storefront='CHN', storefrontId='143465', transactionReason='PURCHASE', price=6000, currency='CNY', offerDiscountType='null', unknownFields=null}
We have develop according to the following document on our end:
https://developer.apple.com/documentation/foundation/nsbundle/1407276-appstorereceipturl#4098404
https://developer.apple.com/documentation/appstoreserverapi/get_transaction_info/
https://developer.apple.com/documentation/appstoreserverapi/data_types
We would like to know if the solutions in the document can be used to solve the problems we encountered?
Is there a problem with our method of parsing bills that prevents us from obtaining the necessary information?
I am working on the integration of subscriptions in my OSX application. The subscription flow works perfectly but after the purchase it is not creating _MASReceipt folder in Contents folder of application so I cannot send the receipt to apple to verify this purchase. when I checked the logs it showing below error. Anyone who is familiar to this issue please help.
Error writing receipt (13401 bytes) using privileged service to /private/var/folders/xw/yd038cts3b94qmtvlxzb1sy80000gp/T/AppTranslocation/9B8BB321-1C16-4F41-93EA-E27675791E79/d/test.app
Error Domain=NSCocoaErrorDomain Code=642 "You can’t save the file “_MASReceipt” because the volume “9B8BB321-1C16-4F41-93EA-E27675791E79” is read only." UserInfo={NSFileOriginalItemLocationKey=file:///private/var/folders/xw/yd038cts3b94qmtvlxzb1sy80000gp/T/AppTranslocation/9B8BB321-1C16-4F41-93EA-E27675791E79/d/Advanced%20Uninstall%20Manager.app/Contents/_MASReceipt, NSURL=file:///private/var/folders/xw/yd038cts3b94qmtvlxzb1sy80000gp/T/AppTranslocation/9B8BB321-1C16-4F41-93EA-E27675791E79/d/abc.app/Contents/_MASReceipt, NSFileNewItemLocationKey=file:///System/Library/Caches/com.apple.appstored/abc.app/_MASReceipt/, NSUnderlyingError=0x7fdc618ded90 {Error Domain=NSCocoaErrorDomain Code=642 "You can’t save the file “_MASReceipt
We are currently experiencing an issue where our server is not receiving Apple’s server notification (webhook) for in-app purchase confirmations. This notification is critical as it helps us confirm the purchase status and fulfill the corresponding services to the users. Despite the successful completion of purchases within the app, the lack of webhook notifications prevents us from tracking and processing these payments on our backend.
In addition to resolving this issue, we are also concerned about the security aspect of receiving server notifications. Specifically, we want to ensure that any requests or notifications we receive are indeed coming from Apple, and not subject to potential man-in-the-middle (MIM) attacks. We are looking for information or best practices on how to validate that the request originates from a legitimate Apple source, ensuring the integrity of the communication and safeguarding our system from spoofed or malicious requests.
Key questions:
Server Notification Issue: Why might we not be receiving Apple's payment confirmation notifications, and what steps can we take to troubleshoot this issue?
Request Validation: What security mechanisms or validation techniques can we implement to confirm that the server notifications are genuinely from Apple, ensuring no interference from MIM attacks?
Does Apple provide any headers, tokens, or signatures in the server notification that we can use to verify the origin?
Are there any known methods or configurations to ensure secure receipt of in-app purchase confirmations?
We are looking for guidance and possible solutions to ensure a secure and reliable payment validation process for our in-app purchases. Any support in this regard would be highly appreciated.
How does the App Store handle localized content fallbacks in the store listing, in app products, and game center content?
For example, if a user's language is set to Portuguese (Portugal) pt-PT, and I don't supply a translation for pt-PT but I do for pt-BR (Brazil), will it show the user the pt-BR translation or as a developer, do I need to provide both translations (i.e. all language variations/regions)?
Another example, if I provide translations for en-US and en-GB and the user's language is Australian English (en-AU), will it show en-US or en-GB on the store or in Game Center? I would expect it to use en-GB.
Hello All,
My team and I are developing a mobile application (offgrid) to help combat screen addiction. Our application will allow users through gamification, to challenge each other to stay off certain predetermined apps on their phone for a set amount of time and risk their own money. The money will act as a reinforcement to stay focused and off the application. Example: Jon challenges Jen to stay off Instagram for 1 hour for $5. If Jen accepts the challenge, she and Jon cannot go on Instagram. If Jen or Jon decides to click the Instagram app within the hour, the $5 automatically goes to the winner via Apple Pay or another service. If they complete the challenge and stay off Instagram then there is no exchange of money. I will also give the option for users to challenge each other and risk their money for a charity cause if someone loses.
My question is, will the exchange of money count as an in-app purchase, or will the winner receive the full amount? Also, if the money goes to charity, will that count as an in-app purchase?
Thanks!
My team is developing a subscription feature where users can subscribe to individual educators on our platform to access their content. We are considering using a web view within our mobile app to handle subscription payments through third-party payment providers like Stripe, similar to how apps like Patreon manage payments. This approach would keep users within the app during the transaction process. Would implementing this payment flow comply with Apple’s policies?
Here's an idea to make it easier for users to get activated in the app. We can't give free access by default, because we incur costs for each activated user in the app. Can I give in-app access for registering with a partner and making a deposit with them, and then give the user a subscription plan for free for 30 days, without IAP and auto-renewal? The rules say you can't use third party payment methods, but it's part of the app that the user has to register with a partner, just for making a deposit to the partner, we give a trial gift.
we have now two Apps in the App store and they both should be only allowed subscription.
App # 1 is working fine with In App Subscription.
We applied the same logic as the first one but still the second App behaves diferentöy
App #2 is now live and for some reason one needs to purchase the App as In App purchase.
In test flight this issue was not present.
Is there someone to contact at Apple to find out why this is the case?
We also do not know from where the price for the in App purchase comes from as there is no value, only in Subscriptions.
Hi,
I've implemented a custom StoreKit2 manager, which can handle nonConsumable and autoRenewable products. All works as expected on the developer machine.
Problem 1: But when I archive the build, distribute to TestFlight, change to a new system user without Apple ID and starting the app, a login popup appears. There I enter the login data from App Store Connect Sandbox User and a message pops up:
If I hit the "Change Store" button, another message pops up which says (in German): "Connection to App Store not possible".
Problem 2: Also the paywall shows the translated text for the German test user, but the products are not using their translations.
Here is what I did:
I've setup 1 nonConsumable product and 2 autoRenewable products in App Store Connect
I've translated the products for US in English(default) and German
In Xcode I created a synced Products.storekit file
The storekit file syncs with App Store and shows all product data and translations correctly
In the build scheme I've added the Products.storekit file under Options for "StoreKit Configuration"
For every TestFlight build I change the build number
On the developer machine:
With the storekit file selected, I can change the default Storefront and default localisation through menu entry Debug
all data shows correctly and purchasing is possible. Everything works as expected
On the test machine:
it does not work and shows the dialogs with the title "Account Not in this Store"
What am I missing here?
Thanks for your help!
Arne
It's a brand new app that hasn't got its first approval yet. I am including IAP subscriptions with it and after each rejection, I am unable to clear the Developer Action Needed status of the Subscriptions and re-include in the binary for review.
To clarify, after I created the Subscriptions I was able to include them in the binary, but after each rejection the Developer Action Needed status is not cleared, even though I edit the descriptions and save.
If I update the Localization on each Subscription, they do change status to Prepare for Submission, but the Subscription itself remains on Developer Action Needed.
I am having to create a new Subscription Group and Subscription with each rejection from the Review Team, because otherwise I cannot submit them with the binary for review.
Can anyone shed some light here? It seems there's a ton of other topics with the same issue that suggest to edit a description, which would then update the status to Ready to Submit but no matter what I try, it won't clear the Developer Action Needed.
Thank you
Hello. For some reason the purchases work perfectly in sandbox but production it’s not working. I can see the purchase in my revenuecat dashboard so it's not a revenuecat issue, but I don’t see any logs in my server.
To make sure I deleted the app and re installed the development build to make another purchase, and it worked perfectly (because they are in sandbox), meaning the purchase appears in the RC dashboard but I also can see the logs in my server.
It’s crucial that this works because it’s my server that adds the tokens to the customer’s account.
I've tried setting the url again and also tried setting only the production URL. But the result is the same, only the sandbox URL is triggered, production URL is not.
We experienced an issue with delayed App Store Server notifications for an Auto-Renewable Subscription purchase in our app.
On September 27, 2024, at 22:28:28 GMT+0900, a user successfully purchased a Premium membership subscription (transaction ID: 190002223966278, webOrderLineItemId: 190001007274949).
However, our server did not receive the corresponding App Store notification for this transaction after purchase.
The App Store Server Notification was only received 66 minutes later, at 23:35:16 (transaction ID: 190002224000004, webOrderLineItemId: 190001007274949).
The delayed notification contained a different transaction ID than the initial purchase.
We would like to inquire about the cause of this delay and request assistance in understanding why the notification took 66 minutes to be delivered to our server, instead of arriving immediately after the transaction was completed.
Additionally, we would appreciate your guidance on how to prevent or mitigate such delays in the future, ensuring a seamless experience for our users.
Are there any best practices or recommended approaches we should implement to handle potential notification delays more effectively?
We have provided detailed information about the received notification and the related transactions in the Feedback Assistant (FB15330451).
Thank you for your assistance in resolving this matter.
Key Details
Purchase time: 2024-09-27T22:28:28 GMT+0900 (1727443708000)
Notification received: 2024-09-27T23:35:16 GMT+0900 (1727447716463)
Delay: 66 minutes and 48 seconds
Initial Purchase Transaction ID: 190002223966278
Initial Purchase Web Order Line Item ID: 190001007274949
Transaction ID in Delayed Notification: 190002224000004
Web Order Line Item ID in Delayed Notification: 190001007274949
Additional info
Bundle ID: com.reppley.ReppleyApp
SKU: com.reppley.ReppleyApp
Feedback Assistant Number: FB15330451
Hi I'm writing my first in-app purchase app, and I'm trying to do some testing with sandbox accounts. I wrote my subscription page use SwiftUI SubscriptionStoreView. And I read the documentation it says :
The sandbox account appears in Settings > App Store after the first time you use the device to attempt a purchase in a development-signed app.
But I have no idea how to make a sandbox purchasing. Every time I click the subscription button it just making a purchase in xcode environment. Did I missed anything? What can I do to make a sandbox pruchasing?
Hi,
Pretty sure abusive refunds are hurting our app placement. Noticed we had two refunds in the exact same hour from Poland and thought it odd since Poland makes up a very small part of our user base. Extra odd since we've had few refunds in general (~2% when comparing against activations + renewals) so I was worried our backend servers were down and the app not working but noticed no problems. I then checked the past 5 months (life time of our app) and noticed that over 60% of our refunds are all from Poland even though it makes up a very, very tiny amount of our sales.
I then also remembered my user support team member telling me they get endless emails from one user in Poland who is making rather unusual and paranoid statements about how various governments are out to get them along with complaining about our app not stopping them...at least that's what the machine translation is telling us, it's all in Polish.
Assuming it's all done by this one guy, their pattern is purchase, a few days later a refund, a few days go by, another sale, a day or two later, refund, etc. Then one day two sales and then two weeks later, two refunds at the same exact hour (presumably from two different Apple IDs this person has). As I was writing this it happened again, two more refunds (although this time I don't see the purchases they are tied to).
I'm considering just removing Poland from the list of countries for my IAPs. I don't want my app placement ruined by refunds associated with one user in one country! I've already noticed a sudden drop in installs in the past week corresponding to this guy increasing the frequency of this and I'm starting to get very worried!
I also noticed that nothing is pro-rated, the refunds match the proceeds exactly while the person does things with the app that cost us money on the server/cloud costs side. Fortunately it's not a lot so more surprised than concerned. I thought each day they waited after a purchase to request a refund they would still owe 1/30 of the monthly subscription price.
My questions are:
Can this truly be the same user or would Apple have blocked them from doing this cycle by now? I assume even if they used a new Apple ID that using the same purchase method would get them flagged.
Are a few refunds hurting our app placement in the App Store or as long as we're relatively low overall it's fine? It's been a marked change in # installs per day in the past week...
Is there a way to ask Apple to block one specific person from buying your app? I know their Apple ID (or at least one of them) since they emailed our support team with it.
Is 2% refunds an acceptable rate? We'd be below 1% if not for Poland.
Aren't IAP refunds pro-rated?
I checked events for Poland over the lifetime of the app and I get the following, which seems odd to me. Like how could we have a reactivation or does a purchase after a refund count as that? If so, would mean same Apple ID being used.
9 refunds
7 activations
3 reactivations
1 cancellation
1 enter grace period
1 entered billing retry
1 renewal
Thank you!
Colin
I am currently facing an issue with the TestFlight app on my iPhone, where I am stuck on the redeem code page and unable to access the apps I am testing. Interestingly, I am able to access TestFlight without any issues on my MacBook (MacOS), but the problem persists only on iOS. Here is a detailed breakdown of the issue:
Issue Description: Upon opening TestFlight on my iPhone, I am immediately directed to a redeem code page with no option to exit or view the main screen, where I should see the apps and builds I am testing.
Steps to Reproduce:
1. Open TestFlight on iPhone.
2. TestFlight opens directly to the redeem code page with no option to access other parts of the app.
3. Enter a valid redeem code (used immediately after receiving it).
4. Receive an error message stating the code is invalid or expired.
5. Attempt to access TestFlight via an email invitation link, but it redirects back to the redeem code page.
Expected Result: I expect to see TestFlight’s homepage with all the apps and builds I am currently testing.
Actual Result: I am stuck on the redeem code page with no option to exit, and valid redeem codes are not being accepted.
I have tried using new codes, accessing the app via email invitations, and reinstalling the app, but the issue continues. Any help or guidance on how to fix this would be greatly appreciated.
I have an app which is very similar to Patreon, where users can subscribe to influencers and get exclusive content. However, I do not know how to implement it with in-app purchase limitations
Since user can not subscribe to 1 subscription several times, but in my app they can subscribe to 2 or more influencers, I have to create a uniques subscription to all influencers, but there is a limitation of 10,000 in-app products. Additionally, since user can subscribe to only 1 sub in sub group, I also have to create a sub group to every influencer. It is crucial for me to have auto-renewable subscription, so I can not use consumables.
How Patreon could implement it, taking into account that they have thousands and millions of influencers?
Can somebody help me figure out a way to resolve this issue?
My app is planning to develop a subscription product, for this type of in-app purchase do I need call finish() to complete the transaction?
And, does currentEntitlements() return the transaction after calling finish()?
Hi,
Our application is a B2B app, supporting users from companies that own our equipment (print industry).
We want to allow company stakeholders to have a "Premium Plan" that will provide their company with numerous advantages in different aspects (service, training, data visibility)
Some features in our app will be locked/hidden if the company is not part of the Premium Plan. We want to allow authorized users to activate the Premium plan for their entire company.
We already have our website, where we already have a marketplace that allows web users to do this (using their company service agreement).
In term of complying with Apple's in-app purchase Policy, is it ok to tell users in the app to go to this marketplace if they want these features (and more)?
Thank you
I’m writing to understand how taxes are applied to our subscription revenue and to clarify a potential issue we’re facing.
For a ₹299 subscription:
Apple deducts a 30% commission, leaving us with ₹209.30.
After that, an additional tax of approximately 18% (₹36.11) is deducted by Apple, which reduces the amount further.
When we receive this ₹173.19 in our bank, we are required to pay 18% GST again on this amount in India.
This appears to result in us paying tax twice. Could you clarify why 18% tax is deducted by Apple, and if we are not required to pay it again, where can we see this adjustment on the GST portal?