The Swift server library for the App Store Server API and App Store Server Notifications. Also available in Java, Python, and Node.js.
- Swift 6
Add the following dependency
.package(url: "https://github.com/apple/app-store-server-library-swift.git", .upToNextMinor(from: "3.1.0")),
To use the App Store Server API or create promotional offer signatures, a signing key downloaded from App Store Connect is required. To obtain this key, you must have the Admin role. Go to Users and Access > Integrations > In-App Purchase. Here you can create and manage keys, as well as find your issuer ID. When using a key, you'll need the key ID and issuer ID as well.
Download and store the root certificates found in the Apple Root Certificates section of the Apple PKI site. Provide these certificates as an array to a SignedDataVerifier to allow verifying the signed data comes from Apple.
import AppStoreServerLibrary let issuerId = "99b16628-15e4-4668-972b-eeff55eeff55" let keyId = "ABCDEFGHIJ" let bundleId = "com.example" let encodedKey = try! String(contentsOfFile: "/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8") let environment = AppStoreEnvironment.sandbox // try! used for example purposes only let client = try! AppStoreServerAPIClient(signingKey: encodedKey, keyId: keyId, issuerId: issuerId, bundleId: bundleId, environment: environment) let response = await client.requestTestNotification() switch response { case .success(let response): print(response.testNotificationToken) case .failure(let errorCode, let rawApiError, let apiError, let errorMessage, let causedBy): print(errorCode) print(rawApiError) print(apiError) print(errorMessage) print(causedBy) }
import AppStoreServerLibrary let bundleId = "com.example" let appleRootCAs = loadRootCAs() // Specific implementation may vary let appAppleId: Int64? = nil // appAppleId must be provided for the Production environment let enableOnlineChecks = true let environment = AppStoreEnvironment.sandbox // try! used for example purposes only let verifier = try! SignedDataVerifier(rootCertificates: appleRootCAs, bundleId: bundleId, appAppleId: appAppleId, environment: environment, enableOnlineChecks: enableOnlineChecks) let notificationPayload = "ey..." let notificationResult = await verifier.verifyAndDecodeNotification(signedPayload: notificationPayload) switch notificationResult { case .valid(let decodedNotificaiton): ... case .invalid(let error): ... }
import AppStoreServerLibrary let issuerId = "99b16628-15e4-4668-972b-eeff55eeff55" let keyId = "ABCDEFGHIJ" let bundleId = "com.example" let encodedKey = try! String(contentsOfFile: "/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8") let environment = AppStoreEnvironment.sandbox // try! used for example purposes only let client = try! AppStoreServerAPIClient(signingKey: encodedKey, keyId: keyId, issuerId: issuerId, bundleId: bundleId, environment: environment) let appReceipt = "MI..." let transactionIdOptional = ReceiptUtility.extractTransactionId(appReceipt: appReceipt) if let transactionId = transactionIdOptional { var transactionHistoryRequest = TransactionHistoryRequest() transactionHistoryRequest.sort = TransactionHistoryRequest.Order.ascending transactionHistoryRequest.revoked = false transactionHistoryRequest.productTypes = [TransactionHistoryRequest.ProductType.autoRenewable] var response: HistoryResponse? var transactions: [String] = [] repeat { let revisionToken = response?.revision let apiResponse = await client.getTransactionHistory(transactionId: transactionId, revision: revisionToken, transactionHistoryRequest: transactionHistoryRequest, version: .v2) switch apiResponse { case .success(let successfulResponse): response = successfulResponse case .failure: // Handle Failure throw } if let signedTransactions = response?.signedTransactions { transactions.append(contentsOf: signedTransactions) } } while (response?.hasMore ?? false) print(transactions) }
import AppStoreServerLibrary let keyId = "ABCDEFGHIJ" let bundleId = "com.example" let encodedKey = try! String(contentsOfFile: "/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8") let productId = "<product_id>" let subscriptionOfferId = "<subscription_offer_id>" let appAccountToken = "<app_account_token>" // try! used for example purposes only let signatureCreator = try! PromotionalOfferSignatureCreator(privateKey: encodedKey, keyId: keyId, bundleId: bundleId) let nonce = UUID() let timestamp = Int64(Date().timeIntervalSince1970) * 1000 let signature = signatureCreator.createSignature(productIdentifier: productIdentifier, subscriptionOfferID: subscriptionOfferID, appAccountToken: appAccountToken, nonce: nonce, timestamp: timestamp) print(signature)
Only the latest major version of the library will receive updates, including security updates. Therefore, it is recommended to update to new major versions.