Showing preview only (661K chars total). Download the full file or copy to clipboard to get everything.
Repository: apple/app-store-server-library-python
Branch: main
Commit: ce1c9e0ced6e
Files: 265
Total size: 589.5 KB
Directory structure:
gitextract_u4cbit1j/
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── ci-prb.yml
│ ├── ci-release-docs.yml
│ ├── ci-release.yml
│ └── ci-snapshot.yml
├── .gitignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── MANIFEST.in
├── NOTICE.txt
├── README.md
├── appstoreserverlibrary/
│ ├── __init__.py
│ ├── api_client.py
│ ├── jws_signature_creator.py
│ ├── models/
│ │ ├── AbstractAdvancedCommerceBaseItem.py
│ │ ├── AbstractAdvancedCommerceInAppRequest.py
│ │ ├── AbstractAdvancedCommerceItem.py
│ │ ├── AbstractAdvancedCommerceResponse.py
│ │ ├── AccountTenure.py
│ │ ├── AdvancedCommerceDescriptors.py
│ │ ├── AdvancedCommerceEffective.py
│ │ ├── AdvancedCommerceOffer.py
│ │ ├── AdvancedCommerceOfferPeriod.py
│ │ ├── AdvancedCommerceOfferReason.py
│ │ ├── AdvancedCommerceOneTimeChargeCreateRequest.py
│ │ ├── AdvancedCommerceOneTimeChargeItem.py
│ │ ├── AdvancedCommercePeriod.py
│ │ ├── AdvancedCommerceReason.py
│ │ ├── AdvancedCommerceRefundReason.py
│ │ ├── AdvancedCommerceRefundType.py
│ │ ├── AdvancedCommerceRequest.py
│ │ ├── AdvancedCommerceRequestInfo.py
│ │ ├── AdvancedCommerceRequestRefundItem.py
│ │ ├── AdvancedCommerceRequestRefundRequest.py
│ │ ├── AdvancedCommerceRequestRefundResponse.py
│ │ ├── AdvancedCommerceSubscriptionCancelRequest.py
│ │ ├── AdvancedCommerceSubscriptionCancelResponse.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataDescriptors.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataItem.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataRequest.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataResponse.py
│ │ ├── AdvancedCommerceSubscriptionCreateItem.py
│ │ ├── AdvancedCommerceSubscriptionCreateRequest.py
│ │ ├── AdvancedCommerceSubscriptionMigrateDescriptors.py
│ │ ├── AdvancedCommerceSubscriptionMigrateItem.py
│ │ ├── AdvancedCommerceSubscriptionMigrateRenewalItem.py
│ │ ├── AdvancedCommerceSubscriptionMigrateRequest.py
│ │ ├── AdvancedCommerceSubscriptionMigrateResponse.py
│ │ ├── AdvancedCommerceSubscriptionModifyAddItem.py
│ │ ├── AdvancedCommerceSubscriptionModifyChangeItem.py
│ │ ├── AdvancedCommerceSubscriptionModifyDescriptors.py
│ │ ├── AdvancedCommerceSubscriptionModifyInAppRequest.py
│ │ ├── AdvancedCommerceSubscriptionModifyPeriodChange.py
│ │ ├── AdvancedCommerceSubscriptionModifyRemoveItem.py
│ │ ├── AdvancedCommerceSubscriptionPriceChangeItem.py
│ │ ├── AdvancedCommerceSubscriptionPriceChangeRequest.py
│ │ ├── AdvancedCommerceSubscriptionPriceChangeResponse.py
│ │ ├── AdvancedCommerceSubscriptionReactivateInAppRequest.py
│ │ ├── AdvancedCommerceSubscriptionReactivateItem.py
│ │ ├── AdvancedCommerceSubscriptionRevokeRequest.py
│ │ ├── AdvancedCommerceSubscriptionRevokeResponse.py
│ │ ├── AdvancedCommerceValidationUtils.py
│ │ ├── AlternateProduct.py
│ │ ├── AppData.py
│ │ ├── AppTransaction.py
│ │ ├── AppTransactionInfoResponse.py
│ │ ├── AutoRenewStatus.py
│ │ ├── BulletPoint.py
│ │ ├── CheckTestNotificationResponse.py
│ │ ├── ConsumptionRequest.py
│ │ ├── ConsumptionRequestReason.py
│ │ ├── ConsumptionRequestV1.py
│ │ ├── ConsumptionStatus.py
│ │ ├── Data.py
│ │ ├── DecodedRealtimeRequestBody.py
│ │ ├── DefaultConfigurationRequest.py
│ │ ├── DefaultConfigurationResponse.py
│ │ ├── DeliveryStatus.py
│ │ ├── DeliveryStatusV1.py
│ │ ├── Environment.py
│ │ ├── ExpirationIntent.py
│ │ ├── ExtendReasonCode.py
│ │ ├── ExtendRenewalDateRequest.py
│ │ ├── ExtendRenewalDateResponse.py
│ │ ├── ExternalPurchaseToken.py
│ │ ├── FirstSendAttemptResult.py
│ │ ├── GetImageListResponse.py
│ │ ├── GetImageListResponseItem.py
│ │ ├── GetMessageListResponse.py
│ │ ├── GetMessageListResponseItem.py
│ │ ├── HeaderPosition.py
│ │ ├── HistoryResponse.py
│ │ ├── ImageSize.py
│ │ ├── ImageState.py
│ │ ├── InAppOwnershipType.py
│ │ ├── JWSRenewalInfoDecodedPayload.py
│ │ ├── JWSTransactionDecodedPayload.py
│ │ ├── LastTransactionsItem.py
│ │ ├── LibraryUtility.py
│ │ ├── LifetimeDollarsPurchased.py
│ │ ├── LifetimeDollarsRefunded.py
│ │ ├── MassExtendRenewalDateRequest.py
│ │ ├── MassExtendRenewalDateResponse.py
│ │ ├── MassExtendRenewalDateStatusResponse.py
│ │ ├── Message.py
│ │ ├── MessageState.py
│ │ ├── NotificationHistoryRequest.py
│ │ ├── NotificationHistoryResponse.py
│ │ ├── NotificationHistoryResponseItem.py
│ │ ├── NotificationTypeV2.py
│ │ ├── OfferDiscountType.py
│ │ ├── OfferType.py
│ │ ├── OrderLookupResponse.py
│ │ ├── OrderLookupStatus.py
│ │ ├── PerformanceTestConfig.py
│ │ ├── PerformanceTestRequest.py
│ │ ├── PerformanceTestResponse.py
│ │ ├── PerformanceTestResponseTimes.py
│ │ ├── PerformanceTestResultResponse.py
│ │ ├── PerformanceTestStatus.py
│ │ ├── Platform.py
│ │ ├── PlayTime.py
│ │ ├── PriceIncreaseStatus.py
│ │ ├── PromotionalOffer.py
│ │ ├── PromotionalOfferSignatureV1.py
│ │ ├── PurchasePlatform.py
│ │ ├── RealtimeRequestBody.py
│ │ ├── RealtimeResponseBody.py
│ │ ├── RealtimeUrlRequest.py
│ │ ├── RealtimeUrlResponse.py
│ │ ├── RefundHistoryResponse.py
│ │ ├── RefundPreference.py
│ │ ├── RefundPreferenceV1.py
│ │ ├── ResponseBodyV2.py
│ │ ├── ResponseBodyV2DecodedPayload.py
│ │ ├── RevocationReason.py
│ │ ├── RevocationType.py
│ │ ├── SendAttemptItem.py
│ │ ├── SendAttemptResult.py
│ │ ├── SendTestNotificationResponse.py
│ │ ├── Status.py
│ │ ├── StatusResponse.py
│ │ ├── SubscriptionGroupIdentifierItem.py
│ │ ├── Subtype.py
│ │ ├── Summary.py
│ │ ├── TransactionHistoryRequest.py
│ │ ├── TransactionInfoResponse.py
│ │ ├── TransactionReason.py
│ │ ├── Type.py
│ │ ├── UpdateAppAccountTokenRequest.py
│ │ ├── UploadMessageImage.py
│ │ ├── UploadMessageRequestBody.py
│ │ ├── UserStatus.py
│ │ └── __init__.py
│ ├── promotional_offer.py
│ ├── py.typed
│ ├── receipt_utility.py
│ └── signed_data_verifier.py
├── docs/
│ └── requirements.txt
├── pyproject.toml
├── requirements.txt
└── tests/
├── __init__.py
├── resources/
│ ├── certs/
│ │ ├── testCA.der
│ │ └── testSigningKey.p8
│ ├── mock_signed_data/
│ │ ├── legacyTransaction
│ │ ├── missingX5CHeaderClaim
│ │ ├── renewalInfo
│ │ ├── testNotification
│ │ ├── transactionInfo
│ │ └── wrongBundleId
│ ├── models/
│ │ ├── advancedCommerceDescriptors.json
│ │ ├── advancedCommerceOffer.json
│ │ ├── advancedCommerceOneTimeChargeCreateRequest.json
│ │ ├── advancedCommerceOneTimeChargeItem.json
│ │ ├── advancedCommerceRequestInfo.json
│ │ ├── advancedCommerceRequestRefundItem.json
│ │ ├── advancedCommerceRequestRefundRequest.json
│ │ ├── advancedCommerceRequestRefundResponse.json
│ │ ├── advancedCommerceSubscriptionCancelRequest.json
│ │ ├── advancedCommerceSubscriptionCancelResponse.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataDescriptors.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataItem.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataRequest.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataResponse.json
│ │ ├── advancedCommerceSubscriptionCreateItem.json
│ │ ├── advancedCommerceSubscriptionCreateRequest.json
│ │ ├── advancedCommerceSubscriptionMigrateDescriptors.json
│ │ ├── advancedCommerceSubscriptionMigrateItem.json
│ │ ├── advancedCommerceSubscriptionMigrateRenewalItem.json
│ │ ├── advancedCommerceSubscriptionMigrateRequest.json
│ │ ├── advancedCommerceSubscriptionMigrateResponse.json
│ │ ├── advancedCommerceSubscriptionModifyAddItem.json
│ │ ├── advancedCommerceSubscriptionModifyChangeItem.json
│ │ ├── advancedCommerceSubscriptionModifyDescriptors.json
│ │ ├── advancedCommerceSubscriptionModifyInAppRequest.json
│ │ ├── advancedCommerceSubscriptionModifyPeriodChange.json
│ │ ├── advancedCommerceSubscriptionModifyRemoveItem.json
│ │ ├── advancedCommerceSubscriptionPriceChangeItem.json
│ │ ├── advancedCommerceSubscriptionPriceChangeRequest.json
│ │ ├── advancedCommerceSubscriptionPriceChangeResponse.json
│ │ ├── advancedCommerceSubscriptionReactivateInAppRequest.json
│ │ ├── advancedCommerceSubscriptionReactivateItem.json
│ │ ├── advancedCommerceSubscriptionRevokeRequest.json
│ │ ├── advancedCommerceSubscriptionRevokeResponse.json
│ │ ├── apiException.json
│ │ ├── apiTooManyRequestsException.json
│ │ ├── apiUnknownError.json
│ │ ├── appData.json
│ │ ├── appTransaction.json
│ │ ├── appTransactionDoesNotExistError.json
│ │ ├── appTransactionInfoResponse.json
│ │ ├── decodedRealtimeRequest.json
│ │ ├── extendRenewalDateForAllActiveSubscribersResponse.json
│ │ ├── extendSubscriptionRenewalDateResponse.json
│ │ ├── familyTransactionNotSupportedError.json
│ │ ├── getAllSubscriptionStatusesResponse.json
│ │ ├── getDefaultMessageResponse.json
│ │ ├── getImageListResponse.json
│ │ ├── getMessageListResponse.json
│ │ ├── getNotificationHistoryResponse.json
│ │ ├── getRealtimeUrlResponse.json
│ │ ├── getRefundHistoryResponse.json
│ │ ├── getStatusOfSubscriptionRenewalDateExtensionsResponse.json
│ │ ├── getTestNotificationStatusResponse.json
│ │ ├── invalidAppAccountTokenUUIDError.json
│ │ ├── invalidTransactionIdError.json
│ │ ├── lookupOrderIdResponse.json
│ │ ├── performanceTestResponse.json
│ │ ├── performanceTestResultResponse.json
│ │ ├── requestTestNotificationResponse.json
│ │ ├── signedConsumptionRequestNotification.json
│ │ ├── signedExternalPurchaseTokenNotification.json
│ │ ├── signedExternalPurchaseTokenSandboxNotification.json
│ │ ├── signedNotification.json
│ │ ├── signedRenewalInfo.json
│ │ ├── signedRescindConsentNotification.json
│ │ ├── signedSummaryNotification.json
│ │ ├── signedTransaction.json
│ │ ├── signedTransactionWithRevocation.json
│ │ ├── transactionHistoryResponse.json
│ │ ├── transactionHistoryResponseWithMalformedAppAppleId.json
│ │ ├── transactionHistoryResponseWithMalformedEnvironment.json
│ │ ├── transactionIdNotFoundError.json
│ │ ├── transactionIdNotOriginalTransactionId.json
│ │ └── transactionInfoResponse.json
│ └── xcode/
│ ├── xcode-app-receipt-empty
│ ├── xcode-app-receipt-with-transaction
│ ├── xcode-signed-app-transaction
│ ├── xcode-signed-renewal-info
│ └── xcode-signed-transaction
├── test_advanced_commerce_models.py
├── test_api_client.py
├── test_api_client_async.py
├── test_app_data.py
├── test_decoded_payloads.py
├── test_jws_signature_creator.py
├── test_payload_verification.py
├── test_promotional_offer_signature_creator.py
├── test_receipt_utility.py
├── test_retention_messaging.py
├── test_x509_verifiction.py
├── test_xcode_signed_data.py
└── util.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
time: "02:00"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
time: "02:00"
================================================
FILE: .github/workflows/ci-prb.yml
================================================
name: PR Builder
permissions:
contents: read
on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
jobs:
build:
name: Python ${{ matrix.python }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
python: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
os: [ ubuntu-latest ]
steps:
- name: Checkout Code
uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: |
python -m unittest
================================================
FILE: .github/workflows/ci-release-docs.yml
================================================
name: Doc Builder
permissions:
contents: read
on:
release:
types: [published]
jobs:
build:
name: Python Doc Builder
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r docs/requirements.txt
- name: Sphinx Api Docs
run: sphinx-apidoc -F -H "App Store Server Library" -A "Apple Inc." -V "0.2.1" -e -a -o _staging . tests pyproject.toml
- name: Spinx build
run: sphinx-build -b html _staging _build
- name: Upload docs
uses: actions/upload-pages-artifact@v4
with:
path: _build
deploy:
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy docs
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .github/workflows/ci-release.yml
================================================
name: Release Builder
permissions:
contents: read
on:
release:
types: [published]
jobs:
build:
# Only non-pre-release builds trigger a release
if: "!github.event.release.prerelease"
name: Python Release Builder
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install build
run: >-
python3 -m
pip install
build
--user
- name: Build the sdist and wheel
run: >-
python3 -m
build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
================================================
FILE: .github/workflows/ci-snapshot.yml
================================================
name: Snapshot Builder
permissions:
contents: read
on:
release:
types: [published]
jobs:
build:
# Pre-release builds trigger a snapshot being created
if: "github.event.release.prerelease"
name: Python Snapshot Builder
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install build
run: >-
python3 -m
pip install
build
--user
- name: Build the sdist and wheel
run: >-
python3 -m
build
- name: Publish to Test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/
================================================
FILE: .gitignore
================================================
__pycache__/
build/
dist/
*.egg-info/
.pytest_cache/
# pyenv
.python-version
# Environments
.env
.venv
venv
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# JetBrains
.idea/
/coverage.xml
/.coverage
.DS_Store
_build
_staging
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## Version 3.0.0
- Incorporate changes for App Store Server API v1.19 [https://github.com/apple/app-store-server-library-python/pull/172] from @riyazpanjwani
- This changes ConsumptionRequest and several dependent types to the V2 variant, while the V1 version was created as a new type, to align with documentation, which is a breaking change
## Version 2.0.0
- Support Retention Messaging API [https://github.com/apple/app-store-server-library-python/pull/160]
- This changes internal details of BaseAppStoreServerAPIClient, which is a breaking change for subclassing clients
- Incorporate changes for App Store Server API v1.17 [https://github.com/apple/app-store-server-library-python/pull/162] from @riyazpanjwani
- Add a new VerificationStatus case for retryable OCSP network failures [https://github.com/apple/app-store-server-library-python/pull/163]
- Add timeout to the AppStoreServerAPIClient [https://github.com/apple/app-store-server-library-python/pull/164]
- Incorporate changes for App Store Server API v1.18 [https://github.com/apple/app-store-server-library-python/pull/166] from @izanger
- This changes OfferType's case SUBSCRIPTION_OFFER_CODE to OFFER_CODE, which is a breaking change
## Version 1.9.0
- Incorporate changes for App Store Server API v1.16 [https://github.com/apple/app-store-server-library-python/pull/141] from @riyazpanjwani
- Fix SyntaxWarning in regex pattern string [https://github.com/apple/app-store-server-library-python/pull/138] from @krepe90
## Version 1.8.0
- Incorporate changes for App Store Server API v1.15 and App Store Server Notifications v2.15 [https://github.com/apple/app-store-server-library-python/pull/134]
## Version 1.7.0
- Update the SignedDataVerifier to cache verified certificate chains, improving performance [https://github.com/apple/app-store-server-library-python/pull/122]
## Version 1.6.0
- Update README to improve Dependabot link discovery [https://github.com/apple/app-store-server-library-python/pull/119]
## Version 1.5.0
- Add an async client built on httpx [https://github.com/apple/app-store-server-library-python/pull/105]
- Drop Python 3.7 support [https://github.com/apple/app-store-server-library-python/pull/106]
- Add check for original transaction id in legacy receipts [https://github.com/apple/app-store-server-library-python/pull/104] from @willhnation
## Version 1.4.0
- Incorporate changes for App Store Server API v1.13 and App Store Server Notifications v2.13 [https://github.com/apple/app-store-server-library-python/pull/102]
- Remove the upper limit on libraries that are unlikely to break upon upgrade [https://github.com/apple/app-store-server-library-python/pull/101]
## Version 1.3.0
- Incorporate changes for App Store Server API v1.12 and App Store Server Notifications v2.12 [https://github.com/apple/app-store-server-library-python/pull/95]
- Fix deprecation warnings from cryptography [https://github.com/apple/app-store-server-library-python/pull/94] from @WFT
- Replace use of deprecated datetime.utcnow() [https://github.com/apple/app-store-server-library-python/pull/93] from @WFT
- Cache cattrs values to prevent memory leak [https://github.com/apple/app-store-server-library-python/pull/92] from @Reskov
## Version 1.2.1
- Fix issue with OfferType in JWSTransactionDecodedPayload [https://github.com/apple/app-store-server-library-python/pull/88] from @devinwang
## Version 1.2.0
- Incorporate changes for App Store Server API v1.11 and App Store Server Notifications v2.11 [https://github.com/apple/app-store-server-library-python/pull/85]
- Various documentation and quality of life improvements, including contributions from @CallumWatkins, @hakusai22, and @sunny-dubey
## Version 1.1.0
- Support App Store Server Notifications v2.10 [https://github.com/apple/app-store-server-library-python/pull/65]
- Bump cryptography and pyOpenSSL maximum versions [https://github.com/apple/app-store-server-library-python/pull/61]/[https://github.com/apple/app-store-server-library-python/pull/63]
- Require appAppleId in SignedDataVerifier for the Production environment [https://github.com/apple/app-store-server-library-python/pull/60]
## 1.0.0
- Add error message to APIException [https://github.com/apple/app-store-server-library-python/pull/52]
## 0.3.0
- Add missing status field to the Data model [https://github.com/apple/app-store-server-library-python/pull/33]
- Add error codes from App Store Server API v1.9 [https://github.com/apple/app-store-server-library-python/pull/39]
- Add new fields from App Store Server API v1.10 [https://github.com/apple/app-store-server-library-python/pull/46]
- Add support for reading unknown enum values [https://github.com/apple/app-store-server-library-python/pull/45]
- Add support for Xcode and LocalTesting environments [https://github.com/apple/app-store-server-library-python/pull/44]
## 0.2.1
- Add py.typed file [https://github.com/apple/app-store-server-library-python/pull/19]
- Correct type annotation in PromotionalOfferSignatureCreator [https://github.com/apple/app-store-server-library-python/pull/17]
## 0.2.0
- Correct type in LastTransactionsItem's status field [https://github.com/apple/app-store-server-library-python/pull/11]
- Fix default value None for fields should require an Optional type [https://github.com/apple/app-store-server-library-python/pull/6]
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[opensource-conduct@group.apple.com](mailto:opensource-conduct@group.apple.com).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Thank you for your interest in contributing!
## Reporting Bugs
Please report bugs by creating [Github issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues).
To help the community understand the bug and get it fixed faster, please provide the following information when creating a new issue:
- A clear and descriptive title
- The exact steps to reproduce the bug
- The observed behavior and expected behavior
If possible, also include payloads, commands, screenshots, etc to help the community identify the problem. Do not include any personal or sensitive data.
## Suggesting Improvements
You can suggest improvements also by creating Github issues.
When creating a new suggestion, please provide the following information:
- A clear and descriptive title
- A description of the proposed improvement in as many details as possible
- Explain why the improvement is important
## Documentation Contribution
Documentation contribution will make it easier for the community to work on the project.
You may add README/diagrams to the components, or improve the existing docs. For major doc changes, we encourage you to create issues before contributing. Let us know what you are planning to change before the contribution.
## Code Contribution
For minor changes (like small bug fixes or typo correction), feel free to open up a PR directly.
For new features or major changes, we encourage you to create a Github issue first, and get agreement before starting on the implementation. This is to save you time in case there's duplicate effort or unforeseen risk.
## Project Licensing
All contributions (including Pull Requests) to this project are provided under the terms of the project’s [LICENSE](LICENSE.txt)
================================================
FILE: LICENSE.txt
================================================
Copyright 2023 Apple Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
include README.md
================================================
FILE: NOTICE.txt
================================================
Acknowledgements
Portions of this App Store Server Library software may utilize the following copyrighted
material, the use of which is hereby acknowledged.
_____________________
Hynek Schlawack and the attrs contributors (attrs)
The MIT License (MIT)
Copyright (c) 2015 Hynek Schlawack and the attrs contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
_____________________
José Padilla (pyjwt)
The MIT License (MIT)
Copyright (c) 2015-2022 José Padilla
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
_____________________
requests contributors (requests)
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
_____________________
cryptography contributors (pyca/cryptography)
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
_____________________
pyOpenSSL contributors (pyOpenSSL)
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
_____________________
The Python-ASN1 authors. (python-asn1)
Copyright (c) 2007-2021 the Python-ASN1 authors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
_____________________
Tin Tvrtković (cattrs)
MIT License
Copyright (c) 2016, Tin Tvrtković
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
_____________________
Encode OSS Ltd. (httpx)
Copyright © 2019, Encode OSS Ltd. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: README.md
================================================
# Apple App Store Server Python Library
The [Python](https://github.com/apple/app-store-server-library-python) server library for the [App Store Server API](https://developer.apple.com/documentation/appstoreserverapi), [App Store Server Notifications](https://developer.apple.com/documentation/appstoreservernotifications), [Retention Messaging API](https://developer.apple.com/documentation/retentionmessaging), and [Advanced Commerce API](https://developer.apple.com/documentation/AdvancedCommerceAPI). Also available in [Swift](https://github.com/apple/app-store-server-library-swift), [Node.js](https://github.com/apple/app-store-server-library-node), and [Java](https://github.com/apple/app-store-server-library-java).
## Table of Contents
1. [Installation](#installation)
2. [Documentation](#documentation)
3. [Usage](#usage)
4. [Support](#support)
## Installation
#### Requirements
- Python 3.8+
### pip
```sh
pip install app-store-server-library
```
## Documentation
[Documentation](https://apple.github.io/app-store-server-library-python/)
[WWDC Video](https://developer.apple.com/videos/play/wwdc2023/10143/)
### Obtaining an In-App Purchase key from App Store Connect
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.
### Obtaining Apple Root Certificates
Download 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.
## Usage
### API Usage
```python
from appstoreserverlibrary.api_client import AppStoreServerAPIClient, APIException
from appstoreserverlibrary.models.Environment import Environment
private_key = read_private_key("/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8") # Implementation will vary
key_id = "ABCDEFGHIJ"
issuer_id = "99b16628-15e4-4668-972b-eeff55eeff55"
bundle_id = "com.example"
environment = Environment.SANDBOX
client = AppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment)
try:
response = client.request_test_notification()
print(response)
except APIException as e:
print(e)
```
### Verification Usage
```python
from appstoreserverlibrary.models.Environment import Environment
from appstoreserverlibrary.signed_data_verifier import VerificationException, SignedDataVerifier
root_certificates = load_root_certificates()
enable_online_checks = True
bundle_id = "com.example"
environment = Environment.SANDBOX
app_apple_id = None # appAppleId must be provided for the Production environment
signed_data_verifier = SignedDataVerifier(root_certificates, enable_online_checks, environment, bundle_id, app_apple_id)
try:
signed_notification = "ey.."
payload = signed_data_verifier.verify_and_decode_notification(signed_notification)
print(payload)
except VerificationException as e:
print(e)
```
### Receipt Usage
```python
from appstoreserverlibrary.api_client import AppStoreServerAPIClient, APIException, GetTransactionHistoryVersion
from appstoreserverlibrary.models.Environment import Environment
from appstoreserverlibrary.receipt_utility import ReceiptUtility
from appstoreserverlibrary.models.HistoryResponse import HistoryResponse
from appstoreserverlibrary.models.TransactionHistoryRequest import TransactionHistoryRequest, ProductType, Order
private_key = read_private_key("/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8") # Implementation will vary
key_id = "ABCDEFGHIJ"
issuer_id = "99b16628-15e4-4668-972b-eeff55eeff55"
bundle_id = "com.example"
environment = Environment.SANDBOX
client = AppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment)
receipt_util = ReceiptUtility()
app_receipt = "MI.."
try:
transaction_id = receipt_util.extract_transaction_id_from_app_receipt(app_receipt)
if transaction_id != None:
transactions = []
response: HistoryResponse = None
request: TransactionHistoryRequest = TransactionHistoryRequest(
sort=Order.ASCENDING,
revoked=False,
productTypes=[ProductType.AUTO_RENEWABLE]
)
while response == None or response.hasMore:
revision = response.revision if response != None else None
response = client.get_transaction_history(transaction_id, revision, request, GetTransactionHistoryVersion.V2)
for transaction in response.signedTransactions:
transactions.append(transaction)
print(transactions)
except APIException as e:
print(e)
```
### Promotional Offer Signature Creation
```python
from appstoreserverlibrary.promotional_offer import PromotionalOfferSignatureCreator
import time
private_key = read_private_key("/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8") # Implementation will vary
key_id = "ABCDEFGHIJ"
bundle_id = "com.example"
promotion_code_signature_generator = PromotionalOfferSignatureCreator(private_key, key_id, bundle_id)
product_id = "<product_id>"
subscription_offer_id = "<subscription_offer_id>"
application_username = "<application_username>"
nonce = "<nonce>"
timestamp = round(time.time()*1000)
base64_encoded_signature = promotion_code_signature_generator.create_signature(product_id, subscription_offer_id, application_username, nonce, timestamp)
```
### Async HTTPX Support
#### Pip
Include the optional async dependency
```sh
pip install app-store-server-library[async]
```
#### API Usage
```python
from appstoreserverlibrary.api_client import AsyncAppStoreServerAPIClient, APIException
from appstoreserverlibrary.models.Environment import Environment
private_key = read_private_key("/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8") # Implementation will vary
key_id = "ABCDEFGHIJ"
issuer_id = "99b16628-15e4-4668-972b-eeff55eeff55"
bundle_id = "com.example"
environment = Environment.SANDBOX
client = AsyncAppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment)
try:
response = await client.request_test_notification()
print(response)
except APIException as e:
print(e)
# Once client use is finished
await client.async_close()
```
## Support
Only the latest major version of the library will receive updates, including security updates. Therefore, it is recommended to update to new major versions.
================================================
FILE: appstoreserverlibrary/__init__.py
================================================
================================================
FILE: appstoreserverlibrary/api_client.py
================================================
# Copyright (c) 2023 Apple Inc. Licensed under MIT License.
import calendar
import datetime
import warnings
from enum import IntEnum, Enum
from typing import Any, Dict, List, MutableMapping, Optional, Type, TypeVar, Union
from attr import define
import requests
import jwt
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from appstoreserverlibrary.models.LibraryUtility import _get_cattrs_converter
from .models.CheckTestNotificationResponse import CheckTestNotificationResponse
from .models.ConsumptionRequest import ConsumptionRequest
from .models.ConsumptionRequestV1 import ConsumptionRequestV1
from .models.DefaultConfigurationRequest import DefaultConfigurationRequest
from .models.DefaultConfigurationResponse import DefaultConfigurationResponse
from .models.Environment import Environment
from .models.ExtendRenewalDateRequest import ExtendRenewalDateRequest
from .models.ExtendRenewalDateResponse import ExtendRenewalDateResponse
from .models.GetImageListResponse import GetImageListResponse
from .models.GetMessageListResponse import GetMessageListResponse
from .models.HistoryResponse import HistoryResponse
from .models.ImageSize import ImageSize
from .models.MassExtendRenewalDateRequest import MassExtendRenewalDateRequest
from .models.MassExtendRenewalDateResponse import MassExtendRenewalDateResponse
from .models.MassExtendRenewalDateStatusResponse import MassExtendRenewalDateStatusResponse
from .models.NotificationHistoryRequest import NotificationHistoryRequest
from .models.NotificationHistoryResponse import NotificationHistoryResponse
from .models.OrderLookupResponse import OrderLookupResponse
from .models.PerformanceTestRequest import PerformanceTestRequest
from .models.PerformanceTestResponse import PerformanceTestResponse
from .models.PerformanceTestResultResponse import PerformanceTestResultResponse
from .models.RealtimeUrlRequest import RealtimeUrlRequest
from .models.RealtimeUrlResponse import RealtimeUrlResponse
from .models.RefundHistoryResponse import RefundHistoryResponse
from .models.SendTestNotificationResponse import SendTestNotificationResponse
from .models.Status import Status
from .models.StatusResponse import StatusResponse
from .models.TransactionHistoryRequest import TransactionHistoryRequest
from .models.TransactionInfoResponse import TransactionInfoResponse
from .models.AppTransactionInfoResponse import AppTransactionInfoResponse
from .models.UpdateAppAccountTokenRequest import UpdateAppAccountTokenRequest
from .models.UploadMessageRequestBody import UploadMessageRequestBody
from uuid import UUID
T = TypeVar('T')
class APIError(IntEnum):
GENERAL_BAD_REQUEST = 4000000
"""
An error that indicates an invalid request.
https://developer.apple.com/documentation/appstoreserverapi/generalbadrequesterror
"""
INVALID_APP_IDENTIFIER = 4000002
"""
An error that indicates an invalid app identifier.
https://developer.apple.com/documentation/appstoreserverapi/invalidappidentifiererror
"""
INVALID_REQUEST_REVISION = 4000005
"""
An error that indicates an invalid request revision.
https://developer.apple.com/documentation/appstoreserverapi/invalidrequestrevisionerror
"""
INVALID_TRANSACTION_ID = 4000006
"""
An error that indicates an invalid transaction identifier.
https://developer.apple.com/documentation/appstoreserverapi/invalidtransactioniderror
"""
INVALID_ORIGINAL_TRANSACTION_ID = 4000008
"""
An error that indicates an invalid original transaction identifier.
https://developer.apple.com/documentation/appstoreserverapi/invalidoriginaltransactioniderror
"""
INVALID_EXTEND_BY_DAYS = 4000009
"""
An error that indicates an invalid extend-by-days value.
https://developer.apple.com/documentation/appstoreserverapi/invalidextendbydayserror
"""
INVALID_EXTEND_REASON_CODE = 4000010
"""
An error that indicates an invalid reason code.
https://developer.apple.com/documentation/appstoreserverapi/invalidextendreasoncodeerror
"""
INVALID_REQUEST_IDENTIFIER = 4000011
"""
An error that indicates an invalid request identifier.
https://developer.apple.com/documentation/appstoreserverapi/invalidrequestidentifiererror
"""
START_DATE_TOO_FAR_IN_PAST = 4000012
"""
An error that indicates that the start date is earlier than the earliest allowed date.
https://developer.apple.com/documentation/appstoreserverapi/startdatetoofarinpasterror
"""
START_DATE_AFTER_END_DATE = 4000013
"""
An error that indicates that the end date precedes the start date, or the two dates are equal.
https://developer.apple.com/documentation/appstoreserverapi/startdateafterenddateerror
"""
INVALID_PAGINATION_TOKEN = 4000014
"""
An error that indicates the pagination token is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidpaginationtokenerror
"""
INVALID_START_DATE = 4000015
"""
An error that indicates the start date is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidstartdateerror
"""
INVALID_END_DATE = 4000016
"""
An error that indicates the end date is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidenddateerror
"""
PAGINATION_TOKEN_EXPIRED = 4000017
"""
An error that indicates the pagination token expired.
https://developer.apple.com/documentation/appstoreserverapi/paginationtokenexpirederror
"""
INVALID_NOTIFICATION_TYPE = 4000018
"""
An error that indicates the notification type or subtype is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidnotificationtypeerror
"""
MULTIPLE_FILTERS_SUPPLIED = 4000019
"""
An error that indicates the request is invalid because it has too many constraints applied.
https://developer.apple.com/documentation/appstoreserverapi/multiplefilterssuppliederror
"""
INVALID_TEST_NOTIFICATION_TOKEN = 4000020
"""
An error that indicates the test notification token is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidtestnotificationtokenerror
"""
INVALID_SORT = 4000021
"""
An error that indicates an invalid sort parameter.
https://developer.apple.com/documentation/appstoreserverapi/invalidsorterror
"""
INVALID_PRODUCT_TYPE = 4000022
"""
An error that indicates an invalid product type parameter.
https://developer.apple.com/documentation/appstoreserverapi/invalidproducttypeerror
"""
INVALID_PRODUCT_ID = 4000023
"""
An error that indicates the product ID parameter is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidproductiderror
"""
INVALID_SUBSCRIPTION_GROUP_IDENTIFIER = 4000024
"""
An error that indicates an invalid subscription group identifier.
https://developer.apple.com/documentation/appstoreserverapi/invalidsubscriptiongroupidentifiererror
"""
INVALID_EXCLUDE_REVOKED = 4000025
"""
An error that indicates the query parameter exclude-revoked is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidexcluderevokederror
.. deprecated:: 1.5
"""
INVALID_IN_APP_OWNERSHIP_TYPE = 4000026
"""
An error that indicates an invalid in-app ownership type parameter.
https://developer.apple.com/documentation/appstoreserverapi/invalidinappownershiptypeerror
"""
INVALID_EMPTY_STOREFRONT_COUNTRY_CODE_LIST = 4000027
"""
An error that indicates a required storefront country code is empty.
https://developer.apple.com/documentation/appstoreserverapi/invalidemptystorefrontcountrycodelisterror
"""
INVALID_STOREFRONT_COUNTRY_CODE = 4000028
"""
An error that indicates a storefront code is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidstorefrontcountrycodeerror
"""
INVALID_REVOKED = 4000030
"""
An error that indicates the revoked parameter contains an invalid value.
https://developer.apple.com/documentation/appstoreserverapi/invalidrevokederror
"""
INVALID_STATUS = 4000031
"""
An error that indicates the status parameter is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidstatuserror
"""
INVALID_ACCOUNT_TENURE = 4000032
"""
An error that indicates the value of the account tenure field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidaccounttenureerror
"""
INVALID_APP_ACCOUNT_TOKEN = 4000033
"""
An error that indicates the value of the app account token field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidappaccounttokenerror
"""
INVALID_CONSUMPTION_STATUS = 4000034
"""
An error that indicates the value of the consumption status field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidconsumptionstatuserror
"""
INVALID_CUSTOMER_CONSENTED = 4000035
"""
An error that indicates the customer consented field is invalid or doesn’t indicate that the customer consented.
https://developer.apple.com/documentation/appstoreserverapi/invalidcustomerconsentederror
"""
INVALID_DELIVERY_STATUS = 4000036
"""
An error that indicates the value in the delivery status field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invaliddeliverystatuserror
"""
INVALID_LIFETIME_DOLLARS_PURCHASED = 4000037
"""
An error that indicates the value in the lifetime dollars purchased field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidlifetimedollarspurchasederror
"""
INVALID_LIFETIME_DOLLARS_REFUNDED = 4000038
"""
An error that indicates the value in the lifetime dollars refunded field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidlifetimedollarsrefundederror
"""
INVALID_PLATFORM = 4000039
"""
An error that indicates the value in the platform field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidplatformerror
"""
INVALID_PLAY_TIME = 4000040
"""
An error that indicates the value in the playtime field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidplaytimeerror
"""
INVALID_SAMPLE_CONTENT_PROVIDED = 4000041
"""
An error that indicates the value in the sample content provided field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invalidsamplecontentprovidederror
"""
INVALID_USER_STATUS = 4000042
"""
An error that indicates the value in the user status field is invalid.
https://developer.apple.com/documentation/appstoreserverapi/invaliduserstatuserror
"""
INVALID_TRANSACTION_NOT_CONSUMABLE = 4000043
"""
An error that indicates the transaction identifier doesn’t represent a consumable in-app purchase.
https://developer.apple.com/documentation/appstoreserverapi/invalidtransactionnotconsumableerror
.. deprecated:: 1.11
"""
INVALID_TRANSACTION_TYPE_NOT_SUPPORTED = 4000047
"""
An error that indicates the transaction identifier represents an unsupported in-app purchase type.
https://developer.apple.com/documentation/appstoreserverapi/invalidtransactiontypenotsupportederror
"""
APP_TRANSACTION_ID_NOT_SUPPORTED_ERROR = 4000048
"""
An error that indicates the endpoint doesn't support an app transaction ID.
https://developer.apple.com/documentation/appstoreserverapi/apptransactionidnotsupportederror
"""
INVALID_IMAGE = 4000161
"""
An error that indicates the image that's uploading is invalid.
https://developer.apple.com/documentation/retentionmessaging/invalidimageerror
"""
HEADER_TOO_LONG = 4000162
"""
An error that indicates the header text is too long.
https://developer.apple.com/documentation/retentionmessaging/headertoolongerror
"""
BODY_TOO_LONG = 4000163
"""
An error that indicates the body text is too long.
https://developer.apple.com/documentation/retentionmessaging/bodytoolongerror
"""
INVALID_LOCALE = 4000164
"""
An error that indicates the locale is invalid.
https://developer.apple.com/documentation/retentionmessaging/invalidlocaleerror
"""
ALT_TEXT_TOO_LONG = 4000175
"""
An error that indicates the alternative text for an image is too long.
https://developer.apple.com/documentation/retentionmessaging/alttexttoolongerror
"""
INVALID_APP_ACCOUNT_TOKEN_UUID_ERROR = 4000183
"""
An error that indicates the app account token value is not a valid UUID.
https://developer.apple.com/documentation/appstoreserverapi/invalidappaccounttokenuuiderror
"""
FAMILY_TRANSACTION_NOT_SUPPORTED_ERROR = 4000185
"""
An error that indicates the transaction is for a product the customer obtains through Family Sharing,
which the endpoint doesn’t support.
https://developer.apple.com/documentation/appstoreserverapi/familytransactionnotsupportederror
"""
TRANSACTION_ID_IS_NOT_ORIGINAL_TRANSACTION_ID_ERROR = 4000187
"""
An error that indicates the endpoint expects an original transaction identifier.
https://developer.apple.com/documentation/appstoreserverapi/transactionidisnotoriginaltransactioniderror
"""
INVALID_PERFORMANCE_TEST_REQUEST = 4000211
"""
An error the API returns that indicates the performance test request is invalid.
https://developer.apple.com/documentation/retentionmessaging/invalidperformancetestrequesterror
"""
INVALID_REQUEST_ID = 4000212
"""
An error that indicates the request ID is invalid.
https://developer.apple.com/documentation/retentionmessaging/invalidrequestiderror
"""
EXISTING_PERFORMANCE_TEST_RUN = 4000213
"""
An error that indicates an error with an existing test.
https://developer.apple.com/documentation/retentionmessaging/existingperformancetestrunerror
"""
BAD_REQUEST_REALTIME_URL = 4000215
"""
An error that indicates the URL is invalid.
https://developer.apple.com/documentation/retentionmessaging/badrequestrealtimeurlerror
"""
BAD_REQUEST_IMAGE_SIZE = 4000216
"""
An error that indicates the image size provided is invalid.
https://developer.apple.com/documentation/retentionmessaging/badrequestimagesizeerror
"""
BAD_REQUEST_TOO_MANY_BULLET_POINTS = 4000218
"""
An error that indicates there are too many bullet points.
https://developer.apple.com/documentation/retentionmessaging/badrequesttoomanybulletpointserror
"""
BAD_REQUEST_BULLET_POINT_TEXT_TOO_LONG = 4000219
"""
An error that indicates the text for a bullet point is too long.
https://developer.apple.com/documentation/retentionmessaging/badrequestbulletpointtexttoolongerror
"""
BAD_REQUEST_ABOVE_IMAGE_REQUIRES_AN_IMAGE = 4000224
"""
An error that indicates that no image object is included, but the request indicates that the header should be placed above the image.
https://developer.apple.com/documentation/retentionmessaging/badrequestaboveimagerequiresanimageerror
"""
SUBSCRIPTION_EXTENSION_INELIGIBLE = 4030004
"""
An error that indicates the subscription doesn't qualify for a renewal-date extension due to its subscription state.
https://developer.apple.com/documentation/appstoreserverapi/subscriptionextensionineligibleerror
"""
SUBSCRIPTION_MAX_EXTENSION = 4030005
"""
An error that indicates the subscription doesn’t qualify for a renewal-date extension because it has already received the maximum extensions.
https://developer.apple.com/documentation/appstoreserverapi/subscriptionmaxextensionerror
"""
FAMILY_SHARED_SUBSCRIPTION_EXTENSION_INELIGIBLE = 4030007
"""
An error that indicates a subscription isn't directly eligible for a renewal date extension because the user obtained it through Family Sharing.
https://developer.apple.com/documentation/appstoreserverapi/familysharedsubscriptionextensionineligibleerror
"""
MAXIMUM_NUMBER_OF_IMAGES_REACHED = 4030014
"""
An error that indicates when you reach the maximum number of uploaded images.
https://developer.apple.com/documentation/retentionmessaging/maximumnumberofimagesreachederror
"""
MAXIMUM_NUMBER_OF_MESSAGES_REACHED = 4030016
"""
An error that indicates when you reach the maximum number of uploaded messages.
https://developer.apple.com/documentation/retentionmessaging/maximumnumberofmessagesreachederror
"""
MESSAGE_NOT_APPROVED = 4030017
"""
An error that indicates the message isn't in the approved state, so you can't configure it as a default message.
https://developer.apple.com/documentation/retentionmessaging/messagenotapprovederror
"""
IMAGE_NOT_APPROVED = 4030018
"""
An error that indicates the image isn't in the approved state, so you can't configure it as part of a default message.
https://developer.apple.com/documentation/retentionmessaging/imagenotapprovederror
"""
IMAGE_IN_USE = 4030019
"""
An error that indicates the image is currently in use as part of a message, so you can't delete it.
https://developer.apple.com/documentation/retentionmessaging/imageinuseerror
"""
FORBIDDEN_NO_PASSING_TEST = 4030026
"""
An error that indicates that passing a performance test is required before you can set a URL for the production environment.
https://developer.apple.com/documentation/retentionmessaging/forbiddennopassingtesterror
"""
ACCOUNT_NOT_FOUND = 4040001
"""
An error that indicates the App Store account wasn’t found.
https://developer.apple.com/documentation/appstoreserverapi/accountnotfounderror
"""
ACCOUNT_NOT_FOUND_RETRYABLE = 4040002
"""
An error response that indicates the App Store account wasn’t found, but you can try again.
https://developer.apple.com/documentation/appstoreserverapi/accountnotfoundretryableerror
"""
APP_NOT_FOUND = 4040003
"""
An error that indicates the app wasn’t found.
https://developer.apple.com/documentation/appstoreserverapi/appnotfounderror
"""
APP_NOT_FOUND_RETRYABLE = 4040004
"""
An error response that indicates the app wasn’t found, but you can try again.
https://developer.apple.com/documentation/appstoreserverapi/appnotfoundretryableerror
"""
ORIGINAL_TRANSACTION_ID_NOT_FOUND = 4040005
"""
An error that indicates an original transaction identifier wasn't found.
https://developer.apple.com/documentation/appstoreserverapi/originaltransactionidnotfounderror
"""
ORIGINAL_TRANSACTION_ID_NOT_FOUND_RETRYABLE = 4040006
"""
An error response that indicates the original transaction identifier wasn’t found, but you can try again.
https://developer.apple.com/documentation/appstoreserverapi/originaltransactionidnotfoundretryableerror
"""
SERVER_NOTIFICATION_URL_NOT_FOUND = 4040007
"""
An error that indicates that the App Store server couldn’t find a notifications URL for your app in this environment.
https://developer.apple.com/documentation/appstoreserverapi/servernotificationurlnotfounderror
"""
TEST_NOTIFICATION_NOT_FOUND = 4040008
"""
An error that indicates that the test notification token is expired or the test notification status isn’t available.
https://developer.apple.com/documentation/appstoreserverapi/testnotificationnotfounderror
"""
STATUS_REQUEST_NOT_FOUND = 4040009
"""
An error that indicates the server didn't find a subscription-renewal-date extension request for the request identifier and product identifier you provided.
https://developer.apple.com/documentation/appstoreserverapi/statusrequestnotfounderror
"""
TRANSACTION_ID_NOT_FOUND = 4040010
"""
An error that indicates a transaction identifier wasn't found.
https://developer.apple.com/documentation/appstoreserverapi/transactionidnotfounderror
"""
IMAGE_NOT_FOUND = 4040014
"""
An error that indicates the system can't find the image identifier.
https://developer.apple.com/documentation/retentionmessaging/imagenotfounderror
"""
MESSAGE_NOT_FOUND = 4040015
"""
An error that indicates the system can't find the message identifier.
https://developer.apple.com/documentation/retentionmessaging/messagenotfounderror
"""
PERFORMANCE_TEST_RUN_NOT_FOUND = 4040018
"""
An error the API returns if the service can't find the specified test run.
https://developer.apple.com/documentation/retentionmessaging/performancetestrunnotfounderror
"""
APP_TRANSACTION_DOES_NOT_EXIST_ERROR = 4040019
"""
An error response that indicates an app transaction doesn’t exist for the specified customer.
https://developer.apple.com/documentation/appstoreserverapi/apptransactiondoesnotexisterror
"""
DEFAULT_MESSAGE_NOT_FOUND = 4040020
"""
An error that indicates a default message isn’t configured.
https://developer.apple.com/documentation/retentionmessaging/defaultmessagenotfounderror
"""
REALTIME_URL_NOT_FOUND = 4040021
"""
An error that indicates that the URL for your endpoint isn’t configured.
https://developer.apple.com/documentation/retentionmessaging/realtimeurlnotfounderror
"""
IMAGE_ALREADY_EXISTS = 4090000
"""
An error that indicates the image identifier already exists.
https://developer.apple.com/documentation/retentionmessaging/imagealreadyexistserror
"""
MESSAGE_ALREADY_EXISTS = 4090001
"""
An error that indicates the message identifier already exists.
https://developer.apple.com/documentation/retentionmessaging/messagealreadyexistserror
"""
RATE_LIMIT_EXCEEDED = 4290000
"""
An error that indicates that the request exceeded the rate limit.
https://developer.apple.com/documentation/appstoreserverapi/ratelimitexceedederror
"""
GENERAL_INTERNAL = 5000000
"""
An error that indicates a general internal error.
https://developer.apple.com/documentation/appstoreserverapi/generalinternalerror
"""
GENERAL_INTERNAL_RETRYABLE = 5000001
"""
An error response that indicates an unknown error occurred, but you can try again.
https://developer.apple.com/documentation/appstoreserverapi/generalinternalretryableerror
"""
@define
class APIException(Exception):
http_status_code: int
api_error: Optional[APIError]
raw_api_error: Optional[int]
error_message: Optional[str]
def __init__(self, http_status_code: int, raw_api_error: Optional[int] = None, error_message: Optional[str] = None):
self.http_status_code = http_status_code
self.raw_api_error = raw_api_error
self.api_error = None
self.error_message = error_message
try:
if raw_api_error is not None:
self.api_error = APIError(raw_api_error)
except ValueError:
pass
class GetTransactionHistoryVersion(str, Enum):
V1 = "v1"
"""
.. deprecated:: 1.3.0
"""
V2 = "v2"
class BaseAppStoreServerAPIClient:
def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str, environment: Environment):
if environment == Environment.XCODE:
raise ValueError("Xcode is not a supported environment for an AppStoreServerAPIClient")
if environment == Environment.PRODUCTION:
self._base_url = "https://api.storekit.itunes.apple.com"
elif environment == Environment.LOCAL_TESTING:
self._base_url = "https://local-testing-base-url"
elif environment == Environment.SANDBOX:
self._base_url = "https://api.storekit-sandbox.itunes.apple.com"
else:
raise ValueError("Invalid environment provided")
self._signing_key = serialization.load_pem_private_key(signing_key, password=None, backend=default_backend())
self._key_id = key_id
self._issuer_id = issuer_id
self._bundle_id = bundle_id
def _generate_token(self) -> str:
future_time = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=5)
return jwt.encode(
{
"bid": self._bundle_id,
"iss": self._issuer_id,
"aud": "appstoreconnect-v1",
"exp": calendar.timegm(future_time.timetuple()),
},
self._signing_key,
algorithm="ES256",
headers={"kid": self._key_id},
)
def _get_full_url(self, path) -> str:
return self._base_url + path
def _get_headers(self) -> Dict[str, str]:
return {
'User-Agent': "app-store-server-library/python/3.0.0",
'Authorization': f'Bearer {self._generate_token()}',
'Accept': 'application/json'
}
def _get_request_json(self, body) -> Dict[str, Any]:
c = _get_cattrs_converter(type(body)) if body is not None else None
return c.unstructure(body) if body is not None else None
def _parse_response(self, status_code: int, headers: MutableMapping, json_supplier, destination_class: Type[T]) -> T:
if 200 <= status_code < 300:
if destination_class is None:
return
c = _get_cattrs_converter(destination_class)
response_body = json_supplier()
return c.structure(response_body, destination_class)
else:
# Best effort parsing of the response body
if not 'content-type' in headers or headers['content-type'] != 'application/json':
raise APIException(status_code)
try:
response_body = json_supplier()
raise APIException(status_code, response_body['errorCode'], response_body['errorMessage'])
except APIException as e:
raise e
except Exception as e:
raise APIException(status_code) from e
class AppStoreServerAPIClient(BaseAppStoreServerAPIClient):
def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str, environment: Environment):
super().__init__(signing_key=signing_key, key_id=key_id, issuer_id=issuer_id, bundle_id=bundle_id, environment=environment)
def _make_request(self, path: str, method: str, queryParameters: Dict[str, Union[str, List[str]]], body, destination_class: Type[T], content_type: Optional[str] = None) -> T:
url = self._get_full_url(path)
headers = self._get_headers()
if isinstance(body, bytes):
if content_type:
headers['Content-Type'] = content_type
response = self._execute_request(method, url, queryParameters, headers, None, body)
else:
json = self._get_request_json(body)
response = self._execute_request(method, url, queryParameters, headers, json, None)
return self._parse_response(response.status_code, response.headers, lambda: response.json(), destination_class)
def _execute_request(self, method: str, url: str, params: Dict[str, Union[str, List[str]]], headers: Dict[str, str], json: Optional[Dict[str, Any]], data: Optional[bytes]) -> requests.Response:
return requests.request(method, url, params=params, headers=headers, json=json, data=data, timeout=30)
def extend_renewal_date_for_all_active_subscribers(self, mass_extend_renewal_date_request: MassExtendRenewalDateRequest) -> MassExtendRenewalDateResponse:
"""
Uses a subscription's product identifier to extend the renewal date for all of its eligible active subscribers.
https://developer.apple.com/documentation/appstoreserverapi/extend_subscription_renewal_dates_for_all_active_subscribers
:param mass_extend_renewal_date_request: The request body for extending a subscription renewal date for all of its active subscribers.
:return: A response that indicates the server successfully received the subscription-renewal-date extension request.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return self._make_request("/inApps/v1/subscriptions/extend/mass", "POST", {}, mass_extend_renewal_date_request, MassExtendRenewalDateResponse, None)
def extend_subscription_renewal_date(self, original_transaction_id: str, extend_renewal_date_request: ExtendRenewalDateRequest) -> ExtendRenewalDateResponse:
"""
Extends the renewal date of a customer's active subscription using the original transaction identifier.
https://developer.apple.com/documentation/appstoreserverapi/extend_a_subscription_renewal_date
:param original_transaction_id: The original transaction identifier of the subscription receiving a renewal date extension.
:param extend_renewal_date_request: The request body containing subscription-renewal-extension data.
:return: A response that indicates whether an individual renewal-date extension succeeded, and related details.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return self._make_request(f"/inApps/v1/subscriptions/extend/{original_transaction_id}", "PUT", {}, extend_renewal_date_request, ExtendRenewalDateResponse, None)
def get_all_subscription_statuses(self, transaction_id: str, status: Optional[List[Status]] = None) -> StatusResponse:
"""
Get the statuses for all of a customer's auto-renewable subscriptions in your app.
https://developer.apple.com/documentation/appstoreserverapi/get_all_subscription_statuses
:param transaction_id: The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:param status: An optional filter that indicates the status of subscriptions to include in the response. Your query may specify more than one status query parameter.
:return: A response that contains status information for all of a customer's auto-renewable subscriptions in your app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if status is not None:
queryParameters["status"] = [s.value for s in status]
return self._make_request(f"/inApps/v1/subscriptions/{transaction_id}", "GET", queryParameters, None, StatusResponse, None)
def get_refund_history(self, transaction_id: str, revision: Optional[str]) -> RefundHistoryResponse:
"""
Get a paginated list of all of a customer's refunded in-app purchases for your app.
https://developer.apple.com/documentation/appstoreserverapi/get_refund_history
:param transaction_id: The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:param revision: A token you provide to get the next set of up to 20 transactions. All responses include a revision token. Use the revision token from the previous RefundHistoryResponse.
:return: A response that contains status information for all of a customer's auto-renewable subscriptions in your app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if revision is not None:
queryParameters["revision"] = [revision]
return self._make_request(f"/inApps/v2/refund/lookup/{transaction_id}", "GET", queryParameters, None, RefundHistoryResponse, None)
def get_status_of_subscription_renewal_date_extensions(self, request_identifier: str, product_id: str) -> MassExtendRenewalDateStatusResponse:
"""
Checks whether a renewal date extension request completed, and provides the final count of successful or failed extensions.
https://developer.apple.com/documentation/appstoreserverapi/get_status_of_subscription_renewal_date_extensions
:param request_identifier: The UUID that represents your request to the Extend Subscription Renewal Dates for All Active Subscribers endpoint.
:param product_id: The product identifier of the auto-renewable subscription that you request a renewal-date extension for.
:return: A response that indicates the current status of a request to extend the subscription renewal date to all eligible subscribers.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return self._make_request(f"/inApps/v1/subscriptions/extend/mass/{product_id}/{request_identifier}", "GET", {}, None, MassExtendRenewalDateStatusResponse, None)
def get_test_notification_status(self, test_notification_token: str) -> CheckTestNotificationResponse:
"""
Check the status of the test App Store server notification sent to your server.
https://developer.apple.com/documentation/appstoreserverapi/get_test_notification_status
:param test_notification_token: The test notification token received from the Request a Test Notification endpoint
:return: A response that contains the contents of the test notification sent by the App Store server and the result from your server.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return self._make_request(f"/inApps/v1/notifications/test/{test_notification_token}", "GET", {}, None, CheckTestNotificationResponse, None)
def get_notification_history(self, pagination_token: Optional[str], notification_history_request: NotificationHistoryRequest) -> NotificationHistoryResponse:
"""
Get a list of notifications that the App Store server attempted to send to your server.
https://developer.apple.com/documentation/appstoreserverapi/get_notification_history
:param pagination_token: An optional token you use to get the next set of up to 20 notification history records. All responses that have more records available include a paginationToken. Omit this parameter the first time you call this endpoint.
:param notification_history_request: The request body that includes the start and end dates, and optional query constraints.
:return: A response that contains the App Store Server Notifications history for your app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if pagination_token is not None:
queryParameters["paginationToken"] = [pagination_token]
return self._make_request("/inApps/v1/notifications/history", "POST", queryParameters, notification_history_request, NotificationHistoryResponse, None)
def get_transaction_history(self, transaction_id: str, revision: Optional[str], transaction_history_request: TransactionHistoryRequest, version: GetTransactionHistoryVersion = GetTransactionHistoryVersion.V1) -> HistoryResponse:
"""
Get a customer's in-app purchase transaction history for your app.
https://developer.apple.com/documentation/appstoreserverapi/get_transaction_history
:param transaction_id: The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:param revision: A token you provide to get the next set of up to 20 transactions. All responses include a revision token. Note: For requests that use the revision token, include the same query parameters from the initial request. Use the revision token from the previous HistoryResponse.
:param transaction_history_request: The request parameters that includes the startDate,endDate,productIds,productTypes and optional query constraints.
:param version: The version of the Get Transaction History endpoint to use. V2 is recommended.
:return: A response that contains the customer's transaction history for an app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if revision is not None:
queryParameters["revision"] = [revision]
if transaction_history_request.startDate is not None:
queryParameters["startDate"] = [str(transaction_history_request.startDate)]
if transaction_history_request.endDate is not None:
queryParameters["endDate"] = [str(transaction_history_request.endDate)]
if transaction_history_request.productIds is not None:
queryParameters["productId"] = transaction_history_request.productIds
if transaction_history_request.productTypes is not None:
queryParameters["productType"] = [product_type.value for product_type in transaction_history_request.productTypes]
if transaction_history_request.sort is not None:
queryParameters["sort"] = [transaction_history_request.sort.value]
if transaction_history_request.subscriptionGroupIdentifiers is not None:
queryParameters["subscriptionGroupIdentifier"] = transaction_history_request.subscriptionGroupIdentifiers
if transaction_history_request.inAppOwnershipType is not None:
queryParameters["inAppOwnershipType"] = [transaction_history_request.inAppOwnershipType.value]
if transaction_history_request.revoked is not None:
queryParameters["revoked"] = [str(transaction_history_request.revoked)]
return self._make_request("/inApps/{}/history/{}".format(version.value, transaction_id), "GET", queryParameters, None, HistoryResponse, None)
def get_transaction_info(self, transaction_id: str) -> TransactionInfoResponse:
"""
Get information about a single transaction for your app.
https://developer.apple.com/documentation/appstoreserverapi/get_transaction_info
:param transaction_id The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:return: A response that contains signed transaction information for a single transaction.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return self._make_request(f"/inApps/v1/transactions/{transaction_id}", "GET", {}, None, TransactionInfoResponse, None)
def look_up_order_id(self, order_id: str) -> OrderLookupResponse:
"""
Get a customer's in-app purchases from a receipt using the order ID.
https://developer.apple.com/documentation/appstoreserverapi/look_up_order_id
:param order_id: The order ID for in-app purchases that belong to the customer.
:return: A response that includes the order lookup status and an array of signed transactions for the in-app purchases in the order.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return self._make_request(f"/inApps/v1/lookup/{order_id}", "GET", {}, None, OrderLookupResponse, None)
def request_test_notification(self) -> SendTestNotificationResponse:
"""
Ask App Store Server Notifications to send a test notification to your server.
https://developer.apple.com/documentation/appstoreserverapi/request_a_test_notification
:return: A response that contains the test notification token.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return self._make_request("/inApps/v1/notifications/test", "POST", {}, None, SendTestNotificationResponse, None)
def send_consumption_data(self, transaction_id: str, consumption_request: ConsumptionRequestV1):
"""
Send consumption information about a consumable in-app purchase to the App Store after your server receives a consumption request notification.
https://developer.apple.com/documentation/appstoreserverapi/send-consumption-information-v1
.. deprecated::
Use :func:`send_consumption_information` instead.
:param transaction_id: The transaction identifier for which you're providing consumption information. You receive this identifier in the CONSUMPTION_REQUEST notification the App Store sends to your server.
:param consumption_request: The request body containing consumption information.
:raises APIException: If a response was returned indicating the request could not be processed
"""
warnings.warn("send_consumption_data is deprecated, use send_consumption_information instead", DeprecationWarning, stacklevel=2)
self._make_request(f"/inApps/v1/transactions/consumption/{transaction_id}", "PUT", {}, consumption_request, None, None)
def send_consumption_information(self, transaction_id: str, consumption_request: ConsumptionRequest):
"""
Send consumption information about an In-App Purchase to the App Store after your server receives a consumption request notification.
https://developer.apple.com/documentation/appstoreserverapi/send-consumption-information
:param transaction_id: The transaction identifier for which you're providing consumption information. You receive this identifier in the CONSUMPTION_REQUEST notification the App Store sends to your server's App Store Server Notifications V2 endpoint.
:param consumption_request: The request body containing consumption information.
:raises APIException: If a response was returned indicating the request could not be processed
"""
self._make_request(f"/inApps/v2/transactions/consumption/{transaction_id}", "PUT", {}, consumption_request, None, None)
def set_app_account_token(self, original_transaction_id: str, update_app_account_token_request: UpdateAppAccountTokenRequest):
"""
Sets the app account token value for a purchase the customer makes outside your app, or updates its value in an existing transaction.
https://developer.apple.com/documentation/appstoreserverapi/set-app-account-token
:param original_transaction_id The original transaction identifier of the transaction to receive the app account token update.
:param update_app_account_token_request The request body that contains a valid app account token value.
:raises APIException: If a response was returned indicating the request could not be processed
"""
self._make_request(f"/inApps/v1/transactions/{original_transaction_id}/appAccountToken", "PUT", {}, update_app_account_token_request, None, None)
def upload_image(self, image_identifier: UUID, image: bytes, image_size: Optional[ImageSize] = None):
"""
Upload an image to use for retention messaging.
:param image_identifier: A UUID you provide to uniquely identify the image you upload.
:param image: The image file to upload.
:param image_size: The size of the image you upload.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/upload-image
"""
query_parameters = {}
if image_size is not None:
query_parameters["imageSize"] = [image_size.value]
self._make_request(f"/inApps/v1/messaging/image/{image_identifier}", "PUT", query_parameters, image, None, "image/png")
def delete_image(self, image_identifier: UUID):
"""
Delete a previously uploaded image.
:param image_identifier: The identifier of the image to delete.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-image
"""
self._make_request(f"/inApps/v1/messaging/image/{image_identifier}", "DELETE", {}, None, None, None)
def get_image_list(self) -> GetImageListResponse:
"""
Get the image identifier and state for all uploaded images.
:return: A response that contains status information for all images.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-image-list
"""
return self._make_request("/inApps/v1/messaging/image/list", "GET", {}, None, GetImageListResponse, None)
def upload_message(self, message_identifier: UUID, upload_message_request_body: UploadMessageRequestBody):
"""
Upload a message to use for retention messaging.
:param message_identifier: A UUID you provide to uniquely identify the message you upload.
:param upload_message_request_body: The message text to upload.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/upload-message
"""
self._make_request(f"/inApps/v1/messaging/message/{message_identifier}", "PUT", {}, upload_message_request_body, None, None)
def delete_message(self, message_identifier: UUID):
"""
Delete a previously uploaded message.
:param message_identifier: The identifier of the message to delete.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-message
"""
self._make_request(f"/inApps/v1/messaging/message/{message_identifier}", "DELETE", {}, None, None, None)
def get_message_list(self) -> GetMessageListResponse:
"""
Get the message identifier and state of all uploaded messages.
:return: A response that contains status information for all messages.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-message-list
"""
return self._make_request("/inApps/v1/messaging/message/list", "GET", {}, None, GetMessageListResponse, None)
def configure_default_message(self, product_id: str, locale: str, default_configuration_request: DefaultConfigurationRequest):
"""
Configure a default message for a specific product in a specific locale.
:param product_id: The product identifier for the default configuration.
:param locale: The locale for the default configuration.
:param default_configuration_request: The request body that includes the message identifier to configure as the default message.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/configure-default-message
"""
self._make_request(f"/inApps/v1/messaging/default/{product_id}/{locale}", "PUT", {}, default_configuration_request, None, None)
def delete_default_message(self, product_id: str, locale: str):
"""
Delete a default message for a product in a locale.
:param product_id: The product ID of the default message configuration.
:param locale: The locale of the default message configuration.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-default-message
"""
self._make_request(f"/inApps/v1/messaging/default/{product_id}/{locale}", "DELETE", {}, None, None, None)
def get_default_message(self, product_id: str, locale: str) -> DefaultConfigurationResponse:
"""
Gets the default message for a specific product in a specific locale, if it’s configured.
:param product_id: The product identifier of the message.
:param locale: The locale of the message.
:return: The response body that contains the default configuration information.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-default-message
"""
return self._make_request(f"/inApps/v1/messaging/default/{product_id}/{locale}", "GET", {}, None, DefaultConfigurationResponse, None)
def configure_realtime_url(self, realtime_url_request: RealtimeUrlRequest):
"""
Configures the URL for your Get Retention Message endpoint in the sandbox and production environments.
:param realtime_url_request: The request body that includes your endpoint’s URL.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/configure-realtime-url
"""
self._make_request("/inApps/v1/messaging/realtime/url", "PUT", {}, realtime_url_request, None, None)
def delete_realtime_url(self):
"""
Deletes the URL for your Get Retention Message endpoint, in the sandbox or production environments.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-realtime-url
"""
self._make_request("/inApps/v1/messaging/realtime/url", "DELETE", {}, None, None, None)
def get_realtime_url(self) -> RealtimeUrlResponse:
"""
Gets the URL for real-time messages that points to your Get Retention Message endpoint, which you previously configured.
:return: The response body that contains the URL for your Get Retention Message endpoint.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-realtime-url
"""
return self._make_request("/inApps/v1/messaging/realtime/url", "GET", {}, None, RealtimeUrlResponse, None)
def initiate_performance_test(self, performance_test_request: PerformanceTestRequest) -> PerformanceTestResponse:
"""
Initiates a performance test of your Get Retention Message endpoint in the sandbox environment.
:param performance_test_request: The request body which specifies a transaction identifier of an In-App Purchase to use for this test.
:return: The performance test response object.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/initiate-performance-test
"""
return self._make_request("/inApps/v1/messaging/performanceTest", "POST", {}, performance_test_request, PerformanceTestResponse, None)
def get_performance_test_results(self, request_id: str) -> PerformanceTestResultResponse:
"""
Gets the results of the performance test for the specified identifier.
:param request_id: The ID of the performance test to return, which you receive in the PerformanceTestResponse when you call Initiate Performance Test.
:return: An object the API returns that describes the performance test results.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-performance-test-results
"""
return self._make_request(f"/inApps/v1/messaging/performanceTest/result/{request_id}", "GET", {}, None, PerformanceTestResultResponse, None)
def get_app_transaction_info(self, transaction_id: str) -> AppTransactionInfoResponse:
"""
Get a customer's app transaction information for your app.
:param transaction_id Any originalTransactionId, transactionId or appTransactionId that belongs to the customer for your app.
:return: A response that contains signed app transaction information for a customer.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/appstoreserverapi/get-app-transaction-info
"""
return self._make_request(f"/inApps/v1/transactions/appTransactions/{transaction_id}", "GET", {}, None, AppTransactionInfoResponse, None)
class AsyncAppStoreServerAPIClient(BaseAppStoreServerAPIClient):
def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str, environment: Environment):
super().__init__(signing_key=signing_key, key_id=key_id, issuer_id=issuer_id, bundle_id=bundle_id, environment=environment)
try:
import httpx
self.http_client = httpx.AsyncClient()
except:
raise ModuleNotFoundError("httpx not found but attempting to instantiate an async client")
async def async_close(self):
await self.http_client.aclose()
async def _make_request(self, path: str, method: str, queryParameters: Dict[str, Union[str, List[str]]], body, destination_class: Type[T], content_type: Optional[str] = None) -> T:
url = self._get_full_url(path)
headers = self._get_headers()
if isinstance(body, bytes):
# For binary data like images
if content_type:
headers['Content-Type'] = content_type
response = await self._execute_request(method, url, queryParameters, headers, None, body)
else:
# For JSON data
json = self._get_request_json(body)
response = await self._execute_request(method, url, queryParameters, headers, json, None)
return self._parse_response(response.status_code, response.headers, lambda: response.json(), destination_class)
async def _execute_request(self, method: str, url: str, params: Dict[str, Union[str, List[str]]], headers: Dict[str, str], json: Optional[Dict[str, Any]], data: Optional[bytes]):
return await self.http_client.request(method, url, params=params, headers=headers, json=json, data=data, timeout=30)
async def extend_renewal_date_for_all_active_subscribers(self, mass_extend_renewal_date_request: MassExtendRenewalDateRequest) -> MassExtendRenewalDateResponse:
"""
Uses a subscription's product identifier to extend the renewal date for all of its eligible active subscribers.
https://developer.apple.com/documentation/appstoreserverapi/extend_subscription_renewal_dates_for_all_active_subscribers
:param mass_extend_renewal_date_request: The request body for extending a subscription renewal date for all of its active subscribers.
:return: A response that indicates the server successfully received the subscription-renewal-date extension request.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return await self._make_request("/inApps/v1/subscriptions/extend/mass", "POST", {}, mass_extend_renewal_date_request, MassExtendRenewalDateResponse, None)
async def extend_subscription_renewal_date(self, original_transaction_id: str, extend_renewal_date_request: ExtendRenewalDateRequest) -> ExtendRenewalDateResponse:
"""
Extends the renewal date of a customer's active subscription using the original transaction identifier.
https://developer.apple.com/documentation/appstoreserverapi/extend_a_subscription_renewal_date
:param original_transaction_id: The original transaction identifier of the subscription receiving a renewal date extension.
:param extend_renewal_date_request: The request body containing subscription-renewal-extension data.
:return: A response that indicates whether an individual renewal-date extension succeeded, and related details.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return await self._make_request(f"/inApps/v1/subscriptions/extend/{original_transaction_id}", "PUT", {}, extend_renewal_date_request, ExtendRenewalDateResponse, None)
async def get_all_subscription_statuses(self, transaction_id: str, status: Optional[List[Status]] = None) -> StatusResponse:
"""
Get the statuses for all of a customer's auto-renewable subscriptions in your app.
https://developer.apple.com/documentation/appstoreserverapi/get_all_subscription_statuses
:param transaction_id: The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:param status: An optional filter that indicates the status of subscriptions to include in the response. Your query may specify more than one status query parameter.
:return: A response that contains status information for all of a customer's auto-renewable subscriptions in your app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if status is not None:
queryParameters["status"] = [s.value for s in status]
return await self._make_request(f"/inApps/v1/subscriptions/{transaction_id}", "GET", queryParameters, None, StatusResponse, None)
async def get_refund_history(self, transaction_id: str, revision: Optional[str]) -> RefundHistoryResponse:
"""
Get a paginated list of all of a customer's refunded in-app purchases for your app.
https://developer.apple.com/documentation/appstoreserverapi/get_refund_history
:param transaction_id: The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:param revision: A token you provide to get the next set of up to 20 transactions. All responses include a revision token. Use the revision token from the previous RefundHistoryResponse.
:return: A response that contains status information for all of a customer's auto-renewable subscriptions in your app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if revision is not None:
queryParameters["revision"] = [revision]
return await self._make_request(f"/inApps/v2/refund/lookup/{transaction_id}", "GET", queryParameters, None, RefundHistoryResponse, None)
async def get_status_of_subscription_renewal_date_extensions(self, request_identifier: str, product_id: str) -> MassExtendRenewalDateStatusResponse:
"""
Checks whether a renewal date extension request completed, and provides the final count of successful or failed extensions.
https://developer.apple.com/documentation/appstoreserverapi/get_status_of_subscription_renewal_date_extensions
:param request_identifier: The UUID that represents your request to the Extend Subscription Renewal Dates for All Active Subscribers endpoint.
:param product_id: The product identifier of the auto-renewable subscription that you request a renewal-date extension for.
:return: A response that indicates the current status of a request to extend the subscription renewal date to all eligible subscribers.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return await self._make_request(f"/inApps/v1/subscriptions/extend/mass/{product_id}/{request_identifier}", "GET", {}, None, MassExtendRenewalDateStatusResponse, None)
async def get_test_notification_status(self, test_notification_token: str) -> CheckTestNotificationResponse:
"""
Check the status of the test App Store server notification sent to your server.
https://developer.apple.com/documentation/appstoreserverapi/get_test_notification_status
:param test_notification_token: The test notification token received from the Request a Test Notification endpoint
:return: A response that contains the contents of the test notification sent by the App Store server and the result from your server.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return await self._make_request(f"/inApps/v1/notifications/test/{test_notification_token}", "GET", {}, None, CheckTestNotificationResponse, None)
async def get_notification_history(self, pagination_token: Optional[str], notification_history_request: NotificationHistoryRequest) -> NotificationHistoryResponse:
"""
Get a list of notifications that the App Store server attempted to send to your server.
https://developer.apple.com/documentation/appstoreserverapi/get_notification_history
:param pagination_token: An optional token you use to get the next set of up to 20 notification history records. All responses that have more records available include a paginationToken. Omit this parameter the first time you call this endpoint.
:param notification_history_request: The request body that includes the start and end dates, and optional query constraints.
:return: A response that contains the App Store Server Notifications history for your app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if pagination_token is not None:
queryParameters["paginationToken"] = [pagination_token]
return await self._make_request("/inApps/v1/notifications/history", "POST", queryParameters, notification_history_request, NotificationHistoryResponse, None)
async def get_transaction_history(self, transaction_id: str, revision: Optional[str], transaction_history_request: TransactionHistoryRequest, version: GetTransactionHistoryVersion = GetTransactionHistoryVersion.V1) -> HistoryResponse:
"""
Get a customer's in-app purchase transaction history for your app.
https://developer.apple.com/documentation/appstoreserverapi/get_transaction_history
:param transaction_id: The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:param revision: A token you provide to get the next set of up to 20 transactions. All responses include a revision token. Note: For requests that use the revision token, include the same query parameters from the initial request. Use the revision token from the previous HistoryResponse.
:param transaction_history_request: The request parameters that includes the startDate,endDate,productIds,productTypes and optional query constraints.
:param version: The version of the Get Transaction History endpoint to use. V2 is recommended.
:return: A response that contains the customer's transaction history for an app.
:throws APIException: If a response was returned indicating the request could not be processed
"""
queryParameters: Dict[str, List[str]] = dict()
if revision is not None:
queryParameters["revision"] = [revision]
if transaction_history_request.startDate is not None:
queryParameters["startDate"] = [str(transaction_history_request.startDate)]
if transaction_history_request.endDate is not None:
queryParameters["endDate"] = [str(transaction_history_request.endDate)]
if transaction_history_request.productIds is not None:
queryParameters["productId"] = transaction_history_request.productIds
if transaction_history_request.productTypes is not None:
queryParameters["productType"] = [product_type.value for product_type in transaction_history_request.productTypes]
if transaction_history_request.sort is not None:
queryParameters["sort"] = [transaction_history_request.sort.value]
if transaction_history_request.subscriptionGroupIdentifiers is not None:
queryParameters["subscriptionGroupIdentifier"] = transaction_history_request.subscriptionGroupIdentifiers
if transaction_history_request.inAppOwnershipType is not None:
queryParameters["inAppOwnershipType"] = [transaction_history_request.inAppOwnershipType.value]
if transaction_history_request.revoked is not None:
queryParameters["revoked"] = [str(transaction_history_request.revoked)]
return await self._make_request("/inApps/" + version + "/history/" + transaction_id, "GET", queryParameters, None, HistoryResponse, None)
async def get_transaction_info(self, transaction_id: str) -> TransactionInfoResponse:
"""
Get information about a single transaction for your app.
https://developer.apple.com/documentation/appstoreserverapi/get_transaction_info
:param transaction_id The identifier of a transaction that belongs to the customer, and which may be an original transaction identifier.
:return: A response that contains signed transaction information for a single transaction.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return await self._make_request(f"/inApps/v1/transactions/{transaction_id}", "GET", {}, None, TransactionInfoResponse, None)
async def look_up_order_id(self, order_id: str) -> OrderLookupResponse:
"""
Get a customer's in-app purchases from a receipt using the order ID.
https://developer.apple.com/documentation/appstoreserverapi/look_up_order_id
:param order_id: The order ID for in-app purchases that belong to the customer.
:return: A response that includes the order lookup status and an array of signed transactions for the in-app purchases in the order.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return await self._make_request(f"/inApps/v1/lookup/{order_id}", "GET", {}, None, OrderLookupResponse, None)
async def request_test_notification(self) -> SendTestNotificationResponse:
"""
Ask App Store Server Notifications to send a test notification to your server.
https://developer.apple.com/documentation/appstoreserverapi/request_a_test_notification
:return: A response that contains the test notification token.
:throws APIException: If a response was returned indicating the request could not be processed
"""
return await self._make_request("/inApps/v1/notifications/test", "POST", {}, None, SendTestNotificationResponse, None)
async def send_consumption_data(self, transaction_id: str, consumption_request: ConsumptionRequestV1):
"""
Send consumption information about a consumable in-app purchase to the App Store after your server receives a consumption request notification.
https://developer.apple.com/documentation/appstoreserverapi/send-consumption-information-v1
.. deprecated::
Use :func:`send_consumption_information` instead.
:param transaction_id: The transaction identifier for which you're providing consumption information. You receive this identifier in the CONSUMPTION_REQUEST notification the App Store sends to your server.
:param consumption_request: The request body containing consumption information.
:raises APIException: If a response was returned indicating the request could not be processed
"""
warnings.warn("send_consumption_data is deprecated, use send_consumption_information instead", DeprecationWarning, stacklevel=2)
await self._make_request(f"/inApps/v1/transactions/consumption/{transaction_id}", "PUT", {}, consumption_request, None, None)
async def send_consumption_information(self, transaction_id: str, consumption_request: ConsumptionRequest):
"""
Send consumption information about an In-App Purchase to the App Store after your server receives a consumption request notification.
https://developer.apple.com/documentation/appstoreserverapi/send-consumption-information
:param transaction_id: The transaction identifier for which you're providing consumption information. You receive this identifier in the CONSUMPTION_REQUEST notification the App Store sends to your server's App Store Server Notifications V2 endpoint.
:param consumption_request: The request body containing consumption information.
:raises APIException: If a response was returned indicating the request could not be processed
"""
await self._make_request(f"/inApps/v2/transactions/consumption/{transaction_id}", "PUT", {}, consumption_request, None, None)
async def set_app_account_token(self, original_transaction_id: str, update_app_account_token_request: UpdateAppAccountTokenRequest):
"""
Sets the app account token value for a purchase the customer makes outside your app, or updates its value in an existing transaction.
https://developer.apple.com/documentation/appstoreserverapi/set-app-account-token
:param original_transaction_id The original transaction identifier of the transaction to receive the app account token update.
:param update_app_account_token_request The request body that contains a valid app account token value.
:raises APIException: If a response was returned indicating the request could not be processed
"""
await self._make_request(f"/inApps/v1/transactions/{original_transaction_id}/appAccountToken", "PUT", {}, update_app_account_token_request, None, None)
async def upload_image(self, image_identifier: UUID, image: bytes, image_size: Optional[ImageSize] = None):
"""
Upload an image to use for retention messaging.
:param image_identifier: A UUID you provide to uniquely identify the image you upload.
:param image: The image file to upload.
:param image_size: The optional size of the image.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/upload-image
"""
query_parameters = {}
if image_size is not None:
query_parameters["imageSize"] = [image_size.value]
await self._make_request(f"/inApps/v1/messaging/image/{image_identifier}", "PUT", query_parameters, image, None, "image/png")
async def delete_image(self, image_identifier: UUID):
"""
Delete a previously uploaded image.
:param image_identifier: The identifier of the image to delete.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-image
"""
await self._make_request(f"/inApps/v1/messaging/image/{image_identifier}", "DELETE", {}, None, None, None)
async def get_image_list(self) -> GetImageListResponse:
"""
Get the image identifier and state for all uploaded images.
:return: A response that contains status information for all images.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-image-list
"""
return await self._make_request("/inApps/v1/messaging/image/list", "GET", {}, None, GetImageListResponse, None)
async def upload_message(self, message_identifier: UUID, upload_message_request_body: UploadMessageRequestBody):
"""
Upload a message to use for retention messaging.
:param message_identifier: A UUID you provide to uniquely identify the message you upload.
:param upload_message_request_body: The message text to upload.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/upload-message
"""
await self._make_request(f"/inApps/v1/messaging/message/{message_identifier}", "PUT", {}, upload_message_request_body, None, None)
async def delete_message(self, message_identifier: UUID):
"""
Delete a previously uploaded message.
:param message_identifier: The identifier of the message to delete.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-message
"""
await self._make_request(f"/inApps/v1/messaging/message/{message_identifier}", "DELETE", {}, None, None, None)
async def get_message_list(self) -> GetMessageListResponse:
"""
Get the message identifier and state of all uploaded messages.
:return: A response that contains status information for all messages.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-message-list
"""
return await self._make_request("/inApps/v1/messaging/message/list", "GET", {}, None, GetMessageListResponse, None)
async def configure_default_message(self, product_id: str, locale: str, default_configuration_request: DefaultConfigurationRequest):
"""
Configure a default message for a specific product in a specific locale.
:param product_id: The product identifier for the default configuration.
:param locale: The locale for the default configuration.
:param default_configuration_request: The request body that includes the message identifier to configure as the default message.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/configure-default-message
"""
await self._make_request(f"/inApps/v1/messaging/default/{product_id}/{locale}", "PUT", {}, default_configuration_request, None, None)
async def delete_default_message(self, product_id: str, locale: str):
"""
Delete a default message for a product in a locale.
:param product_id: The product ID of the default message configuration.
:param locale: The locale of the default message configuration.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-default-message
"""
await self._make_request(f"/inApps/v1/messaging/default/{product_id}/{locale}", "DELETE", {}, None, None, None)
async def get_default_message(self, product_id: str, locale: str) -> DefaultConfigurationResponse:
"""
Get the default message for a specific product in a specific locale.
:param product_id: The product identifier for the default configuration.
:param locale: The locale for the default configuration.
:return: A response that contains the default configuration information.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-default-message
"""
return await self._make_request(f"/inApps/v1/messaging/default/{product_id}/{locale}", "GET", {}, None, DefaultConfigurationResponse, None)
async def configure_realtime_url(self, realtime_url_request: RealtimeUrlRequest):
"""
Configure the real-time URL for retention messaging.
:param realtime_url_request: The request body that contains the real-time URL.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/configure-realtime-url
"""
await self._make_request("/inApps/v1/messaging/realtime/url", "PUT", {}, realtime_url_request, None, None)
async def delete_realtime_url(self):
"""
Delete the real-time URL for retention messaging.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/delete-realtime-url
"""
await self._make_request("/inApps/v1/messaging/realtime/url", "DELETE", {}, None, None, None)
async def get_realtime_url(self) -> RealtimeUrlResponse:
"""
Get the real-time URL for retention messaging.
:return: A response that contains the real-time URL information.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-realtime-url
"""
return await self._make_request("/inApps/v1/messaging/realtime/url", "GET", {}, None, RealtimeUrlResponse, None)
async def initiate_performance_test(self, performance_test_request: PerformanceTestRequest) -> PerformanceTestResponse:
"""
Initiates a performance test of your Get Retention Message endpoint in the sandbox environment.
:param performance_test_request: The request body which specifies a transaction identifier of an In-App Purchase to use for this test.
:return: The performance test response object.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/initiate-performance-test
"""
return await self._make_request("/inApps/v1/messaging/performanceTest", "POST", {}, performance_test_request, PerformanceTestResponse, None)
async def get_performance_test_results(self, request_id: str) -> PerformanceTestResultResponse:
"""
Gets the results of the performance test for the specified identifier.
:param request_id: The ID of the performance test to return, which you receive in the PerformanceTestResponse when you call Initiate Performance Test.
:return: An object the API returns that describes the performance test results.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/retentionmessaging/get-performance-test-results
"""
return await self._make_request(f"/inApps/v1/messaging/performanceTest/result/{request_id}", "GET", {}, None, PerformanceTestResultResponse, None)
async def get_app_transaction_info(self, transaction_id: str) -> AppTransactionInfoResponse:
"""
Get a customer's app transaction information for your app.
:param transaction_id Any originalTransactionId, transactionId or appTransactionId that belongs to the customer for your app.
:return: A response that contains signed app transaction information for a customer.
:raises APIException: If a response was returned indicating the request could not be processed
:see: https://developer.apple.com/documentation/appstoreserverapi/get-app-transaction-info
"""
return await self._make_request(f"/inApps/v1/transactions/appTransactions/{transaction_id}", "GET", {}, None, AppTransactionInfoResponse, None)
================================================
FILE: appstoreserverlibrary/jws_signature_creator.py
================================================
# Copyright (c) 2025 Apple Inc. Licensed under MIT License.
import datetime
from typing import Any, Dict, Optional
import base64
import json
import jwt
import uuid
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from appstoreserverlibrary.models.LibraryUtility import _get_cattrs_converter
class AdvancedCommerceAPIInAppRequest:
def __init__(self):
pass
class JWSSignatureCreator:
def __init__(self, audience: str, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str):
self._audience = audience
self._signing_key = serialization.load_pem_private_key(signing_key, password=None, backend=default_backend())
self._key_id = key_id
self._issuer_id = issuer_id
self._bundle_id = bundle_id
def _create_signature(self, feature_specific_claims: Dict[str, Any]) -> str:
claims = feature_specific_claims
current_time = datetime.datetime.now(datetime.timezone.utc)
claims["bid"] = self._bundle_id
claims["iss"] = self._issuer_id
claims["aud"] = self._audience
claims["iat"] = current_time
claims["nonce"] = str(uuid.uuid4())
return jwt.encode(claims,
self._signing_key,
algorithm="ES256",
headers={"kid": self._key_id},
)
class PromotionalOfferV2SignatureCreator(JWSSignatureCreator):
def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str):
"""
Create a PromotionalOfferV2SignatureCreator
:param signing_key: Your private key downloaded from App Store Connect
:param key_id: Your private key ID from App Store Connect
:param issuer_id: Your issuer ID from the Keys page in App Store Connect
:param bundle_id: Your app's bundle ID
"""
super().__init__(audience="promotional-offer", signing_key=signing_key, key_id=key_id, issuer_id=issuer_id, bundle_id=bundle_id)
def create_signature(self, product_id: str, offer_identifier: str, transaction_id: Optional[str]) -> str:
"""
Create a promotional offer V2 signature.
https://developer.apple.com/documentation/storekit/generating-jws-to-sign-app-store-requests
:param product_id: The unique identifier of the product
:param offer_identifier: The promotional offer identifier that you set up in App Store Connect
:param transaction_id: The unique identifier of any transaction that belongs to the customer. You can use the customer's appTransactionId, even for customers who haven't made any In-App Purchases in your app. This field is optional, but recommended.
:return: The signed JWS.
"""
if product_id is None:
raise ValueError("product_id cannot be null")
if offer_identifier is None:
raise ValueError("offer_identifier cannot be null")
feature_specific_claims = {
"productId": product_id,
"offerIdentifier": offer_identifier
}
if transaction_id is not None:
feature_specific_claims["transactionId"] = transaction_id
return self._create_signature(feature_specific_claims=feature_specific_claims)
class IntroductoryOfferEligibilitySignatureCreator(JWSSignatureCreator):
def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str):
"""
Create an IntroductoryOfferEligibilitySignatureCreator
:param signing_key: Your private key downloaded from App Store Connect
:param key_id: Your private key ID from App Store Connect
:param issuer_id: Your issuer ID from the Keys page in App Store Connect
:param bundle_id: Your app's bundle ID
"""
super().__init__(audience="introductory-offer-eligibility", signing_key=signing_key, key_id=key_id, issuer_id=issuer_id, bundle_id=bundle_id)
def create_signature(self, product_id: str, allow_introductory_offer: bool, transaction_id: str) -> str:
"""
Create an introductory offer eligibility signature.
https://developer.apple.com/documentation/storekit/generating-jws-to-sign-app-store-requests
:param product_id: The unique identifier of the product
:param allow_introductory_offer: A boolean value that determines whether the customer is eligible for an introductory offer
:param transaction_id: The unique identifier of any transaction that belongs to the customer. You can use the customer's appTransactionId, even for customers who haven't made any In-App Purchases in your app.
:return: The signed JWS.
"""
if product_id is None:
raise ValueError("product_id cannot be null")
if allow_introductory_offer is None:
raise ValueError("allow_introductory_offer cannot be null")
if transaction_id is None:
raise ValueError("transaction_id cannot be null")
feature_specific_claims = {
"productId": product_id,
"allowIntroductoryOffer": allow_introductory_offer,
"transactionId": transaction_id
}
return self._create_signature(feature_specific_claims=feature_specific_claims)
class AdvancedCommerceAPIInAppSignatureCreator(JWSSignatureCreator):
def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str):
"""
Create an AdvancedCommerceAPIInAppSignatureCreator
:param signing_key: Your private key downloaded from App Store Connect
:param key_id: Your private key ID from App Store Connect
:param issuer_id: Your issuer ID from the Keys page in App Store Connect
:param bundle_id: Your app's bundle ID
"""
super().__init__(audience="advanced-commerce-api", signing_key=signing_key, key_id=key_id, issuer_id=issuer_id, bundle_id=bundle_id)
def create_signature(self, advanced_commerce_in_app_request: AdvancedCommerceAPIInAppRequest) -> str:
"""
Create an Advanced Commerce in-app signed request.
https://developer.apple.com/documentation/storekit/generating-jws-to-sign-app-store-requests
:param advanced_commerce_in_app_request: The request to be signed.
:return: The signed JWS.
"""
if advanced_commerce_in_app_request is None:
raise ValueError("advanced_commerce_in_app_request cannot be null")
c = _get_cattrs_converter(type(advanced_commerce_in_app_request))
request = c.unstructure(advanced_commerce_in_app_request)
encoded_request = base64.b64encode(json.dumps(request).encode(encoding='utf-8')).decode('utf-8')
feature_specific_claims = {
"request": encoded_request
}
return self._create_signature(feature_specific_claims=feature_specific_claims)
================================================
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceBaseItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from abc import ABC
from attr import define
import attr
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
from .LibraryUtility import AttrsRawValueAware
@define
class AbstractAdvancedCommerceBaseItem(AttrsRawValueAware, ABC):
SKU: str = attr.ib(validator=AdvancedCommerceValidationUtils.sku_validator)
"""
The product identifier of an in-app purchase product you manage in your own system.
https://developer.apple.com/documentation/advancedcommerceapi/sku
"""
================================================
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceInAppRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from abc import ABC
from attr import define
import attr
from .AdvancedCommerceRequest import AdvancedCommerceRequest
from ..jws_signature_creator import AdvancedCommerceAPIInAppRequest
@define
class AbstractAdvancedCommerceInAppRequest(AdvancedCommerceRequest, AdvancedCommerceAPIInAppRequest, ABC):
operation: str = attr.ib()
version: str = attr.ib()
================================================
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
import attr
from .AbstractAdvancedCommerceBaseItem import AbstractAdvancedCommerceBaseItem
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AbstractAdvancedCommerceItem(AbstractAdvancedCommerceBaseItem):
description: str = attr.ib(validator=AdvancedCommerceValidationUtils.description_validator)
"""
A string you provide that describes a SKU.
https://developer.apple.com/documentation/advancedcommerceapi/description
"""
displayName: str = attr.ib(validator=AdvancedCommerceValidationUtils.display_name_validator)
"""
A string with a product name that you can localize and is suitable for display to customers.
https://developer.apple.com/documentation/advancedcommerceapi/displayname
"""
================================================
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceResponse.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from abc import ABC
from typing import Optional
from attr import define
import attr
@define
class AbstractAdvancedCommerceResponse(ABC):
signedRenewalInfo: Optional[str] = attr.ib(default=None)
"""
Subscription renewal information, signed by the App Store, in JSON Web Signature (JWS) format.
https://developer.apple.com/documentation/appstoreserverapi/jwsrenewalinfo
"""
signedTransactionInfo: Optional[str] = attr.ib(default=None)
"""
Transaction information signed by the App Store, in JSON Web Signature (JWS) Compact Serialization format.
https://developer.apple.com/documentation/appstoreserverapi/jwstransaction
"""
================================================
FILE: appstoreserverlibrary/models/AccountTenure.py
================================================
# Copyright (c) 2023 Apple Inc. Licensed under MIT License.
from enum import IntEnum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AccountTenure(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
"""
The age of the customer's account.
https://developer.apple.com/documentation/appstoreserverapi/accounttenure
"""
UNDECLARED = 0
ZERO_TO_THREE_DAYS = 1
THREE_DAYS_TO_TEN_DAYS = 2
TEN_DAYS_TO_THIRTY_DAYS = 3
THIRTY_DAYS_TO_NINETY_DAYS = 4
NINETY_DAYS_TO_ONE_HUNDRED_EIGHTY_DAYS = 5
ONE_HUNDRED_EIGHTY_DAYS_TO_THREE_HUNDRED_SIXTY_FIVE_DAYS = 6
GREATER_THAN_THREE_HUNDRED_SIXTY_FIVE_DAYS = 7
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceDescriptors.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
import attr
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AdvancedCommerceDescriptors:
"""
The display name and description of a subscription product.
https://developer.apple.com/documentation/advancedcommerceapi/descriptors
"""
description: str = attr.ib(validator=AdvancedCommerceValidationUtils.description_validator)
"""
A string you provide that describes a SKU.
https://developer.apple.com/documentation/advancedcommerceapi/description
"""
displayName: str = attr.ib(validator=AdvancedCommerceValidationUtils.display_name_validator)
"""
A string with a product name that you can localize and is suitable for display to customers.
https://developer.apple.com/documentation/advancedcommerceapi/displayname
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceEffective.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from enum import Enum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AdvancedCommerceEffective(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
"""
A string value that indicates when a requested change to an auto-renewable subscription goes into effect.
https://developer.apple.com/documentation/advancedcommerceapi/effective
"""
IMMEDIATELY = "IMMEDIATELY"
NEXT_BILL_CYCLE = "NEXT_BILL_CYCLE"
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceOffer.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
from attr import define
import attr
from .AdvancedCommerceOfferPeriod import AdvancedCommerceOfferPeriod
from .AdvancedCommerceOfferReason import AdvancedCommerceOfferReason
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
from .LibraryUtility import AttrsRawValueAware
@define
class AdvancedCommerceOffer(AttrsRawValueAware):
"""
A discount offer for an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/offer
"""
periodCount: int = attr.ib(validator=AdvancedCommerceValidationUtils.period_count_validator)
"""
The number of periods the offer is active.
"""
price: int = attr.ib()
"""
The offer price, in milliunits.
https://developer.apple.com/documentation/advancedcommerceapi/price
"""
period: AdvancedCommerceOfferPeriod = AdvancedCommerceOfferPeriod.create_main_attr('rawPeriod', raw_required=True)
"""
The period of the offer.
"""
rawPeriod: str = AdvancedCommerceOfferPeriod.create_raw_attr('period', required=True)
"""
See period
"""
reason: AdvancedCommerceOfferReason = AdvancedCommerceOfferReason.create_main_attr('rawReason', raw_required=True)
"""
The reason for the offer.
"""
rawReason: str = AdvancedCommerceOfferReason.create_raw_attr('reason', required=True)
"""
See reason
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceOfferPeriod.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from enum import Enum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AdvancedCommerceOfferPeriod(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
"""
The period of the offer.
https://developer.apple.com/documentation/advancedcommerceapi/offer
"""
P3D = "P3D"
P1W = "P1W"
P2W = "P2W"
P1M = "P1M"
P2M = "P2M"
P3M = "P3M"
P6M = "P6M"
P9M = "P9M"
P1Y = "P1Y"
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceOfferReason.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from enum import Enum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AdvancedCommerceOfferReason(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
"""
The reason for the offer.
https://developer.apple.com/documentation/advancedcommerceapi/offer
"""
ACQUISITION = "ACQUISITION"
WIN_BACK = "WIN_BACK"
RETENTION = "RETENTION"
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceOneTimeChargeCreateRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
from attr import define
import attr
from .AbstractAdvancedCommerceInAppRequest import AbstractAdvancedCommerceInAppRequest
from .AdvancedCommerceOneTimeChargeItem import AdvancedCommerceOneTimeChargeItem
@define
class AdvancedCommerceOneTimeChargeCreateRequest(AbstractAdvancedCommerceInAppRequest):
"""
The request data your app provides when a customer purchases a one-time-charge product.
https://developer.apple.com/documentation/advancedcommerceapi/onetimechargecreaterequest
"""
currency: str = attr.ib()
"""
The currency of the price of the product.
https://developer.apple.com/documentation/advancedcommerceapi/currency
"""
item: AdvancedCommerceOneTimeChargeItem = attr.ib()
"""
The details of the product for purchase.
https://developer.apple.com/documentation/advancedcommerceapi/onetimechargeitem
"""
taxCode: str = attr.ib()
"""
The tax code for this product.
https://developer.apple.com/documentation/advancedcommerceapi/taxCode
"""
operation: str = attr.ib(init=False, default="CREATE_ONE_TIME_CHARGE", on_setattr=attr.setters.frozen)
"""
The constant that represents the operation of this request.
"""
version: str = attr.ib(init=False, default="1", on_setattr=attr.setters.frozen)
"""
The version number of the API.
"""
storefront: Optional[str] = attr.ib(default=None)
"""
The storefront for the transaction.
https://developer.apple.com/documentation/advancedcommerceapi/storefront
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceOneTimeChargeItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
import attr
from .AbstractAdvancedCommerceItem import AbstractAdvancedCommerceItem
@define
class AdvancedCommerceOneTimeChargeItem(AbstractAdvancedCommerceItem):
"""
The details of a one-time charge product, including its display name, price, SKU, and metadata.
https://developer.apple.com/documentation/advancedcommerceapi/onetimechargeitem
"""
price: int = attr.ib()
"""
The price, in milliunits of the currency, of the one-time charge product.
https://developer.apple.com/documentation/advancedcommerceapi/price
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommercePeriod.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from enum import Enum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AdvancedCommercePeriod(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
"""
The duration of a single cycle of an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/period
"""
P1W = "P1W"
P1M = "P1M"
P2M = "P2M"
P3M = "P3M"
P6M = "P6M"
P1Y = "P1Y"
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceReason.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from enum import Enum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AdvancedCommerceReason(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
"""
The data your app provides to change an item of an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifychangeitem
"""
UPGRADE = "UPGRADE"
DOWNGRADE = "DOWNGRADE"
APPLY_OFFER = "APPLY_OFFER"
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceRefundReason.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from enum import Enum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AdvancedCommerceRefundReason(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
"""
A reason to request a refund.
https://developer.apple.com/documentation/advancedcommerceapi/refundreason
"""
UNINTENDED_PURCHASE = "UNINTENDED_PURCHASE"
FULFILLMENT_ISSUE = "FULFILLMENT_ISSUE"
UNSATISFIED_WITH_PURCHASE = "UNSATISFIED_WITH_PURCHASE"
LEGAL = "LEGAL"
OTHER = "OTHER"
MODIFY_ITEMS_REFUND = "MODIFY_ITEMS_REFUND"
SIMULATE_REFUND_DECLINE = "SIMULATE_REFUND_DECLINE"
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceRefundType.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from enum import Enum
from .LibraryUtility import AppStoreServerLibraryEnumMeta
class AdvancedCommerceRefundType(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
"""
Information about the refund request for an item, such as its SKU, the refund amount, reason, and type.
https://developer.apple.com/documentation/advancedcommerceapi/requestrefunditem
"""
FULL = "FULL"
PRORATED = "PRORATED"
CUSTOM = "CUSTOM"
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from abc import ABC
from attr import define
import attr
from .AdvancedCommerceRequestInfo import AdvancedCommerceRequestInfo
from .LibraryUtility import AttrsRawValueAware
@define
class AdvancedCommerceRequest(AttrsRawValueAware, ABC):
requestInfo: AdvancedCommerceRequestInfo = attr.ib()
"""
The metadata to include in server requests.
https://developer.apple.com/documentation/advancedcommerceapi/requestinfo
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestInfo.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
from uuid import UUID
from attr import define
import attr
@define
class AdvancedCommerceRequestInfo:
"""
The metadata to include in server requests.
https://developer.apple.com/documentation/advancedcommerceapi/requestinfo
"""
requestReferenceId: UUID = attr.ib()
"""
A UUID that you provide to uniquely identify each request. If the request times out, you can use the same requestReferenceId value to retry the request. Otherwise, provide a unique value.
"""
appAccountToken: Optional[UUID] = attr.ib(default=None)
"""
A UUID that represents an app account token, to associate with the transaction in the request.
"""
consistencyToken: Optional[str] = attr.ib(default=None)
"""
The value of the advancedCommerceConsistencyToken that you receive in the JWSRenewalInfo renewal information for a subscription. Don’t generate this value.
https://developer.apple.com/documentation/AppStoreServerAPI/advancedCommerceConsistencyToken
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestRefundItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
from attr import define
import attr
from .AbstractAdvancedCommerceBaseItem import AbstractAdvancedCommerceBaseItem
from .AdvancedCommerceRefundReason import AdvancedCommerceRefundReason
from .AdvancedCommerceRefundType import AdvancedCommerceRefundType
@define
class AdvancedCommerceRequestRefundItem(AbstractAdvancedCommerceBaseItem):
"""
Information about the refund request for an item, such as its SKU, the refund amount, reason, and type.
https://developer.apple.com/documentation/advancedcommerceapi/requestrefunditem
"""
revoke: bool = attr.ib()
refundReason: AdvancedCommerceRefundReason = AdvancedCommerceRefundReason.create_main_attr('rawRefundReason', raw_required=True)
"""
The reason for the refund request.
https://developer.apple.com/documentation/advancedcommerceapi/refundreason
"""
rawRefundReason: str = AdvancedCommerceRefundReason.create_raw_attr('refundReason', required=True)
"""
See refundReason
"""
refundType: AdvancedCommerceRefundType = AdvancedCommerceRefundType.create_main_attr('rawRefundType', raw_required=True)
"""
The type of refund requested.
"""
rawRefundType: str = AdvancedCommerceRefundType.create_raw_attr('refundType', required=True)
"""
See refundType
"""
refundAmount: Optional[int] = attr.ib(default=None)
"""
The refund amount you're requesting for the SKU, in milliunits of the currency.
https://developer.apple.com/documentation/advancedcommerceapi/refundamount
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestRefundRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional, List
from attr import define
import attr
from .AdvancedCommerceRequest import AdvancedCommerceRequest
from .AdvancedCommerceRequestRefundItem import AdvancedCommerceRequestRefundItem
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AdvancedCommerceRequestRefundRequest(AdvancedCommerceRequest):
"""
The request body for requesting a refund for a transaction.
https://developer.apple.com/documentation/advancedcommerceapi/requestrefundrequest
"""
items: List[AdvancedCommerceRequestRefundItem] = attr.ib(validator=AdvancedCommerceValidationUtils.items_validator)
"""
https://developer.apple.com/documentation/advancedcommerceapi/requestrefunditem
"""
refundRiskingPreference: bool = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/refundriskingpreference
"""
currency: Optional[str] = attr.ib(default=None)
"""
The currency of the transaction.
https://developer.apple.com/documentation/advancedcommerceapi/currency
"""
storefront: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/storefront
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestRefundResponse.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from .AbstractAdvancedCommerceResponse import AbstractAdvancedCommerceResponse
class AdvancedCommerceRequestRefundResponse(AbstractAdvancedCommerceResponse):
"""
The response body for a transaction refund request.
https://developer.apple.com/documentation/advancedcommerceapi/requestrefundresponse
"""
def __init__(self, signedTransactionInfo: str):
super().__init__(signedRenewalInfo=None, signedTransactionInfo=signedTransactionInfo)
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCancelRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
from attr import define
import attr
from .AdvancedCommerceRequest import AdvancedCommerceRequest
@define
class AdvancedCommerceSubscriptionCancelRequest(AdvancedCommerceRequest):
"""
The request body for turning off automatic renewal of a subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptioncancelrequest
"""
storefront: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/storefront
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCancelResponse.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
from .AbstractAdvancedCommerceResponse import AbstractAdvancedCommerceResponse
@define
class AdvancedCommerceSubscriptionCancelResponse(AbstractAdvancedCommerceResponse):
"""
The response body for a successful subscription cancellation.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptioncancelresponse
"""
pass
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataDescriptors.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
from attr import define
import attr
from .AdvancedCommerceEffective import AdvancedCommerceEffective
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AdvancedCommerceSubscriptionChangeMetadataDescriptors():
"""
The subscription metadata to change, specifically the description and display name.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionchangemetadatadescriptors
"""
effective: AdvancedCommerceEffective = AdvancedCommerceEffective.create_main_attr('rawEffective', raw_required=True)
"""
The string that determines when the metadata change goes into effect.
https://developer.apple.com/documentation/advancedcommerceapi/effective
"""
rawEffective: str = AdvancedCommerceEffective.create_raw_attr('effective', required=True)
"""
See effective
"""
description: Optional[str] = attr.ib(
default=None,
validator=attr.validators.optional(AdvancedCommerceValidationUtils.description_validator)
)
"""
The new description for the subscription.
https://developer.apple.com/documentation/advancedcommerceapi/description
"""
displayName: Optional[str] = attr.ib(
default=None,
validator=attr.validators.optional(AdvancedCommerceValidationUtils.display_name_validator)
)
"""
The new display name for the subscription.
https://developer.apple.com/documentation/advancedcommerceapi/displayname
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
from attr import define
import attr
from .AdvancedCommerceEffective import AdvancedCommerceEffective
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AdvancedCommerceSubscriptionChangeMetadataItem():
"""
The metadata to change for an item, specifically its SKU, description, and display name.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionchangemetadataitem
"""
currentSKU: str = attr.ib(validator=AdvancedCommerceValidationUtils.sku_validator)
"""
The original SKU of the item.
"""
effective: AdvancedCommerceEffective = AdvancedCommerceEffective.create_main_attr('rawEffective', raw_required=True)
"""
The string that determines when the metadata change goes into effect.
https://developer.apple.com/documentation/advancedcommerceapi/effective
"""
rawEffective: str = AdvancedCommerceEffective.create_raw_attr('effective', required=True)
"""
See effective
"""
description: Optional[str] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.description_validator))
"""
The new description for the item.
https://developer.apple.com/documentation/advancedcommerceapi/description
"""
displayName: Optional[str] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.display_name_validator))
"""
The new display name for the item.
https://developer.apple.com/documentation/advancedcommerceapi/displayname
"""
SKU: Optional[str] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.sku_validator))
"""
The new SKU of the item.
https://developer.apple.com/documentation/advancedcommerceapi/sku
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional, List
from attr import define
import attr
from .AdvancedCommerceRequest import AdvancedCommerceRequest
from .AdvancedCommerceSubscriptionChangeMetadataDescriptors import AdvancedCommerceSubscriptionChangeMetadataDescriptors
from .AdvancedCommerceSubscriptionChangeMetadataItem import AdvancedCommerceSubscriptionChangeMetadataItem
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AdvancedCommerceSubscriptionChangeMetadataRequest(AdvancedCommerceRequest):
"""
The request body you provide to change the metadata of a subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionchangemetadatarequest
"""
descriptors: Optional[AdvancedCommerceSubscriptionChangeMetadataDescriptors] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionchangemetadatadescriptors
"""
items: Optional[List[AdvancedCommerceSubscriptionChangeMetadataItem]] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.items_validator))
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionchangemetadataitem
"""
storefront: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/storefront
"""
taxCode: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/taxcode
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataResponse.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from .AbstractAdvancedCommerceResponse import AbstractAdvancedCommerceResponse
class AdvancedCommerceSubscriptionChangeMetadataResponse(AbstractAdvancedCommerceResponse):
"""
The response body for a successful subscription metadata change.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionchangemetadataresponse
"""
def __init__(self, signedRenewalInfo: str, signedTransactionInfo: str):
super().__init__(signedRenewalInfo=signedRenewalInfo, signedTransactionInfo=signedTransactionInfo)
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCreateItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
import attr
from attr import define
from .AbstractAdvancedCommerceItem import AbstractAdvancedCommerceItem
from .AdvancedCommerceOffer import AdvancedCommerceOffer
@define
class AdvancedCommerceSubscriptionCreateItem(AbstractAdvancedCommerceItem):
"""
The data that describes a subscription item.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptioncreateitem
"""
price: int = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/price
"""
offer: Optional[AdvancedCommerceOffer] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/offer
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCreateRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional, List
import attr
from attr import define
from .AbstractAdvancedCommerceInAppRequest import AbstractAdvancedCommerceInAppRequest
from .AdvancedCommerceDescriptors import AdvancedCommerceDescriptors
from .AdvancedCommerceSubscriptionCreateItem import AdvancedCommerceSubscriptionCreateItem
from .AdvancedCommercePeriod import AdvancedCommercePeriod
@define
class AdvancedCommerceSubscriptionCreateRequest(AbstractAdvancedCommerceInAppRequest):
"""
The request data your app provides when a customer purchases an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptioncreaterequest
"""
operation: str = attr.ib(init=False, default="CREATE_SUBSCRIPTION", on_setattr=attr.setters.frozen)
version: str = attr.ib(init=False, default="1", on_setattr=attr.setters.frozen)
currency: str = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/currency
"""
descriptors: AdvancedCommerceDescriptors = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/descriptors
"""
items: List[AdvancedCommerceSubscriptionCreateItem] = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptioncreateitem
"""
taxCode: str = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/taxCode
"""
period: AdvancedCommercePeriod = AdvancedCommercePeriod.create_main_attr('rawPeriod', raw_required=True)
"""
https://developer.apple.com/documentation/advancedcommerceapi/period
"""
rawPeriod: str = AdvancedCommercePeriod.create_raw_attr('period', required=True)
"""
See period
"""
previousTransactionId: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/transactionid
"""
storefront: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/storefront
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateDescriptors.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
from .AdvancedCommerceDescriptors import AdvancedCommerceDescriptors
@define
class AdvancedCommerceSubscriptionMigrateDescriptors(AdvancedCommerceDescriptors):
"""
The description and display name of the subscription to migrate to that you manage.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigratedescriptors
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
from .AbstractAdvancedCommerceItem import AbstractAdvancedCommerceItem
@define
class AdvancedCommerceSubscriptionMigrateItem(AbstractAdvancedCommerceItem):
"""
The SKU, description, and display name to use for a migrated subscription item.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigrateitem
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateRenewalItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
from .AbstractAdvancedCommerceItem import AbstractAdvancedCommerceItem
@define
class AdvancedCommerceSubscriptionMigrateRenewalItem(AbstractAdvancedCommerceItem):
"""
The item information that replaces a migrated subscription item when the subscription renews.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigraterenewalitem
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional, List
import attr
from attr import define
from .AdvancedCommerceRequest import AdvancedCommerceRequest
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
from .AdvancedCommerceSubscriptionMigrateDescriptors import AdvancedCommerceSubscriptionMigrateDescriptors
from .AdvancedCommerceSubscriptionMigrateItem import AdvancedCommerceSubscriptionMigrateItem
from .AdvancedCommerceSubscriptionMigrateRenewalItem import AdvancedCommerceSubscriptionMigrateRenewalItem
@define
class AdvancedCommerceSubscriptionMigrateRequest(AdvancedCommerceRequest):
"""
The subscription details you provide to migrate a subscription from In-App Purchase to the Advanced Commerce API, such as descriptors, items, storefront, and more.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigraterequest
"""
descriptors: AdvancedCommerceSubscriptionMigrateDescriptors = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigratedescriptors
"""
items: List[AdvancedCommerceSubscriptionMigrateItem] = attr.ib(validator=AdvancedCommerceValidationUtils.items_validator)
"""
An array of one or more SKUs, along with descriptions and display names, that are included in the subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigrateitem
"""
targetProductId: str = attr.ib()
"""
Your generic product ID for an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/targetproductid
"""
taxCode: str = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/taxcode
"""
renewalItems: Optional[List[AdvancedCommerceSubscriptionMigrateRenewalItem]] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.items_validator))
"""
An optional array of subscription items that represents the items that renew at the next renewal period, if they differ from items.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigraterenewalitem
"""
storefront: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/storefront
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateResponse.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from attr import define
from .AbstractAdvancedCommerceResponse import AbstractAdvancedCommerceResponse
@define
class AdvancedCommerceSubscriptionMigrateResponse(AbstractAdvancedCommerceResponse):
"""
A response that contains signed renewal and transaction information after a subscription successfully migrates to the Advanced Commerce API.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmigrateresponse
"""
def __init__(self, signedRenewalInfo: str, signedTransactionInfo: str):
super().__init__(signedRenewalInfo=signedRenewalInfo, signedTransactionInfo=signedTransactionInfo)
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyAddItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
import attr
from attr import define
from .AbstractAdvancedCommerceItem import AbstractAdvancedCommerceItem
from .AdvancedCommerceOffer import AdvancedCommerceOffer
@define
class AdvancedCommerceSubscriptionModifyAddItem(AbstractAdvancedCommerceItem):
"""
The data your app provides to add items when it makes changes to an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifyadditem
"""
price: int = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/price
"""
offer: Optional[AdvancedCommerceOffer] = attr.ib(default=None)
"""
A discount offer for an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/offer
"""
proratedPrice: Optional[int] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/proratedprice
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyChangeItem.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
import attr
from attr import define
from .AbstractAdvancedCommerceItem import AbstractAdvancedCommerceItem
from .AdvancedCommerceEffective import AdvancedCommerceEffective
from .AdvancedCommerceOffer import AdvancedCommerceOffer
from .AdvancedCommerceReason import AdvancedCommerceReason
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AdvancedCommerceSubscriptionModifyChangeItem(AbstractAdvancedCommerceItem):
"""
The data your app provides to change an item of an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifychangeitem
"""
currentSKU: str = attr.ib(validator=AdvancedCommerceValidationUtils.sku_validator)
"""
https://developer.apple.com/documentation/advancedcommerceapi/sku
"""
price: int = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/price
"""
reason: AdvancedCommerceReason = AdvancedCommerceReason.create_main_attr('rawReason', raw_required=True)
rawReason: str = AdvancedCommerceReason.create_raw_attr('reason', required=True)
"""
See reason
"""
effective: AdvancedCommerceEffective = AdvancedCommerceEffective.create_main_attr('rawEffective', raw_required=True)
"""
https://developer.apple.com/documentation/advancedcommerceapi/effective
"""
rawEffective: str = AdvancedCommerceEffective.create_raw_attr('effective', required=True)
"""
See effective
"""
offer: Optional[AdvancedCommerceOffer] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/offer
"""
proratedPrice: Optional[int] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/proratedprice
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyDescriptors.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional
import attr
from attr import define
from .AdvancedCommerceEffective import AdvancedCommerceEffective
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
@define
class AdvancedCommerceSubscriptionModifyDescriptors():
"""
The data your app provides to change the description and display name of an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifydescriptors
"""
effective: AdvancedCommerceEffective = AdvancedCommerceEffective.create_main_attr('rawEffective', raw_required=True)
"""
https://developer.apple.com/documentation/advancedcommerceapi/effective
"""
rawEffective: str = AdvancedCommerceEffective.create_raw_attr('effective', required=True)
"""
See effective
"""
description: Optional[str] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.description_validator))
"""
https://developer.apple.com/documentation/advancedcommerceapi/description
"""
displayName: Optional[str] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.display_name_validator)
)
"""
https://developer.apple.com/documentation/advancedcommerceapi/displayname
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyInAppRequest.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
from typing import Optional, List
import attr
from attr import define
from .AbstractAdvancedCommerceInAppRequest import AbstractAdvancedCommerceInAppRequest
from .AdvancedCommerceValidationUtils import AdvancedCommerceValidationUtils
from .AdvancedCommerceSubscriptionModifyAddItem import AdvancedCommerceSubscriptionModifyAddItem
from .AdvancedCommerceSubscriptionModifyChangeItem import AdvancedCommerceSubscriptionModifyChangeItem
from .AdvancedCommerceSubscriptionModifyDescriptors import AdvancedCommerceSubscriptionModifyDescriptors
from .AdvancedCommerceSubscriptionModifyPeriodChange import AdvancedCommerceSubscriptionModifyPeriodChange
from .AdvancedCommerceSubscriptionModifyRemoveItem import AdvancedCommerceSubscriptionModifyRemoveItem
@define
class AdvancedCommerceSubscriptionModifyInAppRequest(AbstractAdvancedCommerceInAppRequest):
"""
The request data your app provides to make changes to an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifyinapprequest
"""
operation: str = attr.ib(default="MODIFY_SUBSCRIPTION", init=False, on_setattr=attr.setters.frozen)
version: str = attr.ib(default="1", init=False, on_setattr=attr.setters.frozen)
transactionId: str = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/transactionid
"""
retainBillingCycle: bool = attr.ib()
"""
https://developer.apple.com/documentation/advancedcommerceapi/retainbillingcycle
"""
addItems: Optional[List[AdvancedCommerceSubscriptionModifyAddItem]] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.items_validator))
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifyadditem
"""
changeItems: Optional[List[AdvancedCommerceSubscriptionModifyChangeItem]] = attr.ib(default=None, validator=attr.validators.optional(AdvancedCommerceValidationUtils.items_validator))
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifychangeitem
"""
currency: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/currency
"""
descriptors: Optional[AdvancedCommerceSubscriptionModifyDescriptors] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifydescriptors
"""
periodChange: Optional[AdvancedCommerceSubscriptionModifyPeriodChange] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifyperiodchange
"""
removeItems: Optional[List[AdvancedCommerceSubscriptionModifyRemoveItem]] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifyremoveitem
"""
storefront: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/storefront
"""
taxCode: Optional[str] = attr.ib(default=None)
"""
https://developer.apple.com/documentation/advancedcommerceapi/taxcode
"""
================================================
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyPeriodChange.py
================================================
# Copyright (c) 2026 Apple Inc. Licensed under MIT License.
import attr
from attr import define
from .AdvancedCommerceEffective import AdvancedCommerceEffective
from .AdvancedCommercePeriod import AdvancedCommercePeriod
from .LibraryUtility import AttrsRawValueAware
@define
class AdvancedCommerceSubscriptionModifyPeriodChange(AttrsRawValueAware):
"""
The data your app provides to change the period of an auto-renewable subscription.
https://developer.apple.com/documentation/advancedcommerceapi/subscriptionmodifyperiodchange
"""
effective: AdvancedCommerceEffective = AdvancedCommerceEffective.create_main_attr('rawEffective', raw_required=True)
"""
https://developer.apple.com/documentation/advancedcommerceapi/effective
"""
rawEffective: str = AdvancedCommerceEffective.create_raw_attr('effective', required=True)
"""
See effective
"""
period: AdvancedCommercePeriod = AdvancedCommercePeriod.create_main_attr('rawPeriod', raw_required=True)
"""
https://developer.apple.com/documentation/advancedcommerceapi/period
"""
rawPeriod: str = AdvancedCommercePeriod.create_raw_a
gitextract_u4cbit1j/
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── ci-prb.yml
│ ├── ci-release-docs.yml
│ ├── ci-release.yml
│ └── ci-snapshot.yml
├── .gitignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── MANIFEST.in
├── NOTICE.txt
├── README.md
├── appstoreserverlibrary/
│ ├── __init__.py
│ ├── api_client.py
│ ├── jws_signature_creator.py
│ ├── models/
│ │ ├── AbstractAdvancedCommerceBaseItem.py
│ │ ├── AbstractAdvancedCommerceInAppRequest.py
│ │ ├── AbstractAdvancedCommerceItem.py
│ │ ├── AbstractAdvancedCommerceResponse.py
│ │ ├── AccountTenure.py
│ │ ├── AdvancedCommerceDescriptors.py
│ │ ├── AdvancedCommerceEffective.py
│ │ ├── AdvancedCommerceOffer.py
│ │ ├── AdvancedCommerceOfferPeriod.py
│ │ ├── AdvancedCommerceOfferReason.py
│ │ ├── AdvancedCommerceOneTimeChargeCreateRequest.py
│ │ ├── AdvancedCommerceOneTimeChargeItem.py
│ │ ├── AdvancedCommercePeriod.py
│ │ ├── AdvancedCommerceReason.py
│ │ ├── AdvancedCommerceRefundReason.py
│ │ ├── AdvancedCommerceRefundType.py
│ │ ├── AdvancedCommerceRequest.py
│ │ ├── AdvancedCommerceRequestInfo.py
│ │ ├── AdvancedCommerceRequestRefundItem.py
│ │ ├── AdvancedCommerceRequestRefundRequest.py
│ │ ├── AdvancedCommerceRequestRefundResponse.py
│ │ ├── AdvancedCommerceSubscriptionCancelRequest.py
│ │ ├── AdvancedCommerceSubscriptionCancelResponse.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataDescriptors.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataItem.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataRequest.py
│ │ ├── AdvancedCommerceSubscriptionChangeMetadataResponse.py
│ │ ├── AdvancedCommerceSubscriptionCreateItem.py
│ │ ├── AdvancedCommerceSubscriptionCreateRequest.py
│ │ ├── AdvancedCommerceSubscriptionMigrateDescriptors.py
│ │ ├── AdvancedCommerceSubscriptionMigrateItem.py
│ │ ├── AdvancedCommerceSubscriptionMigrateRenewalItem.py
│ │ ├── AdvancedCommerceSubscriptionMigrateRequest.py
│ │ ├── AdvancedCommerceSubscriptionMigrateResponse.py
│ │ ├── AdvancedCommerceSubscriptionModifyAddItem.py
│ │ ├── AdvancedCommerceSubscriptionModifyChangeItem.py
│ │ ├── AdvancedCommerceSubscriptionModifyDescriptors.py
│ │ ├── AdvancedCommerceSubscriptionModifyInAppRequest.py
│ │ ├── AdvancedCommerceSubscriptionModifyPeriodChange.py
│ │ ├── AdvancedCommerceSubscriptionModifyRemoveItem.py
│ │ ├── AdvancedCommerceSubscriptionPriceChangeItem.py
│ │ ├── AdvancedCommerceSubscriptionPriceChangeRequest.py
│ │ ├── AdvancedCommerceSubscriptionPriceChangeResponse.py
│ │ ├── AdvancedCommerceSubscriptionReactivateInAppRequest.py
│ │ ├── AdvancedCommerceSubscriptionReactivateItem.py
│ │ ├── AdvancedCommerceSubscriptionRevokeRequest.py
│ │ ├── AdvancedCommerceSubscriptionRevokeResponse.py
│ │ ├── AdvancedCommerceValidationUtils.py
│ │ ├── AlternateProduct.py
│ │ ├── AppData.py
│ │ ├── AppTransaction.py
│ │ ├── AppTransactionInfoResponse.py
│ │ ├── AutoRenewStatus.py
│ │ ├── BulletPoint.py
│ │ ├── CheckTestNotificationResponse.py
│ │ ├── ConsumptionRequest.py
│ │ ├── ConsumptionRequestReason.py
│ │ ├── ConsumptionRequestV1.py
│ │ ├── ConsumptionStatus.py
│ │ ├── Data.py
│ │ ├── DecodedRealtimeRequestBody.py
│ │ ├── DefaultConfigurationRequest.py
│ │ ├── DefaultConfigurationResponse.py
│ │ ├── DeliveryStatus.py
│ │ ├── DeliveryStatusV1.py
│ │ ├── Environment.py
│ │ ├── ExpirationIntent.py
│ │ ├── ExtendReasonCode.py
│ │ ├── ExtendRenewalDateRequest.py
│ │ ├── ExtendRenewalDateResponse.py
│ │ ├── ExternalPurchaseToken.py
│ │ ├── FirstSendAttemptResult.py
│ │ ├── GetImageListResponse.py
│ │ ├── GetImageListResponseItem.py
│ │ ├── GetMessageListResponse.py
│ │ ├── GetMessageListResponseItem.py
│ │ ├── HeaderPosition.py
│ │ ├── HistoryResponse.py
│ │ ├── ImageSize.py
│ │ ├── ImageState.py
│ │ ├── InAppOwnershipType.py
│ │ ├── JWSRenewalInfoDecodedPayload.py
│ │ ├── JWSTransactionDecodedPayload.py
│ │ ├── LastTransactionsItem.py
│ │ ├── LibraryUtility.py
│ │ ├── LifetimeDollarsPurchased.py
│ │ ├── LifetimeDollarsRefunded.py
│ │ ├── MassExtendRenewalDateRequest.py
│ │ ├── MassExtendRenewalDateResponse.py
│ │ ├── MassExtendRenewalDateStatusResponse.py
│ │ ├── Message.py
│ │ ├── MessageState.py
│ │ ├── NotificationHistoryRequest.py
│ │ ├── NotificationHistoryResponse.py
│ │ ├── NotificationHistoryResponseItem.py
│ │ ├── NotificationTypeV2.py
│ │ ├── OfferDiscountType.py
│ │ ├── OfferType.py
│ │ ├── OrderLookupResponse.py
│ │ ├── OrderLookupStatus.py
│ │ ├── PerformanceTestConfig.py
│ │ ├── PerformanceTestRequest.py
│ │ ├── PerformanceTestResponse.py
│ │ ├── PerformanceTestResponseTimes.py
│ │ ├── PerformanceTestResultResponse.py
│ │ ├── PerformanceTestStatus.py
│ │ ├── Platform.py
│ │ ├── PlayTime.py
│ │ ├── PriceIncreaseStatus.py
│ │ ├── PromotionalOffer.py
│ │ ├── PromotionalOfferSignatureV1.py
│ │ ├── PurchasePlatform.py
│ │ ├── RealtimeRequestBody.py
│ │ ├── RealtimeResponseBody.py
│ │ ├── RealtimeUrlRequest.py
│ │ ├── RealtimeUrlResponse.py
│ │ ├── RefundHistoryResponse.py
│ │ ├── RefundPreference.py
│ │ ├── RefundPreferenceV1.py
│ │ ├── ResponseBodyV2.py
│ │ ├── ResponseBodyV2DecodedPayload.py
│ │ ├── RevocationReason.py
│ │ ├── RevocationType.py
│ │ ├── SendAttemptItem.py
│ │ ├── SendAttemptResult.py
│ │ ├── SendTestNotificationResponse.py
│ │ ├── Status.py
│ │ ├── StatusResponse.py
│ │ ├── SubscriptionGroupIdentifierItem.py
│ │ ├── Subtype.py
│ │ ├── Summary.py
│ │ ├── TransactionHistoryRequest.py
│ │ ├── TransactionInfoResponse.py
│ │ ├── TransactionReason.py
│ │ ├── Type.py
│ │ ├── UpdateAppAccountTokenRequest.py
│ │ ├── UploadMessageImage.py
│ │ ├── UploadMessageRequestBody.py
│ │ ├── UserStatus.py
│ │ └── __init__.py
│ ├── promotional_offer.py
│ ├── py.typed
│ ├── receipt_utility.py
│ └── signed_data_verifier.py
├── docs/
│ └── requirements.txt
├── pyproject.toml
├── requirements.txt
└── tests/
├── __init__.py
├── resources/
│ ├── certs/
│ │ ├── testCA.der
│ │ └── testSigningKey.p8
│ ├── mock_signed_data/
│ │ ├── legacyTransaction
│ │ ├── missingX5CHeaderClaim
│ │ ├── renewalInfo
│ │ ├── testNotification
│ │ ├── transactionInfo
│ │ └── wrongBundleId
│ ├── models/
│ │ ├── advancedCommerceDescriptors.json
│ │ ├── advancedCommerceOffer.json
│ │ ├── advancedCommerceOneTimeChargeCreateRequest.json
│ │ ├── advancedCommerceOneTimeChargeItem.json
│ │ ├── advancedCommerceRequestInfo.json
│ │ ├── advancedCommerceRequestRefundItem.json
│ │ ├── advancedCommerceRequestRefundRequest.json
│ │ ├── advancedCommerceRequestRefundResponse.json
│ │ ├── advancedCommerceSubscriptionCancelRequest.json
│ │ ├── advancedCommerceSubscriptionCancelResponse.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataDescriptors.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataItem.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataRequest.json
│ │ ├── advancedCommerceSubscriptionChangeMetadataResponse.json
│ │ ├── advancedCommerceSubscriptionCreateItem.json
│ │ ├── advancedCommerceSubscriptionCreateRequest.json
│ │ ├── advancedCommerceSubscriptionMigrateDescriptors.json
│ │ ├── advancedCommerceSubscriptionMigrateItem.json
│ │ ├── advancedCommerceSubscriptionMigrateRenewalItem.json
│ │ ├── advancedCommerceSubscriptionMigrateRequest.json
│ │ ├── advancedCommerceSubscriptionMigrateResponse.json
│ │ ├── advancedCommerceSubscriptionModifyAddItem.json
│ │ ├── advancedCommerceSubscriptionModifyChangeItem.json
│ │ ├── advancedCommerceSubscriptionModifyDescriptors.json
│ │ ├── advancedCommerceSubscriptionModifyInAppRequest.json
│ │ ├── advancedCommerceSubscriptionModifyPeriodChange.json
│ │ ├── advancedCommerceSubscriptionModifyRemoveItem.json
│ │ ├── advancedCommerceSubscriptionPriceChangeItem.json
│ │ ├── advancedCommerceSubscriptionPriceChangeRequest.json
│ │ ├── advancedCommerceSubscriptionPriceChangeResponse.json
│ │ ├── advancedCommerceSubscriptionReactivateInAppRequest.json
│ │ ├── advancedCommerceSubscriptionReactivateItem.json
│ │ ├── advancedCommerceSubscriptionRevokeRequest.json
│ │ ├── advancedCommerceSubscriptionRevokeResponse.json
│ │ ├── apiException.json
│ │ ├── apiTooManyRequestsException.json
│ │ ├── apiUnknownError.json
│ │ ├── appData.json
│ │ ├── appTransaction.json
│ │ ├── appTransactionDoesNotExistError.json
│ │ ├── appTransactionInfoResponse.json
│ │ ├── decodedRealtimeRequest.json
│ │ ├── extendRenewalDateForAllActiveSubscribersResponse.json
│ │ ├── extendSubscriptionRenewalDateResponse.json
│ │ ├── familyTransactionNotSupportedError.json
│ │ ├── getAllSubscriptionStatusesResponse.json
│ │ ├── getDefaultMessageResponse.json
│ │ ├── getImageListResponse.json
│ │ ├── getMessageListResponse.json
│ │ ├── getNotificationHistoryResponse.json
│ │ ├── getRealtimeUrlResponse.json
│ │ ├── getRefundHistoryResponse.json
│ │ ├── getStatusOfSubscriptionRenewalDateExtensionsResponse.json
│ │ ├── getTestNotificationStatusResponse.json
│ │ ├── invalidAppAccountTokenUUIDError.json
│ │ ├── invalidTransactionIdError.json
│ │ ├── lookupOrderIdResponse.json
│ │ ├── performanceTestResponse.json
│ │ ├── performanceTestResultResponse.json
│ │ ├── requestTestNotificationResponse.json
│ │ ├── signedConsumptionRequestNotification.json
│ │ ├── signedExternalPurchaseTokenNotification.json
│ │ ├── signedExternalPurchaseTokenSandboxNotification.json
│ │ ├── signedNotification.json
│ │ ├── signedRenewalInfo.json
│ │ ├── signedRescindConsentNotification.json
│ │ ├── signedSummaryNotification.json
│ │ ├── signedTransaction.json
│ │ ├── signedTransactionWithRevocation.json
│ │ ├── transactionHistoryResponse.json
│ │ ├── transactionHistoryResponseWithMalformedAppAppleId.json
│ │ ├── transactionHistoryResponseWithMalformedEnvironment.json
│ │ ├── transactionIdNotFoundError.json
│ │ ├── transactionIdNotOriginalTransactionId.json
│ │ └── transactionInfoResponse.json
│ └── xcode/
│ ├── xcode-app-receipt-empty
│ ├── xcode-app-receipt-with-transaction
│ ├── xcode-signed-app-transaction
│ ├── xcode-signed-renewal-info
│ └── xcode-signed-transaction
├── test_advanced_commerce_models.py
├── test_api_client.py
├── test_api_client_async.py
├── test_app_data.py
├── test_decoded_payloads.py
├── test_jws_signature_creator.py
├── test_payload_verification.py
├── test_promotional_offer_signature_creator.py
├── test_receipt_utility.py
├── test_retention_messaging.py
├── test_x509_verifiction.py
├── test_xcode_signed_data.py
└── util.py
SYMBOL INDEX (498 symbols across 157 files)
FILE: appstoreserverlibrary/api_client.py
class APIError (line 52) | class APIError(IntEnum):
class APIException (line 669) | class APIException(Exception):
method __init__ (line 675) | def __init__(self, http_status_code: int, raw_api_error: Optional[int]...
class GetTransactionHistoryVersion (line 686) | class GetTransactionHistoryVersion(str, Enum):
class BaseAppStoreServerAPIClient (line 694) | class BaseAppStoreServerAPIClient:
method __init__ (line 695) | def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bu...
method _generate_token (line 711) | def _generate_token(self) -> str:
method _get_full_url (line 725) | def _get_full_url(self, path) -> str:
method _get_headers (line 728) | def _get_headers(self) -> Dict[str, str]:
method _get_request_json (line 735) | def _get_request_json(self, body) -> Dict[str, Any]:
method _parse_response (line 739) | def _parse_response(self, status_code: int, headers: MutableMapping, j...
class AppStoreServerAPIClient (line 759) | class AppStoreServerAPIClient(BaseAppStoreServerAPIClient):
method __init__ (line 760) | def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bu...
method _make_request (line 763) | def _make_request(self, path: str, method: str, queryParameters: Dict[...
method _execute_request (line 777) | def _execute_request(self, method: str, url: str, params: Dict[str, Un...
method extend_renewal_date_for_all_active_subscribers (line 780) | def extend_renewal_date_for_all_active_subscribers(self, mass_extend_r...
method extend_subscription_renewal_date (line 791) | def extend_subscription_renewal_date(self, original_transaction_id: st...
method get_all_subscription_statuses (line 803) | def get_all_subscription_statuses(self, transaction_id: str, status: O...
method get_refund_history (line 819) | def get_refund_history(self, transaction_id: str, revision: Optional[s...
method get_status_of_subscription_renewal_date_extensions (line 836) | def get_status_of_subscription_renewal_date_extensions(self, request_i...
method get_test_notification_status (line 848) | def get_test_notification_status(self, test_notification_token: str) -...
method get_notification_history (line 859) | def get_notification_history(self, pagination_token: Optional[str], no...
method get_transaction_history (line 875) | def get_transaction_history(self, transaction_id: str, revision: Optio...
method get_transaction_info (line 917) | def get_transaction_info(self, transaction_id: str) -> TransactionInfo...
method look_up_order_id (line 928) | def look_up_order_id(self, order_id: str) -> OrderLookupResponse:
method request_test_notification (line 939) | def request_test_notification(self) -> SendTestNotificationResponse:
method send_consumption_data (line 949) | def send_consumption_data(self, transaction_id: str, consumption_reque...
method send_consumption_information (line 964) | def send_consumption_information(self, transaction_id: str, consumptio...
method set_app_account_token (line 975) | def set_app_account_token(self, original_transaction_id: str, update_a...
method upload_image (line 986) | def upload_image(self, image_identifier: UUID, image: bytes, image_siz...
method delete_image (line 1001) | def delete_image(self, image_identifier: UUID):
method get_image_list (line 1011) | def get_image_list(self) -> GetImageListResponse:
method upload_message (line 1021) | def upload_message(self, message_identifier: UUID, upload_message_requ...
method delete_message (line 1032) | def delete_message(self, message_identifier: UUID):
method get_message_list (line 1042) | def get_message_list(self) -> GetMessageListResponse:
method configure_default_message (line 1052) | def configure_default_message(self, product_id: str, locale: str, defa...
method delete_default_message (line 1064) | def delete_default_message(self, product_id: str, locale: str):
method get_default_message (line 1075) | def get_default_message(self, product_id: str, locale: str) -> Default...
method configure_realtime_url (line 1087) | def configure_realtime_url(self, realtime_url_request: RealtimeUrlRequ...
method delete_realtime_url (line 1097) | def delete_realtime_url(self):
method get_realtime_url (line 1106) | def get_realtime_url(self) -> RealtimeUrlResponse:
method initiate_performance_test (line 1116) | def initiate_performance_test(self, performance_test_request: Performa...
method get_performance_test_results (line 1127) | def get_performance_test_results(self, request_id: str) -> Performance...
method get_app_transaction_info (line 1138) | def get_app_transaction_info(self, transaction_id: str) -> AppTransact...
class AsyncAppStoreServerAPIClient (line 1149) | class AsyncAppStoreServerAPIClient(BaseAppStoreServerAPIClient):
method __init__ (line 1150) | def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bu...
method async_close (line 1158) | async def async_close(self):
method _make_request (line 1161) | async def _make_request(self, path: str, method: str, queryParameters:...
method _execute_request (line 1177) | async def _execute_request(self, method: str, url: str, params: Dict[s...
method extend_renewal_date_for_all_active_subscribers (line 1180) | async def extend_renewal_date_for_all_active_subscribers(self, mass_ex...
method extend_subscription_renewal_date (line 1191) | async def extend_subscription_renewal_date(self, original_transaction_...
method get_all_subscription_statuses (line 1203) | async def get_all_subscription_statuses(self, transaction_id: str, sta...
method get_refund_history (line 1219) | async def get_refund_history(self, transaction_id: str, revision: Opti...
method get_status_of_subscription_renewal_date_extensions (line 1236) | async def get_status_of_subscription_renewal_date_extensions(self, req...
method get_test_notification_status (line 1248) | async def get_test_notification_status(self, test_notification_token: ...
method get_notification_history (line 1259) | async def get_notification_history(self, pagination_token: Optional[st...
method get_transaction_history (line 1275) | async def get_transaction_history(self, transaction_id: str, revision:...
method get_transaction_info (line 1317) | async def get_transaction_info(self, transaction_id: str) -> Transacti...
method look_up_order_id (line 1328) | async def look_up_order_id(self, order_id: str) -> OrderLookupResponse:
method request_test_notification (line 1338) | async def request_test_notification(self) -> SendTestNotificationRespo...
method send_consumption_data (line 1348) | async def send_consumption_data(self, transaction_id: str, consumption...
method send_consumption_information (line 1363) | async def send_consumption_information(self, transaction_id: str, cons...
method set_app_account_token (line 1374) | async def set_app_account_token(self, original_transaction_id: str, up...
method upload_image (line 1385) | async def upload_image(self, image_identifier: UUID, image: bytes, ima...
method delete_image (line 1400) | async def delete_image(self, image_identifier: UUID):
method get_image_list (line 1410) | async def get_image_list(self) -> GetImageListResponse:
method upload_message (line 1420) | async def upload_message(self, message_identifier: UUID, upload_messag...
method delete_message (line 1431) | async def delete_message(self, message_identifier: UUID):
method get_message_list (line 1441) | async def get_message_list(self) -> GetMessageListResponse:
method configure_default_message (line 1451) | async def configure_default_message(self, product_id: str, locale: str...
method delete_default_message (line 1463) | async def delete_default_message(self, product_id: str, locale: str):
method get_default_message (line 1474) | async def get_default_message(self, product_id: str, locale: str) -> D...
method configure_realtime_url (line 1486) | async def configure_realtime_url(self, realtime_url_request: RealtimeU...
method delete_realtime_url (line 1496) | async def delete_realtime_url(self):
method get_realtime_url (line 1505) | async def get_realtime_url(self) -> RealtimeUrlResponse:
method initiate_performance_test (line 1515) | async def initiate_performance_test(self, performance_test_request: Pe...
method get_performance_test_results (line 1526) | async def get_performance_test_results(self, request_id: str) -> Perfo...
method get_app_transaction_info (line 1537) | async def get_app_transaction_info(self, transaction_id: str) -> AppTr...
FILE: appstoreserverlibrary/jws_signature_creator.py
class AdvancedCommerceAPIInAppRequest (line 15) | class AdvancedCommerceAPIInAppRequest:
method __init__ (line 16) | def __init__(self):
class JWSSignatureCreator (line 19) | class JWSSignatureCreator:
method __init__ (line 20) | def __init__(self, audience: str, signing_key: bytes, key_id: str, iss...
method _create_signature (line 27) | def _create_signature(self, feature_specific_claims: Dict[str, Any]) -...
class PromotionalOfferV2SignatureCreator (line 43) | class PromotionalOfferV2SignatureCreator(JWSSignatureCreator):
method __init__ (line 44) | def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bu...
method create_signature (line 55) | def create_signature(self, product_id: str, offer_identifier: str, tra...
class IntroductoryOfferEligibilitySignatureCreator (line 77) | class IntroductoryOfferEligibilitySignatureCreator(JWSSignatureCreator):
method __init__ (line 78) | def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bu...
method create_signature (line 89) | def create_signature(self, product_id: str, allow_introductory_offer: ...
class AdvancedCommerceAPIInAppSignatureCreator (line 112) | class AdvancedCommerceAPIInAppSignatureCreator(JWSSignatureCreator):
method __init__ (line 113) | def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bu...
method create_signature (line 124) | def create_signature(self, advanced_commerce_in_app_request: AdvancedC...
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceBaseItem.py
class AbstractAdvancedCommerceBaseItem (line 12) | class AbstractAdvancedCommerceBaseItem(AttrsRawValueAware, ABC):
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceInAppRequest.py
class AbstractAdvancedCommerceInAppRequest (line 12) | class AbstractAdvancedCommerceInAppRequest(AdvancedCommerceRequest, Adva...
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceItem.py
class AbstractAdvancedCommerceItem (line 10) | class AbstractAdvancedCommerceItem(AbstractAdvancedCommerceBaseItem):
FILE: appstoreserverlibrary/models/AbstractAdvancedCommerceResponse.py
class AbstractAdvancedCommerceResponse (line 10) | class AbstractAdvancedCommerceResponse(ABC):
FILE: appstoreserverlibrary/models/AccountTenure.py
class AccountTenure (line 7) | class AccountTenure(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/AdvancedCommerceDescriptors.py
class AdvancedCommerceDescriptors (line 9) | class AdvancedCommerceDescriptors:
FILE: appstoreserverlibrary/models/AdvancedCommerceEffective.py
class AdvancedCommerceEffective (line 7) | class AdvancedCommerceEffective(str, Enum, metaclass=AppStoreServerLibra...
FILE: appstoreserverlibrary/models/AdvancedCommerceOffer.py
class AdvancedCommerceOffer (line 13) | class AdvancedCommerceOffer(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/AdvancedCommerceOfferPeriod.py
class AdvancedCommerceOfferPeriod (line 7) | class AdvancedCommerceOfferPeriod(str, Enum, metaclass=AppStoreServerLib...
FILE: appstoreserverlibrary/models/AdvancedCommerceOfferReason.py
class AdvancedCommerceOfferReason (line 7) | class AdvancedCommerceOfferReason(str, Enum, metaclass=AppStoreServerLib...
FILE: appstoreserverlibrary/models/AdvancedCommerceOneTimeChargeCreateRequest.py
class AdvancedCommerceOneTimeChargeCreateRequest (line 12) | class AdvancedCommerceOneTimeChargeCreateRequest(AbstractAdvancedCommerc...
FILE: appstoreserverlibrary/models/AdvancedCommerceOneTimeChargeItem.py
class AdvancedCommerceOneTimeChargeItem (line 9) | class AdvancedCommerceOneTimeChargeItem(AbstractAdvancedCommerceItem):
FILE: appstoreserverlibrary/models/AdvancedCommercePeriod.py
class AdvancedCommercePeriod (line 7) | class AdvancedCommercePeriod(str, Enum, metaclass=AppStoreServerLibraryE...
FILE: appstoreserverlibrary/models/AdvancedCommerceReason.py
class AdvancedCommerceReason (line 7) | class AdvancedCommerceReason(str, Enum, metaclass=AppStoreServerLibraryE...
FILE: appstoreserverlibrary/models/AdvancedCommerceRefundReason.py
class AdvancedCommerceRefundReason (line 7) | class AdvancedCommerceRefundReason(str, Enum, metaclass=AppStoreServerLi...
FILE: appstoreserverlibrary/models/AdvancedCommerceRefundType.py
class AdvancedCommerceRefundType (line 7) | class AdvancedCommerceRefundType(str, Enum, metaclass=AppStoreServerLibr...
FILE: appstoreserverlibrary/models/AdvancedCommerceRequest.py
class AdvancedCommerceRequest (line 12) | class AdvancedCommerceRequest(AttrsRawValueAware, ABC):
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestInfo.py
class AdvancedCommerceRequestInfo (line 10) | class AdvancedCommerceRequestInfo:
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestRefundItem.py
class AdvancedCommerceRequestRefundItem (line 13) | class AdvancedCommerceRequestRefundItem(AbstractAdvancedCommerceBaseItem):
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestRefundRequest.py
class AdvancedCommerceRequestRefundRequest (line 13) | class AdvancedCommerceRequestRefundRequest(AdvancedCommerceRequest):
FILE: appstoreserverlibrary/models/AdvancedCommerceRequestRefundResponse.py
class AdvancedCommerceRequestRefundResponse (line 5) | class AdvancedCommerceRequestRefundResponse(AbstractAdvancedCommerceResp...
method __init__ (line 12) | def __init__(self, signedTransactionInfo: str):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCancelRequest.py
class AdvancedCommerceSubscriptionCancelRequest (line 11) | class AdvancedCommerceSubscriptionCancelRequest(AdvancedCommerceRequest):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCancelResponse.py
class AdvancedCommerceSubscriptionCancelResponse (line 8) | class AdvancedCommerceSubscriptionCancelResponse(AbstractAdvancedCommerc...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataDescriptors.py
class AdvancedCommerceSubscriptionChangeMetadataDescriptors (line 11) | class AdvancedCommerceSubscriptionChangeMetadataDescriptors():
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataItem.py
class AdvancedCommerceSubscriptionChangeMetadataItem (line 11) | class AdvancedCommerceSubscriptionChangeMetadataItem():
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataRequest.py
class AdvancedCommerceSubscriptionChangeMetadataRequest (line 14) | class AdvancedCommerceSubscriptionChangeMetadataRequest(AdvancedCommerce...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataResponse.py
class AdvancedCommerceSubscriptionChangeMetadataResponse (line 5) | class AdvancedCommerceSubscriptionChangeMetadataResponse(AbstractAdvance...
method __init__ (line 12) | def __init__(self, signedRenewalInfo: str, signedTransactionInfo: str):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCreateItem.py
class AdvancedCommerceSubscriptionCreateItem (line 11) | class AdvancedCommerceSubscriptionCreateItem(AbstractAdvancedCommerceItem):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionCreateRequest.py
class AdvancedCommerceSubscriptionCreateRequest (line 13) | class AdvancedCommerceSubscriptionCreateRequest(AbstractAdvancedCommerce...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateDescriptors.py
class AdvancedCommerceSubscriptionMigrateDescriptors (line 8) | class AdvancedCommerceSubscriptionMigrateDescriptors(AdvancedCommerceDes...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateItem.py
class AdvancedCommerceSubscriptionMigrateItem (line 8) | class AdvancedCommerceSubscriptionMigrateItem(AbstractAdvancedCommerceIt...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateRenewalItem.py
class AdvancedCommerceSubscriptionMigrateRenewalItem (line 8) | class AdvancedCommerceSubscriptionMigrateRenewalItem(AbstractAdvancedCom...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateRequest.py
class AdvancedCommerceSubscriptionMigrateRequest (line 13) | class AdvancedCommerceSubscriptionMigrateRequest(AdvancedCommerceRequest):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateResponse.py
class AdvancedCommerceSubscriptionMigrateResponse (line 8) | class AdvancedCommerceSubscriptionMigrateResponse(AbstractAdvancedCommer...
method __init__ (line 14) | def __init__(self, signedRenewalInfo: str, signedTransactionInfo: str):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyAddItem.py
class AdvancedCommerceSubscriptionModifyAddItem (line 11) | class AdvancedCommerceSubscriptionModifyAddItem(AbstractAdvancedCommerce...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyChangeItem.py
class AdvancedCommerceSubscriptionModifyChangeItem (line 14) | class AdvancedCommerceSubscriptionModifyChangeItem(AbstractAdvancedComme...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyDescriptors.py
class AdvancedCommerceSubscriptionModifyDescriptors (line 10) | class AdvancedCommerceSubscriptionModifyDescriptors():
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyInAppRequest.py
class AdvancedCommerceSubscriptionModifyInAppRequest (line 16) | class AdvancedCommerceSubscriptionModifyInAppRequest(AbstractAdvancedCom...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyPeriodChange.py
class AdvancedCommerceSubscriptionModifyPeriodChange (line 11) | class AdvancedCommerceSubscriptionModifyPeriodChange(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyRemoveItem.py
class AdvancedCommerceSubscriptionModifyRemoveItem (line 8) | class AdvancedCommerceSubscriptionModifyRemoveItem(AbstractAdvancedComme...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionPriceChangeItem.py
class AdvancedCommerceSubscriptionPriceChangeItem (line 10) | class AdvancedCommerceSubscriptionPriceChangeItem(AbstractAdvancedCommer...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionPriceChangeRequest.py
class AdvancedCommerceSubscriptionPriceChangeRequest (line 10) | class AdvancedCommerceSubscriptionPriceChangeRequest(AdvancedCommerceReq...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionPriceChangeResponse.py
class AdvancedCommerceSubscriptionPriceChangeResponse (line 8) | class AdvancedCommerceSubscriptionPriceChangeResponse(AbstractAdvancedCo...
method __init__ (line 14) | def __init__(self, signedRenewalInfo: str, signedTransactionInfo: str):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionReactivateInAppRequest.py
class AdvancedCommerceSubscriptionReactivateInAppRequest (line 10) | class AdvancedCommerceSubscriptionReactivateInAppRequest(AbstractAdvance...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionReactivateItem.py
class AdvancedCommerceSubscriptionReactivateItem (line 8) | class AdvancedCommerceSubscriptionReactivateItem(AbstractAdvancedCommerc...
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionRevokeRequest.py
class AdvancedCommerceSubscriptionRevokeRequest (line 12) | class AdvancedCommerceSubscriptionRevokeRequest(AdvancedCommerceRequest):
FILE: appstoreserverlibrary/models/AdvancedCommerceSubscriptionRevokeResponse.py
class AdvancedCommerceSubscriptionRevokeResponse (line 8) | class AdvancedCommerceSubscriptionRevokeResponse(AbstractAdvancedCommerc...
method __init__ (line 14) | def __init__(self, signedRenewalInfo: str, signedTransactionInfo: str):
FILE: appstoreserverlibrary/models/AdvancedCommerceValidationUtils.py
class AdvancedCommerceValidationUtils (line 8) | class AdvancedCommerceValidationUtils:
method description_validator (line 16) | def description_validator(instance, attribute, value):
method display_name_validator (line 30) | def display_name_validator(instance, attribute, value):
method sku_validator (line 44) | def sku_validator(instance, attribute, value):
method period_count_validator (line 58) | def period_count_validator(instance, attribute, value):
method items_validator (line 74) | def items_validator(instance, attribute, value):
method dependent_skus_validator (line 89) | def dependent_skus_validator(instance, attribute, value):
FILE: appstoreserverlibrary/models/AlternateProduct.py
class AlternateProduct (line 9) | class AlternateProduct:
FILE: appstoreserverlibrary/models/AppData.py
class AppData (line 11) | class AppData(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/AppTransaction.py
class AppTransaction (line 13) | class AppTransaction(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/AppTransactionInfoResponse.py
class AppTransactionInfoResponse (line 8) | class AppTransactionInfoResponse:
FILE: appstoreserverlibrary/models/AutoRenewStatus.py
class AutoRenewStatus (line 7) | class AutoRenewStatus(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/BulletPoint.py
class BulletPoint (line 9) | class BulletPoint:
FILE: appstoreserverlibrary/models/CheckTestNotificationResponse.py
class CheckTestNotificationResponse (line 10) | class CheckTestNotificationResponse:
FILE: appstoreserverlibrary/models/ConsumptionRequest.py
class ConsumptionRequest (line 12) | class ConsumptionRequest(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/ConsumptionRequestReason.py
class ConsumptionRequestReason (line 7) | class ConsumptionRequestReason(str, Enum, metaclass=AppStoreServerLibrar...
FILE: appstoreserverlibrary/models/ConsumptionRequestV1.py
class ConsumptionRequestV1 (line 19) | class ConsumptionRequestV1(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/ConsumptionStatus.py
class ConsumptionStatus (line 7) | class ConsumptionStatus(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/Data.py
class Data (line 13) | class Data(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/DecodedRealtimeRequestBody.py
class DecodedRealtimeRequestBody (line 13) | class DecodedRealtimeRequestBody(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/DefaultConfigurationRequest.py
class DefaultConfigurationRequest (line 10) | class DefaultConfigurationRequest:
FILE: appstoreserverlibrary/models/DefaultConfigurationResponse.py
class DefaultConfigurationResponse (line 9) | class DefaultConfigurationResponse:
FILE: appstoreserverlibrary/models/DeliveryStatus.py
class DeliveryStatus (line 7) | class DeliveryStatus(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/DeliveryStatusV1.py
class DeliveryStatusV1 (line 7) | class DeliveryStatusV1(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/Environment.py
class Environment (line 7) | class Environment(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/ExpirationIntent.py
class ExpirationIntent (line 7) | class ExpirationIntent(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/ExtendReasonCode.py
class ExtendReasonCode (line 7) | class ExtendReasonCode(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/ExtendRenewalDateRequest.py
class ExtendRenewalDateRequest (line 10) | class ExtendRenewalDateRequest:
FILE: appstoreserverlibrary/models/ExtendRenewalDateResponse.py
class ExtendRenewalDateResponse (line 8) | class ExtendRenewalDateResponse:
FILE: appstoreserverlibrary/models/ExternalPurchaseToken.py
class ExternalPurchaseToken (line 10) | class ExternalPurchaseToken(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/FirstSendAttemptResult.py
class FirstSendAttemptResult (line 8) | class FirstSendAttemptResult(str, Enum, metaclass=AppStoreServerLibraryE...
FILE: appstoreserverlibrary/models/GetImageListResponse.py
class GetImageListResponse (line 11) | class GetImageListResponse:
FILE: appstoreserverlibrary/models/GetImageListResponseItem.py
class GetImageListResponseItem (line 14) | class GetImageListResponseItem(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/GetMessageListResponse.py
class GetMessageListResponse (line 11) | class GetMessageListResponse:
FILE: appstoreserverlibrary/models/GetMessageListResponseItem.py
class GetMessageListResponseItem (line 13) | class GetMessageListResponseItem(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/HeaderPosition.py
class HeaderPosition (line 7) | class HeaderPosition(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/HistoryResponse.py
class HistoryResponse (line 11) | class HistoryResponse(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/ImageSize.py
class ImageSize (line 7) | class ImageSize(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/ImageState.py
class ImageState (line 7) | class ImageState(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/InAppOwnershipType.py
class InAppOwnershipType (line 7) | class InAppOwnershipType(str, Enum, metaclass=AppStoreServerLibraryEnumM...
FILE: appstoreserverlibrary/models/JWSRenewalInfoDecodedPayload.py
class JWSRenewalInfoDecodedPayload (line 16) | class JWSRenewalInfoDecodedPayload(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/JWSTransactionDecodedPayload.py
class JWSTransactionDecodedPayload (line 19) | class JWSTransactionDecodedPayload(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/LastTransactionsItem.py
class LastTransactionsItem (line 11) | class LastTransactionsItem(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/LibraryUtility.py
class AppStoreServerLibraryEnumMeta (line 19) | class AppStoreServerLibraryEnumMeta(EnumMeta):
method __contains__ (line 20) | def __contains__(c, val):
method create_main_attr (line 27) | def create_main_attr(c, raw_field_name: str, raw_required: bool = Fals...
method create_raw_attr (line 37) | def create_raw_attr(c, field_name: str, required: bool = False) -> Any:
class AttrsRawValueAware (line 61) | class AttrsRawValueAware:
method __attrs_post_init__ (line 62) | def __attrs_post_init__(self):
function _get_cattrs_converter (line 78) | def _get_cattrs_converter(destination_class: Type[T]) -> cattrs.Converter:
FILE: appstoreserverlibrary/models/LifetimeDollarsPurchased.py
class LifetimeDollarsPurchased (line 7) | class LifetimeDollarsPurchased(IntEnum, metaclass=AppStoreServerLibraryE...
FILE: appstoreserverlibrary/models/LifetimeDollarsRefunded.py
class LifetimeDollarsRefunded (line 7) | class LifetimeDollarsRefunded(IntEnum, metaclass=AppStoreServerLibraryEn...
FILE: appstoreserverlibrary/models/MassExtendRenewalDateRequest.py
class MassExtendRenewalDateRequest (line 10) | class MassExtendRenewalDateRequest:
FILE: appstoreserverlibrary/models/MassExtendRenewalDateResponse.py
class MassExtendRenewalDateResponse (line 8) | class MassExtendRenewalDateResponse:
FILE: appstoreserverlibrary/models/MassExtendRenewalDateStatusResponse.py
class MassExtendRenewalDateStatusResponse (line 8) | class MassExtendRenewalDateStatusResponse:
FILE: appstoreserverlibrary/models/Message.py
class Message (line 9) | class Message:
FILE: appstoreserverlibrary/models/MessageState.py
class MessageState (line 7) | class MessageState(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/NotificationHistoryRequest.py
class NotificationHistoryRequest (line 11) | class NotificationHistoryRequest:
FILE: appstoreserverlibrary/models/NotificationHistoryResponse.py
class NotificationHistoryResponse (line 10) | class NotificationHistoryResponse:
FILE: appstoreserverlibrary/models/NotificationHistoryResponseItem.py
class NotificationHistoryResponseItem (line 10) | class NotificationHistoryResponseItem:
FILE: appstoreserverlibrary/models/NotificationTypeV2.py
class NotificationTypeV2 (line 7) | class NotificationTypeV2(str, Enum, metaclass=AppStoreServerLibraryEnumM...
FILE: appstoreserverlibrary/models/OfferDiscountType.py
class OfferDiscountType (line 7) | class OfferDiscountType(str, Enum, metaclass=AppStoreServerLibraryEnumMe...
FILE: appstoreserverlibrary/models/OfferType.py
class OfferType (line 7) | class OfferType(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/OrderLookupResponse.py
class OrderLookupResponse (line 11) | class OrderLookupResponse(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/OrderLookupStatus.py
class OrderLookupStatus (line 7) | class OrderLookupStatus(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/PerformanceTestConfig.py
class PerformanceTestConfig (line 9) | class PerformanceTestConfig:
FILE: appstoreserverlibrary/models/PerformanceTestRequest.py
class PerformanceTestRequest (line 7) | class PerformanceTestRequest:
FILE: appstoreserverlibrary/models/PerformanceTestResponse.py
class PerformanceTestResponse (line 11) | class PerformanceTestResponse:
FILE: appstoreserverlibrary/models/PerformanceTestResponseTimes.py
class PerformanceTestResponseTimes (line 9) | class PerformanceTestResponseTimes:
FILE: appstoreserverlibrary/models/PerformanceTestResultResponse.py
function _failures_value_set (line 14) | def _failures_value_set(self, _: Attribute, value: Optional[Dict[SendAtt...
function _raw_failures_value_set (line 20) | def _raw_failures_value_set(self, _: Attribute, value: Optional[Dict[str...
class PerformanceTestResultResponse (line 32) | class PerformanceTestResultResponse(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/PerformanceTestStatus.py
class PerformanceTestStatus (line 7) | class PerformanceTestStatus(str, Enum, metaclass=AppStoreServerLibraryEn...
FILE: appstoreserverlibrary/models/Platform.py
class Platform (line 7) | class Platform(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/PlayTime.py
class PlayTime (line 7) | class PlayTime(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/PriceIncreaseStatus.py
class PriceIncreaseStatus (line 7) | class PriceIncreaseStatus(IntEnum, metaclass=AppStoreServerLibraryEnumMe...
FILE: appstoreserverlibrary/models/PromotionalOffer.py
class PromotionalOffer (line 12) | class PromotionalOffer:
FILE: appstoreserverlibrary/models/PromotionalOfferSignatureV1.py
class PromotionalOfferSignatureV1 (line 10) | class PromotionalOfferSignatureV1:
FILE: appstoreserverlibrary/models/PurchasePlatform.py
class PurchasePlatform (line 7) | class PurchasePlatform(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/RealtimeRequestBody.py
class RealtimeRequestBody (line 9) | class RealtimeRequestBody:
FILE: appstoreserverlibrary/models/RealtimeResponseBody.py
class RealtimeResponseBody (line 13) | class RealtimeResponseBody:
FILE: appstoreserverlibrary/models/RealtimeUrlRequest.py
class RealtimeUrlRequest (line 7) | class RealtimeUrlRequest:
FILE: appstoreserverlibrary/models/RealtimeUrlResponse.py
class RealtimeUrlResponse (line 9) | class RealtimeUrlResponse:
FILE: appstoreserverlibrary/models/RefundHistoryResponse.py
class RefundHistoryResponse (line 8) | class RefundHistoryResponse:
FILE: appstoreserverlibrary/models/RefundPreference.py
class RefundPreference (line 7) | class RefundPreference(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/RefundPreferenceV1.py
class RefundPreferenceV1 (line 7) | class RefundPreferenceV1(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/ResponseBodyV2.py
class ResponseBodyV2 (line 8) | class ResponseBodyV2:
FILE: appstoreserverlibrary/models/ResponseBodyV2DecodedPayload.py
class ResponseBodyV2DecodedPayload (line 17) | class ResponseBodyV2DecodedPayload(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/RevocationReason.py
class RevocationReason (line 7) | class RevocationReason(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/RevocationType.py
class RevocationType (line 7) | class RevocationType(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/SendAttemptItem.py
class SendAttemptItem (line 11) | class SendAttemptItem(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/SendAttemptResult.py
class SendAttemptResult (line 7) | class SendAttemptResult(str, Enum, metaclass=AppStoreServerLibraryEnumMe...
FILE: appstoreserverlibrary/models/SendTestNotificationResponse.py
class SendTestNotificationResponse (line 8) | class SendTestNotificationResponse:
FILE: appstoreserverlibrary/models/Status.py
class Status (line 7) | class Status(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/StatusResponse.py
class StatusResponse (line 12) | class StatusResponse(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/SubscriptionGroupIdentifierItem.py
class SubscriptionGroupIdentifierItem (line 10) | class SubscriptionGroupIdentifierItem:
FILE: appstoreserverlibrary/models/Subtype.py
class Subtype (line 7) | class Subtype(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/Summary.py
class Summary (line 11) | class Summary(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/TransactionHistoryRequest.py
class ProductType (line 10) | class ProductType(str, Enum):
class Order (line 16) | class Order(str, Enum):
class TransactionHistoryRequest (line 21) | class TransactionHistoryRequest:
FILE: appstoreserverlibrary/models/TransactionInfoResponse.py
class TransactionInfoResponse (line 8) | class TransactionInfoResponse:
FILE: appstoreserverlibrary/models/TransactionReason.py
class TransactionReason (line 6) | class TransactionReason(str, Enum, metaclass=AppStoreServerLibraryEnumMe...
FILE: appstoreserverlibrary/models/Type.py
class Type (line 6) | class Type(str, Enum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/models/UpdateAppAccountTokenRequest.py
class UpdateAppAccountTokenRequest (line 6) | class UpdateAppAccountTokenRequest:
FILE: appstoreserverlibrary/models/UploadMessageImage.py
class UploadMessageImage (line 9) | class UploadMessageImage:
FILE: appstoreserverlibrary/models/UploadMessageRequestBody.py
class UploadMessageRequestBody (line 14) | class UploadMessageRequestBody(AttrsRawValueAware):
FILE: appstoreserverlibrary/models/UserStatus.py
class UserStatus (line 7) | class UserStatus(IntEnum, metaclass=AppStoreServerLibraryEnumMeta):
FILE: appstoreserverlibrary/promotional_offer.py
class PromotionalOfferSignatureCreator (line 11) | class PromotionalOfferSignatureCreator:
method __init__ (line 15) | def __init__(self, signing_key: bytes, key_id: str, bundle_id: str):
method create_signature (line 19) | def create_signature(self, product_identifier: str, subscription_offer...
FILE: appstoreserverlibrary/receipt_utility.py
class ReceiptUtility (line 15) | class ReceiptUtility:
method _decode_octet_string (line 16) | def _decode_octet_string(self, octet_string: bytes):
method extract_transaction_id_from_app_receipt (line 22) | def extract_transaction_id_from_app_receipt(self, app_receipt: str) ->...
method extract_transaction_id_from_transaction_receipt (line 50) | def extract_transaction_id_from_transaction_receipt(self, transaction_...
FILE: appstoreserverlibrary/signed_data_verifier.py
class SignedDataVerifier (line 28) | class SignedDataVerifier:
method __init__ (line 32) | def __init__(
method verify_and_decode_renewal_info (line 48) | def verify_and_decode_renewal_info(self, signed_renewal_info: str) -> ...
method verify_and_decode_signed_transaction (line 63) | def verify_and_decode_signed_transaction(self, signed_transaction: str...
method verify_and_decode_notification (line 79) | def verify_and_decode_notification(self, signed_payload: str) -> Respo...
method _verify_notification (line 115) | def _verify_notification(self, bundle_id: Optional[str], app_apple_id:...
method verify_and_decode_app_transaction (line 121) | def verify_and_decode_app_transaction(self, signed_app_transaction: st...
method verify_and_decode_realtime_request (line 139) | def verify_and_decode_realtime_request(self, signed_payload: str) -> D...
method _decode_signed_object (line 156) | def _decode_signed_object(self, signed_obj: str) -> dict:
class _ChainVerifier (line 179) | class _ChainVerifier:
method __init__ (line 183) | def __init__(self, root_certificates: List[bytes], enable_strict_check...
method verify_chain (line 188) | def verify_chain(self, certificates: List[str], perform_online_checks:...
method _verify_chain_without_caching (line 198) | def _verify_chain_without_caching(self, certificates: List[str], perfo...
method check_oid (line 234) | def check_oid(self, cert: x509.Certificate, oid: str):
method check_ocsp_status (line 240) | def check_ocsp_status(self, cert: crypto.X509, issuer: crypto.X509, ro...
method get_cached_public_key (line 341) | def get_cached_public_key(self, certificates: List[str]) -> Optional[s...
method put_verified_public_key (line 349) | def put_verified_public_key(self, certificates: List[str], verified_pu...
class VerificationStatus (line 357) | class VerificationStatus(IntEnum):
class VerificationException (line 368) | class VerificationException(Exception):
method __init__ (line 369) | def __init__(self, status: VerificationStatus):
FILE: tests/test_advanced_commerce_models.py
class AdvancedCommerceModelsTest (line 52) | class AdvancedCommerceModelsTest(unittest.TestCase):
method test_advanced_commerce_period (line 53) | def test_advanced_commerce_period(self):
method test_advanced_commerce_reason (line 68) | def test_advanced_commerce_reason(self):
method test_advanced_commerce_refund_reason (line 80) | def test_advanced_commerce_refund_reason(self):
method test_advanced_commerce_refund_type (line 95) | def test_advanced_commerce_refund_type(self):
method test_advanced_commerce_offer_period (line 107) | def test_advanced_commerce_offer_period(self):
method test_advanced_commerce_offer_reason (line 122) | def test_advanced_commerce_offer_reason(self):
method test_advanced_commerce_effective (line 134) | def test_advanced_commerce_effective(self):
method test_validation_utils_description (line 144) | def test_validation_utils_description(self):
method test_validation_utils_display_name (line 155) | def test_validation_utils_display_name(self):
method test_validation_utils_sku (line 166) | def test_validation_utils_sku(self):
method test_validation_utils_period_count (line 177) | def test_validation_utils_period_count(self):
method test_validation_utils_items (line 188) | def test_validation_utils_items(self):
method test_advanced_commerce_descriptors_deserialization (line 209) | def test_advanced_commerce_descriptors_deserialization(self):
method test_advanced_commerce_one_time_charge_item_deserialization (line 218) | def test_advanced_commerce_one_time_charge_item_deserialization(self):
method test_advanced_commerce_subscription_create_item_deserialization (line 229) | def test_advanced_commerce_subscription_create_item_deserialization(se...
method test_advanced_commerce_request_refund_item_deserialization (line 240) | def test_advanced_commerce_request_refund_item_deserialization(self):
method test_advanced_commerce_offer_deserialization (line 254) | def test_advanced_commerce_offer_deserialization(self):
method test_advanced_commerce_one_time_charge_create_request_deserialization (line 267) | def test_advanced_commerce_one_time_charge_create_request_deserializat...
method test_advanced_commerce_subscription_create_request_deserialization (line 286) | def test_advanced_commerce_subscription_create_request_deserialization...
method test_advanced_commerce_request_refund_request_deserialization (line 308) | def test_advanced_commerce_request_refund_request_deserialization(self):
method test_advanced_commerce_subscription_cancel_request_deserialization (line 328) | def test_advanced_commerce_subscription_cancel_request_deserialization...
method test_advanced_commerce_subscription_revoke_request_deserialization (line 338) | def test_advanced_commerce_subscription_revoke_request_deserialization...
method test_advanced_commerce_subscription_price_change_request_deserialization (line 349) | def test_advanced_commerce_subscription_price_change_request_deseriali...
method test_advanced_commerce_request_refund_response_deserialization (line 362) | def test_advanced_commerce_request_refund_response_deserialization(self):
method test_advanced_commerce_subscription_cancel_response_deserialization (line 370) | def test_advanced_commerce_subscription_cancel_response_deserializatio...
method test_advanced_commerce_subscription_revoke_response_deserialization (line 379) | def test_advanced_commerce_subscription_revoke_response_deserializatio...
method test_advanced_commerce_subscription_price_change_response_deserialization (line 388) | def test_advanced_commerce_subscription_price_change_response_deserial...
method test_advanced_commerce_subscription_change_metadata_response_deserialization (line 397) | def test_advanced_commerce_subscription_change_metadata_response_deser...
method test_advanced_commerce_subscription_migrate_request_deserialization (line 407) | def test_advanced_commerce_subscription_migrate_request_deserializatio...
method test_advanced_commerce_subscription_modify_in_app_request_deserialization (line 423) | def test_advanced_commerce_subscription_modify_in_app_request_deserial...
method test_advanced_commerce_subscription_reactivate_in_app_request_deserialization (line 439) | def test_advanced_commerce_subscription_reactivate_in_app_request_dese...
method test_advanced_commerce_subscription_change_metadata_request_deserialization (line 451) | def test_advanced_commerce_subscription_change_metadata_request_deseri...
method test_advanced_commerce_subscription_migrate_descriptors_deserialization (line 463) | def test_advanced_commerce_subscription_migrate_descriptors_deserializ...
method test_advanced_commerce_subscription_modify_descriptors_deserialization (line 472) | def test_advanced_commerce_subscription_modify_descriptors_deserializa...
method test_advanced_commerce_subscription_change_metadata_descriptors_deserialization (line 481) | def test_advanced_commerce_subscription_change_metadata_descriptors_de...
method test_advanced_commerce_subscription_change_metadata_item_deserialization (line 490) | def test_advanced_commerce_subscription_change_metadata_item_deseriali...
method test_advanced_commerce_subscription_migrate_renewal_item_deserialization (line 501) | def test_advanced_commerce_subscription_migrate_renewal_item_deseriali...
method test_advanced_commerce_subscription_modify_add_item_deserialization (line 511) | def test_advanced_commerce_subscription_modify_add_item_deserializatio...
method test_advanced_commerce_subscription_modify_change_item_deserialization (line 522) | def test_advanced_commerce_subscription_modify_change_item_deserializa...
method test_advanced_commerce_subscription_modify_remove_item_deserialization (line 534) | def test_advanced_commerce_subscription_modify_remove_item_deserializa...
method test_advanced_commerce_subscription_modify_period_change_deserialization (line 542) | def test_advanced_commerce_subscription_modify_period_change_deseriali...
method test_advanced_commerce_subscription_price_change_item_deserialization (line 550) | def test_advanced_commerce_subscription_price_change_item_deserializat...
method test_advanced_commerce_subscription_price_change_item_dependent_sku_validation (line 560) | def test_advanced_commerce_subscription_price_change_item_dependent_sk...
method test_advanced_commerce_subscription_reactivate_item_deserialization (line 576) | def test_advanced_commerce_subscription_reactivate_item_deserializatio...
method test_advanced_commerce_request_info_deserialization (line 584) | def test_advanced_commerce_request_info_deserialization(self):
method test_advanced_commerce_subscription_migrate_item_deserialization (line 594) | def test_advanced_commerce_subscription_migrate_item_deserialization(s...
method test_advanced_commerce_subscription_migrate_response_deserialization (line 604) | def test_advanced_commerce_subscription_migrate_response_deserializati...
FILE: tests/test_api_client.py
class DecodedPayloads (line 58) | class DecodedPayloads(unittest.TestCase):
method test_extend_renewal_date_for_all_active_subscribers (line 59) | def test_extend_renewal_date_for_all_active_subscribers(self):
method test_extend_subscription_renewal_date (line 78) | def test_extend_subscription_renewal_date(self):
method test_get_all_subscription_statuses (line 99) | def test_get_all_subscription_statuses(self):
method test_get_refund_history (line 147) | def test_get_refund_history(self):
method test_get_status_of_subscription_renewal_date_extensions (line 161) | def test_get_status_of_subscription_renewal_date_extensions(self):
method test_get_test_notification_status (line 177) | def test_get_test_notification_status(self):
method test_get_notification_history (line 194) | def test_get_notification_history(self):
method test_get_transaction_history_v1 (line 235) | def test_get_transaction_history_v1(self):
method test_get_transaction_history_v2 (line 272) | def test_get_transaction_history_v2(self):
method test_get_transaction_info (line 309) | def test_get_transaction_info(self):
method test_look_up_order_id (line 321) | def test_look_up_order_id(self):
method test_request_test_notification (line 335) | def test_request_test_notification(self):
method test_send_consumption_data (line 347) | def test_send_consumption_data(self):
method test_send_consumption_information (line 382) | def test_send_consumption_information(self):
method test_api_error (line 404) | def test_api_error(self):
method test_xcode_not_supported_error (line 422) | def test_xcode_not_supported_error(self):
method test_api_too_many_requests (line 432) | def test_api_too_many_requests(self):
method test_unknown_error (line 450) | def test_unknown_error(self):
method test_get_transaction_history_with_unknown_environment (line 468) | def test_get_transaction_history_with_unknown_environment(self):
method test_get_transaction_history_with_malformed_app_apple_id (line 499) | def test_get_transaction_history_with_malformed_app_apple_id(self):
method test_set_app_account_token (line 532) | def test_set_app_account_token(self):
method test_invalid_app_account_token_error (line 543) | def test_invalid_app_account_token_error(self):
method test_family_transaction_not_supported_error (line 561) | def test_family_transaction_not_supported_error(self):
method test_transaction_id_not_original_transaction_id_error (line 580) | def test_transaction_id_not_original_transaction_id_error(self):
method test_upload_image (line 601) | def test_upload_image(self):
method test_delete_image (line 612) | def test_delete_image(self):
method test_get_image_list (line 620) | def test_get_image_list(self):
method test_upload_message (line 633) | def test_upload_message(self):
method test_upload_message_with_image (line 642) | def test_upload_message_with_image(self):
method test_delete_message (line 652) | def test_delete_message(self):
method test_get_message_list (line 660) | def test_get_message_list(self):
method test_configure_default_message (line 672) | def test_configure_default_message(self):
method test_delete_default_message (line 681) | def test_delete_default_message(self):
method test_get_default_message (line 689) | def test_get_default_message(self):
method test_upload_image_with_image_size (line 699) | def test_upload_image_with_image_size(self):
method test_configure_realtime_url (line 710) | def test_configure_realtime_url(self):
method test_delete_realtime_url (line 719) | def test_delete_realtime_url(self):
method test_get_realtime_url (line 727) | def test_get_realtime_url(self):
method test_upload_message_with_bullet_points (line 737) | def test_upload_message_with_bullet_points(self):
method test_initiate_performance_test (line 751) | def test_initiate_performance_test(self):
method test_get_performance_test_results (line 768) | def test_get_performance_test_results(self):
method test_get_app_transaction_info_success (line 796) | def test_get_app_transaction_info_success(self):
method test_get_app_transaction_info_invalid_transaction_id (line 808) | def test_get_app_transaction_info_invalid_transaction_id(self):
method test_get_app_transaction_info_app_transaction_does_not_exist (line 825) | def test_get_app_transaction_info_app_transaction_does_not_exist(self):
method test_get_app_transaction_info_transaction_id_not_found (line 843) | def test_get_app_transaction_info_transaction_id_not_found(self):
method get_signing_key (line 862) | def get_signing_key(self):
method get_client_with_body (line 865) | def get_client_with_body(self, body: str, expected_method: str, expect...
method get_client_with_body_from_file (line 900) | def get_client_with_body_from_file(self, path: str, expected_method: s...
FILE: tests/test_api_client_async.py
class DecodedPayloads (line 64) | class DecodedPayloads(unittest.IsolatedAsyncioTestCase):
method test_extend_renewal_date_for_all_active_subscribers (line 65) | async def test_extend_renewal_date_for_all_active_subscribers(self):
method test_extend_subscription_renewal_date (line 84) | async def test_extend_subscription_renewal_date(self):
method test_get_all_subscription_statuses (line 105) | async def test_get_all_subscription_statuses(self):
method test_get_refund_history (line 153) | async def test_get_refund_history(self):
method test_get_status_of_subscription_renewal_date_extensions (line 167) | async def test_get_status_of_subscription_renewal_date_extensions(self):
method test_get_test_notification_status (line 183) | async def test_get_test_notification_status(self):
method test_get_notification_history (line 200) | async def test_get_notification_history(self):
method test_get_transaction_history_v1 (line 241) | async def test_get_transaction_history_v1(self):
method test_get_transaction_history_v2 (line 278) | async def test_get_transaction_history_v2(self):
method test_get_transaction_info (line 315) | async def test_get_transaction_info(self):
method test_look_up_order_id (line 327) | async def test_look_up_order_id(self):
method test_request_test_notification (line 341) | async def test_request_test_notification(self):
method test_send_consumption_data (line 353) | async def test_send_consumption_data(self):
method test_send_consumption_information (line 388) | async def test_send_consumption_information(self):
method test_api_error (line 409) | async def test_api_error(self):
method test_xcode_not_supported_error (line 427) | async def test_xcode_not_supported_error(self):
method test_api_too_many_requests (line 437) | async def test_api_too_many_requests(self):
method test_unknown_error (line 455) | async def test_unknown_error(self):
method test_get_transaction_history_with_unknown_environment (line 473) | async def test_get_transaction_history_with_unknown_environment(self):
method test_get_transaction_history_with_malformed_app_apple_id (line 504) | async def test_get_transaction_history_with_malformed_app_apple_id(self):
method test_set_app_account_token (line 537) | async def test_set_app_account_token(self):
method test_invalid_app_account_token_error (line 548) | async def test_invalid_app_account_token_error(self):
method test_family_transaction_not_supported_error (line 566) | async def test_family_transaction_not_supported_error(self):
method test_transaction_id_not_original_transaction_id_error (line 585) | async def test_transaction_id_not_original_transaction_id_error(self):
method test_upload_image (line 605) | async def test_upload_image(self):
method test_delete_image (line 616) | async def test_delete_image(self):
method test_get_image_list (line 624) | async def test_get_image_list(self):
method test_upload_message (line 637) | async def test_upload_message(self):
method test_upload_message_with_image (line 646) | async def test_upload_message_with_image(self):
method test_delete_message (line 656) | async def test_delete_message(self):
method test_get_message_list (line 664) | async def test_get_message_list(self):
method test_configure_default_message (line 676) | async def test_configure_default_message(self):
method test_delete_default_message (line 685) | async def test_delete_default_message(self):
method test_get_default_message (line 693) | async def test_get_default_message(self):
method test_upload_image_with_image_size (line 703) | async def test_upload_image_with_image_size(self):
method test_configure_realtime_url (line 714) | async def test_configure_realtime_url(self):
method test_delete_realtime_url (line 723) | async def test_delete_realtime_url(self):
method test_get_realtime_url (line 731) | async def test_get_realtime_url(self):
method test_upload_message_with_bullet_points (line 741) | async def test_upload_message_with_bullet_points(self):
method test_initiate_performance_test (line 755) | async def test_initiate_performance_test(self):
method test_get_performance_test_results (line 772) | async def test_get_performance_test_results(self):
method test_get_app_transaction_info_success (line 800) | async def test_get_app_transaction_info_success(self):
method test_get_app_transaction_info_invalid_transaction_id (line 812) | async def test_get_app_transaction_info_invalid_transaction_id(self):
method test_get_app_transaction_info_app_transaction_does_not_exist (line 830) | async def test_get_app_transaction_info_app_transaction_does_not_exist...
method test_get_app_transaction_info_transaction_id_not_found (line 848) | async def test_get_app_transaction_info_transaction_id_not_found(self):
method get_signing_key (line 866) | def get_signing_key(self):
method get_client_with_body (line 869) | def get_client_with_body(self, body: str, expected_method: str, expect...
method get_client_with_body_from_file (line 901) | def get_client_with_body_from_file(self, path: str, expected_method: s...
FILE: tests/test_app_data.py
class AppDataTest (line 12) | class AppDataTest(unittest.TestCase):
method test_app_data_deserialization (line 13) | def test_app_data_deserialization(self):
FILE: tests/test_decoded_payloads.py
class DecodedPayloads (line 25) | class DecodedPayloads(unittest.TestCase):
method test_app_transaction_decoding (line 26) | def test_app_transaction_decoding(self):
method test_transaction_decoding (line 48) | def test_transaction_decoding(self):
method test_transaction_with_revocation_decoding (line 91) | def test_transaction_with_revocation_decoding(self):
method test_renewal_info_decoding (line 139) | def test_renewal_info_decoding(self):
method test_notification_decoding (line 174) | def test_notification_decoding(self):
method test_consumption_request_notification_decoding (line 203) | def test_consumption_request_notification_decoding(self):
method test_summary_notification_decoding (line 232) | def test_summary_notification_decoding(self):
method test_external_purchase_token_notification_decoding (line 259) | def test_external_purchase_token_notification_decoding(self):
method test_external_purchase_token_sandbox_notification_decoding (line 288) | def test_external_purchase_token_sandbox_notification_decoding(self):
method test_realtime_request_decoding (line 317) | def test_realtime_request_decoding(self):
method test_rescind_consent_notification_decoding (line 332) | def test_rescind_consent_notification_decoding(self):
FILE: tests/test_jws_signature_creator.py
class TestInAppRequest (line 13) | class TestInAppRequest(AdvancedCommerceAPIInAppRequest):
class JWSSignatureCreatorTest (line 16) | class JWSSignatureCreatorTest(unittest.TestCase):
method test_promotional_offer_signature_creator (line 17) | def test_promotional_offer_signature_creator(self):
method test_promotional_offer_signature_creator_transaction_id_missing (line 40) | def test_promotional_offer_signature_creator_transaction_id_missing(se...
method test_promotional_offer_signature_creator_offer_identifier_missing (line 47) | def test_promotional_offer_signature_creator_offer_identifier_missing(...
method test_promotional_offer_signature_creator_product_id_missing (line 53) | def test_promotional_offer_signature_creator_product_id_missing(self):
method test_introductory_offer_eligibility_signature_creator (line 59) | def test_introductory_offer_eligibility_signature_creator(self):
method test_introductory_offer_eligibility_signature_creator_transaction_id_missing (line 82) | def test_introductory_offer_eligibility_signature_creator_transaction_...
method test_introductory_offer_eligibility_signature_creator_allow_introductory_offer_missing (line 88) | def test_introductory_offer_eligibility_signature_creator_allow_introd...
method test_introductory_offer_eligibility_signature_creator_product_id_missing (line 94) | def test_introductory_offer_eligibility_signature_creator_product_id_m...
method test_advanced_commerce_api_in_app_signature_creator (line 100) | def test_advanced_commerce_api_in_app_signature_creator(self):
method test_advanced_commerce_api_in_app_signature_creator_request_missing (line 124) | def test_advanced_commerce_api_in_app_signature_creator_request_missin...
FILE: tests/test_payload_verification.py
class PayloadVerification (line 12) | class PayloadVerification(unittest.TestCase):
method test_app_store_server_notification_decoding (line 13) | def test_app_store_server_notification_decoding(self):
method test_app_store_server_notification_decoding_production (line 19) | def test_app_store_server_notification_decoding_production(self):
method test_missing_x5c_header (line 26) | def test_missing_x5c_header(self):
method test_wrong_bundle_id_for_server_notification (line 33) | def test_wrong_bundle_id_for_server_notification(self):
method test_wrong_app_apple_id_for_server_notification (line 40) | def test_wrong_app_apple_id_for_server_notification(self):
method test_renewal_info_decoding (line 47) | def test_renewal_info_decoding(self):
method test_transaction_info_decoding (line 53) | def test_transaction_info_decoding(self):
method test_malformed_jwt_with_too_many_parts (line 59) | def test_malformed_jwt_with_too_many_parts(self):
method test_malformed_jwt_with_malformed_data (line 65) | def test_malformed_jwt_with_malformed_data(self):
FILE: tests/test_promotional_offer_signature_creator.py
class PromotionalOfferSignatureCreatorTest (line 10) | class PromotionalOfferSignatureCreatorTest(unittest.TestCase):
method test_signature_creator (line 11) | def test_signature_creator(self):
FILE: tests/test_receipt_utility.py
class ReceiptUtilityTest (line 11) | class ReceiptUtilityTest(unittest.TestCase):
method test_xcode_app_receipt_extraction_with_no_transactions (line 12) | def test_xcode_app_receipt_extraction_with_no_transactions(self):
method test_xcode_app_receipt_extraction_with_transactions (line 21) | def test_xcode_app_receipt_extraction_with_transactions(self):
method test_transaction_receipt_extraction (line 30) | def test_transaction_receipt_extraction(self):
FILE: tests/test_retention_messaging.py
class RetentionMessaging (line 16) | class RetentionMessaging(unittest.TestCase):
method test_realtime_response_body_with_message (line 17) | def test_realtime_response_body_with_message(self):
method test_realtime_response_body_with_alternate_product (line 43) | def test_realtime_response_body_with_alternate_product(self):
method test_realtime_response_body_with_promotional_offer_v2 (line 73) | def test_realtime_response_body_with_promotional_offer_v2(self):
method test_realtime_response_body_with_promotional_offer_v1 (line 105) | def test_realtime_response_body_with_promotional_offer_v1(self):
FILE: tests/test_x509_verifiction.py
class X509Verification (line 27) | class X509Verification(unittest.TestCase):
method test_valid_chain_without_ocsp (line 28) | def test_valid_chain_without_ocsp(self):
method test_valid_chain_invalid_intermediate_OID_without_OCSP (line 37) | def test_valid_chain_invalid_intermediate_OID_without_OCSP(self):
method test_valid_chain_invalid_leaf_OID_without_OCSP (line 47) | def test_valid_chain_invalid_leaf_OID_without_OCSP(self):
method test_invalid_chain_length (line 57) | def test_invalid_chain_length(self):
method test_invalid_base64_in_certificate_list (line 63) | def test_invalid_base64_in_certificate_list(self):
method test_invalid_data_in_certificate_list (line 73) | def test_invalid_data_in_certificate_list(self):
method test_malformed_root_cert (line 82) | def test_malformed_root_cert(self):
method test_chain_different_than_root_certificate (line 92) | def test_chain_different_than_root_certificate(self):
method test_valid_expired_chain (line 103) | def test_valid_expired_chain(self):
method test_apple_chain_is_valid_with_ocsp_and_strict (line 113) | def test_apple_chain_is_valid_with_ocsp_and_strict(self):
method test_ocsp_response_caching (line 121) | def test_ocsp_response_caching(self):
method test_ocsp_response_caching_has_expiration (line 140) | def test_ocsp_response_caching_has_expiration(self):
method test_ocsp_response_caching_with_different_chain (line 159) | def test_ocsp_response_caching_with_different_chain(self):
method test_ocsp_response_caching_with_slightly_different_chain (line 178) | def test_ocsp_response_caching_with_slightly_different_chain(self):
FILE: tests/test_xcode_signed_data.py
class ReceiptUtilityTest (line 17) | class ReceiptUtilityTest(unittest.TestCase):
method test_xcode_signed_app_transaction (line 18) | def test_xcode_signed_app_transaction(self):
method test_xcode_signed_transaction (line 37) | def test_xcode_signed_transaction(self):
method test_xcode_signed_renewal_info (line 72) | def test_xcode_signed_renewal_info(self):
method test_xcode_signed_app_transaction_with_production_environment (line 95) | def test_xcode_signed_app_transaction_with_production_environment(self):
FILE: tests/util.py
function create_signed_data_from_json (line 15) | def create_signed_data_from_json(path: str) -> str:
function decode_json_from_signed_date (line 21) | def decode_json_from_signed_date(data: str) -> Dict[str, Any]:
function read_data_from_file (line 25) | def read_data_from_file(path: str) -> str:
function read_data_from_binary_file (line 30) | def read_data_from_binary_file(path: str) -> str:
function get_signed_data_verifier (line 35) | def get_signed_data_verifier(env: Environment, bundle_id: str, app_apple...
function get_default_signed_data_verifier (line 40) | def get_default_signed_data_verifier():
Condensed preview — 265 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (646K chars).
[
{
"path": ".github/dependabot.yml",
"chars": 243,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"pip\"\n directory: \"/\"\n schedule:\n interval: \"daily\"\n time: \"0"
},
{
"path": ".github/workflows/ci-prb.yml",
"chars": 765,
"preview": "name: PR Builder\npermissions:\n contents: read\non:\n pull_request:\n branches: [ main ]\n push:\n branches: [ main ]"
},
{
"path": ".github/workflows/ci-release-docs.yml",
"chars": 1129,
"preview": "name: Doc Builder\npermissions:\n contents: read\non:\n release:\n types: [published]\njobs:\n build:\n name: Python Do"
},
{
"path": ".github/workflows/ci-release.yml",
"chars": 741,
"preview": "name: Release Builder\npermissions:\n contents: read\non:\n release:\n types: [published]\njobs:\n build:\n # Only non-"
},
{
"path": ".github/workflows/ci-snapshot.yml",
"chars": 810,
"preview": "name: Snapshot Builder\npermissions:\n contents: read\non:\n release:\n types: [published]\njobs:\n build:\n # Pre-rele"
},
{
"path": ".gitignore",
"chars": 230,
"preview": "__pycache__/\nbuild/\ndist/\n*.egg-info/\n.pytest_cache/\n\n# pyenv\n.python-version\n\n# Environments\n.env\n.venv\nvenv\n\n\n# mypy\n."
},
{
"path": "CHANGELOG.md",
"chars": 5365,
"preview": "# Changelog\n\n## Version 3.0.0\n- Incorporate changes for App Store Server API v1.19 [https://github.com/apple/app-store-s"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5544,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "CONTRIBUTING.md",
"chars": 1765,
"preview": "# Contributing\n\nThank you for your interest in contributing! \n\n## Reporting Bugs\n\nPlease report bugs by creating [Github"
},
{
"path": "LICENSE.txt",
"chars": 1049,
"preview": "Copyright 2023 Apple Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software"
},
{
"path": "MANIFEST.in",
"chars": 17,
"preview": "include README.md"
},
{
"path": "NOTICE.txt",
"chars": 39274,
"preview": "Acknowledgements\nPortions of this App Store Server Library software may utilize the following copyrighted \nmaterial, the"
},
{
"path": "README.md",
"chars": 6646,
"preview": "# Apple App Store Server Python Library\nThe [Python](https://github.com/apple/app-store-server-library-python) server li"
},
{
"path": "appstoreserverlibrary/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "appstoreserverlibrary/api_client.py",
"chars": 81201,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nimport calendar\nimport datetime\nimport warnings\nfrom enum i"
},
{
"path": "appstoreserverlibrary/jws_signature_creator.py",
"chars": 6904,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nimport datetime\nfrom typing import Any, Dict, Optional\nimpo"
},
{
"path": "appstoreserverlibrary/models/AbstractAdvancedCommerceBaseItem.py",
"chars": 571,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom abc import ABC\n\nfrom attr import define\nimport attr\n\nf"
},
{
"path": "appstoreserverlibrary/models/AbstractAdvancedCommerceInAppRequest.py",
"chars": 423,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom abc import ABC\n\nfrom attr import define\nimport attr\n\nf"
},
{
"path": "appstoreserverlibrary/models/AbstractAdvancedCommerceItem.py",
"chars": 860,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nimport attr\n\nfrom .AbstractAdvanced"
},
{
"path": "appstoreserverlibrary/models/AbstractAdvancedCommerceResponse.py",
"chars": 740,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom abc import ABC\nfrom typing import Optional\n\nfrom attr "
},
{
"path": "appstoreserverlibrary/models/AccountTenure.py",
"chars": 662,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceDescriptors.py",
"chars": 913,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nimport attr\n\nfrom .AdvancedCommerce"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceEffective.py",
"chars": 506,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceOffer.py",
"chars": 1480,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceOfferPeriod.py",
"chars": 495,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceOfferReason.py",
"chars": 438,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceOneTimeChargeCreateRequest.py",
"chars": 1634,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceOneTimeChargeItem.py",
"chars": 648,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nimport attr\n\nfrom .AbstractAdvanced"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommercePeriod.py",
"chars": 489,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceReason.py",
"chars": 504,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceRefundReason.py",
"chars": 665,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceRefundType.py",
"chars": 503,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceRequest.py",
"chars": 499,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom abc import ABC\n\nfrom attr import define\nimport attr\n\nf"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceRequestInfo.py",
"chars": 1103,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom att"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceRequestRefundItem.py",
"chars": 1622,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceRequestRefundRequest.py",
"chars": 1309,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\n\nfrom attr import define\n"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceRequestRefundResponse.py",
"chars": 527,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom .AbstractAdvancedCommerceResponse import AbstractAdvan"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionCancelRequest.py",
"chars": 605,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionCancelResponse.py",
"chars": 446,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\n\nfrom .AbstractAdvancedCommerceResp"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataDescriptors.py",
"chars": 1604,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataItem.py",
"chars": 1911,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataRequest.py",
"chars": 1598,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\n\nfrom attr import define\n"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionChangeMetadataResponse.py",
"chars": 603,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom .AbstractAdvancedCommerceResponse import AbstractAdvan"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionCreateItem.py",
"chars": 765,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nimport attr\nfrom attr import de"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionCreateRequest.py",
"chars": 2127,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\nimport attr\nfrom attr imp"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateDescriptors.py",
"chars": 448,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom .AdvancedCommerceDescriptors i"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateItem.py",
"chars": 437,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom .AbstractAdvancedCommerceItem "
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateRenewalItem.py",
"chars": 461,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom .AbstractAdvancedCommerceItem "
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateRequest.py",
"chars": 2403,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\nimport attr\nfrom attr imp"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionMigrateResponse.py",
"chars": 701,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom .AbstractAdvancedCommerceRespo"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyAddItem.py",
"chars": 1039,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nimport attr\nfrom attr import de"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyChangeItem.py",
"chars": 1911,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nimport attr\nfrom attr import de"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyDescriptors.py",
"chars": 1387,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nimport attr\nfrom attr import de"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyInAppRequest.py",
"chars": 3240,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\nimport attr\nfrom attr imp"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyPeriodChange.py",
"chars": 1211,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nimport attr\nfrom attr import define\nfrom .AdvancedCommerceE"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionModifyRemoveItem.py",
"chars": 461,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom .AbstractAdvancedCommerceBaseI"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionPriceChangeItem.py",
"chars": 929,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nimport attr\nfrom attr import define\nfrom typing import List"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionPriceChangeRequest.py",
"chars": 1231,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\nimport attr\nfrom attr imp"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionPriceChangeResponse.py",
"chars": 687,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom .AbstractAdvancedCommerceRespo"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionReactivateInAppRequest.py",
"chars": 1396,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom __future__ import annotations\nfrom typing import List,"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionReactivateItem.py",
"chars": 438,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom appstoreserverlibrary.models.A"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionRevokeRequest.py",
"chars": 1638,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom __future__ import annotations\nfrom typing import Optio"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceSubscriptionRevokeResponse.py",
"chars": 646,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom appstoreserverlibrary.models.A"
},
{
"path": "appstoreserverlibrary/models/AdvancedCommerceValidationUtils.py",
"chars": 3516,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import TypeVar\n\nT = TypeVar('T')\n\n\nclass Advanc"
},
{
"path": "appstoreserverlibrary/models/AlternateProduct.py",
"chars": 903,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom attr"
},
{
"path": "appstoreserverlibrary/models/AppData.py",
"chars": 1528,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/AppTransaction.py",
"chars": 3933,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/AppTransactionInfoResponse.py",
"chars": 634,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/AutoRenewStatus.py",
"chars": 402,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/BulletPoint.py",
"chars": 981,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom uuid import UUID\n\nfrom attr import define\nimport attr\n"
},
{
"path": "appstoreserverlibrary/models/CheckTestNotificationResponse.py",
"chars": 1129,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import List, Optional\n\nfrom attr import define\ni"
},
{
"path": "appstoreserverlibrary/models/ConsumptionRequest.py",
"chars": 2212,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/ConsumptionRequestReason.py",
"chars": 594,
"preview": "# Copyright (c) 2024 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/ConsumptionRequestV1.py",
"chars": 5589,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/ConsumptionStatus.py",
"chars": 504,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/Data.py",
"chars": 2930,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/DecodedRealtimeRequestBody.py",
"chars": 2066,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom att"
},
{
"path": "appstoreserverlibrary/models/DefaultConfigurationRequest.py",
"chars": 681,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom att"
},
{
"path": "appstoreserverlibrary/models/DefaultConfigurationResponse.py",
"chars": 573,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom uuid import UUID\n\nfrom attr import define\nimport attr\n"
},
{
"path": "appstoreserverlibrary/models/DeliveryStatus.py",
"chars": 665,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/DeliveryStatusV1.py",
"chars": 744,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/Environment.py",
"chars": 502,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/ExpirationIntent.py",
"chars": 521,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/ExtendReasonCode.py",
"chars": 502,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/ExtendRenewalDateRequest.py",
"chars": 1173,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/ExtendRenewalDateResponse.py",
"chars": 1350,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/ExternalPurchaseToken.py",
"chars": 1376,
"preview": "# Copyright (c) 2024 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/FirstSendAttemptResult.py",
"chars": 892,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum, unique\n\nfrom .LibraryUtility import "
},
{
"path": "appstoreserverlibrary/models/GetImageListResponse.py",
"chars": 656,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\n\nfrom attr import define\n"
},
{
"path": "appstoreserverlibrary/models/GetImageListResponseItem.py",
"chars": 1317,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom att"
},
{
"path": "appstoreserverlibrary/models/GetMessageListResponse.py",
"chars": 676,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, List\n\nfrom attr import define\n"
},
{
"path": "appstoreserverlibrary/models/GetMessageListResponseItem.py",
"chars": 1013,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom att"
},
{
"path": "appstoreserverlibrary/models/HeaderPosition.py",
"chars": 437,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/HistoryResponse.py",
"chars": 1980,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom typing import List, Optional\ni"
},
{
"path": "appstoreserverlibrary/models/ImageSize.py",
"chars": 392,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/ImageState.py",
"chars": 418,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/InAppOwnershipType.py",
"chars": 481,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/JWSRenewalInfoDecodedPayload.py",
"chars": 6889,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import List, Optional\n\nfrom attr import define\ni"
},
{
"path": "appstoreserverlibrary/models/JWSTransactionDecodedPayload.py",
"chars": 9418,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/LastTransactionsItem.py",
"chars": 1552,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/LibraryUtility.py",
"chars": 5153,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import EnumMeta\nfrom functools import lru_cache\nf"
},
{
"path": "appstoreserverlibrary/models/LifetimeDollarsPurchased.py",
"chars": 949,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/LifetimeDollarsRefunded.py",
"chars": 960,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/MassExtendRenewalDateRequest.py",
"chars": 1748,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom typing import List, Optional\ni"
},
{
"path": "appstoreserverlibrary/models/MassExtendRenewalDateResponse.py",
"chars": 681,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/MassExtendRenewalDateStatusResponse.py",
"chars": 1793,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/Message.py",
"chars": 587,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom attr"
},
{
"path": "appstoreserverlibrary/models/MessageState.py",
"chars": 425,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/NotificationHistoryRequest.py",
"chars": 2907,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/NotificationHistoryResponse.py",
"chars": 1230,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional, List\n\nfrom attr import define\ni"
},
{
"path": "appstoreserverlibrary/models/NotificationHistoryResponseItem.py",
"chars": 1131,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional, List\n\nfrom attr import define\ni"
},
{
"path": "appstoreserverlibrary/models/NotificationTypeV2.py",
"chars": 1246,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/OfferDiscountType.py",
"chars": 513,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/OfferType.py",
"chars": 426,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/OrderLookupResponse.py",
"chars": 1164,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom typing import List, Optional\ni"
},
{
"path": "appstoreserverlibrary/models/OrderLookupStatus.py",
"chars": 440,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/PerformanceTestConfig.py",
"chars": 1498,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/PerformanceTestRequest.py",
"chars": 638,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nimport attr\n\n@define\nclass Performa"
},
{
"path": "appstoreserverlibrary/models/PerformanceTestResponse.py",
"chars": 783,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/PerformanceTestResponseTimes.py",
"chars": 1273,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/PerformanceTestResultResponse.py",
"chars": 3652,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Dict, Optional\n\nfrom attr import define,"
},
{
"path": "appstoreserverlibrary/models/PerformanceTestStatus.py",
"chars": 428,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/Platform.py",
"chars": 426,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/PlayTime.py",
"chars": 615,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/PriceIncreaseStatus.py",
"chars": 531,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/PromotionalOffer.py",
"chars": 1209,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom att"
},
{
"path": "appstoreserverlibrary/models/PromotionalOfferSignatureV1.py",
"chars": 1354,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom att"
},
{
"path": "appstoreserverlibrary/models/PurchasePlatform.py",
"chars": 439,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/RealtimeRequestBody.py",
"chars": 588,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional, Dict\n\nfrom attr import define\n"
},
{
"path": "appstoreserverlibrary/models/RealtimeResponseBody.py",
"chars": 1178,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/RealtimeUrlRequest.py",
"chars": 577,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nimport attr\n\n@define\nclass Realtime"
},
{
"path": "appstoreserverlibrary/models/RealtimeUrlResponse.py",
"chars": 576,
"preview": "# Copyright (c) 2026 Apple Inc. Licensed under MIT License.\n\nfrom typing import Optional\n\nfrom attr import define\nimport"
},
{
"path": "appstoreserverlibrary/models/RefundHistoryResponse.py",
"chars": 1209,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom typing import List, Optional\ni"
},
{
"path": "appstoreserverlibrary/models/RefundPreference.py",
"chars": 531,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/RefundPreferenceV1.py",
"chars": 549,
"preview": "# Copyright (c) 2024 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/ResponseBodyV2.py",
"chars": 647,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/ResponseBodyV2DecodedPayload.py",
"chars": 3742,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/RevocationReason.py",
"chars": 429,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/RevocationType.py",
"chars": 505,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/SendAttemptItem.py",
"chars": 1240,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/SendAttemptResult.py",
"chars": 875,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/SendTestNotificationResponse.py",
"chars": 612,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/Status.py",
"chars": 450,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/StatusResponse.py",
"chars": 1723,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional, List\n\nfrom attr import define\ni"
},
{
"path": "appstoreserverlibrary/models/SubscriptionGroupIdentifierItem.py",
"chars": 1140,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional, List\n\nfrom attr import define\ni"
},
{
"path": "appstoreserverlibrary/models/Subtype.py",
"chars": 960,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\n\nfrom .LibraryUtility import AppStore"
},
{
"path": "appstoreserverlibrary/models/Summary.py",
"chars": 2568,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom attr import define\nfrom typing import List, Optional\ni"
},
{
"path": "appstoreserverlibrary/models/TransactionHistoryRequest.py",
"chars": 3137,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\nfrom typing import List, Optional\nimp"
},
{
"path": "appstoreserverlibrary/models/TransactionInfoResponse.py",
"chars": 629,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\nfrom typing import Optional\n\nfrom attr import define\nimport "
},
{
"path": "appstoreserverlibrary/models/TransactionReason.py",
"chars": 539,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\nfrom .LibraryUtility import AppStoreS"
},
{
"path": "appstoreserverlibrary/models/Type.py",
"chars": 555,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import Enum\nfrom .LibraryUtility import AppStoreS"
},
{
"path": "appstoreserverlibrary/models/UpdateAppAccountTokenRequest.py",
"chars": 573,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\nfrom attr import define\nimport attr\n\n@define\nclass UpdateApp"
},
{
"path": "appstoreserverlibrary/models/UploadMessageImage.py",
"chars": 714,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom uuid import UUID\n\nfrom attr import define\nimport attr\n"
},
{
"path": "appstoreserverlibrary/models/UploadMessageRequestBody.py",
"chars": 2027,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\nfrom typing import List, Optional\n\nfrom attr import define\n"
},
{
"path": "appstoreserverlibrary/models/UserStatus.py",
"chars": 460,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom enum import IntEnum\n\nfrom .LibraryUtility import AppSt"
},
{
"path": "appstoreserverlibrary/models/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "appstoreserverlibrary/promotional_offer.py",
"chars": 2123,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom cryptography.hazmat.primitives import serialization\nfr"
},
{
"path": "appstoreserverlibrary/py.typed",
"chars": 0,
"preview": ""
},
{
"path": "appstoreserverlibrary/receipt_utility.py",
"chars": 3121,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom base64 import b64decode\nfrom typing import Optional\n\ni"
},
{
"path": "appstoreserverlibrary/signed_data_verifier.py",
"chars": 20776,
"preview": "# Copyright (c) 2023 Apple Inc. Licensed under MIT License.\n\nfrom typing import List, Optional, Dict\nfrom base64 import "
},
{
"path": "docs/requirements.txt",
"chars": 15,
"preview": "sphinx == 9.1.0"
},
{
"path": "pyproject.toml",
"chars": 810,
"preview": "# Copyright (c) 2025 Apple Inc. Licensed under MIT License.\n\n[build-system]\nrequires = [\"setuptools>=61.0\", \"wheel\"]\nbui"
},
{
"path": "requirements.txt",
"chars": 146,
"preview": "attrs >= 21.3.0\nPyJWT >= 2.6.0, < 3\nrequests >= 2.28.0, < 3\ncryptography >= 40.0.0\npyOpenSSL >= 23.1.1\nasn1==3.2.0\ncattr"
},
{
"path": "tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tests/resources/certs/testSigningKey.p8",
"chars": 241,
"preview": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgSpP55ELdXswj9JRZ\nAPRwtTfS4CNRqpKIs+28rNHiPAq"
},
{
"path": "tests/resources/mock_signed_data/legacyTransaction",
"chars": 100,
"preview": "ewoicHVyY2hhc2UtaW5mbyIgPSAiZXdvaWRISmhibk5oWTNScGIyNHRhV1FpSUQwZ0lqTXpPVGt6TXprNUlqc0tmUW89IjsKfQo="
},
{
"path": "tests/resources/mock_signed_data/missingX5CHeaderClaim",
"chars": 2499,
"preview": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsIng1Y3dyb25nIjpbIk1JSUJvRENDQVVhZ0F3SUJBZ0lCRERBS0JnZ3Foa2pPUFFRREF6QkZNUXN3Q1FZRFZR"
},
{
"path": "tests/resources/mock_signed_data/renewalInfo",
"chars": 2404,
"preview": "eyJ4NWMiOlsiTUlJQm9EQ0NBVWFnQXdJQkFnSUJEREFLQmdncWhrak9QUVFEQXpCRk1Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQXdDUTBFeEVqQVFC"
},
{
"path": "tests/resources/mock_signed_data/testNotification",
"chars": 2505,
"preview": "eyJ4NWMiOlsiTUlJQm9EQ0NBVWFnQXdJQkFnSUJDekFLQmdncWhrak9QUVFEQWpCTk1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQXdLUTJGc2FXWnZj"
},
{
"path": "tests/resources/mock_signed_data/transactionInfo",
"chars": 2357,
"preview": "eyJ4NWMiOlsiTUlJQm9EQ0NBVWFnQXdJQkFnSUJDekFLQmdncWhrak9QUVFEQWpCTk1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQXdLUTJGc2FXWnZj"
},
{
"path": "tests/resources/mock_signed_data/wrongBundleId",
"chars": 2501,
"preview": "eyJ4NWMiOlsiTUlJQm9EQ0NBVWFnQXdJQkFnSUJEREFLQmdncWhrak9QUVFEQXpCRk1Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQXdDUTBFeEVqQVFC"
},
{
"path": "tests/resources/models/advancedCommerceDescriptors.json",
"chars": 68,
"preview": "{\n \"description\": \"description\",\n \"displayName\": \"display name\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceOffer.json",
"chars": 83,
"preview": "{\n \"period\": \"P1W\",\n \"periodCount\": 3,\n \"price\": 5000,\n \"reason\": \"WIN_BACK\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceOneTimeChargeCreateRequest.json",
"chars": 328,
"preview": "{\n \"currency\": \"USD\",\n \"item\": {\n \"description\": \"description\",\n \"displayName\": \"display name\",\n \"SKU\": \"sku\""
},
{
"path": "tests/resources/models/advancedCommerceOneTimeChargeItem.json",
"chars": 102,
"preview": "{\n \"description\": \"description\",\n \"displayName\": \"display name\",\n \"SKU\": \"sku\",\n \"price\": 15000\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceRequestInfo.json",
"chars": 177,
"preview": "{\n \"requestReferenceId\": \"550e8400-e29b-41d4-a716-446655440010\",\n \"appAccountToken\": \"660e8400-e29b-41d4-a716-44665544"
},
{
"path": "tests/resources/models/advancedCommerceRequestRefundItem.json",
"chars": 112,
"preview": "{\n \"SKU\": \"sku\",\n \"refundReason\": \"LEGAL\",\n \"refundType\": \"FULL\",\n \"revoke\": true,\n \"refundAmount\": 5000\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceRequestRefundRequest.json",
"chars": 419,
"preview": "{\n \"items\": [\n {\n \"SKU\": \"sku\",\n \"refundReason\": \"LEGAL\",\n \"refundType\": \"FULL\",\n \"revoke\": true"
},
{
"path": "tests/resources/models/advancedCommerceRequestRefundResponse.json",
"chars": 63,
"preview": "{\n \"signedTransactionInfo\": \"signed_transaction_info_value\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionCancelRequest.json",
"chars": 115,
"preview": "{\n \"requestInfo\": {\n \"requestReferenceId\": \"550e8400-e29b-41d4-a716-446655440003\"\n },\n \"storefront\": \"USA\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionCancelResponse.json",
"chars": 103,
"preview": "{\n \"signedRenewalInfo\": \"signed_renewal_info\",\n \"signedTransactionInfo\": \"signed_transaction_info\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionChangeMetadataDescriptors.json",
"chars": 97,
"preview": "{\n \"effective\": \"IMMEDIATELY\",\n \"description\": \"description\",\n \"displayName\": \"displayName\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionChangeMetadataItem.json",
"chars": 147,
"preview": "{\n \"currentSKU\": \"currentSku\",\n \"effective\": \"NEXT_BILL_CYCLE\",\n \"description\": \"description\",\n \"displayName\": \"disp"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionChangeMetadataRequest.json",
"chars": 282,
"preview": "{\n \"requestInfo\": {\n \"requestReferenceId\": \"550e8400-e29b-41d4-a716-446655440009\"\n },\n \"items\": [\n {\n \"cur"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionChangeMetadataResponse.json",
"chars": 103,
"preview": "{\n \"signedRenewalInfo\": \"signed_renewal_info\",\n \"signedTransactionInfo\": \"signed_transaction_info\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionCreateItem.json",
"chars": 102,
"preview": "{\n \"description\": \"description\",\n \"displayName\": \"display name\",\n \"SKU\": \"sku\",\n \"price\": 20000\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionCreateRequest.json",
"chars": 586,
"preview": "{\n \"currency\": \"USD\",\n \"descriptors\": {\n \"description\": \"description\",\n \"displayName\": \"display name\"\n },\n \"it"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionMigrateDescriptors.json",
"chars": 67,
"preview": "{\n \"description\": \"description\",\n \"displayName\": \"displayName\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionMigrateItem.json",
"chars": 83,
"preview": "{\n \"SKU\": \"sku\",\n \"description\": \"description\",\n \"displayName\": \"displayName\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionMigrateRenewalItem.json",
"chars": 83,
"preview": "{\n \"SKU\": \"sku\",\n \"description\": \"description\",\n \"displayName\": \"displayName\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionMigrateRequest.json",
"chars": 370,
"preview": "{\n \"requestInfo\": {\n \"requestReferenceId\": \"550e8400-e29b-41d4-a716-446655440006\"\n },\n \"descriptors\": {\n \"descr"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionMigrateResponse.json",
"chars": 115,
"preview": "{\n \"signedRenewalInfo\": \"signed_renewal_info_value\",\n \"signedTransactionInfo\": \"signed_transaction_info_value\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionModifyAddItem.json",
"chars": 101,
"preview": "{\n \"SKU\": \"sku\",\n \"description\": \"description\",\n \"displayName\": \"displayName\",\n \"price\": 12000\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionModifyChangeItem.json",
"chars": 184,
"preview": "{\n \"currentSKU\": \"currentSku\",\n \"description\": \"description\",\n \"displayName\": \"displayName\",\n \"effective\": \"IMMEDIAT"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionModifyDescriptors.json",
"chars": 97,
"preview": "{\n \"effective\": \"IMMEDIATELY\",\n \"description\": \"description\",\n \"displayName\": \"displayName\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionModifyInAppRequest.json",
"chars": 327,
"preview": "{\n \"requestInfo\": {\n \"requestReferenceId\": \"550e8400-e29b-41d4-a716-446655440007\"\n },\n \"transactionId\": \"transacti"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionModifyPeriodChange.json",
"chars": 52,
"preview": "{\n \"effective\": \"IMMEDIATELY\",\n \"period\": \"P3M\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionModifyRemoveItem.json",
"chars": 19,
"preview": "{\n \"SKU\": \"sku\"\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionPriceChangeItem.json",
"chars": 74,
"preview": "{\n \"SKU\": \"sku\",\n \"price\": 16000,\n \"dependentSKUs\": [\"dependentSKU\"]\n}\n"
},
{
"path": "tests/resources/models/advancedCommerceSubscriptionPriceChangeRequest.json",
"chars": 187,
"preview": "{\n \"requestInfo\": {\n \"requestReferenceId\": \"550e8400-e29b-41d4-a716-446655440005\"\n },\n \"items\": [\n {\n \"SKU"
}
]
// ... and 65 more files (download for full content)
About this extraction
This page contains the full source code of the apple/app-store-server-library-python GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 265 files (589.5 KB), approximately 146.9k tokens, and a symbol index with 498 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.