new in-app flow beginnings
This commit is contained in:
Родитель
05ef908263
Коммит
75f82cea0d
|
@ -1,27 +1,44 @@
|
|||
html {
|
||||
background: none;
|
||||
}
|
||||
body {
|
||||
border: none;
|
||||
}
|
||||
#page {
|
||||
margin: 0;
|
||||
min-height: 250px;
|
||||
min-width: 300px;
|
||||
max-width: none;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
.payment-screen {
|
||||
border: 0;
|
||||
width: 300px;
|
||||
margin: 0 auto;
|
||||
z-index: auto;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
padding: 1em;
|
||||
@import 'lib';
|
||||
|
||||
section {
|
||||
.border-radius(2px);
|
||||
.box-shadow(0 2px 2px fadeOut(#000, 20%));
|
||||
background-color: @bg;
|
||||
.grain;
|
||||
.border-box;
|
||||
margin: 10px;
|
||||
height: 200px;
|
||||
position: relative;
|
||||
float: none;
|
||||
background: none;
|
||||
left: auto;
|
||||
}
|
||||
header {
|
||||
.box-shadow(0 2px 2px fadeOut(#000, 50%));
|
||||
background-color: #404f5a;
|
||||
.grain;
|
||||
color: @white;
|
||||
padding: 10px;
|
||||
}
|
||||
& > div {
|
||||
padding: 10px 1em;
|
||||
margin-bottom: 54px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.product-details {
|
||||
float: left;
|
||||
width: 270px;
|
||||
}
|
||||
.actions {
|
||||
float: right;
|
||||
width: 120px;
|
||||
.button {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
footer {
|
||||
.border-box;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
(function(exports) {
|
||||
"use strict";
|
||||
// (function(exports) {
|
||||
// "use strict";
|
||||
|
||||
// Close the thank you window. TODO: Thank you windows are going away!
|
||||
$('#close-moz-pay-win').click(function(e) {
|
||||
e.preventDefault();
|
||||
_send('moz-pay-success');
|
||||
});
|
||||
// // Close the thank you window. TODO: Thank you windows are going away!
|
||||
// $('#close-moz-pay-win').click(function(e) {
|
||||
// e.preventDefault();
|
||||
// _send('moz-pay-success');
|
||||
// });
|
||||
|
||||
$('#close-moz-error-win').click(function(e) {
|
||||
e.preventDefault();
|
||||
_send('moz-pay-failure');
|
||||
});
|
||||
// $('#close-moz-error-win').click(function(e) {
|
||||
// e.preventDefault();
|
||||
// _send('moz-pay-failure');
|
||||
// });
|
||||
|
||||
function _send(msg) {
|
||||
// This is using '*' because we're not sure what the app domain is.
|
||||
// Maybe we can find that out.
|
||||
window.top.postMessage(msg, '*');
|
||||
}
|
||||
// function _send(msg) {
|
||||
// // This is using '*' because we're not sure what the app domain is.
|
||||
// // Maybe we can find that out.
|
||||
// window.top.postMessage(msg, '*');
|
||||
// }
|
||||
|
||||
})(typeof exports === 'undefined' ? (this.inapp_payments = {}) : exports);
|
||||
// })(typeof exports === 'undefined' ? (this.inapp_payments = {}) : exports);
|
||||
|
|
|
@ -7,6 +7,81 @@ https://developer.mozilla.org/en/Apps/In-app_payments
|
|||
*/
|
||||
(function(exports) {
|
||||
"use strict";
|
||||
// embedded https://github.com/potch/picolib
|
||||
var $ = (function(win, doc, undefined) {
|
||||
|
||||
function pico(sel) {
|
||||
var ret,
|
||||
p,
|
||||
forEach = Array.prototype.forEach;
|
||||
|
||||
ret = sel.nodeType ? [sel] : doc.querySelectorAll(sel);
|
||||
|
||||
ret.each = (function(fn) {
|
||||
forEach.call(this, function(item) {
|
||||
fn.call(item);
|
||||
});
|
||||
return this;
|
||||
}).bind(ret);
|
||||
|
||||
|
||||
ret.on = (function(type, handler) {
|
||||
this.each(function() {
|
||||
on(this, type, handler)
|
||||
});
|
||||
return this;
|
||||
}).bind(ret);
|
||||
|
||||
|
||||
ret.css = (function(o) {
|
||||
if (typeof o == 'object') {
|
||||
for (p in o) {
|
||||
this.each(function() {
|
||||
this.style[p] = o[p];
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return win.getComputedStyle(this[0]).getPropertyValue(o);
|
||||
}).bind(ret);
|
||||
|
||||
|
||||
ret.attr = (function(o) {
|
||||
if (typeof o == 'object') {
|
||||
for (p in o) {
|
||||
this.each(function() {
|
||||
this.setAttribute(p, o[p]);
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return this[0].getAttribute(o);
|
||||
}).bind(ret);
|
||||
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
var on = pico.on = function(el, type, handler) {
|
||||
el.addEventListener(type, function(e) {
|
||||
handler.call(e.target, e);
|
||||
}, false);
|
||||
};
|
||||
|
||||
return pico;
|
||||
})(window, document);
|
||||
|
||||
var format = (function() {
|
||||
var re = /\{([^}]+)\}/g;
|
||||
return function(s, args) {
|
||||
if (!args) return;
|
||||
if (!(args instanceof Array || args instanceof Object))
|
||||
args = Array.prototype.slice.call(arguments, 1);
|
||||
return s.replace(re, function(_, match){ return args[match]; });
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
|
||||
var onPaySuccess, onPayFailure;
|
||||
|
||||
|
@ -21,8 +96,6 @@ exports.buy = function(signedRequest, _onPaySuccess, _onPayFailure) {
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Delete all of this code. This is just a prototype for demos.
|
||||
// -------------------------------------------------------------
|
||||
|
@ -31,25 +104,6 @@ exports.buy = function(signedRequest, _onPaySuccess, _onPayFailure) {
|
|||
|
||||
var server, payWindow;
|
||||
|
||||
// Using jQuery for easy prototyping...
|
||||
if (typeof $ === 'undefined') {
|
||||
console.log('This prototype currently requires jQuery');
|
||||
}
|
||||
|
||||
// TODO: we'll eventually hardcode server to marketplace.mozilla.org,
|
||||
// this is in place for local development and testing.
|
||||
// WARNING: this is pretty much the most insecure code ever.
|
||||
setTimeout(function() {
|
||||
$('script').each(function(i, elem) {
|
||||
var src = $(elem).attr('src');
|
||||
if (src.search('mozmarket.js') != -1) {
|
||||
server = src.replace(/(https?:\/\/[^\/]+).*/g, '$1');
|
||||
// When discovering the server based on a CDN link, convert the URL.
|
||||
server = server.replace(/(marketplace)(-dev?)-cdn/g, '$1$2');
|
||||
}
|
||||
});
|
||||
}, 1);
|
||||
|
||||
|
||||
function handleMessage(msg) {
|
||||
if (msg.origin !== server) {
|
||||
|
@ -81,12 +135,15 @@ function handleMessage(msg) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( window.addEventListener ) {
|
||||
window.addEventListener( "message", handleMessage, false );
|
||||
} else if ( window.attachEvent ) {
|
||||
window.attachEvent( "onmessage", handleMessage );
|
||||
}
|
||||
// if (window.addEventListener ) {
|
||||
// window.addEventListener( "message", handleMessage, false );
|
||||
// } else if ( window.attachEvent ) {
|
||||
// window.attachEvent( "onmessage", handleMessage );
|
||||
// }
|
||||
|
||||
var overlayStyle = 'position:absolute;top:0;left:0;right:0;bottom:0;' +
|
||||
'width:100%;max-width:450px;height:100%;max-height:350px;' +
|
||||
'z-index:2001;margin:auto;border:0';
|
||||
|
||||
function showPaymentScreen(signedRequest, onPaySuccess, onPayFailure) {
|
||||
// check cookie for marketplace session?
|
||||
|
@ -95,38 +152,23 @@ function showPaymentScreen(signedRequest, onPaySuccess, onPayFailure) {
|
|||
}
|
||||
|
||||
function _overlay_showPaymentScreen(signedRequest, onPaySuccess, onPayFailure) {
|
||||
var $overlay = $('#moz-payment-overlay'),
|
||||
width = 450,
|
||||
left = ($(window).width() - width) / 2,
|
||||
top = $(window).scrollTop() + 26; // distance from top of the window;
|
||||
if ($overlay.length) {
|
||||
// If an app defined their own then remove it.
|
||||
// TODO: more click jacking protection :/
|
||||
$overlay.remove();
|
||||
var overlay = $('#moz-payment-overlay')[0];
|
||||
if (overlay) {
|
||||
overlay.parentNode.removeChild(overlay);
|
||||
}
|
||||
$overlay = $('<iframe></iframe>', {'id': 'moz-payment-overlay',
|
||||
'type': 'text/html',
|
||||
'src': server + '/inapp-pay/pay_start?req=' + signedRequest});
|
||||
$overlay.css({'position': 'absolute',
|
||||
'top': top + 'px',
|
||||
'left': left + 'px',
|
||||
'width': width + 'px',
|
||||
'height': '250px',
|
||||
'background': '#fff',
|
||||
'z-index': '2001',
|
||||
'border': '3px solid #2e5186',
|
||||
'-webkit-border-radius': '8px',
|
||||
'-moz-border-radius': '8px',
|
||||
'border-radius': '8px',
|
||||
'box-shadow': '0 1px 3px rgba(0, 0, 0, 0.35)',
|
||||
'-moz-box-shadow': '0 1px 3px rgba(0, 0, 0, 0.35)',
|
||||
'-webkit-box-shadow': '0 1px 3px rgba(0, 0, 0, 0.35)'});
|
||||
$('body').css('z-index', '-1').append($overlay);
|
||||
var $overlay = $(document.createElement('iframe'));
|
||||
$overlay.attr({
|
||||
'id': 'moz-payment-overlay',
|
||||
'type': 'text/html',
|
||||
'src': format('{0}/inapp-pay/pay_start?req={1}', 'http://marketplace-dev.allizom.org', signedRequest),
|
||||
'style': overlayStyle
|
||||
});
|
||||
$('body').css({'z-index': '-1'})[0].appendChild($overlay[0]);
|
||||
}
|
||||
|
||||
function _popup_showPaymentScreen(signedRequest, onPaySuccess, onPayFailure) {
|
||||
if (payWindow == null || payWindow.closed) {
|
||||
payWindow = window.open(server + '/inapp-pay/pay_start?req=' + signedRequest, 'moz-payment-screen',
|
||||
payWindow = window.open('http://marketplace-dev.allizom.org/inapp-pay/pay_start?req=' + signedRequest, 'moz-payment-screen',
|
||||
'menubar=0,location=1,resizable=1,scrollbars=1,status=0,close=1,width=450,height=250,dialog=1');
|
||||
} else {
|
||||
payWindow.focus();
|
||||
|
|
|
@ -93,50 +93,9 @@ CSS = {
|
|||
'css/devreg/l10n.less',
|
||||
),
|
||||
'mkt/in-app-payments': (
|
||||
# Temporarily re-using PayPal styles for in-app-payments UI
|
||||
# until we actually have a UI.
|
||||
'css/impala/base.css',
|
||||
'css/legacy/jquery-lightbox.css',
|
||||
'css/impala/site.less',
|
||||
'css/impala/typography.less',
|
||||
'css/global/headerfooter.css',
|
||||
'css/impala/forms.less',
|
||||
'css/impala/header.less',
|
||||
'css/impala/footer.less',
|
||||
'css/impala/moz-tab.css',
|
||||
'css/impala/hovercards.less',
|
||||
'css/impala/toplist.less',
|
||||
'css/impala/carousel.less',
|
||||
'css/impala/reviews.less',
|
||||
'css/impala/buttons.less',
|
||||
'css/impala/promos.less',
|
||||
'css/impala/addon_details.less',
|
||||
'css/impala/policy.less',
|
||||
'css/impala/expando.less',
|
||||
'css/impala/popups.less',
|
||||
'css/impala/l10n.less',
|
||||
'css/impala/contributions.less',
|
||||
'css/impala/lightbox.less',
|
||||
'css/impala/prose.less',
|
||||
'css/impala/sharing.less',
|
||||
'css/impala/abuse.less',
|
||||
'css/impala/paginator.less',
|
||||
'css/impala/listing.less',
|
||||
'css/impala/versions.less',
|
||||
'css/impala/users.less',
|
||||
'css/impala/collections.less',
|
||||
'css/impala/tooltips.less',
|
||||
'css/impala/search.less',
|
||||
'css/impala/suggestions.less',
|
||||
'css/impala/colorpicker.less',
|
||||
'css/impala/personas.less',
|
||||
'css/impala/login.less',
|
||||
'css/impala/dictionaries.less',
|
||||
'css/impala/apps.less',
|
||||
'css/impala/formset.less',
|
||||
'css/impala/tables.less',
|
||||
'css/impala/compat.less',
|
||||
'css/impala/localizers.less',
|
||||
'css/mkt/reset.less',
|
||||
'css/mkt/typography.less',
|
||||
'css/mkt/buttons.less',
|
||||
'css/mkt/in-app-payments.less',
|
||||
),
|
||||
'mkt/stats': (
|
||||
|
|
|
@ -1,26 +1,14 @@
|
|||
{% extends "mkt/base.html" %}
|
||||
|
||||
{% block site_css %}
|
||||
{{ css('mkt/in-app-payments') }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block siteheader %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block sitefooter %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ js('mkt/in-app-payments') }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="paypal-modal modal payment-screen">
|
||||
{% block screen_content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ LANG }}" dir="{{ DIR }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{{ css('mkt/in-app-payments') }}
|
||||
</head>
|
||||
<body data-user="{{ user_data(amo_user)|json }}">
|
||||
<section>
|
||||
{% block screen_content %}
|
||||
{% endblock %}
|
||||
</section>
|
||||
{#{ js('mkt/in-app-payments') }#}
|
||||
</body>
|
||||
</html>
|
|
@ -1,36 +1,17 @@
|
|||
{% extends "inapp_pay/base.html" %}
|
||||
|
||||
{% block screen_content %}
|
||||
<h2>{{ loc('Mozilla Payments') }}</h2>
|
||||
<div class="paypal-content">
|
||||
<span class="price">{{ currency }} {{ price }}</span>
|
||||
<h5>{{ item }}</h5>
|
||||
<p>{{ description }}</p>
|
||||
<div class="paypal-parent">
|
||||
{% if user.is_authenticated() %}
|
||||
<div class="paypal-user">
|
||||
{% trans user_email=user.email %}
|
||||
You are logged in as <strong>{{ user_email }}</strong>!
|
||||
{% endtrans %}
|
||||
</div>
|
||||
<form method="post" action="{{ url('inapp_pay.pay') }}">
|
||||
{{ csrf() }}
|
||||
<input type="hidden" name="req" value="{{ signed_request }}">
|
||||
<button class="button prominent paypal">
|
||||
{# The <small> makes it smaller, <em> makes it darker. Don't localize "PayPal". #}
|
||||
{{ loc('Pay <small>with</small> Pay<em>Pal</em>')|xssafe }}
|
||||
</button>
|
||||
</form>
|
||||
<p>{{ loc('Complete your purchase with PayPal. No PayPal account is necessary.') }}</p>
|
||||
{% else %}
|
||||
<div class="paypal-user login">
|
||||
<a href="#" class="browserid-login button prominent"
|
||||
data-url="{{ url('users.browserid_login') }}" data-event="login-complete">
|
||||
{{ loc('Log in / Register') }}
|
||||
</a>
|
||||
</div>
|
||||
<p>{{ loc('You need to be logged in to the Mozilla Marketplace to make payments.') }}</p>
|
||||
{% endif %}
|
||||
<header>
|
||||
{{ _('Marketplace') }} — {{ product.name }}
|
||||
</header>
|
||||
<div>
|
||||
<div class="product-details">
|
||||
<h2>{{ item }}</h2>
|
||||
<p>{{ description }}</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a href="#" class="button">{{ currency }} {{ price }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<footer>{{ _('refunds are not available for in-app purchases') }}</footer>
|
||||
{% endblock %}
|
||||
|
|
|
@ -36,6 +36,7 @@ log = commonware.log.getLogger('z.inapp_pay')
|
|||
def pay_start(request, signed_req, pay_req):
|
||||
InappPayLog.log(request, 'PAY_START', config=pay_req['_config'])
|
||||
data = dict(price=pay_req['request']['price'],
|
||||
product=pay_req['_config'].addon,
|
||||
currency=pay_req['request']['currency'],
|
||||
item=pay_req['request']['name'],
|
||||
description=pay_req['request']['description'],
|
||||
|
|
Загрузка…
Ссылка в новой задаче