In-app purchase validation library for Apple AppStore and GooglePlay.
Project description
InAppPy
In-app purchase validation library for Apple AppStore and GooglePlay.
Installation
pip install inapppy
Usage
Currently inapppy supports Google Play and App Store receipts validation.
Google Play (validates receipt against provided signature using RSA):
from inapppy import GooglePlayValidator, InAppPyValidationError
bundle_id = 'com.yourcompany.yourapp'
api_key = 'API key from the developer console'
validator = GooglePlayValidator(bundle_id, api_key)
try:
# receipt means `androidData` in result of purchase
# signature means `signatureAndroid` in result of purchase
validation_result = validator.validate('receipt', 'signature')
except InAppPyValidationError:
# handle validation error
pass
Google Play verification:
from inapppy import GooglePlayVerifier, errors
def google_validator(receipt):
"""
Accepts receipt, validates in Google.
"""
purchase_token = receipt['purchaseToken']
product_sku = receipt['productId']
verifier = GooglePlayVerifier(
GOOGLE_BUNDLE_ID,
GOOGLE_SERVICE_ACCOUNT_KEY_FILE,
)
response = {'valid': False, 'transactions': []}
try:
result = verifier.verify(
purchase_token,
product_sku
)
response['valid'] = True
response['transactions'].append(
(result['orderId'], product_sku)
)
except errors.GoogleError as exc:
logging.error('Purchase validation failed {}'.format(exc))
return response
App Store Response (validation_result / raw_response) Sample:
{
"latest_receipt": "MIIbngYJKoZIhvcNAQcCoIIbj...",
"status": 0,
"receipt": {
"download_id": 0,
"receipt_creation_date_ms": "1486371475000",
"application_version": "2",
"app_item_id": 0,
"receipt_creation_date": "2017-02-06 08:57:55 Etc/GMT",
"original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
"request_date_pst": "2017-02-06 04:41:09 America/Los_Angeles",
"original_application_version": "1.0",
"original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",
"request_date_ms": "1486384869996",
"bundle_id": "com.yourcompany.yourapp",
"request_date": "2017-02-06 12:41:09 Etc/GMT",
"original_purchase_date_ms": "1375340400000",
"in_app": [{
"purchase_date_ms": "1486371474000",
"web_order_line_item_id": "1000000034281189",
"original_purchase_date_ms": "1486371475000",
"original_purchase_date": "2017-02-06 08:57:55 Etc/GMT",
"expires_date_pst": "2017-02-06 01:00:54 America/Los_Angeles",
"original_purchase_date_pst": "2017-02-06 00:57:55 America/Los_Angeles",
"purchase_date_pst": "2017-02-06 00:57:54 America/Los_Angeles",
"expires_date_ms": "1486371654000",
"expires_date": "2017-02-06 09:00:54 Etc/GMT",
"original_transaction_id": "1000000271014363",
"purchase_date": "2017-02-06 08:57:54 Etc/GMT",
"quantity": "1",
"is_trial_period": "false",
"product_id": "com.yourcompany.yourapp",
"transaction_id": "1000000271014363"
}],
"version_external_identifier": 0,
"receipt_creation_date_pst": "2017-02-06 00:57:55 America/Los_Angeles",
"adam_id": 0,
"receipt_type": "ProductionSandbox"
},
"latest_receipt_info": [{
"purchase_date_ms": "1486371474000",
"web_order_line_item_id": "1000000034281189",
"original_purchase_date_ms": "1486371475000",
"original_purchase_date": "2017-02-06 08:57:55 Etc/GMT",
"expires_date_pst": "2017-02-06 01:00:54 America/Los_Angeles",
"original_purchase_date_pst": "2017-02-06 00:57:55 America/Los_Angeles",
"purchase_date_pst": "2017-02-06 00:57:54 America/Los_Angeles",
"expires_date_ms": "1486371654000",
"expires_date": "2017-02-06 09:00:54 Etc/GMT",
"original_transaction_id": "1000000271014363",
"purchase_date": "2017-02-06 08:57:54 Etc/GMT",
"quantity": "1",
"is_trial_period": "true",
"product_id": "com.yourcompany.yourapp",
"transaction_id": "1000000271014363"
}, {
"purchase_date_ms": "1486371719000",
"web_order_line_item_id": "1000000034281190",
"original_purchase_date_ms": "1486371720000",
"original_purchase_date": "2017-02-06 09:02:00 Etc/GMT",
"expires_date_pst": "2017-02-06 01:06:59 America/Los_Angeles",
"original_purchase_date_pst": "2017-02-06 01:02:00 America/Los_Angeles",
"purchase_date_pst": "2017-02-06 01:01:59 America/Los_Angeles",
"expires_date_ms": "1486372019000",
"expires_date": "2017-02-06 09:06:59 Etc/GMT",
"original_transaction_id": "1000000271014363",
"purchase_date": "2017-02-06 09:01:59 Etc/GMT",
"quantity": "1",
"is_trial_period": "false",
"product_id": "com.yourcompany.yourapp",
"transaction_id": "1000000271016119"
}],
"environment": "Sandbox"
}
App Store, asyncio version (available in the inapppy.asyncio package)
from inapppy import InAppPyValidationError
from inapppy.asyncio import AppStoreValidator
bundle_id = 'com.yourcompany.yourapp'
auto_retry_wrong_env_request=False # if True, automatically query sandbox endpoint if
# validation fails on production endpoint
validator = AppStoreValidator(bundle_id, auto_retry_wrong_env_request=auto_retry_wrong_env_request)
try:
exclude_old_transactions=False # if True, include only the latest renewal transaction
validation_result = await validator.validate('receipt', 'optional-shared-secret', exclude_old_transactions=exclude_old_transactions)
except InAppPyValidationError as ex:
# handle validation error
response_from_apple = ex.raw_response # contains actual response from AppStore service.
pass
Development
# setup project
make setup
# check for lint errors
make lint
# run tests
make test
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
inapppy-2.2.tar.gz
(11.0 kB
view hashes)
Built Distribution
inapppy-2.2-py3-none-any.whl
(8.4 kB
view hashes)