My question is simple, I do not have much experience in writing swift code, I am only doing it to create a small executable that I can call from my python application which completes Subcription Management.
I was hoping someone with more experience could point out my flaws along with giving me tips on how to verify that the check is working for my applicaiton. Any inight is appreciated, thank you.
import Foundation
import StoreKit
class SubscriptionValidator {
static func getReceiptURL() -> URL? {
guard let appStoreReceiptURL = Bundle.main.appStoreReceiptURL else {
print("No receipt found.")
return nil
}
return appStoreReceiptURL
}
static func validateReceipt() -> Bool {
guard let receiptURL = getReceiptURL(),
let receiptData = try? Data(contentsOf: receiptURL) else {
print("Could not read receipt.")
return false
}
let receiptString = receiptData.base64EncodedString()
let validationResult = sendReceiptToApple(receiptString: receiptString)
return validationResult
}
static func sendReceiptToApple(receiptString: String) -> Bool {
let isSandbox = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"
let urlString = isSandbox ? "https://sandbox.itunes.apple.com/verifyReceipt" : "https://buy.itunes.apple.com/verifyReceipt"
let url = URL(string: urlString)!
let requestData: [String: Any] = [
"receipt-data": receiptString,
"password": "0b7f88907b77443997838c72be52f5fc"
]
guard let requestBody = try? JSONSerialization.data(withJSONObject: requestData) else {
print("Error creating request body.")
return false
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = requestBody
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let semaphore = DispatchSemaphore(value: 0)
var isValid = false
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil,
let jsonResponse = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let status = jsonResponse["status"] as? Int else {
print("Receipt validation failed.")
semaphore.signal()
return
}
if status == 0, let receipt = jsonResponse["receipt"] as? [String: Any],
let inApp = receipt["in_app"] as? [[String: Any]] {
for purchase in inApp {
if let expiresDateMS = purchase["expires_date_ms"] as? String,
let expiresDate = Double(expiresDateMS) {
let expiryDate = Date(timeIntervalSince1970: expiresDate / 1000.0)
if expiryDate > Date() {
isValid = true
}
}
}
}
semaphore.signal()
}
task.resume()
semaphore.wait()
return isValid
}
}
Subscriptions
RSS for tagGive users access to content, services, or premium features in your app on an ongoing basis with subscriptions, a type of in-app purchase.
Posts under Subscriptions tag
170 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Please help! I have a subscription IAP failing on tvOS 18.2 at:
func makePurchase(_ product: Product) async throws
{
let result = try await product.purchase() //ERROR OCCURS HERE (See error message below)
...
Xcode Console message: "Could not get confirmation scene ID for [insert my IAP id here]"
The IAP subscription was working fine on 18.1 and earlier, and the same IAP and code is also running fine on iOS 18.2. The tvOS error on 18.2 happens both in production and sandbox.
Are there any changes to StoreKit 2 which might cause this error?
Hello,
I originally reported this issue on December 13, 2024, and received a case ID from Apple Developer Program Support: 102485600459.
However, the issue remains unresolved, and I have not received any further updates. Could someone please assist me in getting this matter addressed? Any guidance or escalation options would be greatly appreciated.
Thank you.
Topic:
Developer Tools & Services
SubTopic:
Apple Developer Program
Tags:
Subscriptions
Accounts
Developer Program
I am currently testing my in app subscription via sandbox. I am able to make the purchase and verify it, but it will not auto renew. The sandbox account is flagged as being subscribed, so it can't be purchased again, but I don't actually get the auto renewal.
I did notice that randomly on app boot up, I'll get a bunch of the backlogged auto renewals come in, but they are never actually sent to me when the 3 minute expiration is finished.
This is on macOS, so I am not able to actually look at and manage the sandbox subscriptions. It seems like that's only a thing for iOS. Is this just a behavior with the sandbox environment or will this behavior also happen with legitimate App Store?
The code I use is below:
@MainActor
func updateCustomerProductStatus() async {
var purchasedSubscriptions: [Product] = []
for await result in Transaction.currentEntitlements {
do {
let transaction = try checkVerified(result)
switch transaction.productType {
case .autoRenewable:
if let subscription = subscriptions.first(where: { $0.id == transaction.productID}) {
purchasedSubscriptions.append(subscription)
}
default:
break
}
} catch {
print("catching \(error)")
}
}
init() {
subscriptions = []
updateListenerTask = listenForTransactions()
Task {
await requestProducts()
await updateCustomerProductStatus()
}
}
deinit {
updateListenerTask?.cancel()
}
func listenForTransactions() -> Task<Void, Error> {
return Task.detached {
// Iterate through any transactions that don't come from a direct call to `purchase()`.
for await result in Transaction.updates {
do {
let transaction = try self.checkVerified(result)
// Deliver products to the user.
await self.updateCustomerProductStatus()
// Always finish a transaction.
await transaction.finish()
} catch {
// StoreKit has a transaction that fails verification. Don't deliver content to the user.
print("Transaction failed verification.")
}
}
}
}
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect API
Tags:
Subscriptions
StoreKit
In-App Purchase
We have set monthly/yearly subscriptions in our app and they have been approved. The users can get access to the limited functions of the app for free. For example, they can create limited number of tasks/events in the App. But if they want to create more tasks/events in the App, they need to subscribe the app(monthly/yearly).
But we don't know why the app is shown as an one-time purchase app in App store. The users need to pay the one-time purchase fee at first to download the app. If they haven't tried the app, they wont' pay for it. How to fix it? Look forward to the reply about it ASAP.
Hi! Could you please clarify when and why the subscription auto-renewal rate in TestFlight was changed to a daily cycle? Now, the subscription lasts for 6 days! This is causing significant issues in testing. Previously, the 5-minute auto-renewal for weekly subscriptions was an excellent solution.
Is there a way to adjust the auto-renewal timing for an account in TestFlight?
Documentation link: https://developer.apple.com/help/app-store-connect/test-a-beta-version/subscription-renewal-rate-in-testflight.
Thank you for your clarification!
Hello,
I have a few questions about increasing a price increase for an existing subscription on an iOS application:
1.) Is it possible to test the price increase in the sandbox environment? If so do I have to plan the scheduled increase first or can I create this scenario in the sandbox environment without any scheduling? I ask because id like to test the new price update in some of the local code first without having the risk of a user getting notified that a price increase is coming before the app is ready to display it properly.
2.) When a price increase is scheduled say two weeks out, but then its determined that we need to cancel it by deleting it from app store connect. Are users that were potentially notified of the price increase via the consent form notified a second time that it has been cancelled?
Thanks for any help!
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
Subscriptions
App Store Connect
Testing
Hello,
I would like to ask about how to handle subscription refund notifications.
Here’s what I’ve done.
Environment: Sandbox
Steps to reproduce
1.Subscribe.
2.Request a refund using beginRefundRequest.
3.Receives App store server notifications.
I expected to receive the EXPIRED notification immediately after receiving the REFUND notification, but I have confirmed that the EXPIRED notification is received on the renewal date.
We plan to restrict access to premium content when receiving the EXPIRED notification.
If a user starts an annual subscription in January and requests a refund after 3 months, will the EXPIRED notification be received in January of the following year?
If so, what is the optimal time to restrict access to premium content?
Additionally, is there a possibility of a partial refund?
Thank you in advance for your support!
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect API
Tags:
Subscriptions
App Store Server Notifications
Hello all,
In the App Store Connect API:
Apps have /v1/appPriceSchedules/{id}/baseTerritory.
IAPs have /v1/inAppPurchasePriceSchedules/{id}/baseTerritory.
...but:
Auto-renewing subscriptions don't have a corresponding endpoint for getting the base territory
However, the App Store Connect website does indeed require you to set a base territory when creating new auto-renewable subscriptions.
Why's that?
More importantly, what's the best way of determining what to use for a base territory?
Thank you!!
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect API
Tags:
Subscriptions
App Store Connect API
We uploaded to App Store Connect a new app version with new subscription groups & items. Everything was approved, and we received the emails from App Store connect, but if we visit our App Store Connect account App, some of these subscription items are still "Waiting for review" for more than 4 days. It has no sense as the email informed us that the new app version and all the items had been approved. The app is online, but some subscription items are not available.
We even uploaded a new app version, it was updated, but the subscription items are still "Waiting for review".
Has anyone faced this problem? How do you solved it? We have contacted App Store Connect but it is pretty difficult to get real assistance, most of the time they reply with template email answers.
I have implemented subscription renewals in my app and now want to integrate a referral system. Each user should receive a unique referral code that they can share with others. When a new user signs up using a referral code, both the referrer and the referred user should receive a bonus.
What is the best approach to implementing this feature efficiently?
Hello,
We have an app that offers auto-renewal subscription. Now we would like to increase the subscription price for the new subscribers, but the existing subscribers will still pay the old price when they renew.
What is the best way to do it? On Play Store, if you increase the subscription price, your existing subscribers will automatically be moved into a "legacy price cohort" and they will pay the old price. Does App Store offer something similar?
Jim
Hello
I'm developing a React Native application and I added IAP (like subscriptions) to my app. For it I user react-native-iap, I suppose It's the most common library to integrate in-app purchases.
So, I created 3 subs on App Store Connect and tested it on the iOS simulator. Firstly I was receiving the empty array instead of subs data, but when I have been add StoreKit to my project I became to receive an appropriate subs data with all corresponding information. Moreover, I could successfully subscribe on them.
But, when I released app on the TestFlight for internal testing I forced with the familiar issue, I received an empty array.
In conclusion, on the debug version everything works (subscriptions data returns), but on the release I can't to receive the same result.
Topic:
App Store Distribution & Marketing
SubTopic:
TestFlight
Tags:
Subscriptions
StoreKit
App Store Connect
TestFlight
Hi everyone,
I’m having serious trouble completing the payment for my Apple Developer membership. I’ve tried using several cards (all of which work perfectly fine on other platforms), but Apple simply won’t process the payment.
What’s even more frustrating is that I’ve been trying to resolve this with support for days, and the service has been an absolute disaster. I keep getting generic responses, and no one provides a concrete solution. My account is still stuck.
Has anyone else experienced something similar? Any advice on how to fix this?
Thanks in advance for any help. I’m really disappointed with the support I’ve received so far.
I‘ve been linking my userids in the backend using the server notifications when users subscribe successfully using appAccountToken.
Now i’m introducing an offer code redemption in my app using presentOfferCodeRedeemSheet. But i dont see a way to pass my user id for the app token
any solution or workaround? Thanks
Hello everybody,
We are trying to configure Device APN settings by sending IOS device configuration profiles through OTA. Please refer below url for details which we are following :
https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009505
We’ve encountered an issue where the APN (Access Point Name) settings are not populating correctly on iOS devices, even though we are sending the configuration via our Device Management Center (DMC) and the configuration message is being pushed correctly over the air (OTA).
Path to the APN fields:
Settings > Mobile > Mobile Data Network > APN
Tested iOS version: 17.3, 17.5, 18.2, 18.3
Configuration message received:
Configuration message installed:
APN fields are empty:
Could you give us any suggestions ?
Thank you very much.
Hello,
Is it acceptable to have subscriptions that are available for limited times on the app, for example I would like only 100 new paid subscription purchases on the App every month.
When the 100 quota is finished, users might see something like "Check back next month".
This is to control growth and marketing purposes.
I have developed an app that I had been testing on the hardware device with the developer profile signed builds, I had setup a CloudKit container in development mode and also had tested with Production mode and they are working as expected. I have also tested storekit auto renewal subscriptions using Storekit Config file and all of that is working on the hardware device with the developer profile signed builds.
Now comes the Fun Part, I want to use the Distribution profile to test the app for production readiness, I had created a distribution profile and had set that up in the Release under target of the app in Xcode, I have also created sandbox tester account (which is showing inactive even after 7 days - though I am also logged in with this sandbox tester account on a hardware device and under developer setting it shows as a sandbox tester account)
All the subscriptions are showing Ready to Submit in the App Store Connect.
I need help understand this whole flow, how to ensure I can test CloudKit and storekit for production readiness and then publish my app for the review.
Thank you.
Topic:
Developer Tools & Services
SubTopic:
General
Tags:
Subscriptions
Developer Tools
CloudKit
StoreKit
I am using a credit system and would like to know if it's possible to charge users for the full weekly subscription if they upgrade to a yearly plan after using all their weekly credits within one day. My goal is to ensure that users are billed for the entire weekly period in such cases. Is this compliant with Apple's App Store policies?
Hello everyone,
I’m hoping someone might help with auto-renewable subscription validation in Apple’s Sandbox environment. Here’s the situation:
My Setup:
I’ve configured three auto-renewable subscriptions in App Store Connect and generated an In-App Purchase key (with the correct Issuer ID and Key ID). (I also tried the App Store Connect API Keys)
I’m using Apple’s App Store Server API v2 endpoints (GET /inApps/v2/subscriptions/{originalTransactionId}/latest) to fetch the latest subscription status.
I’ve created several Sandbox test users (with fresh email addresses), signed out of old test accounts on my devices, and tested purchasing subscriptions anew.
What Works:
I am receiving valid Server Notifications from Apple (e.g. SUBSCRIBED, DID_RENEW) with the correct environment: "Sandbox" field.
My JWT generation appears to be correct because I’m no longer receiving 401 errors—only 404. That suggests Apple accepts the key and credentials.
My fallback logic attempts production first; if it sees a 404 or 410, it switches over to the Sandbox endpoint. This is exactly what Apple’s documentation recommends.
The Problem:
Whenever I query GET https://api.storekit-sandbox.itunes.apple.com/inApps/v2/subscriptions/{originalTransactionId}/latest using the originalTransactionId from Apple’s own Server Notification, Apple returns a 404 (indicating it can’t find that subscription).
This happens even though the subscription is active in Sandbox (I see notifications arriving for it).
I’ve tried adding a brief waiting period (2 seconds) before calling the Sandbox endpoint, but it consistently returns 404. I’ve also tried multiple retries over a longer timeframe without success.
I tested multiple fresh Sandbox test users, ensuring each one was signed in to the device’s App Store. After each new purchase, I still get the same 404.
Additional Checks:
These are definitely auto-renewable subscriptions, not non-renewing or consumable products.
I also tried calling GET /inApps/v2/subscriptions/{transactionId}/latest but I still see 404.
I tried everything mentioned above in production as I said to no avail:
GET https://api.storekit.itunes.apple.com/inApps/v2/subscriptions/{originalTransactionId}/latest