set up bluevia developer onboarding on manage payments page (bug 776675)
This commit is contained in:
Родитель
d5ff95aef2
Коммит
17bf1bff0b
|
@ -1,6 +1,7 @@
|
|||
import hashlib
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
from tower import ugettext as _
|
||||
|
||||
import paypal
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
cursor: default;
|
||||
text-decoration: none;
|
||||
}
|
||||
.item-actions ul li a {
|
||||
color: @light-gray;
|
||||
}
|
||||
span.req, #payments-payment-account p, .status-fail {
|
||||
color: @light-gray !important;
|
||||
}
|
||||
|
@ -165,7 +168,7 @@
|
|||
}
|
||||
|
||||
/* paypal-setup */
|
||||
.paypal-inline {
|
||||
.paypal-inline, .bluevia-inline {
|
||||
&.brform {
|
||||
p, li label {
|
||||
margin: 0;
|
||||
|
@ -248,3 +251,19 @@ section.add-paypal-email {
|
|||
font-style: italic;
|
||||
}
|
||||
}
|
||||
section.add-bluevia {
|
||||
max-width: 400px;
|
||||
.redirect-info {
|
||||
margin-top: 13px;
|
||||
}
|
||||
}
|
||||
section.add-bluevia-iframe {
|
||||
height: 80%;
|
||||
overflow: hidden;
|
||||
width: 80%;
|
||||
iframe {
|
||||
height: 90%;
|
||||
margin-top: 13px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,15 @@ function escape_(s) {
|
|||
}
|
||||
|
||||
|
||||
z.anonymous = JSON.parse(document.body.getAttribute('data-anonymous'))
|
||||
z.receiveMessage = function(cb) {
|
||||
// Because jQuery chokes, do cross-browser receiving for `postMessage`.
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('message', cb, false);
|
||||
} else {
|
||||
window.attachEvent('onmessage', cb);
|
||||
}
|
||||
};
|
||||
z.anonymous = JSON.parse(document.body.getAttribute('data-anonymous'));
|
||||
z.media_url = document.body.getAttribute('data-media-url');
|
||||
z.readonly = JSON.parse(document.body.getAttribute('data-readonly'));
|
||||
z.apps = true;
|
||||
|
|
|
@ -35,6 +35,8 @@ exports.payment_setup = function() {
|
|||
overlay.html($('#choose-payment-account-template').html());
|
||||
handlePaymentOverlay(overlay);
|
||||
|
||||
var emailRe = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
|
||||
// PayPal chosen.
|
||||
$('button.paypal').click(_pd(function(e) {
|
||||
$('.overlay').remove();
|
||||
|
@ -43,7 +45,6 @@ exports.payment_setup = function() {
|
|||
handlePaymentOverlay(overlay);
|
||||
|
||||
// Email entered and submitted.
|
||||
var emailRe = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
var continue_button = $('.continue');
|
||||
continue_button.click(function(e) {
|
||||
// Validate email.
|
||||
|
@ -63,44 +64,77 @@ exports.payment_setup = function() {
|
|||
});
|
||||
}));
|
||||
|
||||
// Bluevia chosen.
|
||||
$('button.bluevia').click(_pd(function(e) {
|
||||
alert('TODO: bluevia onboarding');
|
||||
// Open Bluevia iframe.
|
||||
$('.overlay').remove();
|
||||
var overlay = makeOrGetOverlay('bluevia-iframe');
|
||||
overlay.html($('#bluevia-iframe-template').html());
|
||||
handlePaymentOverlay(overlay);
|
||||
|
||||
// Set iframe src with the JWT.
|
||||
var blueviaFrame = $('.add-bluevia-iframe iframe');
|
||||
var blueviaOrigin;
|
||||
$.get(blueviaFrame.data('bluevia-url'), function(data) {
|
||||
if (!data.error) {
|
||||
blueviaOrigin = data.bluevia_origin;
|
||||
blueviaFrame.attr('src', data.bluevia_url);
|
||||
} else {
|
||||
successNotification(data.message);
|
||||
}
|
||||
});
|
||||
|
||||
// Set up postMessage handler.
|
||||
z.receiveMessage(function(msg) {
|
||||
// Ensure that this came from only BlueVia.
|
||||
if (msg.origin !== blueviaOrigin) {
|
||||
return;
|
||||
}
|
||||
var postData = JSON.parse(msg.data);
|
||||
switch (postData.status) {
|
||||
case 'failed':
|
||||
// TODO: Log this.
|
||||
successNotification(gettext('There was an error setting up your BlueVia account.'));
|
||||
break;
|
||||
case 'canceled':
|
||||
overlay.remove();
|
||||
return;
|
||||
case 'loggedin': case 'registered':
|
||||
// User already existed or new registration.
|
||||
$.post(blueviaFrame.data('bluevia-callback'), postData, function(data) {
|
||||
$('#bluevia').remove();
|
||||
$('#payments-payment-account').append(data.html);
|
||||
successNotification(data.message[0]);
|
||||
$('.bluevia-actions #remove-account').on('click', _pd(function(e) {
|
||||
removeAccount('bluevia', 'BlueVia');
|
||||
}));
|
||||
});
|
||||
$('#no-payment-providers').addClass('js-hidden');
|
||||
break;
|
||||
}
|
||||
overlay.remove();
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
// Remove PayPal account from app.
|
||||
var paypalRemove = _pd(function(e) {
|
||||
var success = $('.success h2');
|
||||
|
||||
var $remove = $('.paypal-actions #remove-account');
|
||||
var resp = $.get($remove.data('remove-url'));
|
||||
if (!resp.success) {
|
||||
if (success.length) {
|
||||
success.text(gettext('There was an error removing the Paypal account.'));
|
||||
} else {
|
||||
$('#page').prepend($('<section class="full notification-box">' +
|
||||
'<div class="success"><h2>' +
|
||||
gettext('There was an error removing the PayPal account.') +
|
||||
'</h2></div></section>'));
|
||||
}
|
||||
function removeAccount(type, typePretty) {
|
||||
var $remove = $('.' + type + '-actions #remove-account');
|
||||
var resp = $.post($remove.data('remove-url'));
|
||||
if (resp.error) {
|
||||
// L10n: first parameter is the name of a payment provider.
|
||||
successNotification(format(gettext('There was an error removing the {0} account.'), typePretty));
|
||||
}
|
||||
|
||||
var $paypal = $('#paypal');
|
||||
$paypal.addClass('deleting');
|
||||
var $account = $('#' + type);
|
||||
$account.addClass('deleting');
|
||||
setTimeout(function() {
|
||||
$paypal.addClass('deleted');
|
||||
|
||||
// If already existing Django message, replace message.
|
||||
if (success.length) {
|
||||
success.text(gettext('PayPal account successfully removed from app.'));
|
||||
} else {
|
||||
$('#page').prepend($('<section class="full notification-box">' +
|
||||
'<div class="success"><h2>' +
|
||||
gettext('PayPal account successfully removed from app.') +
|
||||
'</h2></div></section>'));
|
||||
$account.addClass('deleted').remove();
|
||||
// L10n: first parameter is the name of a payment provider.
|
||||
successNotification(format(gettext('{0} account successfully removed from app.'), typePretty));
|
||||
if (!$('.payment-option').length) {
|
||||
$('#no-payment-providers').removeClass('js-hidden');
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
var update_forms = function(value) {
|
||||
var fields = [
|
||||
|
@ -143,7 +177,12 @@ exports.payment_setup = function() {
|
|||
});
|
||||
|
||||
$('.payment-account-actions').on('click', _pd(newPaymentAccount));
|
||||
$('#remove-account').on('click', _pd(paypalRemove));
|
||||
$('.paypal-actions #remove-account').on('click', _pd(function(e) {
|
||||
removeAccount('paypal', 'PayPal');
|
||||
}));
|
||||
$('.bluevia-actions #remove-account').on('click', _pd(function(e) {
|
||||
removeAccount('bluevia', 'BlueVia');
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -166,8 +205,7 @@ exports.payment_setup = function() {
|
|||
}
|
||||
|
||||
function handlePaymentOverlay(overlay) {
|
||||
overlay.addClass('show');
|
||||
overlay.on('click', '.close', _pd(function() {
|
||||
overlay.addClass('show').on('click', '.close', _pd(function() {
|
||||
overlay.remove();
|
||||
}));
|
||||
}
|
||||
|
@ -202,7 +240,7 @@ exports.check_with_paypal = function() {
|
|||
|
||||
// Make error messages inactive when initial premium type is
|
||||
// free.
|
||||
if ($.inArray($('section.payments input[name=premium_type]:checked').val(), [0, 3, 4])) {
|
||||
if ($.inArray($('section.payments input[name=premium_type]:checked').val(), [0, 3, 4]) > -1) {
|
||||
$('.status-fail').addClass('inactive');
|
||||
}
|
||||
}
|
|
@ -123,6 +123,18 @@ function initCharCount() {
|
|||
}
|
||||
|
||||
|
||||
function successNotification(msg) {
|
||||
var success = $('.success h2');
|
||||
if (success.length) {
|
||||
success.text(msg);
|
||||
} else {
|
||||
$('#page').prepend($('<section class="full notification-box">' +
|
||||
'<div class="success"><h2>' + msg +
|
||||
'</h2></div></section>'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$('html').ajaxSuccess(function(event, xhr, ajaxSettings) {
|
||||
$(window).trigger('resize'); // Redraw what needs to be redrawn.
|
||||
});
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
CREATE TABLE `bluevia` (
|
||||
`id` int(11) unsigned AUTO_INCREMENT NOT NULL PRIMARY KEY,
|
||||
`created` datetime NOT NULL,
|
||||
`modified` datetime NOT NULL,
|
||||
`user_id` int(11) unsigned NOT NULL,
|
||||
`developer_id` varchar(64) NOT NULL
|
||||
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
ALTER TABLE `bluevia` ADD CONSTRAINT `user_id_refs_id_99d7c3ef` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`);
|
||||
|
||||
CREATE TABLE `addon_bluevia` (
|
||||
`id` int(11) unsigned AUTO_INCREMENT NOT NULL PRIMARY KEY,
|
||||
`created` datetime NOT NULL,
|
||||
`modified` datetime NOT NULL,
|
||||
`addon_id` int(11) unsigned NOT NULL UNIQUE,
|
||||
`bluevia_config_id` int(11) unsigned NOT NULL,
|
||||
`status` int(11) unsigned NOT NULL
|
||||
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
|
||||
ALTER TABLE `addon_bluevia` ADD CONSTRAINT `addon_id_refs_id_5ed7b414` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`);
|
||||
ALTER TABLE `addon_bluevia` ADD CONSTRAINT `bluevia_config_id_refs_id_ef26bb4` FOREIGN KEY (`bluevia_config_id`) REFERENCES `bluevia` (`id`);
|
||||
CREATE INDEX `bluevia_fbfc09f1` ON `bluevia` (`user_id`);
|
||||
CREATE INDEX `bluevia_dev_id_index` ON `bluevia` (`developer_id`);
|
||||
CREATE INDEX `addon_bluevia_a27b43ff` ON `addon_bluevia` (`bluevia_config_id`);
|
||||
CREATE INDEX `addon_bluevia_c9ad71dd` ON `addon_bluevia` (`status`);
|
||||
|
||||
|
||||
INSERT INTO `waffle_switch_mkt` (name, active, note)
|
||||
VALUES ('enabled-paypal', 0, 'Enable this to enable PayPal payments in '
|
||||
'Developer Hub (and soon in consumer pages).');
|
||||
|
||||
INSERT INTO `waffle_switch_mkt` (name, active, note)
|
||||
VALUES ('enabled-bluevia', 1, 'Enable this to enable BlueVia payments in '
|
||||
'Developer Hub (and soon in consumer pages).');
|
|
@ -213,7 +213,7 @@ JS = {
|
|||
'js/devreg/edit.js',
|
||||
|
||||
# Specific stuff for making payments nicer.
|
||||
'js/devreg/paypal.js',
|
||||
'js/devreg/payments.js',
|
||||
'js/zamboni/validator.js',
|
||||
),
|
||||
'mkt/consumer': (
|
||||
|
|
|
@ -1 +1,27 @@
|
|||
from django.db import models
|
||||
|
||||
import amo
|
||||
from devhub.models import ActivityLog
|
||||
from users.models import UserForeignKey
|
||||
|
||||
|
||||
class BlueViaConfig(amo.models.ModelBase):
|
||||
user = UserForeignKey()
|
||||
developer_id = models.CharField(max_length=64)
|
||||
|
||||
class Meta:
|
||||
db_table = 'bluevia'
|
||||
unique_together = ('user', 'developer_id')
|
||||
|
||||
|
||||
class AddonBlueViaConfig(amo.models.ModelBase):
|
||||
addon = models.OneToOneField('addons.Addon',
|
||||
related_name='addonblueviaconfig')
|
||||
bluevia_config = models.ForeignKey(BlueViaConfig)
|
||||
status = models.PositiveIntegerField(choices=amo.INAPP_STATUS_CHOICES,
|
||||
default=amo.INAPP_STATUS_INACTIVE,
|
||||
db_index=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'addon_bluevia'
|
||||
unique_together = ('addon', 'bluevia_config')
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<script type="text/template" id="bluevia-iframe-template">
|
||||
<section class="add-bluevia-iframe">
|
||||
<h2>{{ _('Add BlueVia Account') }}</h2>
|
||||
<a class="close">{{ _('close') }}</a>
|
||||
<iframe data-bluevia-url="{{ addon.get_dev_url('get_bluevia_url') }}"
|
||||
data-bluevia-callback="{{ addon.get_dev_url('bluevia_callback') }}"
|
||||
target="_blank"></iframe>
|
||||
</section>
|
||||
</script>
|
|
@ -3,19 +3,21 @@
|
|||
<h2>{{ _('Select Payment Provider') }}</h2>
|
||||
<a class="close">{{ _('close') }}</a>
|
||||
<div id="choose" class="brform c paypal-inline">
|
||||
<div>
|
||||
<form>
|
||||
<button type="submit" class="bluevia prominent">BlueVia</button>
|
||||
</form>
|
||||
<a href="https://bluevia.com/" target="_blank">{{ _('Learn More') }}</a>
|
||||
</div>
|
||||
<div class="or">{{ _('or') }}</div>
|
||||
<div>
|
||||
<form>
|
||||
<button type="submit" class="paypal prominent">Pay<em>Pal</em></button>
|
||||
</form>
|
||||
<a href="https://paypal.com/" target="_blank">{{ _('Learn More') }}</a>
|
||||
</div>
|
||||
{% if waffle.switch('enabled-bluevia') %}
|
||||
<div>
|
||||
<button class="bluevia prominent" data-bluevia-url="{{ bluevia_url }}">BlueVia</button>
|
||||
<a href="https://bluevia.com/" target="_blank">{{ _('Learn More') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if waffle.switch('enabled-bluevia') and waffle.switch('enabled-paypal') %}
|
||||
<div class="or">{{ _('or') }}</div>
|
||||
{% endif %}
|
||||
{% if waffle.switch('enabled-paypal') %}
|
||||
<div>
|
||||
<button class="paypal prominent">Pay<em>Pal</em></button>
|
||||
<a href="https://paypal.com/" target="_blank">{{ _('Learn More') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
</script>
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
<label>{{ _('What is the email for your PayPal account?') }}</label>
|
||||
<input type="text" name="email" class="email">
|
||||
</div>
|
||||
<span class="email-error">{{ _('Please enter a valid Paypal email.') }}</span>
|
||||
<span class="email-error">{{ _('Please enter a valid PayPal email.') }}</span>
|
||||
<a href="{{ paypal_create_url }}" target="_blank">{{ _('No Premier or Business PayPal account? Sign up.') }}</a>
|
||||
<p class='redirect-info'>
|
||||
{{ _('On continue, log in to PayPal to give Marketplace
|
||||
<p class="redirect-info">
|
||||
{{ _('On continue, log in to PayPal to give the Marketplace
|
||||
permissions to process refunds and access your PayPal account
|
||||
information.') }}
|
||||
</p>
|
|
@ -0,0 +1,19 @@
|
|||
<div id="bluevia" class="indent payment-option">
|
||||
<label for="bluevia-account">BlueVia</label>
|
||||
<span>
|
||||
{% trans time=bluevia.created %}
|
||||
BlueVia account set up on {{ time }}.
|
||||
{% endtrans %}
|
||||
</span>
|
||||
<span id="check-passed" class="check-icon"></span>
|
||||
<div class="item-actions bluevia-actions">
|
||||
<ul>
|
||||
<li>
|
||||
<a id="remove-account"
|
||||
data-remove-url="{{ addon.get_dev_url('bluevia_remove') }}">
|
||||
{{ _('Remove Account') }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
|
@ -1,9 +1,12 @@
|
|||
{% from 'developers/includes/macros.html' import required %}
|
||||
<div class="brform" id="payments-payment-account">
|
||||
<label id="payment-label" for="id_payment_account">{{ _('Use Payment Account') }} {{ required() }}</label>
|
||||
<div class="extra">
|
||||
<a href="#" class="payment-account-actions" data-action="add">{{ _('Add Account') }}</a>
|
||||
</div>
|
||||
|
||||
{% if waffle.switch('enabled-bluevia') and waffle.switch('enabled-paypal') %}
|
||||
<div class="extra">
|
||||
<a href="#" class="payment-account-actions" data-action="add">{{ _('Add Account') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if addon.paypal_id %}
|
||||
<div id="paypal" class="indent payment-option">
|
||||
|
@ -50,13 +53,15 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bluevia" class="indent payment-option">
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<p>{{ _('You have not yet setup any payment providers. You will not be able to
|
||||
receive payments until you do so.') }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if bluevia %}
|
||||
{% include 'developers/payments/includes/bluevia.html' %}
|
||||
{% endif %}
|
||||
|
||||
<p id="no-payment-providers" {% if addon.paypal_id or bluevia %}class="js-hidden"{% endif %}>
|
||||
{{ _('You have not yet set up any payment providers. You will not be able to
|
||||
receive payments until you do so.') }}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="brform c" id="payments-upsell">
|
||||
{% if form.fields['free'].queryset.count() %}
|
||||
{{ form.free.errors }}
|
||||
<label>{{ form.free.label }} {{ required() }}</label>
|
||||
<label for="{{ form.free.auto_id }}">{{ form.free.label }} {{ required() }}</label>
|
||||
{{ form.free }}
|
||||
<p class="note">
|
||||
{% trans %}
|
||||
|
|
|
@ -49,5 +49,6 @@
|
|||
</section>
|
||||
{% include 'developers/includes/addons_edit_nav.html' %}
|
||||
{% include 'developers/payments/includes/add_payment_account_choose.html' %}
|
||||
{% include 'developers/payments/includes/add_payment_account_paypal_email.html' %}
|
||||
{% include 'developers/payments/includes/add_payment_account_paypal.html' %}
|
||||
{% include 'developers/payments/includes/add_payment_account_bluevia.html' %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
import json
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
import amo
|
||||
import amo.tests
|
||||
from market.models import AddonPremium
|
||||
from mkt.developers.models import AddonBlueViaConfig, BlueViaConfig
|
||||
from users.models import UserProfile
|
||||
|
||||
|
||||
class TestBlueVia(amo.tests.WebappTestCase):
|
||||
fixtures = ['base/apps', 'base/users', 'webapps/337141-steamcube']
|
||||
|
||||
def setUp(self):
|
||||
super(TestBlueVia, self).setUp()
|
||||
self.url = self.app.get_dev_url('payments')
|
||||
self.client.login(username='admin@mozilla.com', password='password')
|
||||
self.user = UserProfile.objects.get(username='admin')
|
||||
AddonPremium.objects.create(addon=self.app)
|
||||
|
||||
def test_get_bluevia_url(self):
|
||||
url = self.app.get_dev_url('get_bluevia_url')
|
||||
res = json.loads(self.client.get(url).content)
|
||||
eq_(res['error'], False)
|
||||
eq_(res['bluevia_url'].startswith(settings.BLUEVIA_URL), True)
|
||||
|
||||
def test_bluevia_callback_register(self):
|
||||
url = self.app.get_dev_url('bluevia_callback')
|
||||
developer_id = 'abc123wootrofllolomgbbqznyandragons'
|
||||
res = self.client.post(url, data={'developerId': developer_id,
|
||||
'status': 'registered'})
|
||||
data = json.loads(res.content)
|
||||
eq_(data['error'], False)
|
||||
eq_(BlueViaConfig.objects.count(), 1)
|
||||
eq_(AddonBlueViaConfig.objects.count(), 1)
|
||||
eq_(AddonBlueViaConfig.objects.get(addon=self.app).bluevia_config
|
||||
.developer_id, developer_id)
|
||||
|
||||
def bluevia_callback_test(self):
|
||||
url = self.app.get_dev_url('bluevia_callback')
|
||||
developer_id = 'abc123wootrofllolomgbbqznyandragons'
|
||||
res = self.client.post(url, data={'developerId': developer_id,
|
||||
'status': 'loggedin'})
|
||||
data = json.loads(res.content)
|
||||
eq_(data['error'], False)
|
||||
eq_(AddonBlueViaConfig.objects.count(), 1)
|
||||
eq_(AddonBlueViaConfig.objects.get(addon=self.app).bluevia_config
|
||||
.developer_id, developer_id)
|
||||
eq_(str(AddonBlueViaConfig.objects.get(addon=self.app).bluevia_config
|
||||
.created) in data['html'], True)
|
||||
|
||||
def test_bluevia_callback_log_in(self):
|
||||
self.bluevia_callback_test()
|
||||
eq_(BlueViaConfig.objects.count(), 1)
|
||||
|
||||
def create_bluevia_configs(self):
|
||||
bluevia_config = BlueViaConfig.objects.create(developer_id='old123',
|
||||
user=self.user)
|
||||
AddonBlueViaConfig.objects.create(addon=self.app,
|
||||
bluevia_config=bluevia_config)
|
||||
|
||||
def test_bluevia_callback_existing(self):
|
||||
self.create_bluevia_configs()
|
||||
self.bluevia_callback_test()
|
||||
eq_(BlueViaConfig.objects.count(), 2)
|
||||
|
||||
def test_bluevia_remove(self):
|
||||
self.create_bluevia_configs()
|
||||
|
||||
url = self.app.get_dev_url('bluevia_remove')
|
||||
res = self.client.post(url)
|
||||
data = json.loads(res.content)
|
||||
eq_(data['error'], False)
|
||||
eq_(BlueViaConfig.objects.count(), 1)
|
||||
eq_(AddonBlueViaConfig.objects.count(), 0)
|
||||
|
||||
def test_bluevia_remove_error(self):
|
||||
url = self.app.get_dev_url('bluevia_remove')
|
||||
res = self.client.post(url)
|
||||
data = json.loads(res.content)
|
||||
eq_(data['error'], True)
|
||||
|
||||
def test_bluevia_payments_page(self):
|
||||
res = self.client.get(self.url)
|
||||
eq_(pq(res.content)('#bluevia').length, 0)
|
||||
|
||||
self.create_bluevia_configs()
|
||||
|
||||
res = self.client.get(self.url)
|
||||
eq_(pq(res.content)('#bluevia').length, 1)
|
|
@ -50,7 +50,14 @@ app_detail_patterns = patterns('',
|
|||
url('^payments$', views.payments, name='mkt.developers.apps.payments'),
|
||||
# PayPal-specific stuff.
|
||||
url('^paypal/', include(paypal_patterns('apps'))),
|
||||
url('^paypal/', include(paypal_patterns('addons'))),
|
||||
|
||||
# Bluevia-specific stuff.
|
||||
url('^bluevia$', views.get_bluevia_url,
|
||||
name='mkt.developers.apps.get_bluevia_url'),
|
||||
url('^bluevia/callback$', views.bluevia_callback,
|
||||
name='mkt.developers.apps.bluevia_callback'),
|
||||
url('^bluevia/remove$', views.bluevia_remove,
|
||||
name='mkt.developers.apps.bluevia_remove'),
|
||||
|
||||
# in-app payments.
|
||||
url('^in-app-config$', views.in_app_config,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import calendar
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from django import http
|
||||
|
@ -14,9 +16,10 @@ from django.views.decorators.csrf import csrf_view_exempt
|
|||
|
||||
import commonware.log
|
||||
import jingo
|
||||
import waffle
|
||||
import jwt
|
||||
from session_csrf import anonymous_csrf
|
||||
from tower import ugettext as _, ugettext_lazy as _lazy
|
||||
import waffle
|
||||
from waffle.decorators import waffle_switch
|
||||
|
||||
import amo
|
||||
|
@ -49,13 +52,14 @@ from users.models import UserProfile
|
|||
from users.views import _login
|
||||
from versions.models import Version
|
||||
|
||||
from mkt.constants import APP_IMAGE_SIZES
|
||||
from mkt.constants import APP_IMAGE_SIZES, regions
|
||||
from mkt.developers.decorators import dev_required
|
||||
from mkt.developers.forms import (AppFormBasic, AppFormDetails, AppFormMedia,
|
||||
AppFormSupport, CategoryForm,
|
||||
ImageAssetFormSet, InappConfigForm,
|
||||
PaypalSetupForm, PreviewFormSet, RegionForm,
|
||||
trap_duplicate)
|
||||
from mkt.developers.models import AddonBlueViaConfig, BlueViaConfig
|
||||
from mkt.developers.utils import check_upload
|
||||
from mkt.inapp_pay.models import InappConfig
|
||||
from mkt.submit.forms import NewWebappForm
|
||||
|
@ -66,6 +70,7 @@ from . import forms, tasks
|
|||
|
||||
log = commonware.log.getLogger('z.devhub')
|
||||
paypal_log = commonware.log.getLogger('z.paypal')
|
||||
bluevia_log = commonware.log.getLogger('z.bluevia')
|
||||
|
||||
|
||||
# We use a session cookie to make sure people see the dev agreement.
|
||||
|
@ -298,7 +303,7 @@ def paypal_setup(request, addon_id, addon, webapp):
|
|||
|
||||
return {'valid': True, 'message': [], 'paypal_url': paypal_url}
|
||||
|
||||
return {'valid': False, 'message': [_('Form not valid')]}
|
||||
return {'valid': False, 'message': [_('Form not valid.')]}
|
||||
|
||||
|
||||
def get_paypal_bounce_url(request, addon_id, addon, webapp, json_view=False):
|
||||
|
@ -486,6 +491,7 @@ def paypal_setup_check(request, addon_id, addon, webapp):
|
|||
|
||||
|
||||
@json_view
|
||||
@post_required
|
||||
@dev_required(owner_for_post=True, webapp=True)
|
||||
def paypal_remove(request, addon_id, addon, webapp):
|
||||
"""
|
||||
|
@ -497,8 +503,83 @@ def paypal_remove(request, addon_id, addon, webapp):
|
|||
.safer_get_or_create(addon=addon))
|
||||
addonpremium.update(paypal_permissions_token='')
|
||||
except Exception as e:
|
||||
return {'success': False, 'error': [e]}
|
||||
return {'success': True, 'error': []}
|
||||
return {'error': True, 'message': [e]}
|
||||
return {'error': False, 'message': []}
|
||||
|
||||
|
||||
@json_view
|
||||
@dev_required(webapp=True)
|
||||
def get_bluevia_url(request, addon_id, addon, webapp):
|
||||
"""
|
||||
Email choices:
|
||||
registered_data@user.com
|
||||
registered_no_data@user.com
|
||||
"""
|
||||
data = {
|
||||
'email': request.GET.get('email', request.user.email),
|
||||
'locale': request.LANG,
|
||||
'country': getattr(request, 'REGION', regions.US).mcc
|
||||
}
|
||||
if addon.paypal_id:
|
||||
data['paypal'] = addon.paypal_id
|
||||
issued_at = calendar.timegm(time.gmtime())
|
||||
# JWT-specific fields.
|
||||
data.update({
|
||||
'aud': addon.id, # app ID
|
||||
'typ': 'dev-registration',
|
||||
'iat': issued_at,
|
||||
'exp': issued_at + 3600, # expires in 1 hour
|
||||
'iss': settings.SITE_URL, # expires in 1 hour
|
||||
})
|
||||
signed_data = jwt.encode(data, settings.BLUEVIA_SECRET, algorithm='HS256')
|
||||
return {'error': False, 'message': [],
|
||||
'bluevia_origin': settings.BLUEVIA_ORIGIN,
|
||||
'bluevia_url': settings.BLUEVIA_URL + signed_data}
|
||||
|
||||
|
||||
@json_view
|
||||
@post_required
|
||||
@transaction.commit_on_success
|
||||
@dev_required(owner_for_post=True, webapp=True)
|
||||
def bluevia_callback(request, addon_id, addon, webapp):
|
||||
developer_id = request.POST.get('developerId')
|
||||
status = request.POST.get('status')
|
||||
if status in ['registered', 'loggedin']:
|
||||
bluevia = BlueViaConfig.objects.create(user=request.amo_user,
|
||||
developer_id=developer_id)
|
||||
try:
|
||||
(AddonBlueViaConfig.objects.get(addon=addon)
|
||||
.update(bluevia_config=bluevia))
|
||||
except AddonBlueViaConfig.DoesNotExist:
|
||||
AddonBlueViaConfig.objects.create(addon=addon,
|
||||
bluevia_config=bluevia)
|
||||
bluevia_log.info('BlueVia account, %s, paired with %s app'
|
||||
% (developer_id, addon_id))
|
||||
return {'error': False,
|
||||
'message': [_('You have successfully paired your BlueVia '
|
||||
'account with the Marketplace.')],
|
||||
'html': jingo.render(
|
||||
request, 'developers/payments/includes/bluevia.html',
|
||||
dict(addon=addon, bluevia=bluevia)).content}
|
||||
|
||||
|
||||
@json_view
|
||||
@post_required
|
||||
@transaction.commit_on_success
|
||||
@dev_required(owner_for_post=True, webapp=True)
|
||||
def bluevia_remove(request, addon_id, addon, webapp):
|
||||
"""
|
||||
Unregisters BlueVia account from app.
|
||||
"""
|
||||
try:
|
||||
bv = AddonBlueViaConfig.objects.get(addon=addon)
|
||||
developer_id = bv.bluevia_config.developer_id
|
||||
bv.delete()
|
||||
bluevia_log.info('BlueVia account, %s, removed from %s app'
|
||||
% (developer_id, addon_id))
|
||||
except AddonBlueViaConfig.DoesNotExist as e:
|
||||
return {'error': True, 'message': [str(e)]}
|
||||
return {'error': False, 'message': []}
|
||||
|
||||
|
||||
@waffle_switch('in-app-payments')
|
||||
|
@ -586,10 +667,15 @@ def _premium(request, addon_id, addon, webapp=False):
|
|||
messages.success(request, _('Changes successfully saved.'))
|
||||
return redirect(addon.get_dev_url('payments'))
|
||||
|
||||
try:
|
||||
bluevia = addon.addonblueviaconfig.bluevia_config
|
||||
except AddonBlueViaConfig.DoesNotExist:
|
||||
bluevia = None
|
||||
|
||||
return jingo.render(request, 'developers/payments/premium.html',
|
||||
dict(addon=addon, webapp=webapp, premium=addon.premium,
|
||||
paypal_create_url=settings.PAYPAL_CGI_URL,
|
||||
form=premium_form))
|
||||
bluevia=bluevia, form=premium_form))
|
||||
|
||||
|
||||
@waffle_switch('allow-refund')
|
||||
|
|
|
@ -273,6 +273,11 @@ STATSD_RECORD_KEYS = [
|
|||
|
||||
PISTON_DISPLAY_ERRORS = False
|
||||
|
||||
# Key for signing requests to BlueVia for developer registration.
|
||||
BLUEVIA_SECRET = ''
|
||||
BLUEVIA_ORIGIN = 'https://opentel20.tidprojects.com'
|
||||
BLUEVIA_URL = BLUEVIA_ORIGIN + '/en/mozilla/?req='
|
||||
|
||||
# Link to the appcache manifest (activate it) when True.
|
||||
USE_APPCACHE = False
|
||||
|
||||
|
|
|
@ -68,8 +68,10 @@ class NewWebappForm(happyforms.Form):
|
|||
|
||||
class PaypalSetupForm(happyforms.Form):
|
||||
business_account = forms.ChoiceField(widget=forms.RadioSelect, choices=[],
|
||||
label=_(u'Do you already have a PayPal Premier or Business account?'))
|
||||
email = forms.EmailField(required=False, label=_(u'PayPal email address'))
|
||||
label=_lazy(u'Do you already have a PayPal Premier '
|
||||
'or Business account?'))
|
||||
email = forms.EmailField(required=False,
|
||||
label=_lazy(u'PayPal email address'))
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(PaypalSetupForm, self).__init__(*args, **kw)
|
||||
|
|
Загрузка…
Ссылка в новой задаче