Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/apps/system/js/payment.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/system/js/payment.js')
-rw-r--r--apps/system/js/payment.js151
1 files changed, 151 insertions, 0 deletions
diff --git a/apps/system/js/payment.js b/apps/system/js/payment.js
new file mode 100644
index 0000000..a953f5c
--- /dev/null
+++ b/apps/system/js/payment.js
@@ -0,0 +1,151 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+// TODO: Blocked by [Payment] UX and visuals for the payment request
+// confirmation screen https://github.com/mozilla-b2g/gaia/issues/2692
+
+'use strict';
+
+const kPaymentConfirmationScreen = '../payment.html';
+
+var Payment = {
+ chromeEventId: null,
+ trustedUILayers: {},
+
+ init: function init() {
+ window.addEventListener('mozChromeEvent', this);
+ },
+
+ handleEvent: function onMozChromeEvent(e) {
+ // We save the mozChromeEvent identifiers to send replies back from content
+ // with this exact value.
+ this.chromeEventId = e.detail.id;
+ if (!this.chromeEventId)
+ return;
+
+ var requestId = e.detail.requestId;
+
+ switch (e.detail.type) {
+ // Chrome asks Gaia to show the payment request confirmation dialog.
+ case 'open-payment-confirmation-dialog':
+ var requests = e.detail.paymentRequests;
+ if (!requests)
+ return;
+
+ var returnSelection = (function returnSelection(selection) {
+ if (!selection)
+ return;
+
+ this._dispatchEvent({
+ id: this.chromeEventId,
+ userSelection: selection
+ });
+ }).bind(this);
+
+ // If there is only one request, we skip the confirmation dialog and
+ // send the request type back to the chrome as a user selection, so
+ // the payment flow can continue.
+ if (requests.length == 1) {
+ returnSelection(requests[0].type);
+ return;
+ }
+
+ var frame = document.createElement('iframe');
+ frame.setAttribute('mozbrowser', 'true');
+ frame.setAttribute('remote', true);
+ frame.classList.add('screen');
+ frame.src = kPaymentConfirmationScreen;
+ frame.addEventListener('mozbrowserloadend', function addReqs(evt) {
+ var frame = evt.target;
+ if (!frame || !requests)
+ return;
+
+ // TODO: Temp layout until issue #2692 is solved.
+ var frameDocument = frame.contentWindow.document;
+ var requestsList = frameDocument.getElementById('requests')
+ .getElementsByTagName('ul')[0];
+ for (var i in requests) {
+ var requestElement = frameDocument.createElement('li');
+ var button = frameDocument.createElement('button');
+ button.setAttribute('value', requests[i].type);
+ var requestText = 'Pay with ' + requests[i].providerName + '\n' +
+ requests[i].productName + '\n' +
+ requests[i].productDescription + '\n' +
+ requests[i].productPrice[0].amount + ' ' +
+ requests[i].productPrice[0].currency;
+ button.appendChild(frameDocument.createTextNode(requestText));
+ button.onclick = function selectRequest() {
+ // We send the selected request back to Chrome so it can start
+ // the appropriate payment flow.
+ returnSelection(this.getAttribute('value'));
+ };
+ requestElement.appendChild(button);
+ requestsList.appendChild(requestElement);
+ }
+ });
+
+ this._openTrustedUI(frame);
+ break;
+
+ // Chrome asks Gaia to show the payment flow according to the
+ // payment request selected by the user.
+ case 'open-payment-flow-dialog':
+ if (!e.detail.uri)
+ return;
+
+ // TODO: For now, known payment providers (BlueVia and Mozilla Market)
+ // only accepts the JWT by GET, so we just add it to the URI.
+ e.detail.uri += e.detail.jwt;
+
+ this.trustedUILayers[requestId] = this.chromeEventId;
+
+ var frame = document.createElement('iframe');
+ frame.setAttribute('mozbrowser', 'true');
+ frame.classList.add('screen');
+ frame.src = e.detail.uri;
+ frame.addEventListener('mozbrowserloadstart', (function loadStart(evt) {
+ // After creating the new frame containing the payment provider buy
+ // flow, we send it back to chrome so the payment callbacks can be
+ // injected.
+ this._dispatchEvent({
+ id: this.chromeEventId,
+ frame: evt.target
+ });
+ }).bind(this));
+
+ // The payment flow is shown within the trusted UI
+ this._openTrustedUI(frame);
+ break;
+
+ case 'close-payment-flow-dialog':
+ TrustedUIManager.close(this.trustedUILayers[requestId],
+ (function dialogClosed() {
+ this._dispatchEvent({ id: this.chromeEventId });
+ delete this.trustedUILayers[requestId];
+ }).bind(this));
+ break;
+ }
+ },
+
+ _openTrustedUI: function _openTrustedUI(frame) {
+ // The payment flow is shown within the trusted UI with the name of
+ // the mozPay caller application as title.
+ var title = WindowManager.getCurrentDisplayedApp().name;
+ title = title ? title : navigator.mozL10n.get('payment-flow');
+ TrustedUIManager.open(title, frame, this.chromeEventId);
+ },
+
+ _dispatchEvent: function _dispatchEvent(obj) {
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('mozContentEvent', true, true, obj);
+ window.dispatchEvent(event);
+ }
+};
+
+// Make sure L10n is ready before init
+if (navigator.mozL10n.readyState == 'complete' ||
+ navigator.mozL10n.readyState == 'interactive') {
+ Payment.init();
+} else {
+ window.addEventListener('localized', Payment.init.bind(Payment));
+}