Giter Club home page Giter Club logo

itunes-iap's Introduction

itunes-iap v2

Python 2 & 3 compatible! Even with asyncio support!

image

image

Quickstart

Create request to create a request to itunes verifying api.

python

>>> import itunesiap >>> try: >>> response = itunesiap.verify(raw_data) # base64-encoded data >>> except itunesiap.exc.InvalidReceipt as e: >>> print('invalid receipt') >>> print response.receipt.last_in_app.product_id # other values are also available as property!

The common attributes are:

product_id, original_transaction_id and quantity.

See the full document in:
  • itunesiap.verify: The verifying function.
  • itunesiap.receipt.Receipt: The receipt object.

asyncio

python

>>> import itunesiap >>> response = await itunesiap.aioverify(raw_data) # verify -> aioverify

The other parts are the same.

See the full document in:
  • itunesiap.aioverify: The verifying function.

Installation

PyPI is the recommended way.

shell

$ pip install itunes-iap

To browse versions and tarballs, visit:

https://pypi.python.org/pypi/itunes-iap/

Apple in-review mode

In review mode, your actual users who use older versions want to verify in production server but the reviewers in Apple office want to verify in sandbox server.

Note: The default env is production mode which doesn't allow any sandbox verifications.

You can change the verifying mode by specifying env.

python

>>> # review mode >>> itunesiap.verify(raw_data, env=itunesiap.env.review)

Note for v1 users

There was breaking changes between v1 and v2 APIs.

  • Specify version 0.6.6 for latest v1 API when you don't need new APIs.
  • Or use import itunesiap.legacy as itunesiap instead of import itunesiap. (from itunesiap import xxx to from itunesiap.legacy import xxx)

Contributors

See https://github.com/youknowone/itunes-iap/graphs/contributors

itunes-iap's People

Contributors

0xbepresent avatar brandon-clair avatar dahlia avatar davogler avatar djm avatar dlm avatar dreadatour avatar emmilco avatar ericvaladas avatar eturimike avatar gak avatar kmitrovic avatar marinampires avatar mihaibalint avatar miukal avatar mm-eturi avatar pirateandy avatar seleznev-nvkz avatar stephen-liu-storymotions avatar tbartelmess avatar yoloseem avatar youknowone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

itunes-iap's Issues

receipt.last_in_app is not the latest purchase

I'm not sure if this issue is an Apple problem or my my incorrect interpretation of how the receipt validation process works or a shortcoming of itunes-iap.

If I send a receipt to get validated and get back a response and then do a response.receipt.last_in_app I get the last purchase in the in_app array contained in the receipt. The problem is that this is not the latest purchase if the receipt hasn't been refreshed on the device. Since I'm handling subscriptions I will be periodically checking the receipt from the server and do not have the ability to refresh the receipt (at least I don't think I can).

The latest purchase information is however contained in 'latest_receipt_info' of the receipt and Pablo Rivera pointed out how to obtain this in his wiki post https://github.com/youknowone/itunes-iap/wiki/Getting-the-receipt-with-the-latest-expiration-date by doing response._.get('latest_receipt_info') you can get access to this information. However this is just the raw dictionary of the data and then I need to parse it manually which is all nicely done for the in_app part by itunes-iap.

So my question is, when validating a receipt, is there a way to always get the last purchase history in the in_app part or if not, could itunes-iap be changed in a way to more natively access 'last_receipt_info'? I've already worked around this but I'd like to know if I'm doing something wrong or there is an easier way to do this.

Installation of 2.5.0 fails on python2

After the update to 2.5.0 itunes-iap cannot be upgraded anymore on python versions <3.4.2.
pip2 install --upgrade itunes-iap tries to install aiohttp, which fails:

[...]
Collecting aiohttp (from itunes-iap)
  1 location(s) to search for versions of aiohttp:
  * https://pypi.python.org/simple/aiohttp/
  Getting page https://pypi.python.org/simple/aiohttp/
  Looking up "https://pypi.python.org/simple/aiohttp/" in the cache
  Current age based on date: 311
  Freshness lifetime from max-age: 600
  Freshness lifetime from request max-age: 600
  The response is "fresh", returning cached response
  600 > 311
  Analyzing links from page https://pypi.python.org/simple/aiohttp/
  [...]
  Using version 2.2.3 (newest of versions: 0.1, 0.2, 0.3, 0.4, 0.4.1, 0.4.2, 0.4.3, 0.4.4, 0.5.0, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.6.4, 0.6.5,$
  Looking up "https://pypi.python.org/packages/9b/3a/b560a411b97203fb20b5eee084c1e292862b3092029d9d9faaa8714797fa/aiohttp-2.2.3.tar.gz" in $
  Current age based on date: 108202
  Freshness lifetime from max-age: 31557600
  The response is "fresh", returning cached response
  31557600 > 108202
  Using cached aiohttp-2.2.3.tar.gz
  Downloading from URL https://pypi.python.org/packages/9b/3a/b560a411b97203fb20b5eee084c1e292862b3092029d9d9faaa8714797fa/aiohttp-2.2.3.ta$
  Running setup.py (path:/tmp/pip-build-DwBsrd/aiohttp/setup.py) egg_info for package aiohttp
    Running command python setup.py egg_info
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-DwBsrd/aiohttp/setup.py", line 66, in <module>
        raise RuntimeError("aiohttp requires Python 3.4.2+")
    RuntimeError: aiohttp requires Python 3.4.2+
Cleaning up...
Exception information:
Traceback (most recent call last):
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/commands/install.py", line 335, in run
    wb.build(autobuilding=True)
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/wheel.py", line 749, in build
    self.requirement_set.prepare_files(self.finder)
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/req/req_set.py", line 380, in prepare_files
    ignore_dependencies=self.ignore_dependencies))
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/req/req_set.py", line 634, in _prepare_file
    abstract_dist.prep_for_dist()
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/req/req_set.py", line 129, in prep_for_dist
    self.req_to_install.run_egg_info()
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/req/req_install.py", line 439, in run_egg_info
    command_desc='python setup.py egg_info')
  File "/home/prettyvanilla/.local/share/virtualenvs/bikemap/lib/python2.7/site-packages/pip/utils/__init__.py", line 707, in call_subproce$
    % (command_desc, proc.returncode, cwd))
InstallationError: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-DwBsrd/aiohttp/

Most likely the conditional in setup.py isn't working the way you'd expect when using wheels, instead environment markers seem to be the recommended way now: https://wheel.readthedocs.io/en/latest/#defining-conditional-dependencies

IndexError: list index out of range

Hello. We got this problem with itunes-iap 2.5

[2017-11-08 15:00:20,934] [ERROR] views.py:3308 - root: list index out of range
Traceback (most recent call last):
  File "/home/django/atcontrol/releases/1510061996/mayak/api_v3/views.py", line 3243, in purchase_ios
    log.info(res.receipt.last_in_app)
  File "/home/django/atcontrol/releases/1510061996/venv/local/lib/python2.7/site-packages/itunesiap/receipt.py", line 245, in last_in_app	
    self.in_app, key=lambda x: x['original_purchase_date_ms'])[-1]
IndexError: list index out of range

part of view from our django rest framework api with problem line of code

@api_view(['POST'])
def purchase_ios(request):
    log.info('purchase_ios (%s) POST: %s' % (request.user, request.POST))
    try:
        res = itunesiap.verify(request.POST.get("receipt", None), settings.ITUNES_PASSWORD, verify_ssl=False,
                               use_production=True, use_sandbox=True)
        log.info(res.receipt.last_in_app)
...

Any ideas what's wrong?

Error when receiving expiration_intent

I have noticed in the past week that when going through the sandbox renewal cycle (monthly, so 5 minutes chunks from Apple), everything is fine until the Apple sets expiration_intent to 1. For some reason, itunes-iap raises InvalidReceipt even though it is seemingly sufficient to process.

I invoke itunes-iap like so:

itunesiap.verify(receipt_data, app_secret, env=appstore_env)

Here is the distilled dict that is causing the InvalidReceipt exception:

{'auto_renew_status': 0, 
 'latest_expired_receipt_info': {'original_purchase_date_pst': '2018-04-30 14:43:08 America/Los_Angeles', 'unique_identifier': '44c0c23d0f2a77146f16f90604555450e619c210', 'original_transaction_id': '...', 'expires_date': '1526998664000', 'transaction_id': '...', 'quantity': '1', 'product_id': 'my.product', 'bvrs': '2', 'bid': 'my.app', 'unique_vendor_identifier': '...', 'web_order_line_item_id': '...', 'original_purchase_date_ms': '1525124588000', 'expires_date_formatted': '2018-05-22 14:17:44 Etc/GMT', 'purchase_date': '2018-05-22 14:12:44 Etc/GMT', 'is_in_intro_offer_period': 'false', 'purchase_date_ms': '1526998364000', 'expires_date_formatted_pst': '2018-05-22 07:17:44 America/Los_Angeles', 'is_trial_period': 'false', 'purchase_date_pst': '2018-05-22 07:12:44 America/Los_Angeles', 'original_purchase_date': '2018-04-30 21:43:08 Etc/GMT', 'item_id': '...'},
 'status': 21006, 
 'auto_renew_product_id': 'my.product', 
 'receipt': {'original_purchase_date_pst': '2018-04-30 14:43:08 America/Los_Angeles', 'quantity': '1', 'unique_vendor_identifier': '...', 'bvrs': '4', 'expires_date_formatted': '2018-05-22 13:52:44 Etc/GMT', 'is_in_intro_offer_period': 'false', 'purchase_date_ms': '1526996864000', 'expires_date_formatted_pst': '2018-05-22 06:52:44 America/Los_Angeles', 'is_trial_period': 'false', 'item_id': '...', 'unique_identifier': '...', 'original_transaction_id': '...', 'expires_date': '1526997164000', 'transaction_id': '...', 'web_order_line_item_id': '...', 'version_external_identifier': '0', 'bid': 'my.app', 'product_id': 'my.product', 'purchase_date': '2018-05-22 13:47:44 Etc/GMT', 'original_purchase_date': '2018-04-30 21:43:08 Etc/GMT', 'purchase_date_pst': '2018-05-22 06:47:44 America/Los_Angeles', 'original_purchase_date_ms': '1525124588000'}, 
 'expiration_intent': '1', 
 'is_in_billing_retry_period': '0'}

Has anyone else noticed this happening?

EDIT: formatting

MissingFieldError: expires_date_ms during validation on Server Notification reception

Important informations to reproduce:

  • itunes-iap==2.5.0 (latest available on pip)
  • using an auto-renewable subscription, with a server receiving Status Update Notifications (feature was added by Apple during July 2017)
  • the issue does NOT happen when first purchasing, but when the renewal happens and your server is called. For practical purpose, you only need to intercept the 'latest_receipt' or 'latest_expired_receipt' (whichever is present) part of the POSTed JSON and try to verify it manually.

I am at a loss if this issue is poor documentation by Apple or an actual bug with Apple API, but when trying to verify a receipt with those conditions, itunes-iap will throw "MissingFieldError: expires_date_ms". I sent a bug report to Apple, but have no idea if it will move the needle on their side.

In the meantime, it would be great if itunes-iap could handle this gracefully without waiting for Apple to acknowledge the issue and fix it.

Please find attached an anonymised status notification call and anonymised response of the API which exhibit the issue when trying to validate after that status notification.

You'll notice that the Status Notification doesn't have expires_date_ms either, so if itunes-iap want to support it at some point, it'll need to be able to work without that field.

apple-status-notification.txt
verify-result.txt

Here is the full unedited stacktrace:
17-09-27T15:08:20.564417+00:00 app[web.1]: ERROR [django.request:132] Internal Server Error: /api/apple_subscription_notif/
2017-09-27T15:08:20.564419+00:00 app[web.1]: Traceback (most recent call last):
2017-09-27T15:08:20.564420+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/itunesiap/receipt.py", line 141, in _get
2017-09-27T15:08:20.564421+00:00 app[web.1]: value = self.[name]
2017-09-27T15:08:20.564422+00:00 app[web.1]: KeyError: 'expires_date_ms'
2017-09-27T15:08:20.564423+00:00 app[web.1]:
2017-09-27T15:08:20.564423+00:00 app[web.1]: During handling of the above exception, another exception occurred:
2017-09-27T15:08:20.564424+00:00 app[web.1]:
2017-09-27T15:08:20.564425+00:00 app[web.1]: Traceback (most recent call last):
2017-09-27T15:08:20.564425+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/django/core/handlers/exception.py", line 42, in inner
2017-09-27T15:08:20.564426+00:00 app[web.1]: response = get_response(request)
2017-09-27T15:08:20.564427+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
2017-09-27T15:08:20.564428+00:00 app[web.1]: response = self.process_exception_by_middleware(e, request)
2017-09-27T15:08:20.564429+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
2017-09-27T15:08:20.564429+00:00 app[web.1]: response = wrapped_callback(request, *callback_args, **callback_kwargs)
2017-09-27T15:08:20.564430+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
2017-09-27T15:08:20.564431+00:00 app[web.1]: return view_func(*args, **kwargs)
2017-09-27T15:08:20.564431+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/tastypie/resources.py", line 219, in wrapper
2017-09-27T15:08:20.564432+00:00 app[web.1]: response = callback(request, *args, **kwargs)
2017-09-27T15:08:20.564433+00:00 app[web.1]: return self.dispatch('list', request, **kwargs)
2017-09-27T15:08:20.564433+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/tastypie/resources.py", line 450, in dispatch_list
2017-09-27T15:08:20.564434+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/tastypie/resources.py", line 482, in dispatch
2017-09-27T15:08:20.564434+00:00 app[web.1]: response = method(request, **kwargs)
2017-09-27T15:08:20.564435+00:00 app[web.1]: File "/app/licensing/api.py", line 828, in post_list
2017-09-27T15:08:20.564436+00:00 app[web.1]: notif = self.obj_create(bundle=basic_bundle, **self.remove_api_resource_names(kwargs))
2017-09-27T15:08:20.564436+00:00 app[web.1]: File "/app/licensing/api.py", line 804, in obj_create
2017-09-27T15:08:20.564437+00:00 app[web.1]: False
2017-09-27T15:08:20.564438+00:00 app[web.1]: File "/app/licensing/models.py", line 93, in authorize_purchase
2017-09-27T15:08:20.564439+00:00 app[web.1]: if (in_app.expires_date_ms is not None and
2017-09-27T15:08:20.564439+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/itunesiap/receipt.py", line 148, in getattr
2017-09-27T15:08:20.564440+00:00 app[web.1]: return self.getattribute(name)
2017-09-27T15:08:20.564440+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/itunesiap/tools.py", line 14, in get
2017-09-27T15:08:20.564441+00:00 app[web.1]: value = self.function(obj)
2017-09-27T15:08:20.564442+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/itunesiap/receipt.py", line 143, in _get
2017-09-27T15:08:20.564442+00:00 app[web.1]: raise MissingFieldError(name)
2017-09-27T15:08:20.564446+00:00 app[web.1]: itunesiap.receipt.MissingFieldError: expires_date_ms

IndexError: pop index out of range

I'm getting the following error when trying to validate in sandbox mode:

Internal Server Error: /api/validate/
Traceback (most recent call last):
  File "/Users/hanleyhansen/.virtualenvs/mkl/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/hanleyhansen/.virtualenvs/mkl/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/hanleyhansen/.virtualenvs/mkl/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/hanleyhansen/Google Drive/Work/Projects/git/mkl-web/mkl/views/api_views.py", line 99, in validate
    response = itunesiap.verify(receipt_data, IAP_SHARED_SECRET)
  File "/Users/hanleyhansen/.virtualenvs/mkl/lib/python2.7/site-packages/itunesiap/environment.py", line 39, in __exit__
    self._stack.pop(self._ctx_id)
IndexError: pop index out of range

Any ideas?

Here is my code:

    try:
        if IAP_SANDBOX:
            with itunesiap.env.sandbox:
                response = itunesiap.verify(receipt_data, IAP_SHARED_SECRET)
        else:
            with itunesiap.env.default:
                response = itunesiap.verify(receipt_data, IAP_SHARED_SECRET)
    except itunesiap.exc.InvalidReceipt as e:
        return HttpResponseForbidden({'message': 'not valid', 'error': e}, content_type='application/json')

'InvalidReceipt' object has no attribute 'kwargs' in 2.5.0

Hello. There's a problem with the string representation of the package exceptions. Not sure if the problem in the prettyexc dependency package.

The code below prints the string response=<Response({u'status': 21002})>,status=21002 in 2.4.1.

try:
    itunesiap.verify('bad data')
except itunesiap.exc.InvalidReceipt as e:
    print(e)

And raises AttributeError in 2.5.0:

AttributeError                            Traceback (most recent call last)
<ipython-input-18-c29f6377615f> in <module>()
      2     itunesiap.verify('bad data')
      3 except itunesiap.exc.InvalidReceipt as e:
----> 4     print(e)
      5 

/home/notex/.virtualenvs/antisocial/lib/python2.7/site-packages/prettyexc/core.pyc in __str__(self)
    121 
    122     def __str__(self):
--> 123         unistr = self.__unicode__()
    124         if PY3:
    125             return unistr

/home/notex/.virtualenvs/antisocial/lib/python2.7/site-packages/prettyexc/core.pyc in __unicode__(self)
    118 
    119     def __unicode__(self):
--> 120         return self.format(self.unicode_environment)
    121 
    122     def __str__(self):

/home/notex/.virtualenvs/antisocial/lib/python2.7/site-packages/prettyexc/core.pyc in format(self, env)
    105                 ss.append(args)
    106                 ss.append(u')')
--> 107         msg = self._message(env)
    108         if typ and msg:
    109             ss.append(u': ')

/home/notex/.virtualenvs/antisocial/lib/python2.7/site-packages/prettyexc/core.pyc in _message(self, env)
     87         if env.SHOW_MESSAGE is False:
     88             return ''
---> 89         msg = self.message
     90         if not self._show_message(msg):
     91             return ''

/home/notex/.virtualenvs/antisocial/lib/python2.7/site-packages/prettyexc/core.pyc in __getattr__(self, key)
    136             return sup.__getattr__(key)
    137         except:
--> 138             return sup.__getattribute__(key)
    139 
    140     def __getitem__(self, index):

/home/notex/.virtualenvs/antisocial/lib/python2.7/site-packages/prettyexc/core.pyc in message(self)
    153                 return text_type(self.args[0])
    154             argss = list(self.args)
--> 155             for kw, arg in self.kwargs.items():
    156                 argss.append('='.join((kw, text_type(arg))))
    157             if argss:

/home/notex/.virtualenvs/antisocial/lib/python2.7/site-packages/prettyexc/core.pyc in __getattr__(self, key)
    136             return sup.__getattr__(key)
    137         except:
--> 138             return sup.__getattribute__(key)
    139 
    140     def __getitem__(self, index):

AttributeError: 'InvalidReceipt' object has no attribute 'kwargs'

Any ideas?

Error install with python version 3.5.2

Getting this dependency error, going to do a manual workaround for now but thought I would let you know

Could not find a version that satisfies the requirement aiohttp>=3.0.1 (from itunes-iap) (from versions: 0.1, 0.2, 0.3, 0.4, 0.4.1, 0.4.2, 0.4.3, 0.4.4, 0.5.0, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.6.4, 0.6.5, 0.7.0, 0.7.1, 0.7.2, 0.7.3, 0.8.0, 0.8.1, 0.8.2, 0.8.3, 0.8.4, 0.9.0, 0.9.1, 0.9.2, 0.9.3, 0.10.0, 0.10.1, 0.10.2, 0.11.0, 0.12.0, 0.13.0, 0.13.1, 0.14.0, 0.14.1, 0.14.2, 0.14.3, 0.14.4, 0.15.0, 0.15.1, 0.15.2, 0.15.3, 0.16.0, 0.16.1, 0.16.2, 0.16.3, 0.16.4, 0.16.5, 0.16.6, 0.17.0, 0.17.1, 0.17.2, 0.17.3, 0.17.4, 0.18.0, 0.18.1, 0.18.2, 0.18.3, 0.18.4, 0.19.0, 0.20.0, 0.20.1, 0.20.2, 0.21.0, 0.21.1, 0.21.2, 0.21.4, 0.21.5, 0.21.6, 0.22.0a0, 0.22.0b0, 0.22.0b1, 0.22.0b2, 0.22.0b3, 0.22.0b4, 0.22.0b5, 0.22.0b6, 0.22.0, 0.22.1, 0.22.2, 0.22.3, 0.22.4, 0.22.5, 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.5, 1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.2.0, 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.3.5, 2.0.0rc1, 2.0.0, 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.6.post1, 2.0.7, 2.1.0, 2.2.0, 2.2.1, 2.2.2, 2.2.3, 2.2.4, 2.2.5, 2.3.0a1, 2.3.0a2, 2.3.0a4, 2.3.0, 2.3.1a1, 2.3.1, 2.3.2b2, 2.3.2b3, 2.3.2, 2.3.3, 2.3.4, 2.3.5, 2.3.6, 2.3.7, 2.3.8, 2.3.9, 2.3.10, 3.0.0b0)
No matching distribution found for aiohttp>=3.0.1 (from itunes-iap)

UnboundLocalError: local variable 'e' referenced before assignment

Hello everyone!

I have an 'UnboundLocalError' when I send an invalid receipt and put the 'sandbox' mode.

from itunesiap import Request, set_verification_mode
set_verification_mode('sandbox')
Request('').use_sandbox
True
request = Request('testinvalidreceipt')
request.verify()
{"password": "", "receipt-data": "testinvalidreceipt"}
Traceback (most recent call last):
File "", line 1, in
File "/home/myuser/envs/myenv/local/lib/python2.7/site-packages/itunesiap/core.py", line 98, in verify
raise e # raise original error
UnboundLocalError: local variable 'e' referenced before assignment

IndexError when exiting context manager

I'm experiencing a similar IndexError in one of my api views when using itunesiap.env.sandbox context manager:

# ...
if sandbox:
    with itunesiap.env.sandbox:
        try:
            response = itunesiap.verify(raw_data, use_sandbox=True)
            return True, response
        except (ItunesServerNotAvailable, ItunesServerNotReachable):
            no_response = True
        except itunesiap.exc.InvalidReceipt as exc:
            error = exc.description

Sentry actually indicates the error/exception being raised when exiting the contextmanager:

itunesiap/environment.py in __exit__ at line 42
        self._ctx_id = len(self._stack)
        self.push()
        return self
    def __exit__(self, exc_type, exc_value, tb):
        self._stack.pop(self._ctx_id)  # this line

Any clues on what might be happening?

Would there ever be a case to not use 'review' environment in production?

This is a question, not an issue but I don't have a way to mark it as such.

It appears when env.review is used a receipt will first be tried on the production environment and fall back to the sandbox which is what apple requires for the reviewers to test with. It would seem this would be needed in the production version of my app to make sure it passes review.

I can see where you'd want to use the sandbox env to speed up testing but when would you ever use production or default (which is the same)? That wouldn't pass review and you'd have to implement your own check for 21007 which is what you already are doing in the review env.

Please let me know if I'm missing something.

Requests POST "verify=False"

What is your reason to use the field "verify=False" on your request?
I use pretty much the same code to validate receipt (without this field), but recently I had several SSL errors (Bad handshake). I hope this field can help fix this.

Local Verification

Do you have any plans on adding local receipt verification? I mean we can use it to answer users fast, then in a batch process we could check the receipts with apple servers and detect fraud.

Bit of doco on auto_renew_status

I noticed (by a quick search of the repo) that you added some machinery around this new field Apple has added. Can you give an example of how to access it through your library's API?

recruiting maintainer

Hello,

I didn't develop iOS app with in-app purchase for very long time. I maintained this project depends on patches for a few more years, but it seems not very responsible.

Anyone who interested in this project contact me please.

Thanks

wrond status

Library works incorrect sometimes, when I sending request with receipt that was expired, library output status code: {'status': 21007}
But, when I make request using curl, then I see ..."status": 21006...

refunds

If the user refunds, is there any support

Example doesn't work as InvalidReceipt is not imported in itunesiap/__init__.py

As the title pretty much.

The line in question is incorrect in the current state:

>>> from itunesiap import Request, InvalidReceipt

Happy to make a pull request but I'm not sure whether you:

a) want to import that exception in the __init__.py
b) change the example to import from the correct location (exceptions.py).

Let me know, happy to do so.

Add parameter "timeout" for method "verify"

We are using this lib to verify ios orders on our servers constantly.
However, we found that the verification process sometimes got stuck.
We found code in itunes-iap as follows:
http_response = requests.post(url, post_body, verify=verify_ssl, proxies={protocol: self.proxy_url})

and description from docs of the lib "requests":
“By default, requests do not time out unless a timeout value is set explicitly”
http://docs.python-requests.org/en/master/user/advanced/#timeouts

That means, the verification process using itunesiap might got stuck because timeout is not set.

Aioverify error

response = await itunesiap.aioverify(receipt, env=itunesiap.env.review, password="xxx")

               ^
SyntaxError: 'await' outside function

How can I solve this error?

transactionReceipt depreciation

Now that transactionReceipt is depreceated at iOS7 what is your recommended way of getting receipt-data for a transaction?

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.