All Projects → dotpot → Inapppy

dotpot / Inapppy

Licence: mit
Python In-app purchase validator for Apple AppStore and GooglePlay.

Programming Languages

python
139335 projects - #7 most used programming language
python3
1442 projects

Projects that are alternatives of or similar to Inapppy

Aiohttp Apispec
Build and document REST APIs with aiohttp and apispec
Stars: ✭ 172 (+56.36%)
Mutual labels:  asyncio, validation
Easyvalidation
✔️ A text and input validation library in Kotlin for Android
Stars: ✭ 328 (+198.18%)
Mutual labels:  validation, library
Paco
Small utility library for coroutine-driven asynchronous generic programming in Python 3.4+
Stars: ✭ 198 (+80%)
Mutual labels:  asyncio, library
Php Validate
Lightweight and feature-rich PHP validation and filtering library. Support scene grouping, pre-filtering, array checking, custom validators, custom messages. 轻量且功能丰富的PHP验证、过滤库。支持场景分组,前置过滤,数组检查,自定义验证器,自定义消息。
Stars: ✭ 225 (+104.55%)
Mutual labels:  validation, library
In App Purchase
A Node.js module for in-App-Purchase for iOS, Android, Amazon and Windows.
Stars: ✭ 868 (+689.09%)
Mutual labels:  validation, purchase
Svelte Forms Lib
📝. A lightweight library for managing forms in Svelte
Stars: ✭ 238 (+116.36%)
Mutual labels:  validation, library
Inapppurchase
A Simple and Lightweight framework for In App Purchase
Stars: ✭ 202 (+83.64%)
Mutual labels:  appstore, purchase
Androidrate
AndroidRate is a library to help you promote your Android app by prompting users to rate the app after using it for a few days.
Stars: ✭ 117 (+6.36%)
Mutual labels:  appstore, library
Accord
Accord: A sane validation library for Scala
Stars: ✭ 519 (+371.82%)
Mutual labels:  validation, library
Bunny
BunnyJS - Lightweight native (vanilla) JavaScript (JS) and ECMAScript 6 (ES6) browser library, package of small stand-alone components without dependencies: FormData, upload, image preview, HTML5 validation, Autocomplete, Dropdown, Calendar, Datepicker, Ajax, Datatable, Pagination, URL, Template engine, Element positioning, smooth scrolling, routing, inversion of control and more. Simple syntax and architecture. Next generation jQuery and front-end framework. Documentation and examples available.
Stars: ✭ 473 (+330%)
Mutual labels:  validation, library
Validatetor
Android library for fast and simple string validation
Stars: ✭ 136 (+23.64%)
Mutual labels:  validation, library
Aiodine
🧪 Async-first Python dependency injection library
Stars: ✭ 51 (-53.64%)
Mutual labels:  asyncio, library
Ratifier
Ratifier is a form validation library for Android.
Stars: ✭ 123 (+11.82%)
Mutual labels:  validation, library
Netius
Readable, simple and fast asynchronous non-blocking network apps
Stars: ✭ 114 (+3.64%)
Mutual labels:  asyncio, library
V8n
☑️ JavaScript fluent validation library
Stars: ✭ 3,858 (+3407.27%)
Mutual labels:  validation, library
Restless
Express.js api, type safe validations and more
Stars: ✭ 32 (-70.91%)
Mutual labels:  validation, library
Lcformvalidation
Javascript based form validation library, third party library / framework agnostic.
Stars: ✭ 58 (-47.27%)
Mutual labels:  validation, library
Xseries
Library for cross-version Minecraft Bukkit support and various efficient API methods.
Stars: ✭ 109 (-0.91%)
Mutual labels:  library
Yaep
Yet Another Earley Parser
Stars: ✭ 110 (+0%)
Mutual labels:  library
Maz Ui
Stand-alone components library to build your interfaces with Vue.JS & Nuxt.JS
Stars: ✭ 109 (-0.91%)
Mutual labels:  library

InAppPy

|travis| |pypi| |downloads|

.. |travis| image:: https://travis-ci.org/dotpot/InAppPy.svg?branch=master :target: https://travis-ci.org/dotpot/InAppPy .. |pypi| image:: https://badge.fury.io/py/inapppy.svg :target: https://badge.fury.io/py/inapppy .. |downloads| image:: https://img.shields.io/pypi/dm/inapppy.svg :target: https://pypi.python.org/pypi/inapppy

Table of contents

  1. Introduction

  2. Installation

  3. Google Play (receipt + signature)

  4. Google Play (verification)

  5. Google Play (verification with result)

  6. App Store (receipt + using optional shared-secret)

  7. App Store Response (validation_result / raw_response) example

  8. App Store, asyncio version (available in the inapppy.asyncio package)

  9. Development

  10. Donate

  11. Introduction ===============

In-app purchase validation library for Apple AppStore and GooglePlay (App Store validator have async support!). Works on python3.6+

  1. Installation =============== ::

    pip install inapppy

  2. Google Play (validates receipt against provided signature using RSA) =========================================================================== .. code:: python

    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

An additional example showing how to authenticate using dict credentials instead of loading from a file

.. code:: python

import json
from inapppy import GooglePlayValidator, InAppPyValidationError


bundle_id = 'com.yourcompany.yourapp'
# Avoid hard-coding credential data in your code. This is just an example. 
api_credentials = json.loads('{'
                             '   "type": "service_account",'
                             '   "project_id": "xxxxxxx",'
                             '   "private_key_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",'
                             '   "private_key": "-----BEGIN PRIVATE KEY-----\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==\n-----END PRIVATE KEY-----\n",'
                             '   "client_email": "[email protected]",'
                             '   "client_id": "XXXXXXXXXXXXXXXXXX",'
                             '   "auth_uri": "https://accounts.google.com/o/oauth2/auth",'
                             '   "token_uri": "https://oauth2.googleapis.com/token",'
                             '   "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",'
                             '   "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXXXXXXX.iam.gserviceaccount.com"'
                             ' }')
validator = GooglePlayValidator(bundle_id, api_credentials)

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
  1. Google Play verification =========================== .. code:: python

    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, is_subscription=True ) response['valid'] = True response['transactions'].append( (result['orderId'], product_sku) ) except errors.GoogleError as exc: logging.error('Purchase validation failed {}'.format(exc)) return response

  2. Google Play verification (with result) ========================================= Alternative to .verify method, instead of raising an error result class will be returned.

.. code:: python

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': []}

    result = verifier.verify_with_result(
        purchase_token,
        product_sku,
        is_subscription=True
    )

    # result contains data
    raw_response = result.raw_response
    is_canceled = result.is_canceled
    is_expired = result.is_expired

    return result
  1. App Store (validates receipt using optional shared-secret against iTunes service) ======================================================================================== .. code:: python

    from inapppy import AppStoreValidator, InAppPyValidationError

    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 = 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

  2. App Store Response (validation_result / raw_response) example ==================================================================== .. code:: json

    { "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" }

  3. App Store, asyncio version (available in the inapppy.asyncio package) ======================================================================== .. code:: python

    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

  4. Development ==============

.. code:: bash

# run checks and tests
tox

# setup project
make setup

# check for lint errors
make lint

# run tests
make test

# run black
make black
  1. Donate ========== You can support development of this project by buying me a coffee ;)

+------+--------------------------------------------+ | Coin | Wallet | +======+============================================+ | EUR | https://paypal.me/LukasSalkauskas | +------+--------------------------------------------+ | DOGE | DGjSG3T6g9h2k6iSku7mtKCynCpmwowpyN | +------+--------------------------------------------+ | BTC | 1LZAiWmLYzZae4hq3ai9hFYD3e3qcwjDsU | +------+--------------------------------------------+ | ETH | 0xD62245986345130edE10e4b545fF577Bd5BaE3E4 | +------+--------------------------------------------+

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].