StoreKit

RSS for tag

Support in-app purchases and interactions with the App Store using StoreKit.

StoreKit Documentation

Post

Replies

Boosts

Views

Activity

How to fetch historical introductory offers from App Store Connect API
Hello! I am wondering what the best way is to fetch previous introductory offers from the App Store Connect API. I have tried hitting this endpoint: https://developer.apple.com/documentation/appstoreconnectapi/list_all_introductory_offers_for_a_subscription which seemed to only return the current, active introductory offer. I am looking to gather all introductory offers for my subscription products, including the following attributes: Start date End date Customer price Territory Currency Introductory offer mode Number of periods Thank you.
0
0
383
Jan ’24
IAP or apple pay for video question/answer
Hi there, I am here to ask for help regarding IAP and Apple Pay. So in my app, there are user two types, fan and athlete where a fan can ask the user text questions, or video questions or can directly tip the athlete(note: these questions are under the name of tip). I was using Stripe for payment but Apple rejected that and forced us to implement IAP by mentioning that as the question/tip is video/text based so you have to remove Stripe and use IAP. Therefore, I am here to ask whether I should use IAP or Apple Pay because in IAP we have limitations for predefined products while what if a fan wanted to tip a dynamic amount (here can we use Apple Pay for tipping) Please share your thoughts on what is the best way to tip while asking a question and free tip. One thing more to add we want to implement a bidding feature in the app as well where fans can bid dynamic amounts that IAP lacks). Thank you
0
0
447
Jan ’24
SKTestSession.buyProduct(identifier: options:) doesn't work in swift package
We are doing a Swift Package to manage our iap with storekit 2. This packages also contains the unit tests for the code. (as well as all the required files .storekit, certificate, ...) when calling SKTestSession.buyProduct(identifier: options:) we catch an error : Error Domain=SKErrorDomain Code=0 "(null)" Note when trying exactly the same code but in a project instead of a package that works perfectly. Any idea what could it be? The code is really simple : var testSession: SKTestSession! override func setUpWithError() throws { testSession = try SKTestSession(configurationFileNamed: "Products") } func testExample() async throws { do { let productID = "nonConsumable.crystal.tier1" try await testSession.buyProduct(identifier: productID) } catch { XCTFail("An error occured during purchase : \(error)") } } }
0
0
536
Jan ’24
Can't change store kit renewal rate, stuck at every two seconds
I wrote a StoreKit unit test and set the renewal rate to .oneRenewalEveryTwoSeconds for the test session. But now my App expires and renews every two seconds when running normally, even though the StoreKit Configuration file is set to "Real Time." Changing it to anything else doesn't change the renewal rate. I've tried cleaning the build folder. If, however, I set my SKTestSession explicitly to .realTime and run the test again, then my app behaves. However, again, it doesn't matter what I set the Configuration Settings to. Anyone know where this information is stored?
0
0
584
Jan ’24
Are travel bookings subject to the 30% tax?
Hello, I'm curious to know if in the situation that I build an app where people can book and pay for vacations (Hotel + Flights) and I have suppliers for those vacations making the payments to the hotels and the airlines, the booking would be subject to an in app purchases tax? Basically apps like booking.com, airbnb, expedia etc... does Apple let this kind of apps to use their own payment processor like stripe?
2
1
485
Jan ’24
SKAN not receiving postbacks correctly / wrong attribution to "direct"
SKAN / SkAdNetwork Error ERROR: We never received any http request from the "skan.ourdomain.com" as expected. ERROR: All the attributions(YES! ALL OF THE INSTALLS) in the Google Analytics / Singular / AppsFlyer / Twitter / Facebook, shows the source are "direct organic". We Did These We use Google Ads and Twitter Ads and Facebook Ads to promote our apps. We spent enough money, and got thousands of paid installs from these ads. We set the NSAdvertisingAttributionReportEndpoint to "skan.ourdomain.com". We call the SKAdNetwork.updatePostbackConversionValue(1). in "AppDelegate" and "Subscribe" source codes. And from our app logs, we see there are SKAN_UPDATE_CONVERSION_VALUE_OK. Source Code if #available(iOS 15.4, *) { SKAdNetwork.updatePostbackConversionValue(1) { err in if let err = err { Tracker.shared.reportEvent(.SKAN_UPDATE_CONVERSION_VALUE_FAIL, name: err.localizedDescription, value: 1) } else { Tracker.shared.reportEvent(.SKAN_UPDATE_CONVERSION_VALUE_OK) } } } else { SKAdNetwork.registerAppForAdNetworkAttribution() Tracker.shared.reporxtEvent( .SKAN_UPDATE_CONVERSION_VALUE_OLD_VERSION, name: "AppDelegate") }
0
1
845
Jan ’24
In-app purchase on visionOS
Hello! I would like to add In-app purchase capability to my visionOS app. However, unlike in iOS project, I can't add this capability to visionOS project. On Apple's In-app purchase page there is an indicator that it is supported by Apple Vision Pro. Please help me on how can I add paid subscriptions to my visionOS app. Best regards, Vladyslav.
2
1
824
Jan ’24
Clarification Needed: Integrating Custom App Development Fees in Mobile App — Compliance and Best Practices
Background We are currently working on two apps: a Church Management System (ChMS) and a Giving App. Both apps are free to use. The Giving App will incorporate a Stripe payment gateway for users to make donations to churches. The Question: Now, here's the scenario: If a church desires a custom-branded app developed specifically for their ChMS (will be hosted in their developer account), we plan to charge a one-time development fee for this service. We would like to facilitate the payment within the app itself. However, we're exploring the possibility of using a third-party payment service (such as Stripe) rather than relying on the Apple in-app payment system. Key Points: Both apps are free to use. The Giving App will have Stripe integration for donations to churches. Churches interested in a custom-branded ChMS app will be required to pay a one-time development fee. We will develop the app and add it to their developer account. We want to know if it's feasible to collect this development fee within the app using a third-party payment service and not give it as in-app purchase. Common Sign-Up: It's worth mentioning that the sign-up process is common for both apps. Users can sign up on the ChMS app, and the same logins can be used for the Giving App. Specific Questions: Can we use a third-party payment service (like Stripe) to collect the one-time development fee within the app without utilizing the Apple in-app payment system? Any insights on potential challenges or best practices related to this approach? Considering the common sign-up, are there considerations we should be aware of for such purchases? I'd love to hear from the community based on your experiences. Any advice, tips, or shared experiences would be incredibly helpful. Thank you
0
0
291
Jan ’24
How to use Sandbox for IAP testing
Need some help here. I've got an iPhone 11 PM on 16.6.1 and I'm trying to test Family Sharing IAPs. However, I can't seem to test via the Sandbox environment (which I need to validate receipt handling for Family Sharing). The app is running locally on my device and was built straight from Xcode. When I tap to make a purchase in my app (which uses StoreKit2, if that makes any difference) a sheet pops up with a purchase button which, when tapped, immediately completes and I get the following dialog box: "Your purchase was successful" [Environment: Xcode] How do I get my app to use the Sandbox environment? All documentation suggestions when I tap my purchase button I should simply be presented with a login modal and then, after the purchase has completed, be able to see my Sandbox credentials under Settings -> App Store. At the moment no dialog is presented (the purchase completes immediately) and the entire "Sandbox Account" section is missing from Settings -> App Store. Any help will be greatly appreciated!
1
0
797
Jan ’24
App Review Rejected - 3.1.1 In-App Purchase
We are trying to distribute an app for our digital ministry. It is a religious Bible app. We offer our app 100% free of charge, however, we do accept voluntary donations. These donations do not result in any sort of in-app content incentives for the user, they strictly go to supporting our ministry. However, every time we explain this to the App Review Team, this is their response: Tips or donations may be optional, if they are connected to or associated with receiving digital content, they must use in-app purchase in accordance with guideline 3.1.1 To resolve this issue, please revise your app to use in-app purchase to pay for this type of transaction or remove these transactions from your app. We am stuck, because we do not know what to do. We want to keep the donation in the app, however, using In-App purchases tarnishes the image of 100% free.
2
0
519
Jan ’24
Verifying In-App Purchases with iOS App Sandbox
The iOS App Sandbox plays a pivotal role in ensuring the secure testing of In-App Purchases (IAPs) without impacting real users. To utilize the sandbox, set up your app's IAPs in App Store Connect. Begin by importing the StoreKit framework and fetching product information using SKProductsRequest. Once products are retrieved, initiate purchases through SKPaymentQueue. Implement the SKPaymentTransactionObserver to handle transaction updates, distinguishing between successful, failed, and restored purchases. When testing, remember to use test user accounts and sign in to the App Store with a test account on your device. This ensures a controlled environment for validating IAPs during development. URL - https://www.controlf5.in/ios-mobile-app-development-company/ swift Copy code import StoreKit class YourViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver { func fetchProducts() { let productIdentifiers: Set<String> = ["com.yourapp.product1", "com.yourapp.product2"] let request = SKProductsRequest(productIdentifiers: productIdentifiers) request.delegate = self request.start() } func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { let products = response.products // Handle retrieved products } func request(_ request: SKRequest, didFailWithError error: Error) { // Handle error } func purchaseProduct(product: SKProduct) { let payment = SKPayment(product: product) SKPaymentQueue.default().add(payment) } func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch transaction.transactionState { case .purchased: // Handle successful purchase case .failed: // Handle failed purchase case .restored: // Handle restored purchase default: break } } } }
0
0
424
Jan ’24
Non-StoreKit Free Trial Guidelines
I've seen several posts (mostly from 3+ years ago) asking about implementing a "home-rolled" free trial for subscriptions in iOS. I'm still a bit confused though as there doesn't seem to be a definitive answer. I'm wanting to try to increase registration -> free trial conversion by offering users a time-based free trial from my backend rather than going through StoreKit. It will be clear up front that it's a subscription service and has a cost, but they won't need to agree to the auto payment after X days. Is anyone currently doing this without getting rejected or is this still considered a no-no by Apple?
3
0
406
Jan ’24
Mac Appstore StoreKit 2 - validate purchase & where is purchase receipt cached?
This is re-posted from this Stack Overflow post. I am looking at validating the purchase of a paid app from Mac AppStore. Based on this WWDC video about StoreKit 2, I am attempting to this with AppTransaction. I have not found meaningful high-level documentation about this specific use case beyond that. My approach is to first get the "cached" AppTransaction by calling AppTransaction.shared. If that is not there I proceed to getting it from Apple, via AppTransaction.refresh(). If they don't have it, or when the network is down, the user automagically gets the familiar "log in to your store account" UI that has been around as long as the Mac AppStore. Once I have the AppTransaction I use it to verify we are on the right device, using code like this, where the returned Bool represents validation success: guard let deviceVID = AppStore.deviceVerificationID?.uuidString.lowercased() else { return false } let nonce = appTransaction.deviceVerificationNonce.uuidString.lowercased() let combo = nonce + deviceVID let digest = SHA384.hash(data: Data(combo.utf8)) return (digest == appTransaction.deviceVerification) My first question is: Does that look like the right approach? Is there something else I should do, or check? My second question is around testing this approach. Refreshing the AppTransaction in the sandbox invariably yields a valid item, even if the app version does not yet exist in AppStoreConnect. This is also the case when I log out in the App Store app on the Mac. This makes me think it is using my AppleID which I am logged into in System Settings. Does that sound right? I would like to be able to remove / delete the cached AppTransactions - where might I find those on the system? Thanks for everyone's help!
2
1
1.1k
Jan ’24
Something happens in Testflight environment
I wanted to test some purchasing situations in Testflight. So I pressed purchase button in my app. Then when product was being loaded, I closed the app. I expected that purchase popup would show failure process like real purchase. But in my case,it was shown with purchase button and it was able to press. Purchase was completed outside of the app(In home screen). Receipt was remaining in pending state Is this the correct purchase process?
0
0
218
Jan ’24
consumable inapp purchase server side validation
Since verifyReceipt is marked as deprecated, there is appstore server library; e.g. this is the java version: https://github.com/apple/app-store-server-library-java/tree/main According to https://developer.apple.com/videos/play/wwdc2023/10143/, client (game) sends receipt to server for validation and server extracts transactionId with ReceiptUtility and asks for transaction history to appstore to receive signed transactions. During this request, server can filter to receive only consumables; e.g: TransactionHistoryRequest request = new TransactionHistoryRequest() .sort(TransactionHistoryRequest.Order.DESCENDING) .revoked(false) .productTypes(List.of( TransactionHistoryRequest.ProductType.CONSUMABLE)); Working in sanbox env, everything seems fine, I can make a successful in app purchase; but I receive below from transaction history request: APIException{httpStatusCode=404, apiError=4040010, apiErrorMessage='Transaction id not found.'} But when I use getTransactionInfo with the same extracted transactionId, I receive a successful response like below: TransactionInfoResponse{signedTransactionInfo='eyJ.... I have 2 questions here: 1- why am i getting error in TransactionHistoryRequest 2- what is the correct way to validate an in app purchase server side without verifyReceipt? Thanks in advance PS: Here are sample codes for TransactionHistoryRequest and getTransactionInfo: TransactionHistoryRequest String encodedKey = Files.readString(filePath); Environment environment = Environment.SANDBOX; AppStoreServerAPIClient client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment); String receipt = "MIIUW......"; ReceiptUtility receiptUtil = new ReceiptUtility(); String transactionId = receiptUtil.extractTransactionIdFromAppReceipt(receipt); System.out.println("extracted txId is " + transactionId); if (transactionId != null) { 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; System.out.println("revision is " + revision); response = client.getTransactionHistory(transactionId, revision, request); transactions.addAll(response.getSignedTransactions()); } while (response.getHasMore()); System.out.println(transactions); } getTransactionInfo String encodedKey = Files.readString(filePath); System.out.println("encoded key is " + encodedKey); String receipt = "MIIUW..."; ReceiptUtility receiptUtil = new ReceiptUtility(); String txId = receiptUtil.extractTransactionIdFromAppReceipt(receipt); Environment environment = Environment.SANDBOX; AppStoreServerAPIClient client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment); try { TransactionInfoResponse response = client.getTransactionInfo(txId); String signed = response.getSignedTransactionInfo(); System.out.println(">>>" + signed.split("\\.").length); String jws_payload = signed.split("\\.")[1]; String payload = new String(Base64.decodeBase64(jws_payload)); System.out.println(response); System.out.println("payload is " + payload); } catch (APIException | IOException e) { e.printStackTrace(); }
0
0
835
Jan ’24
Subscriptions - In app purchase
I'm having trouble with "Subscriptions" on the Apple Store. Users can purchase multiple courses. Multiple courses can have the same price and use the same "Subscriptions". Suppose I have user A, course C1 costs 200 USD (PRODUCT_ID: 200_USD), course C2 costs 200 USD (PRODUCT_ID: 200_USD). When creating a registration, the json response from apple is all in the in_app section, has the same id_product_id, it is not possible to distinguish which element belongs to course C1, which element belongs to course C2. How do I know which renewal item belongs to course C1 or C2? "in_app": [ { "quantity": "1", "product_id": "200_1jp", "transaction_id": "2000000497632148", "original_transaction_id": "2000000497632148", "purchase_date": "2024-01-11 05:06:49 Etc/GMT", "purchase_date_ms": "1704949609000", "purchase_date_pst": "2024-01-10 21:06:49 America/Los_Angeles", "original_purchase_date": "2024-01-11 05:06:57 Etc/GMT", "original_purchase_date_ms": "1704949617000", "original_purchase_date_pst": "2024-01-10 21:06:57 America/Los_Angeles", "expires_date": "2024-01-11 05:21:49 Etc/GMT", "expires_date_ms": "1704950509000", "expires_date_pst": "2024-01-10 21:21:49 America/Los_Angeles", "web_order_line_item_id": "2000000047929472", "is_trial_period": "false", "is_in_intro_offer_period": "false", "in_app_ownership_type": "PURCHASED" }, { "quantity": "1", "product_id": "200_1jp", "transaction_id": "2000000497640048", "original_transaction_id": "2000000497632148", "purchase_date": "2024-01-11 05:22:32 Etc/GMT", "purchase_date_ms": "1704950552000", "purchase_date_pst": "2024-01-10 21:22:32 America/Los_Angeles", "original_purchase_date": "2024-01-11 05:06:57 Etc/GMT", "original_purchase_date_ms": "1704949617000", "original_purchase_date_pst": "2024-01-10 21:06:57 America/Los_Angeles", "expires_date": "2024-01-11 05:37:32 Etc/GMT", "expires_date_ms": "1704951452000", "expires_date_pst": "2024-01-10 21:37:32 America/Los_Angeles", "web_order_line_item_id": "2000000047929473", "is_trial_period": "false", "is_in_intro_offer_period": "false", "in_app_ownership_type": "PURCHASED" },
1
0
369
Jan ’24
Allow other 3rd party apps to provide subscription options to my application - Apple compliance
Hello, I want to provide in- app subscription option for my application services inside other apps. Is this possible? Does Apple in app subscription guidelines allow this? Reading the guidelines this use case is not clear. UseCase: I am embedding the services that my app provides inside other 3rd party apps (embed my application Framework/library within the other application) but want to provide in-app subscription option to use services provided by my library. Users can purchase this service by subscribing to monthly subscription option using Apple in-app subscription. Because there are multiple other 3rd party applications that will include my library and since these 3rd party applications in some cases are not from the same developer account I do not want to use individual in-app subscription for each application. Instead, I am looking for a way to create in-app subscription from my main application and provide the same purchase option within all other 3rd party apps that embed my application library. Can this be done? Does Apple in-app subscription allow this use case?
0
0
644
Jan ’24
Beta testers have to keep subscribing to recurring subscriptions
I have an app that I distribute to beta testers via TestFlight. The app has auto-renewable subscriptions. In the sandbox environment the subscriptions expire at an accelerated rate; every hour. They renew up to 12 times. This means that my testers have to re-subscribe every 12 hours. Is there a way to make the sandbox operate at realtime for certain users?
0
0
623
Jan ’24