예제 #1
0
파일: api.py 프로젝트: tempbottle/webpay
def _callback_url(request, is_success):
    status = is_success and 'success' or 'error'
    signed_notice = request.POST['signed_notice']
    statsd.incr('purchase.payment_{0}_callback.received'.format(status))

    # This is currently only used by Bango and Zippy.
    # Future providers should probably get added to the notification
    # abstraction in provider/views.py
    provider = ProviderHelper(settings.PAYMENT_PROVIDER)

    if provider.is_callback_token_valid(signed_notice):
        statsd.incr('purchase.payment_{0}_callback.ok'.format(status))
        log.info('Callback {0} token was valid.'.format(status))
        querystring = http.QueryDict(signed_notice)
        if 'ext_transaction_id' in querystring:
            ext_transaction_id = querystring['ext_transaction_id']
            if is_success:
                tasks.payment_notify.delay(ext_transaction_id)
            else:
                tasks.chargeback_notify.delay(ext_transaction_id)
            return http.HttpResponse(status=204)
        else:
            statsd.incr('purchase.payment_{0}_callback.incomplete'
                        ''.format(status))
            log.error('Callback {0} token was incomplete: '
                      '{1}'.format(status, querystring))
    else:
        statsd.incr('purchase.payment_{0}_callback.fail'.format(status))
        log.error('Callback {0} token was invalid: '
                  '{1}'.format(status, signed_notice))
    return http.HttpResponseBadRequest()
예제 #2
0
파일: views.py 프로젝트: Witia1/webpay
def _callback_url(request, is_success):
    status = is_success and 'success' or 'error'
    signed_notice = request.POST['signed_notice']
    statsd.incr('purchase.payment_{0}_callback.received'.format(status))

    # This is currently only used by Bango and Zippy.
    # Future providers should probably get added to the notification
    # abstraction in provider/views.py
    provider = ProviderHelper(settings.PAYMENT_PROVIDER)

    if provider.is_callback_token_valid(signed_notice):
        statsd.incr('purchase.payment_{0}_callback.ok'.format(status))
        log.info('Callback {0} token was valid.'.format(status))
        querystring = http.QueryDict(signed_notice)
        if 'ext_transaction_id' in querystring:
            ext_transaction_id = querystring['ext_transaction_id']
            if is_success:
                tasks.payment_notify.delay(ext_transaction_id)
            else:
                tasks.chargeback_notify.delay(ext_transaction_id)
            return http.HttpResponse(status=204)
        else:
            statsd.incr('purchase.payment_{0}_callback.incomplete'
                        ''.format(status))
            log.error('Callback {0} token was incomplete: '
                      '{1}'.format(status, querystring))
    else:
        statsd.incr('purchase.payment_{0}_callback.fail'.format(status))
        log.error('Callback {0} token was invalid: '
                  '{1}'.format(status, signed_notice))
    return http.HttpResponseBadRequest()
예제 #3
0
파일: views.py 프로젝트: lissyx/webpay
def notification(request, provider_name):
    """
    Handle server to server notification responses.
    """
    provider = ProviderHelper(provider_name)

    try:
        provider.server_notification(request)
    except msg.DevMessage as m:
        return HttpResponse(m.code, status=502)

    return HttpResponse('OK')
예제 #4
0
파일: views.py 프로젝트: lissyx/webpay
def notification(request, provider_name):
    """
    Handle server to server notification responses.
    """
    provider = ProviderHelper(provider_name)

    try:
        provider.server_notification(request)
    except msg.DevMessage as m:
        return HttpResponse(m.code, status=502)

    return HttpResponse('OK')
예제 #5
0
파일: views.py 프로젝트: jincreator/webpay
def notification(request, provider_name):
    """
    Handle server to server notification responses.
    """
    provider = ProviderHelper(provider_name)

    try:
        transaction_uuid = provider.server_notification(request)
    except msg.DevMessage as m:
        return HttpResponse(m.code, status=502)

    tasks.payment_notify.delay(transaction_uuid)
    return HttpResponse('OK')
예제 #6
0
파일: views.py 프로젝트: unghost/webpay
def success(request, provider_name):
    provider = ProviderHelper(provider_name)
    if provider.name != 'reference':
        raise NotImplementedError(
            'only the reference provider is implemented so far')

    try:
        transaction_id = provider.prepare_notice(request)
    except msg.DevMessage as m:
        return system_error(request, code=m.code)

    tasks.payment_notify.delay(transaction_id)
    return render(request, 'provider/success.html')
예제 #7
0
파일: views.py 프로젝트: lissyx/webpay
def success(request, provider_name):
    provider = ProviderHelper(provider_name)
    if provider.name != 'reference':
        raise NotImplementedError(
            'only the reference provider is implemented so far')

    try:
        transaction_id = provider.prepare_notice(request)
    except msg.DevMessage as m:
        return system_error(request, code=m.code)

    tasks.payment_notify.delay(transaction_id)
    return render(request, 'provider/success.html')
예제 #8
0
파일: views.py 프로젝트: jincreator/webpay
def _callback_url(request, is_success):
    status = is_success and "success" or "error"
    signed_notice = request.POST["signed_notice"]
    statsd.incr("purchase.payment_{0}_callback.received".format(status))

    # This is currently only used by Bango and Zippy.
    # Future providers should probably get added to the notification
    # abstraction in provider/views.py
    provider = ProviderHelper.choose()

    if provider.is_callback_token_valid(signed_notice):
        statsd.incr("purchase.payment_{0}_callback.ok".format(status))
        log.info("Callback {0} token was valid.".format(status))
        querystring = http.QueryDict(signed_notice)
        if "ext_transaction_id" in querystring:
            ext_transaction_id = querystring["ext_transaction_id"]
            if is_success:
                tasks.payment_notify.delay(ext_transaction_id)
            else:
                tasks.chargeback_notify.delay(ext_transaction_id)
            return http.HttpResponse(status=204)
        else:
            statsd.incr("purchase.payment_{0}_callback.incomplete" "".format(status))
            log.error("Callback {0} token was incomplete: " "{1}".format(status, querystring))
    else:
        statsd.incr("purchase.payment_{0}_callback.fail".format(status))
        log.error("Callback {0} token was invalid: " "{1}".format(status, signed_notice))
    return http.HttpResponseBadRequest()
예제 #9
0
파일: tests.py 프로젝트: tempbottle/webpay
    def test_from_wrong_mexican_operator(self):
        mcc = '334'  # Mexico
        mnc = '03'  # Movistar

        providers = ProviderHelper.supported_providers(mcc=mcc, mnc=mnc)
        provider_names = [provider.name for provider in providers]
        eq_(provider_names, [settings.PAYMENT_PROVIDER])
예제 #10
0
파일: tests.py 프로젝트: tempbottle/webpay
    def test_not_from_mexico(self):
        mcc = '214'  # Spain
        mnc = '01'  # Vodaphone

        providers = ProviderHelper.supported_providers(mcc=mcc, mnc=mnc)
        provider_names = [provider.name for provider in providers]
        eq_(provider_names, [settings.PAYMENT_PROVIDER])
예제 #11
0
파일: tests.py 프로젝트: MorrisJobke/webpay
    def test_not_from_mexico(self):
        mcc = '214'  # Spain
        mnc = '01'  # Vodaphone

        providers = ProviderHelper.supported_providers(mcc=mcc, mnc=mnc)
        provider_names = [provider.name for provider in providers]
        eq_(provider_names, [settings.PAYMENT_PROVIDER])
예제 #12
0
파일: tests.py 프로젝트: MorrisJobke/webpay
    def test_from_wrong_mexican_operator(self):
        mcc = '334'  # Mexico
        mnc = '03'  # Movistar

        providers = ProviderHelper.supported_providers(mcc=mcc, mnc=mnc)
        provider_names = [provider.name for provider in providers]
        eq_(provider_names, [settings.PAYMENT_PROVIDER])
예제 #13
0
파일: tests.py 프로젝트: tempbottle/webpay
    def test_from_boku_operator(self):
        mcc = '334'  # Mexico
        mnc = '020'  # AMX

        providers = ProviderHelper.supported_providers(mcc=mcc, mnc=mnc)
        provider_names = [provider.name for provider in providers]
        eq_(provider_names, [
            BokuProvider.name, settings.PAYMENT_PROVIDER])
예제 #14
0
파일: views.py 프로젝트: Joergen/webpay
def notification(request, provider_name):
    """
    Handle server to server notification responses.
    """
    provider = ProviderHelper(provider_name)

    try:
        transaction_uuid = provider.server_notification(request)
    except msg.DevMessage as m:
        return HttpResponse(m.code, status=502)

    trans = client.get_transaction(transaction_uuid)
    log.info("Processing notification for transaction {t}; status={s}".format(t=transaction_uuid, s=trans["status"]))
    if trans["status"] == STATUS_COMPLETED:
        tasks.payment_notify.delay(transaction_uuid)

    return HttpResponse("OK")
예제 #15
0
파일: tests.py 프로젝트: MorrisJobke/webpay
    def test_from_boku_operator(self):
        mcc = '334'  # Mexico
        mnc = '020'  # AMX

        providers = ProviderHelper.supported_providers(mcc=mcc, mnc=mnc)
        provider_names = [provider.name for provider in providers]
        eq_(provider_names, [
            BokuProvider.name, settings.PAYMENT_PROVIDER])
예제 #16
0
파일: tasks.py 프로젝트: jincreator/webpay
def configure_transaction(request, trans=None):
    """
    Begins a background task to configure a payment transaction.
    """
    if request.session.get('is_simulation', False):
        log.info('is_simulation: skipping configure payments step')
        return False

    if not trans and not 'trans_id' in request.session:
        log.error('trans_id: not found in session')
        return False

    try:
        if not trans:
            trans = client.get_transaction(uuid=request.session['trans_id'])
        log.info('attempt to reconfigure trans {0} (status={1})'
                 .format(request.session['trans_id'], trans['status']))
    except ObjectDoesNotExist:
        trans = {}

    if trans.get('status') in constants.STATUS_RETRY_OK:
        new_trans_id = trans_id()
        log.info('retrying trans {0} (status={1}) as {2}'
                 .format(request.session['trans_id'],
                         trans['status'], new_trans_id))
        request.session['trans_id'] = new_trans_id

    last_configured = request.session.get('configured_trans')
    if last_configured == request.session['trans_id']:
        log.info('trans %s (status=%r) already configured: '
                 'skipping configure payments step'
                 % (request.session['trans_id'], trans.get('status')))
        return False

    # Prevent configuration from running twice.
    request.session['configured_trans'] = request.session['trans_id']

    # Localize the product before sending it off to solitude/bango.
    _localize_pay_request(request)

    log.info('configuring payment in background for trans {t} (status={s}); '
             'Last configured: {c}'.format(t=request.session['trans_id'],
                                           s=trans.get('status'),
                                           c=last_configured))

    network = request.session['notes'].get('network', {})
    provider = ProviderHelper.choose(mcc=network.get('mcc'),
                                     mnc=network.get('mnc'))

    start_pay.delay(request.session['trans_id'],
                    request.session['notes'],
                    request.session['uuid'],
                    provider.name)

    # We passed notes to start_pay (which saves it to the transaction
    # object), so delete it from the session to save cookie space.
    del request.session['notes']
    return True
예제 #17
0
파일: views.py 프로젝트: lissyx/webpay
def error(request, provider_name):
    provider = ProviderHelper(provider_name)
    if provider.name != 'reference':
        raise NotImplementedError(
            'only the reference provider is implemented so far')

    try:
        provider.prepare_notice(request)
    except msg.DevMessage as m:
        return system_error(request, code=m.code)

    # TODO: handle user cancellation, bug 957774.

    log.error('Fatal payment error for {provider}: {code}; query string: {qs}'.
              format(provider=provider.name,
                     code=request.GET.get('ResponseCode'),
                     qs=request.GET))
    return system_error(request, code=msg.EXT_ERROR)
예제 #18
0
파일: views.py 프로젝트: flodolo/webpay
def success(request, provider_name):
    provider = ProviderHelper(provider_name)
    if provider.name != 'reference':
        raise NotImplementedError(
            'only the reference provider is implemented so far')

    try:
        transaction_id = provider.prepare_notice(request)
    except msg.DevMessage as m:
        return system_error(request, code=m.code)

    tasks.payment_notify.delay(transaction_id)

    state, fxa_url = fxa_auth_info(request)
    ctx = {'start_view': 'payment-success',
           'fxa_state': state,
           'fxa_auth_url': fxa_url}
    return render(request, 'spa/index.html', ctx)
예제 #19
0
def error(request, provider_name):
    provider = ProviderHelper(provider_name)
    if provider.name != 'reference':
        raise NotImplementedError(
            'only the reference provider is implemented so far')

    try:
        provider.prepare_notice(request)
    except msg.DevMessage as m:
        return system_error(request, code=m.code)

    # TODO: handle user cancellation, bug 957774.

    log.error('Fatal payment error for {provider}: {code}; query string: {qs}'
              .format(provider=provider.name,
                      code=request.GET.get('ResponseCode'),
                      qs=request.GET))
    return system_error(request, code=msg.EXT_ERROR)
예제 #20
0
파일: views.py 프로젝트: Joergen/webpay
def success(request, provider_name):
    provider = ProviderHelper(provider_name)
    if provider.name != "reference":
        raise NotImplementedError("only the reference provider is implemented so far")

    try:
        transaction_id = provider.prepare_notice(request)
    except msg.DevMessage as m:
        return system_error(request, code=m.code)

    tasks.payment_notify.delay(transaction_id)

    if settings.SPA_ENABLE:
        state, fxa_url = fxa_auth_info(request)
        ctx = {"start_view": "payment-success", "fxa_state": state, "fxa_auth_url": fxa_url}
        return render(request, "spa/index.html", ctx)

    return render(request, "provider/success.html")
예제 #21
0
파일: views.py 프로젝트: Nurtas/webpay
def success(request, provider_name):
    provider = ProviderHelper(provider_name)
    if provider.name != 'reference':
        raise NotImplementedError(
            'only the reference provider is implemented so far')

    try:
        transaction_id = provider.prepare_notice(request)
    except msg.DevMessage as m:
        return system_error(request, code=m.code)

    tasks.payment_notify.delay(transaction_id)

    if settings.SPA_ENABLE:
        ctx = {'start_view': 'payment-success'}
        if settings.USE_FXA:
            ctx['fxa_state'], ctx['fxa_auth_url'] = fxa_auth_info(request)
        return render(request, 'spa/index.html', ctx)

    return render(request, 'provider/success.html')
예제 #22
0
파일: tasks.py 프로젝트: unghost/webpay
def configure_transaction(request, trans=None):
    """
    Begins a background task to configure a payment transaction.
    """
    if request.session.get("is_simulation", False):
        log.info("is_simulation: skipping configure payments step")
        return False

    if not trans and not "trans_id" in request.session:
        log.error("trans_id: not found in session")
        return False

    try:
        if not trans:
            trans = client.get_transaction(uuid=request.session["trans_id"])
        log.info("attempt to reconfigure trans {0} (status={1})".format(request.session["trans_id"], trans["status"]))
    except ObjectDoesNotExist:
        trans = {}

    if trans.get("status") in constants.STATUS_RETRY_OK:
        new_trans_id = trans_id()
        log.info(
            "retrying trans {0} (status={1}) as {2}".format(request.session["trans_id"], trans["status"], new_trans_id)
        )
        request.session["trans_id"] = new_trans_id

    last_configured = request.session.get("configured_trans")
    if last_configured == request.session["trans_id"]:
        log.info(
            "trans %s (status=%r) already configured: "
            "skipping configure payments step" % (request.session["trans_id"], trans.get("status"))
        )
        return False

    # Prevent configuration from running twice.
    request.session["configured_trans"] = request.session["trans_id"]

    # Localize the product before sending it off to solitude/bango.
    _localize_pay_request(request)

    log.info(
        "configuring payment in background for trans {t} (status={s}); "
        "Last configured: {c}".format(t=request.session["trans_id"], s=trans.get("status"), c=last_configured)
    )

    network = request.session["notes"].get("network", {})
    providers = ProviderHelper.supported_providers(mcc=network.get("mcc"), mnc=network.get("mnc"))

    start_pay.delay(request.session["trans_id"], request.session["notes"], request.session["uuid"], providers)

    # We passed notes to start_pay (which saves it to the transaction
    # object), so delete it from the session to save cookie space.
    del request.session["notes"]
    return True
예제 #23
0
파일: views.py 프로젝트: jincreator/webpay
def wait_to_finish(request, provider_name):
    """
    After the payment provider finishes the pay flow, wait for completion.

    The provider redirects here so the UI can poll Solitude until the
    transaction is complete.
    """
    helper = ProviderHelper(provider_name)
    trans_uuid = helper.provider.transaction_from_notice(request.GET)
    if not trans_uuid:
        # This could happen if someone is tampering with the URL or if
        # the payment provider changed their URL parameters.
        log.info('no transaction found for provider {p}; url: {u}'
                 .format(p=helper.provider.name, u=request.get_full_path()))
        return HttpResponseNotFound()

    trans_url = reverse('provider.transaction_status', args=[trans_uuid])
    return render(request, 'provider/wait-to-finish.html',
                  {'transaction_status_url': trans_url})
예제 #24
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))
예제 #25
0
파일: tests.py 프로젝트: lissyx/webpay
    def test_from_wrong_mexican_operator(self):
        mcc = '334'  # Mexico
        mnc = '03'  # Movistar

        provider = ProviderHelper.choose(mcc=mcc, mnc=mnc)
        eq_(provider.name, BangoProvider.name)
예제 #26
0
파일: tests.py 프로젝트: lissyx/webpay
    def test_from_boku_operator(self):
        mcc = '334'  # Mexico
        mnc = '020'  # AMX

        provider = ProviderHelper.choose(mcc=mcc, mnc=mnc)
        eq_(provider.name, BokuProvider.name)
예제 #27
0
파일: tests.py 프로젝트: jincreator/webpay
    def test_from_boku_operator(self):
        mcc = '334'  # Mexico
        mnc = '020'  # AMX

        provider = ProviderHelper.choose(mcc=mcc, mnc=mnc)
        eq_(provider.name, BokuProvider.name)
예제 #28
0
파일: tests.py 프로젝트: MorrisJobke/webpay
    def test_supported_providers_returns_default_provider(self):
        providers = ProviderHelper.supported_providers()
        eq_(len(providers), 1)

        provider = providers[0]
        eq_(provider.name, settings.PAYMENT_PROVIDER)
예제 #29
0
파일: tests.py 프로젝트: jincreator/webpay
    def test_from_wrong_mexican_operator(self):
        mcc = '334'  # Mexico
        mnc = '03'  # Movistar

        provider = ProviderHelper.choose(mcc=mcc, mnc=mnc)
        eq_(provider.name, BangoProvider.name)
예제 #30
0
파일: tests.py 프로젝트: MorrisJobke/webpay
class TestBango(TestCase):
    uuid = 'some:pin'
    seller = {'bango': {'seller': 's', 'resource_uri': 'r',
                        'package_id': '1234'},
              'resource_uri': '/seller/1',
              'resource_pk': 'seller_pk'}

    def setUp(self):
        super(TestBango, self).setUp()
        self.slumber = mock.MagicMock()
        self.provider = ProviderHelper('bango', slumber=self.slumber)

    def start(self):
        return self.provider.start_transaction(*range(0, 9))

    def test_create_without_bango_seller(self):
        self.slumber.generic.seller.get_object.return_value = {
            'bango': None, 'resource_pk': '1',
            'resource_uri': '/seller/1'
        }
        with self.assertRaises(ValueError):
            self.provider.create_product(
                external_id='ext:id', product_name='product name',
                generic_seller={},
                provider_seller_uuid='provider_seller_uuid',
                generic_product={'resource_pk': '2',
                                 'resource_uri': '/foo'})
        self.slumber.generic.seller.get_object.assert_called_with(
            uuid='provider_seller_uuid')

    def test_create_bango_product(self):
        slumber = self.slumber
        slumber.bango.generic.post.return_value = {'product': 'some:uri'}
        slumber.bango.product.post.return_value = {'resource_uri': 'some:uri',
                                                   'bango_id': '5678'}
        assert self.provider.create_product(
            external_id='ext:id', product_name='product:name',
            generic_seller=self.seller, provider_seller_uuid='xyz')
        assert slumber.generic.product.post.called
        kw = slumber.generic.product.post.call_args[0][0]
        eq_(kw['external_id'], 'ext:id')
        eq_(slumber.bango.rating.post.call_count, 2)
        assert slumber.bango.premium.post.called

    def test_no_seller(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.side_effect = (
            ObjectDoesNotExist)
        with self.assertRaises(SellerNotConfigured):
            self.start()

    def test_no_bango_product(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': 'bill_id'}
        slumber.bango.product.get_object_or_404.side_effect = (
            ObjectDoesNotExist)
        trans_id, pay_url, seller_uuid = self.start()
        eq_(trans_id, 'bill_id')

    def test_with_bango_product(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': 'bill_id'}
        slumber.bango.product.get_object.return_value = {
            'resource_uri': 'foo'}
        trans_id, pay_url, seller_uuid = self.start()
        eq_(trans_id, 'bill_id')

    def test_pay_url(self):
        bill_id = '123'
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': bill_id}

        with self.settings(
            PAY_URLS={'bango': {'base': 'http://bango',
                                'pay': '/pay?bcid={uid_pay}'}}):
            trans_id, pay_url, seller_uuid = self.start()

        eq_(pay_url, 'http://bango/pay?bcid={b}'.format(b=bill_id))
예제 #31
0
파일: tests.py 프로젝트: MorrisJobke/webpay
class TestReferenceProvider(ProviderTestCase):

    def setUp(self):
        super(TestReferenceProvider, self).setUp()
        self.provider = ProviderHelper('reference', slumber=self.slumber)

    def test_start_with_existing_prod(self):
        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        self.slumber.generic.buyer.get_object_or_404.return_value = {
            'resource_uri': self.buyer_uri,
        }

        trans_id, pay_url, seller_id = self.configure(
            seller_uuid=self.seller_uuid, product_uuid=self.product_uuid)

        eq_(trans_id, 'zippy-trans-token')
        eq_(seller_id, self.seller_id)
        assert pay_url.endswith('tx={t}'.format(t=trans_id)), (
            'Unexpected: {url}'.format(url=pay_url))

        kw = (self.slumber.provider.reference.products
                                             .get_object_or_404).call_args[1]
        eq_(kw['seller_product__seller'], self.seller_id)
        eq_(kw['seller_product__external_id'], 'app-xyz')

        self.slumber.generic.transaction.post.assert_called_with({
            'amount': '0.99',
            'carrier': 'USA_TMOBILE',
            'currency': 'EUR',
            'provider': constants.PROVIDER_REFERENCE,
            'region': '123',
            'buyer': self.buyer_uri,
            'seller': self.seller_uri,
            'seller_product': self.product_uri,
            'source': 'unknown',
            'status': constants.STATUS_PENDING,
            'type': constants.TYPE_PAYMENT,
            'uuid': 'trans-xyz',
        })

    def test_with_new_prod(self):
        name = 'Magic Unicorn'
        new_product_uuid = 'new-product'

        self.slumber.generic.buyer.get_object_or_404.return_value = {
            'resource_uri': self.buyer_uri,
        }

        (self.slumber.generic.product.get_object_or_404
                                     .side_effect) = ObjectDoesNotExist

        self.slumber.generic.product.post.return_value = {
            'access': 1,
            'public_id': '6597288d-7bce-409b-a35b-772acfe04b1e',
            'external_id': self.product_uuid,
            'seller': self.seller_uri,
            'resource_uri': self.product_uri,
        }

        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        seller_ref_uri = '/reference/seller/1'
        (self.slumber.provider.reference.sellers.get_object_or_404
                                                .return_value) = {
            'resource_uri': seller_ref_uri
        }

        seller_prod_uri = '/reference/product/1'
        self.slumber.provider.reference.products.post.return_value = {
            'reference': {
                'uuid': new_product_uuid
            },
            'resource_uri': seller_prod_uri
        }
        (self.slumber.provider.reference.products
                                        .side_effect) = ObjectDoesNotExist

        result = self.configure(seller_uuid=self.seller_uuid,
                                product_uuid=self.product_uuid,
                                product_name=name)

        eq_(result[0], 'zippy-trans-token')

        kw = self.slumber.provider.reference.products.post.call_args[0][0]
        eq_(kw['name'], name)
        eq_(kw['seller_reference'], seller_ref_uri)
        eq_(kw['seller_product'], self.product_uri)
        assert 'uuid' in kw, kw

        kw = self.slumber.provider.reference.transactions.post.call_args[0][0]
        eq_(kw['product_id'], new_product_uuid)
        eq_(kw['product_image_url'], '/todo/icons')
        assert kw['success_url'].endswith('/provider/reference/success'), (
            'Unexpected: {0}'.format(kw['success_url']))
        assert kw['error_url'].endswith('/provider/reference/error'), (
            'Unexpected: {0}'.format(kw['error_url']))
        self.slumber.generic.transaction.post.assert_called_with({
            'amount': '0.99',
            'carrier': 'USA_TMOBILE',
            'currency': 'EUR',
            'provider': constants.PROVIDER_REFERENCE,
            'region': '123',
            'buyer': self.buyer_uri,
            'seller': self.seller_uri,
            'seller_product': self.product_uri,
            'source': 'unknown',
            'status': constants.STATUS_PENDING,
            'type': constants.TYPE_PAYMENT,
            'uuid': 'trans-xyz',
        })

    def test_callback_validation_success(self):
        self.slumber.provider.reference.notices.post.return_value = {
            'result': 'OK',
        }
        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, True)
        eq_(self.slumber.provider.reference.notices.post.call_args[0][0],
            {'qs': {'foo': 'bar'}})

    def test_callback_validation_failure(self):
        self.slumber.provider.reference.notices.post.return_value = {
            'result': 'FAIL',
            'reason': 'signature mismatch',
        }
        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, False)
예제 #32
0
파일: tests.py 프로젝트: lissyx/webpay
    def test_not_from_mexico(self):
        mcc = '214'  # Spain
        mnc = '01'  # Vodaphone

        provider = ProviderHelper.choose(mcc=mcc, mnc=mnc)
        eq_(provider.name, BangoProvider.name)
예제 #33
0
파일: tests.py 프로젝트: jincreator/webpay
    def test_not_from_mexico(self):
        mcc = '214'  # Spain
        mnc = '01'  # Vodaphone

        provider = ProviderHelper.choose(mcc=mcc, mnc=mnc)
        eq_(provider.name, BangoProvider.name)
예제 #34
0
파일: tests.py 프로젝트: tempbottle/webpay
 def setUp(self):
     super(TestBoku, self).setUp()
     self.provider = ProviderHelper('boku', slumber=self.slumber)
예제 #35
0
파일: tests.py 프로젝트: tempbottle/webpay
    def test_supported_providers_returns_default_provider(self):
        providers = ProviderHelper.supported_providers()
        eq_(len(providers), 1)

        provider = providers[0]
        eq_(provider.name, settings.PAYMENT_PROVIDER)
예제 #36
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
예제 #37
0
파일: tests.py 프로젝트: jincreator/webpay
 def test_no_network(self):
     provider = ProviderHelper.choose()
     eq_(provider.name, BangoProvider.name)
예제 #38
0
파일: tests.py 프로젝트: jincreator/webpay
class TestReferenceProvider(ProviderTestCase):

    def setUp(self):
        self.slumber = mock.MagicMock()
        self.provider = ProviderHelper('reference', slumber=self.slumber)

    def set_mocks(self, returns={}, keys=None, **kw):
        if not keys:
            keys = ('generic.seller',
                    'generic.product',
                    'generic.buyer',
                    'provider.reference.products',
                    'provider.reference.transactions',)
        return super(TestReferenceProvider, self).set_mocks(
            returns=returns, keys=keys, **kw)

    def test_start_with_existing_prod(self):
        seller_uuid = 'seller-xyz'
        product_uuid = 'app-xyz'

        self.set_mocks({
            'provider.reference.transactions': {
                'method': 'post',
                'return': {
                    'token': 'zippy-trans-token',
                }
            }},
            seller_uuid=seller_uuid,
            product_uuid=product_uuid
        )

        trans_id, pay_url, seller_uuid = self.configure(
            seller_uuid=seller_uuid, product_uuid=product_uuid)

        eq_(trans_id, 'zippy-trans-token')
        eq_(seller_uuid, seller_uuid)
        assert pay_url.endswith('tx={t}'.format(t=trans_id)), (
            'Unexpected: {url}'.format(url=pay_url))

        kw = self.slumber.provider.reference.products\
                                            .get_object_or_404.call_args[1]
        eq_(kw['external_id'], product_uuid)
        eq_(kw['seller_id'], seller_uuid)

    def test_with_new_prod(self):
        new_product_id = 66
        product_uuid = 'app-xyz'
        seller_uuid = 'seller-xyz'

        self.set_mocks({
            'generic.product': {
                'side_effect': ObjectDoesNotExist,
            },
            'provider.reference.transactions': {
                'method': 'post',
                'return': {
                    'token': 'zippy-trans-token',
                }
            },
            'provider.reference.products': {
                'side_effect': ObjectDoesNotExist,
            },
            'provider.reference.sellers': {
                'return': {
                    'resource_pk': seller_uuid,
                }
            }},
            seller_uuid=seller_uuid
        )

        self.slumber.provider.reference.products.post.return_value = {
            'resource_pk': new_product_id,
        }

        result = self.configure(seller_uuid=seller_uuid,
                                product_uuid=product_uuid)

        eq_(result[0], 'zippy-trans-token')

        kw = self.slumber.provider.reference.products.post.call_args[0][0]
        eq_(kw['external_id'], product_uuid)
        eq_(kw['seller_id'], seller_uuid)

        kw = self.slumber.provider.reference.transactions.post.call_args[0][0]
        eq_(kw['product_id'], new_product_id)
        eq_(kw['product_image_url'], '/todo/icons')
        assert kw['success_url'].endswith('/provider/reference/success'), (
            'Unexpected: {0}'.format(kw['success_url']))
        assert kw['error_url'].endswith('/provider/reference/error'), (
            'Unexpected: {0}'.format(kw['error_url']))

    def test_callback_validation_success(self):
        self.set_mocks({
            'provider.reference.notices': {
                'method': 'post',
                'return': {
                    'result': 'OK',
                }
            },
            'provider.reference.transactions': {
                'method': 'post',
                'return': {
                    'token': 'zippy-trans-token',
                }
            }},
            product_uuid='XYZ'
        )

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, True)
        eq_(self.slumber.provider.reference.notices.post.call_args[0][0],
            {'qs': {'foo': 'bar'}})

    def test_callback_validation_failure(self):
        self.set_mocks({
            'provider.reference.notices': {
                'method': 'post',
                'return': {
                    'result': 'FAIL',
                    'reason': 'signature mismatch',
                }
            },
            'provider.reference.transactions': {
                'method': 'post',
                'return': {
                    'token': 'zippy-trans-token',
                }
            }},
            product_uuid='XYZ'
        )

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, False)
예제 #39
0
파일: tests.py 프로젝트: lissyx/webpay
 def test_no_network(self):
     provider = ProviderHelper.choose()
     eq_(provider.name, BangoProvider.name)
예제 #40
0
파일: tests.py 프로젝트: tempbottle/webpay
 def setUp(self):
     super(TestReferenceProvider, self).setUp()
     self.provider = ProviderHelper('reference', slumber=self.slumber)
예제 #41
0
파일: tasks.py 프로젝트: flodolo/webpay
def configure_transaction(request, trans=None, mcc=None, mnc=None):
    """
    Begins a background task to configure a payment transaction.

    Returns a tuple of (was_configured, error_code)

    * was_configured is a boolean
    * error_code, when not None, is an error code for the failure
    """
    if request.session.get('is_simulation', False):
        log.info('is_simulation: skipping configure payments step')
        return (False, None)

    notes = request.session.get('notes', {})
    if mcc and mnc:
        notes['network'] = {'mnc': mnc, 'mcc': mcc}
    else:
        # Reset network state to avoid leakage from previous states.
        notes['network'] = {}
    request.session['notes'] = notes
    log.info('Added mcc/mnc to session: '
             '{network}'.format(network=notes['network']))

    log.info('configuring transaction {0} from client'
             .format(request.session.get('trans_id')))

    if not trans and 'trans_id' not in request.session:
        log.error('trans_id: not found in session')
        return (False, dev_messages.TRANS_MISSING)

    try:
        if not trans:
            trans = client.get_transaction(uuid=request.session['trans_id'])
        log.info('attempt to reconfigure trans {0} (status={1})'
                 .format(request.session['trans_id'], trans['status']))
    except ObjectDoesNotExist:
        trans = {}

    if trans.get('status') in constants.STATUS_RETRY_OK:
        new_trans_id = trans_id()
        log.info('retrying trans {0} (status={1}) as {2}'
                 .format(request.session['trans_id'],
                         trans['status'], new_trans_id))
        request.session['trans_id'] = new_trans_id

    last_configured = request.session.get('configured_trans')
    if last_configured == request.session['trans_id']:
        log.info('trans %s (status=%r) already configured: '
                 'skipping configure payments step'
                 % (request.session['trans_id'], trans.get('status')))
        return (False, None)

    # Localize the product before sending it off to solitude/bango.
    _localize_pay_request(request)

    log.info('configuring payment in background for trans {t} (status={s}); '
             'Last configured: {c}'.format(t=request.session['trans_id'],
                                           s=trans.get('status'),
                                           c=last_configured))

    network = request.session['notes'].get('network', {})
    providers = ProviderHelper.supported_providers(
        mcc=network.get('mcc'),
        mnc=network.get('mnc'),
    )

    start_pay.delay(request.session['trans_id'],
                    request.session['notes'],
                    request.session['uuid'],
                    [p.name for p in providers])

    # Now that the background task has been started successfully,
    # prevent configuration from running twice.
    request.session['configured_trans'] = request.session['trans_id']

    return (True, None)
예제 #42
0
파일: tests.py 프로젝트: tempbottle/webpay
class TestReferenceProvider(ProviderTestCase):

    def setUp(self):
        super(TestReferenceProvider, self).setUp()
        self.provider = ProviderHelper('reference', slumber=self.slumber)

    def test_start_with_existing_prod(self):
        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        self.slumber.generic.buyer.get_object_or_404.return_value = {
            'resource_uri': self.buyer_uri,
        }

        trans_id, pay_url, seller_id = self.configure(
            seller_uuid=self.seller_uuid, product_uuid=self.product_uuid)

        eq_(trans_id, 'zippy-trans-token')
        eq_(seller_id, self.seller_id)
        assert pay_url.endswith('tx={t}'.format(t=trans_id)), (
            'Unexpected: {url}'.format(url=pay_url))

        kw = (self.slumber.provider.reference.products
                                             .get_object_or_404).call_args[1]
        eq_(kw['seller_product__seller'], self.seller_id)
        eq_(kw['seller_product__external_id'], 'app-xyz')

        self.slumber.generic.transaction.post.assert_called_with({
            'amount': '1.99',
            'carrier': 'FAKE',
            'currency': 'USD',
            'provider': constants.PROVIDER_REFERENCE,
            'region': 'CAN',
            'buyer': self.buyer_uri,
            'seller': self.seller_uri,
            'seller_product': self.product_uri,
            'source': 'unknown',
            'status': constants.STATUS_PENDING,
            'type': constants.TYPE_PAYMENT,
            'uuid': 'trans-xyz',
        })

    def test_with_new_prod(self):
        name = u'Ivan Krsti\u0107'
        new_product_uuid = 'new-product'

        self.slumber.generic.buyer.get_object_or_404.return_value = {
            'resource_uri': self.buyer_uri,
        }

        (self.slumber.generic.product.get_object_or_404
                                     .side_effect) = ObjectDoesNotExist

        self.slumber.generic.product.post.return_value = {
            'access': 1,
            'public_id': '6597288d-7bce-409b-a35b-772acfe04b1e',
            'external_id': self.product_uuid,
            'seller': self.seller_uri,
            'resource_uri': self.product_uri,
        }

        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        seller_ref_uri = '/reference/seller/1'
        (self.slumber.provider.reference.sellers.get_object_or_404
                                                .return_value) = {
            'resource_uri': seller_ref_uri
        }

        seller_prod_uri = '/reference/product/1'
        self.slumber.provider.reference.products.post.return_value = {
            'reference': {
                'uuid': new_product_uuid
            },
            'resource_uri': seller_prod_uri
        }
        (self.slumber.provider.reference.products
                                        .side_effect) = ObjectDoesNotExist

        result = self.configure(seller_uuid=self.seller_uuid,
                                product_uuid=self.product_uuid,
                                product_name=name)

        eq_(result[0], 'zippy-trans-token')

        kw = self.slumber.provider.reference.products.post.call_args[0][0]
        eq_(kw['name'], name)
        eq_(kw['seller_reference'], seller_ref_uri)
        eq_(kw['seller_product'], self.product_uri)
        assert 'uuid' in kw, kw

        kw = self.slumber.provider.reference.transactions.post.call_args[0][0]
        eq_(kw['product_id'], new_product_uuid)
        eq_(kw['product_image_url'], '/todo/icons')
        assert kw['success_url'].endswith('/provider/reference/success'), (
            'Unexpected: {0}'.format(kw['success_url']))
        assert kw['error_url'].endswith('/provider/reference/error'), (
            'Unexpected: {0}'.format(kw['error_url']))
        self.slumber.generic.transaction.post.assert_called_with({
            'amount': '1.99',
            'carrier': 'FAKE',
            'currency': 'USD',
            'provider': constants.PROVIDER_REFERENCE,
            'region': 'CAN',
            'buyer': self.buyer_uri,
            'seller': self.seller_uri,
            'seller_product': self.product_uri,
            'source': 'unknown',
            'status': constants.STATUS_PENDING,
            'type': constants.TYPE_PAYMENT,
            'uuid': 'trans-xyz',
        })

    def test_callback_validation_success(self):
        self.slumber.provider.reference.notices.post.return_value = {
            'result': 'OK',
        }
        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, True)
        eq_(self.slumber.provider.reference.notices.post.call_args[0][0],
            {'qs': {'foo': 'bar'}})

    def test_callback_validation_failure(self):
        self.slumber.provider.reference.notices.post.return_value = {
            'result': 'FAIL',
            'reason': 'signature mismatch',
        }
        self.slumber.provider.reference.transactions.post.return_value = {
            'token': 'zippy-trans-token',
        }

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, False)

    @raises(ValueError)
    def test_no_usd(self):
        self.configure(prices={})
예제 #43
0
파일: tests.py 프로젝트: MorrisJobke/webpay
 def setUp(self):
     super(TestBango, self).setUp()
     self.slumber = mock.MagicMock()
     self.provider = ProviderHelper('bango', slumber=self.slumber)
예제 #44
0
파일: tests.py 프로젝트: lissyx/webpay
class TestBango(TestCase):
    uuid = 'some:pin'
    seller = {
        'bango': {
            'seller': 's',
            'resource_uri': 'r',
            'package_id': '1234'
        },
        'resource_uri': '/seller/1',
        'resource_pk': 'seller_pk'
    }

    def setUp(self):
        super(TestBango, self).setUp()
        self.slumber = mock.MagicMock()
        self.provider = ProviderHelper('bango', slumber=self.slumber)

    def test_create_without_bango_seller(self):
        with self.assertRaises(ValueError):
            self.provider.create_product('ext:id',
                                         'product name', {
                                             'bango': None,
                                             'resource_pk': '1',
                                             'resource_uri': '/seller/1'
                                         },
                                         generic_product={'resource_pk': '2'})

    def test_create_bango_product(self):
        slumber = self.slumber
        slumber.bango.generic.post.return_value = {'product': 'some:uri'}
        slumber.bango.product.post.return_value = {
            'resource_uri': 'some:uri',
            'bango_id': '5678'
        }
        assert self.provider.create_product('ext:id', 'product:name',
                                            self.seller)
        assert slumber.generic.product.post.called
        kw = slumber.generic.product.post.call_args[0][0]
        eq_(kw['external_id'], 'ext:id')
        eq_(slumber.bango.rating.post.call_count, 2)
        assert slumber.bango.premium.post.called

    def test_no_seller(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.side_effect = (
            ObjectDoesNotExist)
        with self.assertRaises(SellerNotConfigured):
            self.provider.start_transaction(*range(0, 8))

    def test_no_bango_product(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': 'bill_id'
        }
        slumber.bango.product.get_object_or_404.side_effect = (
            ObjectDoesNotExist)
        trans_id, pay_url, seller_uuid = self.provider.start_transaction(
            *range(0, 8))
        eq_(trans_id, 'bill_id')

    def test_with_bango_product(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': 'bill_id'
        }
        slumber.bango.product.get_object.return_value = {'resource_uri': 'foo'}
        trans_id, pay_url, seller_uuid = self.provider.start_transaction(
            *range(0, 8))
        eq_(trans_id, 'bill_id')

    def test_pay_url(self):
        bill_id = '123'
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': bill_id
        }

        with self.settings(PAY_URLS={
                'bango': {
                    'base': 'http://bango',
                    'pay': '/pay?bcid={uid_pay}'
                }
        }):
            trans_id, pay_url, seller_uuid = self.provider.start_transaction(
                *range(0, 8))

        eq_(pay_url, 'http://bango/pay?bcid={b}'.format(b=bill_id))
예제 #45
0
파일: tests.py 프로젝트: MorrisJobke/webpay
 def setUp(self):
     super(TestReferenceProvider, self).setUp()
     self.provider = ProviderHelper('reference', slumber=self.slumber)
예제 #46
0
파일: tests.py 프로젝트: lissyx/webpay
 def setUp(self):
     super(TestBango, self).setUp()
     self.slumber = mock.MagicMock()
     self.provider = ProviderHelper('bango', slumber=self.slumber)
예제 #47
0
파일: tests.py 프로젝트: tempbottle/webpay
class TestBango(TestCase):
    uuid = 'some:pin'
    seller = {'bango': {'seller': 's', 'resource_uri': 'r',
                        'package_id': '1234'},
              'resource_uri': '/seller/1',
              'resource_pk': 'seller_pk'}

    def setUp(self):
        super(TestBango, self).setUp()
        self.slumber = mock.MagicMock()
        self.provider = ProviderHelper('bango', slumber=self.slumber)

    def start(self):
        return self.provider.start_transaction(*range(0, 9))

    def test_create_without_bango_seller(self):
        self.slumber.generic.seller.get_object.return_value = {
            'bango': None, 'resource_pk': '1',
            'resource_uri': '/seller/1'
        }
        with self.assertRaises(ValueError):
            self.provider.create_product(
                external_id='ext:id', product_name=u'Ivan Krsti\u0107',
                generic_seller={},
                provider_seller_uuid='provider_seller_uuid',
                generic_product={'resource_pk': '2',
                                 'resource_uri': '/foo'})
        self.slumber.generic.seller.get_object.assert_called_with(
            uuid='provider_seller_uuid')

    def test_create_bango_product(self):
        slumber = self.slumber
        slumber.bango.generic.post.return_value = {'product': 'some:uri'}
        slumber.bango.product.post.return_value = {'resource_uri': 'some:uri',
                                                   'bango_id': '5678'}
        assert self.provider.create_product(
            external_id='ext:id', product_name=u'Ivan Krsti\u0107',
            generic_seller=self.seller, provider_seller_uuid='xyz')
        assert slumber.generic.product.post.called
        kw = slumber.generic.product.post.call_args[0][0]
        eq_(kw['external_id'], 'ext:id')
        eq_(slumber.bango.rating.post.call_count, 2)
        assert slumber.bango.premium.post.called

    def test_no_seller(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.side_effect = (
            ObjectDoesNotExist)
        with self.assertRaises(SellerNotConfigured):
            self.start()

    def test_no_bango_product(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': 'bill_id'}
        slumber.bango.product.get_object_or_404.side_effect = (
            ObjectDoesNotExist)
        trans_id, pay_url, seller_uuid = self.start()
        eq_(trans_id, 'bill_id')

    def test_with_bango_product(self):
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': 'bill_id'}
        slumber.bango.product.get_object.return_value = {
            'resource_uri': 'foo'}
        trans_id, pay_url, seller_uuid = self.start()
        eq_(trans_id, 'bill_id')

    def test_pay_url(self):
        bill_id = '123'
        slumber = self.slumber
        slumber.generic.seller.get_object_or_404.return_value = self.seller
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': bill_id}

        with self.settings(
            PAY_URLS={'bango': {'base': 'http://bango',
                                'pay': '/pay?bcid={uid_pay}'}}):
            trans_id, pay_url, seller_uuid = self.start()

        eq_(pay_url, 'http://bango/pay?bcid={b}'.format(b=bill_id))

    def test_transaction_created(self):
        slumber = self.slumber
        slumber.bango.billing.post.return_value = {
            'billingConfigurationId': 'uid:pay'
        }
        slumber.generic.buyer.get_object_or_404.return_value = {
            'resource_pk': '1',
            'resource_uri': '/generic/buyer/1/'
        }
        slumber.generic.product.get_object_or_404.return_value = {
            'external_id': 'ext:id',
            'resource_pk': '1',
            'resource_uri': '/generic/product/1/'
        }
        slumber.generic.seller.get_object_or_404.return_value = {
            'resource_pk': '1',
            'resource_uri': '/generic/seller/1/'
        }

        data = {
            'status': constants.STATUS_PENDING,
            'source': 'unknown',
            'uid_pay': 'uid:pay',
            'uuid': 0,
            'provider': constants.PROVIDER_BANGO,
            'buyer': '/generic/buyer/1/',
            'seller_product': '/generic/product/1/',
            'type': constants.TYPE_PAYMENT,
            'seller': '/generic/seller/1/',
        }

        self.start()
        slumber.generic.transaction.post.assert_called_with(data)
예제 #48
0
파일: tests.py 프로젝트: lissyx/webpay
class TestReferenceProvider(ProviderTestCase):
    def setUp(self):
        self.slumber = mock.MagicMock()
        self.provider = ProviderHelper('reference', slumber=self.slumber)

    def set_mocks(self, returns={}, keys=None, **kw):
        if not keys:
            keys = (
                'generic.seller',
                'generic.product',
                'generic.buyer',
                'provider.reference.products',
                'provider.reference.transactions',
            )
        return super(TestReferenceProvider, self).set_mocks(returns=returns,
                                                            keys=keys,
                                                            **kw)

    def test_start_with_existing_prod(self):
        seller_uuid = 'seller-xyz'
        product_uuid = 'app-xyz'

        self.set_mocks(
            {
                'provider.reference.transactions': {
                    'method': 'post',
                    'return': {
                        'token': 'zippy-trans-token',
                    }
                }
            },
            seller_uuid=seller_uuid,
            product_uuid=product_uuid)

        trans_id, pay_url, seller_uuid = self.configure(
            seller_uuid=seller_uuid, product_uuid=product_uuid)

        eq_(trans_id, 'zippy-trans-token')
        eq_(seller_uuid, seller_uuid)
        assert pay_url.endswith('tx={t}'.format(
            t=trans_id)), ('Unexpected: {url}'.format(url=pay_url))

        kw = self.slumber.provider.reference.products\
                                            .get_object_or_404.call_args[1]
        eq_(kw['external_id'], product_uuid)
        eq_(kw['seller_id'], seller_uuid)

    def test_with_new_prod(self):
        new_product_id = 66
        product_uuid = 'app-xyz'
        seller_uuid = 'seller-xyz'

        self.set_mocks(
            {
                'generic.product': {
                    'side_effect': ObjectDoesNotExist,
                },
                'provider.reference.transactions': {
                    'method': 'post',
                    'return': {
                        'token': 'zippy-trans-token',
                    }
                },
                'provider.reference.products': {
                    'side_effect': ObjectDoesNotExist,
                },
                'provider.reference.sellers': {
                    'return': {
                        'resource_pk': seller_uuid,
                    }
                }
            },
            seller_uuid=seller_uuid)

        self.slumber.provider.reference.products.post.return_value = {
            'resource_pk': new_product_id,
        }

        result = self.configure(seller_uuid=seller_uuid,
                                product_uuid=product_uuid)

        eq_(result[0], 'zippy-trans-token')

        kw = self.slumber.provider.reference.products.post.call_args[0][0]
        eq_(kw['external_id'], product_uuid)
        eq_(kw['seller_id'], seller_uuid)

        kw = self.slumber.provider.reference.transactions.post.call_args[0][0]
        eq_(kw['product_id'], new_product_id)
        eq_(kw['product_image_url'], '/todo/icons')
        assert kw['success_url'].endswith('/provider/reference/success'), (
            'Unexpected: {0}'.format(kw['success_url']))
        assert kw['error_url'].endswith('/provider/reference/error'), (
            'Unexpected: {0}'.format(kw['error_url']))

    def test_callback_validation_success(self):
        self.set_mocks(
            {
                'provider.reference.notices': {
                    'method': 'post',
                    'return': {
                        'result': 'OK',
                    }
                },
                'provider.reference.transactions': {
                    'method': 'post',
                    'return': {
                        'token': 'zippy-trans-token',
                    }
                }
            },
            product_uuid='XYZ')

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, True)
        eq_(self.slumber.provider.reference.notices.post.call_args[0][0],
            {'qs': {
                'foo': 'bar'
            }})

    def test_callback_validation_failure(self):
        self.set_mocks(
            {
                'provider.reference.notices': {
                    'method': 'post',
                    'return': {
                        'result': 'FAIL',
                        'reason': 'signature mismatch',
                    }
                },
                'provider.reference.transactions': {
                    'method': 'post',
                    'return': {
                        'token': 'zippy-trans-token',
                    }
                }
            },
            product_uuid='XYZ')

        self.configure(seller_uuid='seller-xyz', product_uuid='app-xyz')
        is_valid = self.provider.is_callback_token_valid({'foo': 'bar'})
        eq_(is_valid, False)
예제 #49
0
파일: tests.py 프로젝트: lissyx/webpay
 def setUp(self):
     self.slumber = mock.MagicMock()
     self.provider = ProviderHelper('reference', slumber=self.slumber)
예제 #50
0
파일: tests.py 프로젝트: lissyx/webpay
 def setUp(self):
     self.slumber = mock.MagicMock()
     self.provider = ProviderHelper('boku', slumber=self.slumber)
예제 #51
0
def configure_transaction(request, trans=None, mcc=None, mnc=None):
    """
    Begins a background task to configure a payment transaction.

    Returns a tuple of (was_configured, error_code)

    * was_configured is a boolean
    * error_code, when not None, is an error code for the failure
    """
    if request.session.get('is_simulation', False):
        log.info('is_simulation: skipping configure payments step')
        return (False, None)

    notes = request.session.get('notes', {})
    if mcc and mnc:
        notes['network'] = {'mnc': mnc, 'mcc': mcc}
    else:
        # Reset network state to avoid leakage from previous states.
        notes['network'] = {}
    request.session['notes'] = notes
    log.info('Added mcc/mnc to session: '
             '{network}'.format(network=notes['network']))

    log.info('configuring transaction {0} from client'.format(
        request.session.get('trans_id')))

    if not trans and 'trans_id' not in request.session:
        log.error('trans_id: not found in session')
        return (False, dev_messages.TRANS_MISSING)

    try:
        if not trans:
            trans = client.get_transaction(uuid=request.session['trans_id'])
        log.info('attempt to reconfigure trans {0} (status={1})'.format(
            request.session['trans_id'], trans['status']))
    except ObjectDoesNotExist:
        trans = {}

    if trans.get('status') in constants.STATUS_RETRY_OK:
        new_trans_id = trans_id()
        log.info('retrying trans {0} (status={1}) as {2}'.format(
            request.session['trans_id'], trans['status'], new_trans_id))
        request.session['trans_id'] = new_trans_id

    last_configured = request.session.get('configured_trans')
    if last_configured == request.session['trans_id']:
        log.info('trans %s (status=%r) already configured: '
                 'skipping configure payments step' %
                 (request.session['trans_id'], trans.get('status')))
        return (False, None)

    # Localize the product before sending it off to solitude/bango.
    _localize_pay_request(request)

    log.info('configuring payment in background for trans {t} (status={s}); '
             'Last configured: {c}'.format(t=request.session['trans_id'],
                                           s=trans.get('status'),
                                           c=last_configured))

    network = request.session['notes'].get('network', {})
    providers = ProviderHelper.supported_providers(
        mcc=network.get('mcc'),
        mnc=network.get('mnc'),
    )

    start_pay.delay(request.session['trans_id'], request.session['notes'],
                    request.session['uuid'], [p.name for p in providers])

    # Now that the background task has been started successfully,
    # prevent configuration from running twice.
    request.session['configured_trans'] = request.session['trans_id']

    return (True, None)
예제 #52
0
파일: tests.py 프로젝트: jincreator/webpay
 def setUp(self):
     self.slumber = mock.MagicMock()
     self.provider = ProviderHelper('reference', slumber=self.slumber)