Post not yet marked as solved
I have some questions about your Commerce refund/chargeback area. I would really appreciate it if you could help clarify these questions.
As we are a Saas game backend company helping game studios build their backend, and our system is not directly integrated with your platform transaction system, it is very difficult for us to detect any refund/chargeback and perform revocation of items/VCs accordingly. So, I’m wondering if your platform provides any kind of workaround for us to gather player refund/chargeback events? Any suggestions or guidance will be highly appreciated.
Thank you!
Post not yet marked as solved
I want to ask about the App store Api Get Transaction History APl .The response data JWSTransaction does not have an is_trialperiod field.How can I determine whether it is in the trialperiod?
Post not yet marked as solved
The signed payload I got from the notification V2 doesn't have the bundleId and caused a verified error.
I'm using the app-store-server-library-python to verify and decode verification and it raised an exception that bundleId doesn't match, from the stack I found there is no bundleId in it,
Post not yet marked as solved
The missing bundleId caused a verified error of the notification, why the bundleId is missing in the notification body?
Post not yet marked as solved
On my purchase page I use RevenueCat to make the initial purchase and in my SettingsVC I have the in-app purchase API (as required) to later resubscribe:
// ...
try await AppStore.showManageSubscriptions(in: window as! UIWindowScene)
I followed these directions and these directions. Using an iPhone 8 simulator I logged into iCloud as a sandbox tester eg. sandboxtest%test.com, then logged into its Settings, loaded my app, made a purchase, the subscription went through and eventually expired. While in the iPhone 8 I checked my SettingsVC > in-app purchase API and it said Expired Nov 5, 2023 ... Select an option to resubscribe. So it worked. I send sandboxtest%test.com and the pw to App Review and got the below rejection:
Guideline 2.1 - Performance - App Completeness
We discovered one or more bugs in your app. Specifically, your app
displayed an error page when the Mange Subscription tab was tapped. We
found that while you have submitted in-app purchase products for your
app, the in-app purchase functionality is not present in your binary.
If you would like to include in-app purchases in your app, you will
need to upload a new binary that incorporates the in-app purchase API
to enable users to make a purchase
They sent me a screenshot and the in-app purchase API said Cannot Connect - Retry.
I later use my actual device and try these 3 ways:
1- While logged in as myself, without using any Sandbox Account, delete the app, run it again, then log into my app with sandboxtest%test.com
2- While logged in as myself, use a different sandbox tester such as whatever%test.com to log into the Sandbox Account, delete the app, run it again, then log into my app with sandboxtest%test.com
3- While logged in as myself, use sandboxtest%test.com for the Sandbox Account, delete the app, run it again, then log into my app with sandboxtest%test.com
For all 3 RevenueCat prints the initial subscription and the expiration date, but for some reason when I go to the in-app purchase API, it always returns You do not have any subscriptions.
What's strange is when I go back to the iPhone 8 while still logged in as sandboxtest%test.com, the in-app purchase API still shows Expired Nov 5, 2023 ... Select an option to resubscribe.
I'm kinda lost here because to use an actual device to login, it sends a SMS, so I don't see how giving the App Reviewer the sandboxtest%test.com/pw info to login into the device and iCloud will help him/her make a purchase because they can't get the SMS. I would assume they would only need sandboxtest%test.com, but that does't work for them.
Any advice?
Post not yet marked as solved
Here is a summary of the steps we have taken:
Endpoint Configuration: We have set up an HTTPS endpoint on our server hosted with Heroku. Our application is built with Node.js and Express, and it is designed to listen for POST requests for processing Apple's server notifications.
App Store Connect Setup: We have entered the correct endpoint URL in App Store Connect for both production and sandbox environments. We have also ensured that we are set up to receive version 2 notifications, as this is the latest format.
TLS Support: We have verified that Heroku supports TLS 1.2 by default, and our server is configured to utilize this protocol.
Receipt and Shared Secret: We have generated the shared secret from App Store Connect and stored it securely as a config var in Heroku. This shared secret is used to validate receipts with Apple's verifyReceipt endpoint.
Testing: We have conducted tests using Apple's sandbox environment by performing transactions to trigger server notifications. Additionally, we have also checked the Heroku logs for any incoming requests and haven't observed any related to the Apple server notifications.
Firewall and IP Whitelisting: Our server does not have any IP whitelisting or firewall rules that would block incoming HTTP POST requests from external services.
However, despite these measures, we have not been able to receive any server-to-server notifications
Post not yet marked as solved
1.We are making a request to Apple's GetTransactionInfo api:
request_uri: GET https://api.storekit.itunes.apple.com/inApps/v1/transactions/570xxxxxx152928
request_response_body`
:{"signedTransactionInfo":"eyJh....."}
2.Parse the signedTransactionInfo content returned by the GetTransactionInfo Api
JWSTransactionDecodedPayload:
{
"appAccountToken": "FBACxxxx376",
"bundleId": "com.test.xx",
"currency": "VND",
"environment": "Production",
"inAppOwnershipType": "PURCHASED",
"originalPurchaseDate": 1700369755000,
"originalTransactionId": "57xxxxxx2928",
"price": -1795967296,
"productId": "com.text.xx9",
"purchaseDate": 1700364444000,
"quantity": 1,
"signedDate": 1700364444000,
"storefront": "VNM",
"storefrontId": "123456",
"transactionId": "57xxxxxx2928",
"transactionReason": "PURCHASE",
"type": "Consumable"
}
3. The Apple Api returned an abnormal price: -1,795,967,296.
Personal speculation: The original price of the current order item [com.text.xx9] is 2,499,000 VND, and the Apple Api multiplies the price amount by 1000, resulting in a final amount of 2,499,000,000. However, due to an overflow issue in the length of the price amount, the price in the order details becomes -1,795,967,296, a negative number.
Appstore api doc:
GetTransactionInfo Api docGet Transaction Info | Apple Developer Documentation
JWSTransactionDecodedPayload doc:JWSTransactionDecodedPayload | Apple Developer Documentation
Post not yet marked as solved
Currently, 'Get Transaction History', 'Get Transaction Info', 'Get All Subscription Statuses' and 'Notifications V2' are being used in the App store Server API.
When I decoded the JWS received in response and checked the root certificate, it was always 'AppleRootCA-G3'.
Are there cases where the root certificate is not 'AppleRootCA-G3'?
Post not yet marked as solved
App Store的评论是否有开放API,方便APP在内部评论同步到App Store评论区
Post not yet marked as solved
Is the Apple root certificate in the App Store Server API response always 'Apple Root CA - G3'?
When isn't it?
What criteria should I set for the 'performRevocationChecking' parameter value of the verifyChain method of the ChainVerifier class in the App Store Server Library?
I am implementing the 'App Store Server API' call myself. Do you include the root certificate in the certificate chain verification process?
Can root certificates be forged?
We're able to successfully perform test notifications using the app-store-server-library-python in SANDBOX environment, but the second we switch to PRODUCTION (for testing purposes), the call fails with 401 and it doesn't seem to reach our server at all. This suggests that something is wrong with singing production environment headers, however I've seen posts from others that suggest this is not specific to the App Store server library code.
It's very clear that the libraries are marked Beta – however, most replies to questions about the v2 API are replied to with suggestions to use the library. Just FWIW – there's some contradictory advice there.
Anyway, the main point is that we're currently blocked on making sure that our v2 API hooks are working properly, since we can't send production test notifications.
Any idea why the signed requests would work to send sandbox test notifications, but not production environment? We've triple checked the URLs, etc – as far as we know, the private key should be the same regardless of environment.
Thanks!
(P.S. If anyone has been able to send v2 test notifications with the PRODUCTION environment, please let us know!)
Post not yet marked as solved
We are currently managing four root certificates.
Checked the ChainVerifier class code in 'App Store Server Library'.
I checked that the root certificate was excluded when I called the CertPathValidator.validate method. So the root certificate is not falsified?
Is it okay if I don't even check my fingerprints?
Post not yet marked as solved
my find documents(app store server notifications and app store server api), not find next billing date description, i want new subscription and renew subscription send email to customer, context contains next billing date
We want to know whether the refund requested by the user for the consumable IAP of Apple is refunded fully or partially. I can get the revocation date on when the refund was processed but I also want to know whether the user got a refund fully or partially and its amount as well if possible.
we tried to get transaction info and also the refund history of App Store Server API but we are only getting the revocation date and revocation reason we also want to know if the refund was processed as fully or partially and how much money did the user got back on refund successful. Also checked the webhook data we get for REFUND notificationType, we don't get back any field that helps us identify whether refund was full or partial and its amount as well.
Post not yet marked as solved
Hello.
I have a question about migrating from Original StoreKit to StoreKit2.
In my app, there are two in-app purchase products implemented using Original StoreKit: Product A and Product B.
For each product, there are separate backend servers, and due to certain reasons, we need to migrate one of those servers to use the AppStore Server API instead of the VerifyReceipt API.
During this migration, the iOS app needs to have code that combines both Original StoreKit and StoreKit2 for each product.
I heard that combining StoreKit2 with the VerifyReceipt API is not recommended. To avoid doing so, I believe the implementation would look like the below. Is this approach problematic? Is it not recommended by Apple?
If anyone has successfully implemented a similar migration and has insights, I would appreciate hearing about it.
Code implemented using Original StoreKit
SKPaymentQueue.default().add(payment)
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions.filter({ $0.payment.productIdentifier.hasPrefix("...Original StoreKit product only...")}) {
switch transaction.transactionState {
case .purchasing: break
case .deferred: print(Messages.deferred)
case .purchased: handlePurchased(transaction) // send base64 encoded receipt file.
case .failed: handleFailed(transaction)
case .restored: handleRestored(transaction)
@unknown default: fatalError(Messages.unknownPaymentTransaction)
}
}
}
Code implemented using StoreKit2
let result: Product.PurchaseResult = try await product.purchase()
switch result {
case .success(let verification):
let transaction = try checkVerified(verification)
// send transaction id
// ...
await transaction.finish()
case .pending:
break
case .userCancelled:
break
@unknown default:
break
}
func observeTransactions() -> Task<Void, Error> {
return Task(priority: .background) {
for await result in Transaction.unfinished {
do {
let transaction = try self.checkVerified(result)
guard transaction.productID.hasPrefix("... StoreKit2 product only...") else {
return
}
// send transaction id
// ...
await transaction.finish()
} catch {
// ...
}
}
}
}
Post not yet marked as solved
Hi!
I have an iOS app which I want to publish to the App Store. Within my app, users can scan physical item bar codes in grocery stores and earn points for their scans. They are then re-directed to a marketplace on the web, where they can spend these points on physical items (e.g. clothes).
Does App Store block such external linking to marketplace?
Thank you in advance!
Hello.
Currently, I am testing for the transition to the App Store Server API(v1/transactions/{transactionId}) as the verifyReceipt API we are utilizing has become deprecated.
API currently in use: https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
API planned to switch to: https://developer.apple.com/documentation/appstoreserverapi/get_transaction_info
I am doing the testing in the sandbox, but I cannot acquire a valid transaction_id with the App Store Server API. Below,
I am detailing what I conducted.
1.I call the verifyReceipt API and receive a response.
※Here's a part of the response. The product_id is a dummy.
"latest_receipt_info": [
{
"quantity": "1",
"product_id": "dummy_product_id",
"transaction_id": "2000000497573524",
"original_transaction_id": "2000000293926363",
"purchase_date": "2024-01-11 03:06:43 Etc/GMT",
"purchase_date_ms": "1704942403000",
"purchase_date_pst": "2024-01-10 19:06:43 America/Los_Angeles",
"original_purchase_date": "2023-03-10 04:11:01 Etc/GMT",
"original_purchase_date_ms": "1678421461000",
"original_purchase_date_pst": "2023-03-09 20:11:01 America/Los_Angeles",
"expires_date": "2024-01-11 03:11:43 Etc/GMT",
"expires_date_ms": "1704942703000",
"expires_date_pst": "2024-01-10 19:11:43 America/Los_Angeles",
"web_order_line_item_id": "2000000047921358",
"is_trial_period": "false",
"is_in_intro_offer_period": "false",
"in_app_ownership_type": "PURCHASED",
"subscription_group_identifier": "20230239"
}
],
2.I call the App Store Server API.
Request used with transaction_id: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/2000000497573524
Request used with original_transaction_id: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/2000000293926363
3.I receive an error stating the transaction id cannot be found.
Response: 404 Not Found: "{"errorCode":4040010,"errorMessage":"Transaction id not found."}"
Additionally, as I found similar questions, I also tried shifting the numbers of the transaction_id and original_transaction_id when calling the App Store Server API. However, this did not resolve the error I received.
https://developer.apple.com/forums/thread/84812
https://developer.apple.com/forums/thread/68944
In this case, what should I do with the transactionId to get the Transaction information?
I would appreciate it if anyone who knows can enlighten me.
Thank you in advance.
Post not yet marked as solved
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?
Post not yet marked as solved
first, i am new with apple in-app purchase.
in-app purchase step (is this right?):
front processing in-app purchase.
front send receipt data to validate on server (server get transaction to check it)
confirm purchase to apple
the 3rd step i know that front can confirm the purchase.
my question:
from the the 3rd step, can server confirm it after validated?
if it can, how do i imprement it?
Post not yet marked as solved
I don't often get CONSUMPTION_REQUEST or indeed REFUND but when I do I receive the same CONSUMPTION_REQUEST 3 times, 8 hours apart, before I do get the REFUND notification several hours after the 3rd and final CONSUMPTION_REQUEST.
The response I get from the PUT of /inApps/v1/transactions/consumption/{transactionId} is 202 so I can only assume it was accepted and good.
Is the fact I received it 3 times an indication that it was poorly formatted or incorrect somehow?
Is there anyway to test the consumption PUT?
I've yet to see an in-app consumable that I received a CONSUMPTION_REQUEST for, that was 100% consumed, and wasn't REFUND_DECLINED.
They have all been refunded to date.
This makes me suspicious that I'm doing something wrong even though all the information I'm getting says otherwise?