Example #1
0
    def test_connection_flaky(self, slumber):
        sample = mock.Mock()
        sample.get_object.return_value = sample_price

        self.count = 1
        def failure():
            if self.count == 3:
                return sample
            self.count += 1
            raise ConnectionError

        slumber.webpay.prices.side_effect = failure
        client.get_price(1)
        eq_(slumber.webpay.prices.call_count, 3)
Example #2
0
    def test_connection_flaky(self, slumber):
        sample = mock.Mock()
        sample.get_object.return_value = sample_price

        self.count = 1

        def failure():
            if self.count == 3:
                return sample
            self.count += 1
            raise ConnectionError

        slumber.webpay.prices.side_effect = failure
        client.get_price(1)
        eq_(slumber.webpay.prices.call_count, 3)
Example #3
0
def start_pay(transaction_uuid, notes, **kw):
    """
    Work with Solitude to begin a Bango payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by Bango.
    """
    # Because this is called from views, we get a new transaction every
    # time. If you re-use this task, you'd want to add some checking about the
    # transaction state.
    pay = notes["pay_request"]
    try:
        seller_uuid = get_seller_uuid(notes["issuer_key"], pay["request"].get("productData", ""))
        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay["request"]["pricePoint"])
        # Set up the product for sale.
        bill_id, seller_product = client.configure_product_for_billing(
            transaction_uuid,
            seller_uuid,
            pay["request"]["id"],
            pay["request"]["name"],  # app/product name
            absolutify(reverse("bango.success")),
            absolutify(reverse("bango.error")),
            prices["prices"],
        )
        trans_pk = client.slumber.generic.transaction.get_object(uuid=transaction_uuid)["resource_pk"]
        client.slumber.generic.transaction(trans_pk).patch(
            {"notes": json.dumps(notes), "uid_pay": bill_id, "status": constants.STATUS_PENDING}
        )
    except Exception, exc:
        log.exception("while configuring for payment")
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #4
0
def start_pay(transaction_uuid, notes, **kw):
    """
    Work with Solitude to begin a Bango payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by Bango.
    """
    # Because this is called from views, we get a new transaction every
    # time. If you re-use this task, you'd want to add some checking about the
    # transaction state.
    pay = notes['pay_request']
    try:
        seller_uuid = get_seller_uuid(notes['issuer_key'],
                                      pay['request'].get('productData', ''))
        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay['request']['pricePoint'])
        # Set up the product for sale.
        bill_id, seller_product = client.configure_product_for_billing(
            transaction_uuid,
            seller_uuid,
            pay['request']['id'],
            pay['request']['name'],  # app/product name
            absolutify(reverse('bango.success')),
            absolutify(reverse('bango.error')),
            prices['prices']
        )
        client.slumber.generic.transaction(transaction_uuid).patch({
            'notes': json.dumps(notes),
            'uid_pay': bill_id,
            'status': constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring for payment')
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #5
0
def start_pay(transaction_uuid, notes, user_uuid, **kw):
    """
    Work with Solitude to begin a Bango payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by Bango.
    """
    try:
        # This task is fired from multiple locations. This checks first to
        # see if it already ran.
        trans = (client.slumber.generic.transaction
                 .get_object(uuid=transaction_uuid))
        if trans['status'] in (constants.STATUS_RECEIVED,
                               constants.STATUS_PENDING):
            log.info('trans %s (status=%r) already configured: '
                     'skipping configure payments step' % (transaction_uuid,
                                                           trans['status']))
            return
    except ObjectDoesNotExist:
        pass

    pay = notes['pay_request']
    try:
        seller_uuid = get_seller_uuid(notes['issuer_key'],
                                      pay['request'].get('productData', ''))
        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay['request']['pricePoint'])
        log.debug('pricePoint=%s prices=%s' % (pay['request']['pricePoint'],
                                               prices['prices']))
        try:
            icon_url = (get_icon_url(pay['request'])
                        if settings.USE_PRODUCT_ICONS else None)
        except:
            log.exception('Calling get_icon_url')
            icon_url = None
        log.info('icon URL for %s: %s' % (transaction_uuid, icon_url))
        # Set up the product for sale.
        bill_id, seller_product = client.configure_product_for_billing(
            transaction_uuid,
            seller_uuid,
            pay['request']['id'],
            pay['request']['name'],  # app/product name
            absolutify(reverse('bango.success')),
            absolutify(reverse('bango.error')),
            prices['prices'],
            icon_url,
            user_uuid
        )
        trans_pk = client.slumber.generic.transaction.get_object(
            uuid=transaction_uuid)['resource_pk']
        client.slumber.generic.transaction(trans_pk).patch({
            'notes': json.dumps(notes),
            'uid_pay': bill_id,
            'status': constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring for payment')
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #6
0
    def test_cached(self, slumber):
        sample = mock.Mock()
        sample.get_object.return_value = sample_price
        slumber.webpay.prices.return_value = sample

        # First one queries, second one hits the cache.
        for x in range(0, 2):
            prices = client.get_price(1)
            eq_(slumber.webpay.prices.call_count, 1)  # This stays the same.
            eq_(prices, sample_price)
Example #7
0
    def test_cached(self, slumber):
        sample = mock.Mock()
        sample.get_object.return_value = sample_price
        slumber.webpay.prices.return_value = sample

        # First one queries, second one hits the cache.
        for x in range(0, 2):
            prices = client.get_price(1)
            eq_(slumber.webpay.prices.call_count, 1)  # This stays the same.
            eq_(prices, sample_price)
Example #8
0
def start_pay(transaction_uuid, notes, user_uuid, **kw):
    """
    Work with Solitude to begin a Bango payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by Bango.
    """
    pay = notes['pay_request']
    product_data = urlparse.parse_qs(pay['request'].get('productData', ''))
    try:
        seller_uuid = get_seller_uuid(notes['issuer_key'], product_data)
        try:
            application_size = int(product_data['application_size'][0])
        except (KeyError, ValueError):
            application_size = None

        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay['request']['pricePoint'])
        log.debug('pricePoint=%s prices=%s' %
                  (pay['request']['pricePoint'], prices['prices']))
        try:
            icon_url = (get_icon_url(pay['request'])
                        if settings.USE_PRODUCT_ICONS else None)
        except:
            log.exception('Calling get_icon_url')
            icon_url = None
        log.info('icon URL for %s: %s' % (transaction_uuid, icon_url))
        # Set up the product for sale.
        bill_id, seller_id = client.configure_product_for_billing(
            transaction_uuid,
            seller_uuid,
            pay['request']['id'],
            pay['request']['name'],  # app/product name
            absolutify(reverse('bango.success')),
            absolutify(reverse('bango.error')),
            prices['prices'],
            icon_url,
            user_uuid,
            application_size,
        )
        trans_pk = client.slumber.generic.transaction.get_object(
            uuid=transaction_uuid)['resource_pk']
        client.slumber.generic.transaction(trans_pk).patch({
            'notes':
            json.dumps(notes),
            'uid_pay':
            bill_id,
            'status':
            constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring for payment')
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #9
0
def start_pay(transaction_uuid, notes, user_uuid, **kw):
    """
    Work with Solitude to begin a Bango payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by Bango.
    """
    key = notes['issuer_key']
    pay = notes['pay_request']
    product_data = urlparse.parse_qs(pay['request'].get('productData', ''))
    try:
        seller_uuid = get_seller_uuid(key, product_data)
        try:
            application_size = int(product_data['application_size'][0])
        except (KeyError, ValueError):
            application_size = None

        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay['request']['pricePoint'])
        log.debug('pricePoint=%s prices=%s' % (pay['request']['pricePoint'],
                                               prices['prices']))
        try:
            icon_url = (get_icon_url(pay['request'])
                        if settings.USE_PRODUCT_ICONS else None)
        except:
            log.exception('Calling get_icon_url')
            icon_url = None
        log.info('icon URL for %s: %s' % (transaction_uuid, icon_url))
        # Set up the product for sale.
        bill_id, seller_id = client.configure_product_for_billing(
            transaction_uuid,
            seller_uuid,
            pay['request']['id'],
            pay['request']['name'],  # app/product name
            absolutify(reverse('bango.success')),
            absolutify(reverse('bango.error')),
            prices['prices'],
            icon_url,
            user_uuid,
            application_size,
            source='marketplace' if is_marketplace(key) else 'other'
        )
        trans_pk = client.slumber.generic.transaction.get_object(
            uuid=transaction_uuid)['resource_pk']
        client.slumber.generic.transaction(trans_pk).patch({
            'notes': json.dumps(notes),
            'uid_pay': bill_id,
            'status': constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring for payment')
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #10
0
def simulate_notify(issuer_key, pay_request, trans_uuid=None, **kw):
    """
    Post JWT notice to an app about a simulated payment.

    This isn't really much different from a regular notice except
    that a fake transaction_uuid is created.
    """
    if not trans_uuid:
        trans_uuid = 'simulate:%s' % uuid.uuid4()
    trans = {
        'uuid': trans_uuid,
        'notes': {
            'pay_request': pay_request,
            'issuer_key': issuer_key
        }
    }

    price_point = pay_request['request']['pricePoint']
    try:
        # Just pick the first random price from the tiers to make it realistic.
        price = mkt_client.get_price(price_point)['prices'][0]
    except IndexError:
        # No prices were returned.
        raise IndexError('No prices for pricePoint: {0}'.format(price_point))
    except UnknownPricePoint:
        # This price point wasn't even valid.
        raise UnknownPricePoint('No pricePoint: {0}'.format(price_point))

    trans['amount'] = price['price']
    trans['currency'] = price['currency']

    extra_response = None
    sim = pay_request['request']['simulate']
    if sim.get('reason'):
        extra_response = {'reason': sim['reason']}

    if sim['result'] == 'postback':
        trans['type'] = constants.TYPE_PAYMENT
        sim_flag = SIMULATED_POSTBACK
    elif sim['result'] == 'chargeback':
        trans['type'] = constants.TYPE_REFUND
        sim_flag = SIMULATED_CHARGEBACK
    else:
        raise NotImplementedError('Not sure how to simulate %s' % sim)

    log.info('Sending simulate notice %s to %s' % (sim, issuer_key))
    _notify(simulate_notify,
            trans,
            extra_response=extra_response,
            simulated=sim_flag,
            task_args=[issuer_key, pay_request])
Example #11
0
File: tasks.py Project: cvan/webpay
def start_pay(transaction_uuid, notes, **kw):
    """
    Work with Solitude to begin a Bango payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by Bango.
    """
    # Because this is called from views, we get a new transaction every
    # time. If you re-use this task, you'd want to add some checking about the
    # transaction state.
    pay_request = notes['pay_request']
    iss = Issuer.objects.get(pk=notes['issuer']) if notes['issuer'] else None
    try:
        seller_uuid = get_effective_issuer_key(iss, notes['issuer_key'])
        if seller_uuid == settings.KEY:
            # The issuer of the JWT is Firefox Marketplace.
            # This is a special case where we need to find the
            # actual Solitude/Bango seller_uuid to associate the
            # product to the right account.
            prod_data = pay_request['request'].get('productData', '')
            try:
                seller_uuid = urlparse.parse_qs(prod_data)['seller_uuid'][0]
            except KeyError:
                raise ValueError('Marketplace %r did not put a seller_uuid '
                                 'in productData: %r' % (settings.KEY,
                                                         prod_data))
            log.info('Using real seller_uuid %r for Marketplace %r '
                     'app payment' % (seller_uuid, settings.KEY))

        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay_request['request']['pricePoint'])
        # Set up the product for sale.
        bill_id, seller_product = client.configure_product_for_billing(
            transaction_uuid,
            seller_uuid,
            pay_request['request']['id'],
            pay_request['request']['name'],  # app/product name
            absolutify(reverse('bango.success')),
            absolutify(reverse('bango.error')),
            prices['prices']
        )
        client.slumber.generic.transaction(transaction_uuid).patch({
            'notes': json.dumps(notes),
            'uid_pay': bill_id,
            'status': constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring for payment')
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #12
0
def start_pay(transaction_uuid, notes, **kw):
    """
    Work with Solitude to begin a Bango payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by Bango.
    """
    # Because this is called from views, we get a new transaction every
    # time. If you re-use this task, you'd want to add some checking about the
    # transaction state.
    pay = notes['pay_request']
    try:
        seller_uuid = get_seller_uuid(notes['issuer_key'],
                                      pay['request'].get('productData', ''))
        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay['request']['pricePoint'])
        try:
            icon_url = (get_icon_url(pay['request'])
                        if settings.USE_PRODUCT_ICONS else None)
        except:
            log.exception('Calling get_icon_url')
            icon_url = None
        log.info('icon URL for %s: %s' % (transaction_uuid, icon_url))
        # Set up the product for sale.
        bill_id, seller_product = client.configure_product_for_billing(
            transaction_uuid,
            seller_uuid,
            pay['request']['id'],
            pay['request']['name'],  # app/product name
            absolutify(reverse('bango.success')),
            absolutify(reverse('bango.error')),
            prices['prices'],
            icon_url,
        )
        trans_pk = client.slumber.generic.transaction.get_object(
            uuid=transaction_uuid)['resource_pk']
        client.slumber.generic.transaction(trans_pk).patch({
            'notes':
            json.dumps(notes),
            'uid_pay':
            bill_id,
            'status':
            constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring for payment')
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #13
0
def _fake_amount(price_point):
    """
    For fake and simulated transactions we don't know the amount a customer
    paid. So we'll just pick the first random price from the tiers to make it
    realistic.
    """
    try:
        price = mkt_client.get_price(price_point)['prices'][0]
    except IndexError:
        # No prices were returned.
        raise IndexError('No prices for pricePoint: {0}'.format(price_point))
    except UnknownPricePoint:
        # This price point wasn't even valid.
        raise UnknownPricePoint('No pricePoint: {0}'.format(price_point))

    return {'amount': price['price'], 'currency': price['currency']}
Example #14
0
def _fake_amount(price_point):
    """
    For fake and simulated transactions we don't know the amount a customer
    paid. So we'll just pick the first random price from the tiers to make it
    realistic.
    """
    try:
        price = mkt_client.get_price(price_point)['prices'][0]
    except IndexError:
        # No prices were returned.
        raise IndexError('No prices for pricePoint: {0}'.format(price_point))
    except UnknownPricePoint:
        # This price point wasn't even valid.
        raise UnknownPricePoint('No pricePoint: {0}'.format(price_point))

    return {'amount': price['price'], 'currency': price['currency']}
Example #15
0
File: tasks.py Project: diox/webpay
def simulate_notify(issuer_key, pay_request, trans_uuid=None, **kw):
    """
    Post JWT notice to an app about a simulated payment.

    This isn't really much different from a regular notice except
    that a fake transaction_uuid is created.
    """
    if not trans_uuid:
        trans_uuid = 'simulate:%s' % uuid.uuid4()
    trans = {'uuid': trans_uuid,
             'notes': {'pay_request': pay_request,
                       'issuer_key': issuer_key}}

    price_point = pay_request['request']['pricePoint']
    try:
        # Just pick the first random price from the tiers to make it realistic.
        price = mkt_client.get_price(price_point)['prices'][0]
    except IndexError:
        # No prices were returned.
        raise IndexError('No prices for pricePoint: {0}'.format(price_point))
    except UnknownPricePoint:
        # This price point wasn't even valid.
        raise UnknownPricePoint('No pricePoint: {0}'.format(price_point))

    trans['amount'] = price['price']
    trans['currency'] = price['currency']

    extra_response = None
    sim = pay_request['request']['simulate']
    if sim.get('reason'):
        extra_response = {'reason': sim['reason']}

    if sim['result'] == 'postback':
        trans['type'] = constants.TYPE_PAYMENT
        sim_flag = SIMULATED_POSTBACK
    elif sim['result'] == 'chargeback':
        trans['type'] = constants.TYPE_REFUND
        sim_flag = SIMULATED_CHARGEBACK
    else:
        raise NotImplementedError('Not sure how to simulate %s' % sim)

    log.info('Sending simulate notice %s to %s' % (sim, issuer_key))
    _notify(simulate_notify, trans, extra_response=extra_response,
            simulated=sim_flag, task_args=[issuer_key, pay_request])
Example #16
0
def get_best_provider(price_point, seller_uuids, provider_names):
    """
    Looks through the providers requested by user. Check the provider exists on
    the seller and then check the price point exists in the marketplace.
    """
    log.info('Choosing best provider, requested: {p}'.format(p=provider_names))
    for provider in provider_names:
        provider_seller_uuid = seller_uuids.get(provider)
        log.info('Provider: {p} {s} in sellers account'.format(
            p=provider, s='found' if provider_seller_uuid else 'NOT FOUND'))

        if provider_seller_uuid:
            prices = mkt_client.get_price(price_point, provider=provider)
            if not prices['prices']:
                log.info('No prices for provider: {p}'.format(p=provider))
                continue

            log.info('Price found for provider: {p}'.format(p=provider))
            return ProviderHelper(provider), provider_seller_uuid, prices

    raise NoValidSeller(
        'Unable to find a valid seller_uuid '
        'using providers: {providers}'.format(providers=provider_names))
Example #17
0
def get_best_provider(price_point, seller_uuids, provider_names):
    """
    Looks through the providers requested by user. Check the provider exists on
    the seller and then check the price point exists in the marketplace.
    """
    log.info('Choosing best provider, requested: {p}'.format(p=provider_names))
    for provider in provider_names:
        provider_seller_uuid = seller_uuids.get(provider)
        log.info('Provider: {p} {s} in sellers account'
                 .format(p=provider,
                         s='found' if provider_seller_uuid else 'NOT FOUND'))

        if provider_seller_uuid:
            prices = mkt_client.get_price(price_point, provider=provider)
            if not prices['prices']:
                log.info('No prices for provider: {p}'.format(p=provider))
                continue

            log.info('Price found for provider: {p}' .format(p=provider))
            return ProviderHelper(provider), provider_seller_uuid, prices

    raise NoValidSeller(
        'Unable to find a valid seller_uuid '
        'using providers: {providers}'.format(providers=provider_names))
Example #18
0
    try:
        pay_req = verify_jwt(
            form.cleaned_data['req'],
            settings.DOMAIN,  # JWT audience.
            form.secret,
            required_keys=('request.id',
                           'request.pricePoint',  # A price tier we'll lookup.
                           'request.name',
                           'request.description'))
    except (TypeError, InvalidJWT, RequestExpired), exc:
        log.exception('calling verify_jwt')
        return _error(request, exception=exc)

    # Assert pricePoint is valid.
    try:
        marketplace.get_price(pay_req['request']['pricePoint'])
    except (TierNotFound, HttpClientError), exc:
        log.exception('calling verifying tier')
        return _error(request, exception=exc)

    try:
        iss = Issuer.objects.get(issuer_key=form.key)
    except Issuer.DoesNotExist:
        iss = None # marketplace

    # TODO(Kumar) fix this for reals. See bug 820198.
    desc = pay_req['request']['description']
    if len(desc) > 255:
        desc = desc[0:255]

    # Before we verify the user's PIN let's save some
Example #19
0
        icon_urls = pay_req['request']['icons'].values()
    # Verify that all URLs are valid.
    try:
        verify_urls(pay_req['request']['postbackURL'],
                    pay_req['request']['chargebackURL'],
                    is_simulation=form.is_simulation)
        verify_urls(*icon_urls,
                    is_simulation=form.is_simulation,
                    check_postbacks=False)
    except ValueError, exc:
        log.exception('invalid URLs')
        return app_error(request, code=msg.MALFORMED_URL)

    # Assert pricePoint is valid.
    try:
        marketplace.get_price(pay_req['request']['pricePoint'])
    except UnknownPricePoint:
        log.exception('UnknownPricePoint calling get price_price()')
        return app_error(request, code=msg.BAD_PRICE_POINT)

    _trim_pay_request(pay_req)

    # All validation passed, save state to the session.
    request.session['is_simulation'] = form.is_simulation
    # This is an ephemeral session value, do not rely on it.
    # It gets saved to the solitude transaction so you can access it there.
    # Otherwise it is used for simulations and fake payments.
    notes = request.session.get('notes', {})
    notes['pay_request'] = pay_req
    notes['issuer_key'] = form.key
    request.session['notes'] = notes
Example #20
0
    def test_connection_error_raises(self, slumber):
        slumber.webpay.prices.side_effect = ConnectionError
        with self.assertRaises(ConnectionError):
            client.get_price(1)

        eq_(slumber.webpay.prices.call_count, NUMBER_ATTEMPTS)
Example #21
0
def start_pay(transaction_uuid, notes, user_uuid, provider_name, **kw):
    """
    Work with Solitude to begin a payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by the payment provider.

    Arguments:

    **transaction_uuid**
        Unique identifier for a new transaction.

    **notes**
        Dict of notes about this transaction.

    **user_uuid**
        Unique identifier for the buyer user.

    **provider_name**
        One of a predefined strings to activate a payment provider.
        Example: 'bango' or 'reference'

    """
    key = notes['issuer_key']
    pay = notes['pay_request']
    network = notes.get('network', {})
    product_data = urlparse.parse_qs(pay['request'].get('productData', ''))
    provider = ProviderHelper(provider_name)
    try:
        seller_uuid = get_seller_uuid(key, product_data)
        try:
            application_size = int(product_data['application_size'][0])
        except (KeyError, ValueError):
            application_size = None

        # Ask the marketplace for a valid price point.
        prices = mkt_client.get_price(pay['request']['pricePoint'])
        log.debug('pricePoint=%s prices=%s' % (pay['request']['pricePoint'],
                                               prices['prices']))
        try:
            icon_url = (get_icon_url(pay['request'])
                        if settings.USE_PRODUCT_ICONS else None)
        except:
            log.exception('Calling get_icon_url')
            icon_url = None
        log.info('icon URL for %s: %s' % (transaction_uuid, icon_url))

        bill_id, pay_url, seller_id = provider.start_transaction(
            transaction_uuid,
            seller_uuid,
            pay['request']['id'],
            pay['request']['name'],  # app/product name
            prices['prices'],
            icon_url,
            user_uuid,
            application_size,
            source='marketplace' if is_marketplace(key) else 'other',
            mcc=network.get('mcc'),
            mnc=network.get('mnc')
        )
        trans_pk = client.slumber.generic.transaction.get_object(
            uuid=transaction_uuid)['resource_pk']
        client.slumber.generic.transaction(trans_pk).patch({
            'notes': json.dumps(notes),
            'uid_pay': bill_id,
            'pay_url': pay_url,
            'status': constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring for payment')
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #22
0
 def test_no_connection(self, slumber):
     slumber.webpay.prices.side_effect = HttpServerError
     client.get_price(1)
Example #23
0
 def test_get_prices(self, slumber):
     sample = mock.Mock()
     sample.get_object.return_value = sample_price
     slumber.webpay.prices.return_value = sample
     prices = client.get_price(1)
     eq_(prices['name'], sample_price['name'])
Example #24
0
 def test_invalid_price_point(self, slumber):
     slumber.webpay.prices.side_effect = ObjectDoesNotExist
     client.get_price(1)
Example #25
0
def start_pay(transaction_uuid, notes, user_uuid, providers, **kw):
    """
    Work with Solitude to begin a payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by the payment provider.

    Arguments:

    **transaction_uuid**
        Unique identifier for a new transaction.

    **notes**
        Dict of notes about this transaction.

    **user_uuid**
        Unique identifier for the buyer user.

    **provider_name**
        One of a predefined strings to activate a payment provider.
        Example: 'bango' or 'reference'

    """
    key = notes["issuer_key"]
    pay = notes["pay_request"]
    network = notes.get("network", {})
    product_data = urlparse.parse_qs(pay["request"].get("productData", ""))
    try:
        provider_helper, seller_uuid = get_provider_seller_uuid(key, product_data, providers)
        try:
            application_size = int(product_data["application_size"][0])
        except (KeyError, ValueError):
            application_size = None

        # Ask the marketplace for a valid price point.
        # Note: the get_price_country API might be more helpful.
        prices = mkt_client.get_price(pay["request"]["pricePoint"], provider=provider_helper.provider.name)
        log.debug("pricePoint=%s prices=%s" % (pay["request"]["pricePoint"], prices["prices"]))
        try:
            icon_url = get_icon_url(pay["request"]) if settings.USE_PRODUCT_ICONS else None
        except:
            log.exception("Calling get_icon_url")
            icon_url = None
        log.info("icon URL for %s: %s" % (transaction_uuid, icon_url))

        bill_id, pay_url, seller_id = provider_helper.start_transaction(
            transaction_uuid,
            seller_uuid,
            pay["request"]["id"],
            pay["request"]["name"],  # app/product name
            prices["prices"],
            icon_url,
            user_uuid,
            application_size,
            source="marketplace" if is_marketplace(key) else "other",
            mcc=network.get("mcc"),
            mnc=network.get("mnc"),
        )
        trans_pk = client.slumber.generic.transaction.get_object(uuid=transaction_uuid)["resource_pk"]
        client.slumber.generic.transaction(trans_pk).patch(
            {"notes": json.dumps(notes), "uid_pay": bill_id, "pay_url": pay_url, "status": constants.STATUS_PENDING}
        )
    except Exception, exc:
        log.exception("while configuring for payment")
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #26
0
 def test_no_connection(self, slumber):
     slumber.webpay.prices.side_effect = HttpServerError
     client.get_price(1)
Example #27
0
 def test_get_prices(self, slumber):
     self.mock(slumber)
     prices = client.get_price(1)
     eq_(prices['name'], sample_price['name'])
Example #28
0
def start_pay(transaction_uuid, notes, user_uuid, provider_names, **kw):
    """
    Work with Solitude to begin a payment.

    This puts the transaction in a state where it's
    ready to be fulfilled by the payment provider.

    Arguments:

    **transaction_uuid**
        Unique identifier for a new transaction.

    **notes**
        Dict of notes about this transaction.

    **user_uuid**
        Unique identifier for the buyer user.

    **provider_names**
        A list of predefined provider names that this transaction can
        support. This list is influenced by region/carrier.
        Example: ['bango', 'boku'].

    """
    key = notes['issuer_key']
    pay = notes['pay_request']
    network = notes.get('network', {})
    product_data = urlparse.parse_qs(pay['request'].get('productData', ''))
    try:
        (provider_helper,
         provider_seller_uuid,
         generic_seller_uuid) = get_provider_seller_uuid(key,
                                                         product_data,
                                                         provider_names)
        try:
            application_size = int(product_data['application_size'][0])
        except (KeyError, ValueError):
            application_size = None

        # Ask the marketplace for a valid price point.
        # Note: the get_price_country API might be more helpful.
        prices = mkt_client.get_price(pay['request']['pricePoint'],
                                      provider=provider_helper.provider.name)
        log.debug('pricePoint=%s prices=%s' % (pay['request']['pricePoint'],
                                               prices['prices']))
        try:
            icon_url = (get_icon_url(pay['request'])
                        if settings.USE_PRODUCT_ICONS else None)
        except:
            log.exception('Calling get_icon_url')
            icon_url = None
        log.info('icon URL for %s: %s' % (transaction_uuid, icon_url))

        bill_id, pay_url, seller_id = provider_helper.start_transaction(
            transaction_uuid=transaction_uuid,
            generic_seller_uuid=generic_seller_uuid,
            provider_seller_uuid=provider_seller_uuid,
            product_id=pay['request']['id'],
            product_name=pay['request']['name'],
            prices=prices['prices'],
            icon_url=icon_url,
            user_uuid=user_uuid,
            application_size=application_size,
            source='marketplace' if is_marketplace(key) else 'other',
            mcc=network.get('mcc'),
            mnc=network.get('mnc')
        )
        trans_pk = client.slumber.generic.transaction.get_object(
            uuid=transaction_uuid)['resource_pk']
        client.slumber.generic.transaction(trans_pk).patch({
            'notes': json.dumps(notes),
            'uid_pay': bill_id,
            'pay_url': pay_url,
            'status': constants.STATUS_PENDING
        })
    except Exception, exc:
        log.exception('while configuring payment for transaction {t}: '
                      '{exc.__class__.__name__}: {exc}'
                      .format(t=transaction_uuid, exc=exc))
        etype, val, tb = sys.exc_info()
        raise exc, None, tb
Example #29
0
 def test_invalid_price_point(self, slumber):
     slumber.webpay.prices.side_effect = ObjectDoesNotExist
     client.get_price(1)
Example #30
0
 def test_get_prices(self, slumber):
     sample = mock.Mock()
     sample.get_object.return_value = sample_price
     slumber.webpay.prices.return_value = sample
     prices = client.get_price(1)
     eq_(prices['name'], sample_price['name'])
Example #31
0
 def test_get_prices(self, slumber):
     self.mock(slumber)
     prices = client.get_price(1)
     eq_(prices['name'], sample_price['name'])
Example #32
0
    icon_urls = []
    if pay_req["request"].get("icons"):
        icon_urls = pay_req["request"]["icons"].values()
    # Verify that all URLs are valid.
    try:
        verify_urls(
            pay_req["request"]["postbackURL"], pay_req["request"]["chargebackURL"], is_simulation=form.is_simulation
        )
        verify_urls(*icon_urls, is_simulation=form.is_simulation, check_postbacks=False)
    except ValueError, exc:
        log.exception("invalid URLs")
        return app_error(request, code=msg.MALFORMED_URL)

    # Assert pricePoint is valid.
    try:
        marketplace.get_price(pay_req["request"]["pricePoint"])
    except UnknownPricePoint:
        log.exception("UnknownPricePoint calling get price_price()")
        return app_error(request, code=msg.BAD_PRICE_POINT)

    _trim_pay_request(pay_req)

    # All validation passed, save state to the session.
    request.session["is_simulation"] = form.is_simulation
    # This is an ephemeral session value, do not rely on it.
    # It gets saved to the solitude transaction so you can access it there.
    # Otherwise it is used for simulations and fake payments.
    notes = request.session.get("notes", {})
    notes["pay_request"] = pay_req
    notes["issuer_key"] = form.key
    request.session["notes"] = notes