{"id":15036535,"url":"https://github.com/apple/app-store-server-library-swift","last_synced_at":"2025-04-13T02:18:52.527Z","repository":{"id":173162365,"uuid":"647516197","full_name":"apple/app-store-server-library-swift","owner":"apple","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-08T02:24:10.000Z","size":975,"stargazers_count":244,"open_issues_count":3,"forks_count":39,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-04-04T04:11:57.781Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apple.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-31T00:36:54.000Z","updated_at":"2025-03-19T06:42:46.000Z","dependencies_parsed_at":"2024-01-30T04:30:31.827Z","dependency_job_id":"4f58309a-95b4-49f4-b4fc-5299e254f44b","html_url":"https://github.com/apple/app-store-server-library-swift","commit_stats":null,"previous_names":["apple/app-store-server-library-swift"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apple%2Fapp-store-server-library-swift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apple%2Fapp-store-server-library-swift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apple%2Fapp-store-server-library-swift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apple%2Fapp-store-server-library-swift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apple","download_url":"https://codeload.github.com/apple/app-store-server-library-swift/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654265,"owners_count":21140271,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T20:31:27.676Z","updated_at":"2025-04-13T02:18:52.477Z","avatar_url":"https://github.com/apple.png","language":"Swift","funding_links":[],"categories":["HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"# Apple App Store Server Swift Library\nThe Swift server library for the [App Store Server API](https://developer.apple.com/documentation/appstoreserverapi) and [App Store Server Notifications](https://developer.apple.com/documentation/appstoreservernotifications). Also available in [Java](https://github.com/apple/app-store-server-library-java), [Python](https://github.com/apple/app-store-server-library-python), and [Node.js](https://github.com/apple/app-store-server-library-node).\n\n## Table of Contents\n1. [Installation](#installation)\n2. [Documentation](#documentation)\n3. [Usage](#usage)\n4. [Support](#support)\n\n## Installation\n\n### Requirements\n\n- Swift 6\n\n### Swift Package Manager\nAdd the following dependency\n```swift\n.package(url: \"https://github.com/apple/app-store-server-library-swift.git\", .upToNextMinor(from: \"3.0.0\")),\n```\n\n## Documentation\n\n[Documentation](https://apple.github.io/app-store-server-library-swift/documentation/appstoreserverlibrary/)\n\n[WWDC Video](https://developer.apple.com/videos/play/wwdc2023/10143/)\n\n### Obtaining an In-App Purchase key from App Store Connect\n\nTo 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 \u003e Integrations \u003e 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.\n\n### Obtaining Apple Root Certificates\n\nDownload and store the root certificates found in the Apple Root Certificates section of the [Apple PKI](https://www.apple.com/certificateauthority/) site. Provide these certificates as an array to a SignedDataVerifier to allow verifying the signed data comes from Apple.\n\n## Usage\n\n### API Usage\n\n```swift\nimport AppStoreServerLibrary\n\nlet issuerId = \"99b16628-15e4-4668-972b-eeff55eeff55\"\nlet keyId = \"ABCDEFGHIJ\"\nlet bundleId = \"com.example\"\nlet encodedKey = try! String(contentsOfFile: \"/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8\")\nlet environment = AppStoreEnvironment.sandbox\n\n// try! used for example purposes only\nlet client = try! AppStoreServerAPIClient(signingKey: encodedKey, keyId: keyId, issuerId: issuerId, bundleId: bundleId, environment: environment)\n\nlet response = await client.requestTestNotification()\nswitch response {\ncase .success(let response):\n    print(response.testNotificationToken)\ncase .failure(let errorCode, let rawApiError, let apiError, let errorMessage, let causedBy):\n    print(errorCode)\n    print(rawApiError)\n    print(apiError)\n    print(errorMessage)\n    print(causedBy)\n}\n```\n\n### Verification Usage\n\n```swift\nimport AppStoreServerLibrary\n\nlet bundleId = \"com.example\"\nlet appleRootCAs = loadRootCAs() // Specific implementation may vary\nlet appAppleId: Int64? = nil // appAppleId must be provided for the Production environment\nlet enableOnlineChecks = true\nlet environment = AppStoreEnvironment.sandbox\n\n// try! used for example purposes only\nlet verifier = try! SignedDataVerifier(rootCertificates: appleRootCAs, bundleId: bundleId, appAppleId: appAppleId, environment: environment, enableOnlineChecks: enableOnlineChecks)\n\nlet notificationPayload = \"ey...\"\nlet notificationResult = await verifier.verifyAndDecodeNotification(signedPayload: notificationPayload)\nswitch notificationResult {\ncase .valid(let decodedNotificaiton):\n    ...\ncase .invalid(let error):\n    ...\n}\n```\n\n### Receipt Usage\n\n```swift\nimport AppStoreServerLibrary\n\nlet issuerId = \"99b16628-15e4-4668-972b-eeff55eeff55\"\nlet keyId = \"ABCDEFGHIJ\"\nlet bundleId = \"com.example\"\nlet encodedKey = try! String(contentsOfFile: \"/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8\")\nlet environment = AppStoreEnvironment.sandbox\n\n// try! used for example purposes only\nlet client = try! AppStoreServerAPIClient(signingKey: encodedKey, keyId: keyId, issuerId: issuerId, bundleId: bundleId, environment: environment)\n\nlet appReceipt = \"MI...\"\nlet transactionIdOptional = ReceiptUtility.extractTransactionId(appReceipt: appReceipt)\nif let transactionId = transactionIdOptional {\n    var transactionHistoryRequest = TransactionHistoryRequest()\n    transactionHistoryRequest.sort = TransactionHistoryRequest.Order.ascending\n    transactionHistoryRequest.revoked = false\n    transactionHistoryRequest.productTypes = [TransactionHistoryRequest.ProductType.autoRenewable]\n\n    var response: HistoryResponse?\n    var transactions: [String] = []\n    repeat {\n        let revisionToken = response?.revision\n        let apiResponse = await client.getTransactionHistory(transactionId: transactionId, revision: revisionToken, transactionHistoryRequest: transactionHistoryRequest, version: .v2)\n        switch apiResponse {\n        case .success(let successfulResponse):\n            response = successfulResponse\n        case .failure:\n            // Handle Failure\n            throw\n        }\n        if let signedTransactions = response?.signedTransactions {\n            transactions.append(contentsOf: signedTransactions)\n        }\n    } while (response?.hasMore ?? false)\n    print(transactions)\n}\n```\n\n### Promotional Offer Signature Creation\n\n```swift\nimport AppStoreServerLibrary\n\nlet keyId = \"ABCDEFGHIJ\"\nlet bundleId = \"com.example\"\nlet encodedKey = try! String(contentsOfFile: \"/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8\")\n\nlet productId = \"\u003cproduct_id\u003e\"\nlet subscriptionOfferId = \"\u003csubscription_offer_id\u003e\"\nlet appAccountToken = \"\u003capp_account_token\u003e\"\n\n// try! used for example purposes only\nlet signatureCreator = try! PromotionalOfferSignatureCreator(privateKey: encodedKey, keyId: keyId, bundleId: bundleId)\n\nlet nonce = UUID()\nlet timestamp = Int64(Date().timeIntervalSince1970) * 1000\nlet signature = signatureCreator.createSignature(productIdentifier: productIdentifier, subscriptionOfferID: subscriptionOfferID, appAccountToken: appAccountToken, nonce: nonce, timestamp: timestamp)\nprint(signature)\n```\n\n## Support\n\nOnly the latest major version of the library will receive updates, including security updates. Therefore, it is recommended to update to new major versions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapple%2Fapp-store-server-library-swift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapple%2Fapp-store-server-library-swift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapple%2Fapp-store-server-library-swift/lists"}