Exemple #1
0
    def post(self, request, *args, **kwargs):
        form = PrepareWebAppForm(request.DATA)
        if not form.is_valid():
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
        app = form.cleaned_data['app']

        region = getattr(request, 'REGION', None)
        if region and region.id not in app.get_price_region_ids():
            log.info('Region {0} is not in {1}'
                     .format(region.id, app.get_price_region_ids()))
            return Response('Payments are limited and flag not enabled',
                            status=status.HTTP_403_FORBIDDEN)

        if app.is_premium() and app.has_purchased(request._request.amo_user):
            log.info('Already purchased: {0}'.format(app.pk))
            return Response({'reason': u'Already purchased app.'},
                            status=status.HTTP_409_CONFLICT)

        app_pay_cef.log(request._request, 'Preparing JWT', 'preparing_jwt',
                        'Preparing JWT for: {0}'.format(app.pk), severity=3)

        token = get_product_jwt(
            WebAppProduct(app),
            client_data=ClientData.get_or_create(request._request),
            lang=request._request.LANG,
            region=request._request.REGION,
            source=request._request.REQUEST.get('src', ''),
            user=request._request.amo_user,
        )

        return Response(token, status=status.HTTP_201_CREATED)
Exemple #2
0
def prepare_pay(request, addon):
    if addon.is_premium() and addon.has_purchased(request.user):
        log.info('Already purchased: %d' % addon.pk)
        raise AlreadyPurchased

    app_pay_cef.log(request, 'Preparing JWT', 'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk), severity=3)

    log.debug('Starting purchase of app: {0} by user: {1}'.format(
        addon.pk, request.user))

    contribution = Contribution.objects.create(
        addon_id=addon.pk,
        amount=addon.get_price(region=request.REGION.id),
        paykey=None,
        price_tier=addon.premium.price,
        source=request.REQUEST.get('src', ''),
        source_locale=request.LANG,
        type=amo.CONTRIB_PENDING,
        user=request.user,
        uuid=str(uuid.uuid4()),
    )

    log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid))

    return get_product_jwt(WebAppProduct(addon), contribution)
Exemple #3
0
    def post(self, request, *args, **kwargs):
        form = PrepareInAppForm(request.DATA)
        if not form.is_valid():
            app_pay_cef.log(
                request._request,
                'Preparing InApp JWT Failed',
                'preparing_inapp_jwt_failed',
                'Preparing InApp JWT Failed error: {0}'.format(form.errors),
                severity=3
            )
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)

        inapp = form.cleaned_data['inapp']

        app_pay_cef.log(
            request._request,
            'Preparing InApp JWT',
            'preparing_inapp_jwt',
            'Preparing InApp JWT for: {0}'.format(inapp.pk), severity=3
        )

        token = get_product_jwt(
            InAppProduct(inapp),
            client_data=ClientData.get_or_create(request._request),
            lang=request._request.LANG,
            source=request._request.REQUEST.get('src', ''),
        )

        return Response(token, status=status.HTTP_201_CREATED)
Exemple #4
0
def prepare_pay(request, addon):
    if addon.is_premium() and addon.has_purchased(request.amo_user):
        log.info('Already purchased: %d' % addon.pk)
        raise AlreadyPurchased

    app_pay_cef.log(request, 'Preparing JWT', 'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk), severity=3)

    log.debug('Starting purchase of app: {0} by user: {1}'.format(
        addon.pk, request.amo_user))

    contribution = Contribution.objects.create(
        addon_id=addon.pk,
        amount=addon.get_price(region=request.REGION.id),
        paykey=None,
        price_tier=addon.premium.price,
        source=request.REQUEST.get('src', ''),
        source_locale=request.LANG,
        type=amo.CONTRIB_PENDING,
        user=request.amo_user,
        uuid=str(uuid.uuid4()),
    )

    log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid))

    return get_product_jwt(WebAppProduct(addon), contribution)
Exemple #5
0
def _prepare_pay(request, addon):
    """Prepare a JWT to pass into navigator.pay()"""
    if addon.is_premium() and addon.has_purchased(request.amo_user):
        log.info('Already purchased: %d' % addon.pk)
        raise AlreadyPurchased

    amount, currency, uuid_, contrib_for = start_purchase(request, addon)
    log.debug('Storing contrib for uuid: %s' % uuid_)
    Contribution.objects.create(addon_id=addon.id, amount=amount,
                                source=request.REQUEST.get('src', ''),
                                source_locale=request.LANG,
                                uuid=str(uuid_), type=amo.CONTRIB_PENDING,
                                paykey=None, user=request.amo_user,
                                price_tier=addon.premium.price,
                                client_data=ClientData.get_or_create(request))

    # Until atob() supports encoded HTML we are stripping all tags.
    # See bug 831524
    app_description = bleach.clean(unicode(addon.description), strip=True,
                                   tags=[])

    acct = addon.app_payment_account.payment_account
    seller_uuid = acct.solitude_seller.uuid
    application_size = addon.current_version.all_files[0].size
    issued_at = calendar.timegm(time.gmtime())
    icons = {}
    for size in amo.ADDON_ICON_SIZES:
        icons[str(size)] = absolutify(addon.get_icon_url(size))
    req = {
        'iss': settings.APP_PURCHASE_KEY,
        'typ': settings.APP_PURCHASE_TYP,
        'aud': settings.APP_PURCHASE_AUD,
        'iat': issued_at,
        'exp': issued_at + 3600,  # expires in 1 hour
        'request': {
            'name': unicode(addon.name),
            'description': app_description,
            'pricePoint': addon.premium.price.name,
            'id': make_ext_id(addon.pk),
            'postbackURL': absolutify(reverse('webpay.postback')),
            'chargebackURL': absolutify(reverse('webpay.chargeback')),
            'productData': urlencode({'contrib_uuid': uuid_,
                                      'seller_uuid': seller_uuid,
                                      'addon_id': addon.pk,
                                      'application_size': application_size}),
            'icons': icons,
        }
    }

    jwt_ = sign_webpay_jwt(req)
    log.debug('Preparing webpay JWT for addon %s: %s' % (addon, jwt_))
    app_pay_cef.log(request, 'Preparing JWT', 'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk), severity=3)

    if request.API:
        url = reverse('webpay-status', kwargs={'uuid': uuid_})
    else:
        url = reverse('webpay.pay_status', args=[addon.app_slug, uuid_])
    return {'webpayJWT': jwt_, 'contribStatusURL': url}
Exemple #6
0
def postback(request):
    """Verify signature and set contribution to paid."""
    signed_jwt = request.POST.get('notice', '')
    try:
        data = parse_from_webpay(signed_jwt, request.META.get('REMOTE_ADDR'))
    except InvalidSender, exc:
        app_pay_cef.log(request, 'Unknown app', 'invalid_postback',
                        'Ignoring invalid JWT %r: %s' % (signed_jwt, exc),
                        severity=4)
        return http.HttpResponseBadRequest()
Exemple #7
0
def postback(request):
    """Verify signature and set contribution to paid."""
    signed_jwt = request.POST.get('notice', '')
    try:
        data = parse_from_webpay(signed_jwt, request.META.get('REMOTE_ADDR'))
    except InvalidSender, exc:
        app_pay_cef.log(request, 'Unknown app', 'invalid_postback',
                        'Ignoring invalid JWT %r: %s' % (signed_jwt, exc),
                        severity=4)
        return http.HttpResponseBadRequest()
Exemple #8
0
def free_postback(request, contrib, trans_id, user_profile):
    log.info(u'Got free product postback: fulfilling purchase for '
             u'contrib={c}; trans={t}; user={u}'.format(
                 c=contrib, t=trans_id, u=user_profile))
    app_pay_cef.log(request, 'Purchase complete', 'purchase_complete',
                    'Purchase complete for: %s' % (contrib.addon.pk),
                    severity=3)
    contrib.update(transaction_id=trans_id,
                   type=mkt.CONTRIB_PURCHASE,
                   user=user_profile)
    tasks.send_purchase_receipt.delay(contrib.pk)
    return http.HttpResponse(trans_id)
Exemple #9
0
def free_postback(request, contrib, trans_id, user_profile):
    log.info(u'Got free product postback: fulfilling purchase for '
             u'contrib={c}; trans={t}; user={u}'.format(
                 c=contrib, t=trans_id, u=user_profile))
    app_pay_cef.log(request, 'Purchase complete', 'purchase_complete',
                    'Purchase complete for: %s' % (contrib.webapp.pk),
                    severity=3)
    contrib.update(transaction_id=trans_id,
                   type=mkt.CONTRIB_PURCHASE,
                   user=user_profile)
    tasks.send_purchase_receipt.delay(contrib.pk)
    return http.HttpResponse(trans_id)
Exemple #10
0
    def post(self, request, *args, **kwargs):
        form = PrepareWebAppForm(request.DATA)
        if not form.is_valid():
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)

        app = form.cleaned_data['app']

        region = getattr(request, 'REGION', None)
        if region:
            enabled_regions = app.get_price_region_ids()
            region_can_purchase = region.id in enabled_regions
            restofworld_can_purchase = RESTOFWORLD.id in enabled_regions

            if not region_can_purchase and not restofworld_can_purchase:
                log.info('Region {0} is not in {1}; '
                         'restofworld purchases are inactive'.format(
                             region.id, enabled_regions))
                return Response(
                    {'reason': 'Payments are restricted for this region'},
                    status=status.HTTP_403_FORBIDDEN)

        if app.is_premium() and app.has_purchased(request._request.user):
            log.info('Already purchased: {0}'.format(app.pk))
            return Response({'reason': u'Already purchased app.'},
                            status=status.HTTP_409_CONFLICT)

        app_pay_cef.log(request._request,
                        'Preparing JWT',
                        'preparing_jwt',
                        'Preparing JWT for: {0}'.format(app.pk),
                        severity=3)

        log.debug('Starting purchase of app: {0} by user: {1}'.format(
            app.pk, request._request.user))

        contribution = Contribution.objects.create(
            addon_id=app.pk,
            amount=app.get_price(region=request._request.REGION.id),
            paykey=None,
            price_tier=app.premium.price,
            source=request._request.GET.get('src', ''),
            source_locale=request._request.LANG,
            type=mkt.CONTRIB_PENDING,
            user=request._request.user,
            uuid=str(uuid.uuid4()),
        )

        log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid))

        token = get_product_jwt(WebAppProduct(app), contribution)

        return Response(token, status=status.HTTP_201_CREATED)
Exemple #11
0
    def post(self, request, *args, **kwargs):
        form = PrepareInAppForm(request.DATA)
        if not form.is_valid():
            app_pay_cef.log(
                request._request,
                'Preparing InApp JWT Failed',
                'preparing_inapp_jwt_failed',
                'Preparing InApp JWT Failed error: {0}'.format(form.errors),
                severity=3
            )
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)

        inapp = form.cleaned_data['inapp']

        app_pay_cef.log(
            request._request,
            'Preparing InApp JWT',
            'preparing_inapp_jwt',
            'Preparing InApp JWT for: {0}'.format(inapp.pk), severity=3
        )

        log.debug('Starting purchase of in app: {0}'.format(inapp.pk))

        contribution = Contribution.objects.create(
            addon_id=inapp.webapp and inapp.webapp.pk,
            inapp_product=inapp,
            # In-App payments are unauthenticated so we have no user
            # and therefore can't determine a meaningful region.
            amount=None,
            paykey=None,
            price_tier=inapp.price,
            source=request._request.REQUEST.get('src', ''),
            source_locale=request._request.LANG,
            type=amo.CONTRIB_PENDING,
            user=None,
            uuid=str(uuid.uuid4()),
        )

        log.info('Storing contrib for uuid: {0}'.format(contribution.uuid))

        if inapp.simulate:
            log.info('Preparing in-app JWT simulation for {i}'
                     .format(i=inapp))
            product = SimulatedInAppProduct(inapp)
        else:
            log.info('Preparing in-app JWT for {i}'.format(i=inapp))
            product = InAppProduct(inapp)
        token = get_product_jwt(product, contribution)

        return Response(token, status=status.HTTP_201_CREATED)
Exemple #12
0
    def post(self, request, *args, **kwargs):
        form = PrepareInAppForm(request.DATA)
        if not form.is_valid():
            app_pay_cef.log(
                request._request,
                'Preparing InApp JWT Failed',
                'preparing_inapp_jwt_failed',
                'Preparing InApp JWT Failed error: {0}'.format(form.errors),
                severity=3
            )
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)

        inapp = form.cleaned_data['inapp']

        app_pay_cef.log(
            request._request,
            'Preparing InApp JWT',
            'preparing_inapp_jwt',
            'Preparing InApp JWT for: {0}'.format(inapp.pk), severity=3
        )

        log.debug('Starting purchase of in app: {0}'.format(inapp.pk))

        contribution = Contribution.objects.create(
            addon_id=inapp.webapp and inapp.webapp.pk,
            inapp_product=inapp,
            # In-App payments are unauthenticated so we have no user
            # and therefore can't determine a meaningful region.
            amount=None,
            paykey=None,
            price_tier=inapp.price,
            source=request._request.GET.get('src', ''),
            source_locale=request._request.LANG,
            type=mkt.CONTRIB_PENDING,
            user=None,
            uuid=str(uuid.uuid4()),
        )

        log.info('Storing contrib for uuid: {0}'.format(contribution.uuid))

        if inapp.simulate:
            log.info('Preparing in-app JWT simulation for {i}'
                     .format(i=inapp))
            product = SimulatedInAppProduct(inapp)
        else:
            log.info('Preparing in-app JWT for {i}'.format(i=inapp))
            product = InAppProduct(inapp)
        token = get_product_jwt(product, contribution)

        return Response(token, status=status.HTTP_201_CREATED)
Exemple #13
0
    def post(self, request, *args, **kwargs):
        form = PrepareWebAppForm(request.DATA)
        if not form.is_valid():
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)

        app = form.cleaned_data['app']

        region = getattr(request, 'REGION', None)
        if region:
            enabled_regions = app.get_price_region_ids()
            region_can_purchase = region.id in enabled_regions
            restofworld_can_purchase = RESTOFWORLD.id in enabled_regions

            if not region_can_purchase and not restofworld_can_purchase:
                log.info('Region {0} is not in {1}; '
                         'restofworld purchases are inactive'
                         .format(region.id, enabled_regions))
                return Response(
                    {'reason': 'Payments are restricted for this region'},
                    status=status.HTTP_403_FORBIDDEN)

        if app.is_premium() and app.has_purchased(request._request.user):
            log.info('Already purchased: {0}'.format(app.pk))
            return Response({'reason': u'Already purchased app.'},
                            status=status.HTTP_409_CONFLICT)

        app_pay_cef.log(request._request, 'Preparing JWT', 'preparing_jwt',
                        'Preparing JWT for: {0}'.format(app.pk), severity=3)

        log.debug('Starting purchase of app: {0} by user: {1}'.format(
            app.pk, request._request.user))

        contribution = Contribution.objects.create(
            addon_id=app.pk,
            amount=app.get_price(region=request._request.REGION.id),
            paykey=None,
            price_tier=app.premium.price,
            source=request._request.REQUEST.get('src', ''),
            source_locale=request._request.LANG,
            type=mkt.CONTRIB_PENDING,
            user=request._request.user,
            uuid=str(uuid.uuid4()),
        )

        log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid))

        token = get_product_jwt(WebAppProduct(app), contribution)

        return Response(token, status=status.HTTP_201_CREATED)
Exemple #14
0
def prepare_pay(request, addon):
    if addon.is_premium() and addon.has_purchased(request.amo_user):
        log.info('Already purchased: %d' % addon.pk)
        raise AlreadyPurchased

    app_pay_cef.log(request, 'Preparing JWT', 'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk), severity=3)

    return get_product_jwt(
        WebAppProduct(addon),
        user=request.amo_user,
        region=request.REGION,
        source=request.REQUEST.get('src', ''),
        lang=request.LANG,
        client_data=ClientData.get_or_create(request),
    )
Exemple #15
0
def prepare_pay(request, addon):
    """Prepare a BlueVia JWT to pass into navigator.pay()"""
    amount, currency, uuid_, contrib_for = start_purchase(request, addon)
    log.debug("Storing contrib for uuid: %s" % uuid_)
    Contribution.objects.create(
        addon_id=addon.id,
        amount=amount,
        source=request.REQUEST.get("src", ""),
        source_locale=request.LANG,
        uuid=str(uuid_),
        type=amo.CONTRIB_PENDING,
        paykey=None,
        user=request.amo_user,
        price_tier=addon.premium.price,
        client_data=ClientData.get_or_create(request),
    )

    # Until atob() supports encoded HTML we are stripping all tags.
    # See bug 831524
    app_summary = bleach.clean(unicode(addon.summary), strip=True, tags=[])

    acct = addon.app_payment_account.payment_account
    seller_uuid = acct.solitude_seller.uuid
    issued_at = calendar.timegm(time.gmtime())
    req = {
        "iss": settings.APP_PURCHASE_KEY,
        "typ": settings.APP_PURCHASE_TYP,
        "aud": settings.APP_PURCHASE_AUD,
        "iat": issued_at,
        "exp": issued_at + 3600,  # expires in 1 hour
        "request": {
            "name": unicode(addon.name),
            "description": app_summary,
            "pricePoint": addon.premium.price.pk,
            "id": make_ext_id(addon.pk),
            "postbackURL": absolutify(reverse("webpay.postback")),
            "chargebackURL": absolutify(reverse("webpay.chargeback")),
            "productData": urlencode({"contrib_uuid": uuid_, "seller_uuid": seller_uuid, "addon_id": addon.pk}),
        },
    }

    jwt_ = sign_webpay_jwt(req)
    log.debug("Preparing webpay JWT for addon %s: %s" % (addon, jwt_))
    app_pay_cef.log(request, "Preparing JWT", "preparing_jwt", "Preparing JWT for: %s" % (addon.pk), severity=3)
    return {"webpayJWT": jwt_, "contribStatusURL": reverse("webpay.pay_status", args=[addon.app_slug, uuid_])}
Exemple #16
0
def prepare_pay(request, addon):
    """Prepare a BlueVia JWT to pass into navigator.pay()"""
    amount, currency, uuid_, contrib_for = start_purchase(request, addon)
    log.debug('Storing contrib for uuid: %s' % uuid_)
    Contribution.objects.create(addon_id=addon.id, amount=amount,
                                source=request.REQUEST.get('src', ''),
                                source_locale=request.LANG,
                                uuid=str(uuid_), type=amo.CONTRIB_PENDING,
                                paykey=None, user=request.amo_user,
                                price_tier=addon.premium.price,
                                client_data=ClientData.get_or_create(request))

    # Until atob() supports encoded HTML we are stripping all tags.
    # See bug 831524
    app_summary = bleach.clean(unicode(addon.summary), strip=True, tags=[])

    acct = addon.app_payment_account.payment_account
    seller_uuid = acct.solitude_seller.uuid
    issued_at = calendar.timegm(time.gmtime())
    req = {
        'iss': settings.APP_PURCHASE_KEY,
        'typ': settings.APP_PURCHASE_TYP,
        'aud': settings.APP_PURCHASE_AUD,
        'iat': issued_at,
        'exp': issued_at + 3600,  # expires in 1 hour
        'request': {
            'name': unicode(addon.name),
            'description': app_summary,
            'pricePoint': addon.premium.price.pk,
            'id': make_ext_id(addon.pk),
            'postbackURL': absolutify(reverse('webpay.postback')),
            'chargebackURL': absolutify(reverse('webpay.chargeback')),
            'productData': urlencode({'contrib_uuid': uuid_,
                                      'seller_uuid': seller_uuid,
                                      'addon_id': addon.pk}),
        }
    }

    jwt_ = sign_webpay_jwt(req)
    log.debug('Preparing webpay JWT for addon %s: %s' % (addon, jwt_))
    app_pay_cef.log(request, 'Preparing JWT', 'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk), severity=3)
    return {'webpayJWT': jwt_,
            'contribStatusURL': reverse('webpay.pay_status',
                                        args=[addon.app_slug, uuid_])}
Exemple #17
0
def prepare_pay(request, addon):
    if addon.is_premium() and addon.has_purchased(request.amo_user):
        log.info('Already purchased: %d' % addon.pk)
        raise AlreadyPurchased

    app_pay_cef.log(request,
                    'Preparing JWT',
                    'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk),
                    severity=3)

    return get_product_jwt(
        WebAppProduct(addon),
        user=request.amo_user,
        region=request.REGION,
        source=request.REQUEST.get('src', ''),
        lang=request.LANG,
        client_data=ClientData.get_or_create(request),
    )
Exemple #18
0
def _prepare_pay(request, webapp):
    app_pay_cef.log(request, 'Preparing JWT', 'preparing_jwt',
                    'Preparing JWT for: %s' % (webapp.pk), severity=3)

    log.debug('Starting purchase of app: {0} by user: {1}'.format(
        webapp.pk, request.user))

    contribution = Contribution.objects.create(
        webapp_id=webapp.pk,
        amount=webapp.get_price(region=request.REGION.id),
        paykey=None,
        price_tier=webapp.premium.price,
        source=request.GET.get('src', ''),
        source_locale=request.LANG,
        type=mkt.CONTRIB_PENDING,
        user=request.user,
        uuid=str(uuid.uuid4()),
    )

    log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid))

    return get_product_jwt(WebAppProduct(webapp), contribution)
Exemple #19
0
    pd = urlparse.parse_qs(data["request"]["productData"])
    contrib_uuid = pd["contrib_uuid"][0]
    try:
        contrib = Contribution.objects.get(uuid=contrib_uuid)
    except Contribution.DoesNotExist:
        etype, val, tb = sys.exc_info()
        raise LookupError(
            "JWT (iss:%s, aud:%s) for trans_id %s "
            "links to contrib %s which doesn't exist"
            % (data["iss"], data["aud"], data["response"]["transactionID"], contrib_uuid)
        ), None, tb

    trans_id = data["response"]["transactionID"]
    log.info("webpay postback: fulfilling purchase for contrib %s with " "transaction %s" % (contrib, trans_id))
    app_pay_cef.log(
        request, "Purchase complete", "purchase_complete", "Purchase complete for: %s" % (contrib.addon.pk), severity=3
    )
    contrib.update(transaction_id=trans_id, type=amo.CONTRIB_PURCHASE)

    tasks.send_purchase_receipt.delay(contrib.pk)
    return http.HttpResponse(trans_id)


@csrf_exempt
@write
@post_required
def chargeback(request):
    """
    Verify signature from and create a refund contribution tied
    to the original transaction.
    """
Exemple #20
0
        etype, val, tb = sys.exc_info()
        raise LookupError('JWT (iss:%s, aud:%s) for trans_id %s '
                          'links to contrib %s which doesn\'t exist'
                          % (data['iss'], data['aud'],
                             data['response']['transactionID'],
                             contrib_uuid)), None, tb

    trans_id = data['response']['transactionID']

    if contrib.is_inapp_simulation():
        return simulated_postback(contrib, trans_id)

    if contrib.transaction_id is not None:
        if contrib.transaction_id == trans_id:
            app_pay_cef.log(
                request, 'Repeat postback', 'repeat_postback',
                'Postback sent again for: %s' % (contrib.webapp.pk),
                severity=4)
            return http.HttpResponse(trans_id)
        else:
            app_pay_cef.log(request, 'Repeat postback with new trans_id',
                            'repeat_postback_new_trans_id',
                            'Postback sent again for: %s, but with new '
                            'trans_id: %s' % (contrib.webapp.pk, trans_id),
                            severity=7)
            raise LookupError(
                'JWT (iss:{iss}, aud:{aud}) for trans_id {jwt_trans} is '
                'for contrib {contrib_uuid} that is already paid and has '
                'a different trans_id: {contrib_trans}'
                .format(iss=data['iss'], aud=data['aud'],
                        jwt_trans=data['response']['transactionID'],
                        contrib_uuid=contrib_uuid,
Exemple #21
0
            "JWT (iss:%s, aud:%s) for trans_id %s "
            "links to contrib %s which doesn't exist"
            % (data["iss"], data["aud"], data["response"]["transactionID"], contrib_uuid)
        ), None, tb

    trans_id = data["response"]["transactionID"]

    if contrib.is_inapp_simulation():
        return simulated_postback(contrib, trans_id)

    if contrib.transaction_id is not None:
        if contrib.transaction_id == trans_id:
            app_pay_cef.log(
                request,
                "Repeat postback",
                "repeat_postback",
                "Postback sent again for: %s" % (contrib.addon.pk),
                severity=4,
            )
            return http.HttpResponse(trans_id)
        else:
            app_pay_cef.log(
                request,
                "Repeat postback with new trans_id",
                "repeat_postback_new_trans_id",
                "Postback sent again for: %s, but with new " "trans_id: %s" % (contrib.addon.pk, trans_id),
                severity=7,
            )
            raise LookupError(
                "JWT (iss:%s, aud:%s) for trans_id %s is for "
                "contrib %s that is already paid and has "
Exemple #22
0
    try:
        contrib = Contribution.objects.get(uuid=contrib_uuid)
    except Contribution.DoesNotExist:
        etype, val, tb = sys.exc_info()
        raise LookupError('JWT (iss:%s, aud:%s) for trans_id %s '
                          'links to contrib %s which doesn\'t exist'
                          % (data['iss'], data['aud'],
                             data['response']['transactionID'],
                             contrib_uuid)), None, tb

    trans_id = data['response']['transactionID']

    if contrib.transaction_id is not None:
        if contrib.transaction_id == trans_id:
            app_pay_cef.log(request, 'Repeat postback', 'repeat_postback',
                            'Postback sent again for: %s' % (contrib.addon.pk),
                            severity=4)
            return http.HttpResponse(trans_id)
        else:
            app_pay_cef.log(request, 'Repeat postback with new trans_id',
                            'repeat_postback_new_trans_id',
                            'Postback sent again for: %s, but with new '
                            'trans_id: %s' % (contrib.addon.pk, trans_id),
                            severity=7)
            raise LookupError('JWT (iss:%s, aud:%s) for trans_id %s is for '
                              'contrib %s that is already paid and has '
                              'existing differnet trans_id: %s'
                              % (data['iss'], data['aud'],
                                 data['response']['transactionID'],
                                 contrib_uuid, contrib.transaction_id))
Exemple #23
0
    contrib_uuid = pd['contrib_uuid'][0]
    try:
        contrib = Contribution.objects.get(uuid=contrib_uuid)
    except Contribution.DoesNotExist:
        etype, val, tb = sys.exc_info()
        raise LookupError('JWT (iss:%s, aud:%s) for trans_id %s '
                          'links to contrib %s which doesn\'t exist'
                          % (data['iss'], data['aud'],
                             data['response']['transactionID'],
                             contrib_uuid)), None, tb

    trans_id = data['response']['transactionID']
    log.info('webpay postback: fulfilling purchase for contrib %s with '
             'transaction %s' % (contrib, trans_id))
    app_pay_cef.log(request, 'Purchase complete', 'purchase_complete',
                    'Purchase complete for: %s' % (contrib.addon.pk),
                    severity=3)
    contrib.update(transaction_id=trans_id, type=amo.CONTRIB_PURCHASE)

    tasks.send_purchase_receipt.delay(contrib.pk)
    return http.HttpResponse(trans_id)


@csrf_exempt
@write
@post_required
def chargeback(request):
    """
    Verify signature from and create a refund contribution tied
    to the original transaction.
    """
Exemple #24
0
    try:
        contrib = Contribution.objects.get(uuid=contrib_uuid)
    except Contribution.DoesNotExist:
        etype, val, tb = sys.exc_info()
        raise LookupError(
            'JWT (iss:%s, aud:%s) for trans_id %s '
            'links to contrib %s which doesn\'t exist' %
            (data['iss'], data['aud'], data['response']['transactionID'],
             contrib_uuid)), None, tb

    trans_id = data['response']['transactionID']
    log.info('webpay postback: fulfilling purchase for contrib %s with '
             'transaction %s' % (contrib, trans_id))
    app_pay_cef.log(request,
                    'Purchase complete',
                    'purchase_complete',
                    'Purchase complete for: %s' % (contrib.addon.pk),
                    severity=3)
    contrib.update(transaction_id=trans_id, type=amo.CONTRIB_PURCHASE)

    tasks.send_purchase_receipt.delay(contrib.pk)
    return http.HttpResponse(trans_id)


@csrf_exempt
@write
@post_required
def chargeback(request):
    """
    Verify signature from and create a refund contribution tied
    to the original transaction.
Exemple #25
0
def _prepare_pay(request, addon):
    """Prepare a JWT to pass into navigator.pay()"""
    if addon.is_premium() and addon.has_purchased(request.amo_user):
        log.info('Already purchased: %d' % addon.pk)
        raise AlreadyPurchased

    amount, currency, uuid_, contrib_for = start_purchase(request, addon)
    log.debug('Storing contrib for uuid: %s' % uuid_)
    Contribution.objects.create(addon_id=addon.id,
                                amount=amount,
                                source=request.REQUEST.get('src', ''),
                                source_locale=request.LANG,
                                uuid=str(uuid_),
                                type=amo.CONTRIB_PENDING,
                                paykey=None,
                                user=request.amo_user,
                                price_tier=addon.premium.price,
                                client_data=ClientData.get_or_create(request))

    # Until atob() supports encoded HTML we are stripping all tags.
    # See bug 831524
    app_description = bleach.clean(unicode(addon.description),
                                   strip=True,
                                   tags=[])

    acct = addon.app_payment_account.payment_account
    seller_uuid = acct.solitude_seller.uuid
    application_size = addon.current_version.all_files[0].size
    issued_at = calendar.timegm(time.gmtime())
    icons = {}
    for size in amo.ADDON_ICON_SIZES:
        icons[str(size)] = absolutify(addon.get_icon_url(size))
    req = {
        'iss': settings.APP_PURCHASE_KEY,
        'typ': settings.APP_PURCHASE_TYP,
        'aud': settings.APP_PURCHASE_AUD,
        'iat': issued_at,
        'exp': issued_at + 3600,  # expires in 1 hour
        'request': {
            'name':
            unicode(addon.name),
            'description':
            app_description,
            'pricePoint':
            addon.premium.price.name,
            'id':
            make_ext_id(addon.pk),
            'postbackURL':
            absolutify(reverse('webpay.postback')),
            'chargebackURL':
            absolutify(reverse('webpay.chargeback')),
            'productData':
            urlencode({
                'contrib_uuid': uuid_,
                'seller_uuid': seller_uuid,
                'addon_id': addon.pk,
                'application_size': application_size
            }),
            'icons':
            icons,
        }
    }

    jwt_ = sign_webpay_jwt(req)
    log.debug('Preparing webpay JWT for addon %s: %s' % (addon, jwt_))
    app_pay_cef.log(request,
                    'Preparing JWT',
                    'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk),
                    severity=3)

    if request.API:
        url = reverse('api_dispatch_detail',
                      kwargs={
                          'resource_name': 'status',
                          'api_name': 'webpay',
                          'uuid': uuid_
                      })
    else:
        url = reverse('webpay.pay_status', args=[addon.app_slug, uuid_])
    return {'webpayJWT': jwt_, 'contribStatusURL': url}