Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Credentials payment #1

Merged
merged 14 commits into from
Nov 7, 2016
1 change: 1 addition & 0 deletions src/lazy-resources.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<link rel="import" href="shop-snackbar.html">
<link rel="import" href="shop-tabs.html">
<link rel="import" href="shop-tab.html">
<link rel="import" href="shop-payment-request.html">

<!-- shop-home -->

Expand Down
111 changes: 45 additions & 66 deletions src/shop-app.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
<link rel="import" href="../bower_components/iron-selector/iron-selector.html">
<link rel="import" href="shop-category-data.html">
<link rel="import" href="shop-payment-request.html">
<!-- Since 'home' is the default route, eagerly load it. -->
<link rel="import" href="shop-home.html">

Expand Down Expand Up @@ -232,7 +231,7 @@
<!--
app-location and app-route elements provide the state of the URL for the app.
-->
<app-location route="{{route}}"></app-location>
<app-location id="location" route="{{route}}"></app-location>
<app-route
route="{{route}}"
pattern="/:page"
Expand Down Expand Up @@ -269,14 +268,11 @@
shop-payment-request provides the logic and hooks into the PaymentRequest API.
-->
<shop-payment-request
id="paymentRequest"
page="[[page]]"
cart="[[cart]]"
total="[[total]]"
currency="USD"
supported-methods='["visa", "mastercard", "amex", "discover", "maestro", "diners", "jcb", "unionpay", "bitcoin"]'
android-pay='{"merchantName":"Android Pay Demo","merchantId":"12345678901234567890","environment":"TEST","allowedCardNetworks":["AMEX","DISCOVER","MASTERCARD","VISA"],"paymentMethodTokenizationParameters":{"tokenizationType":"GATEWAY_TOKEN","parameters":{"gateway":"stripe","stripe:publishableKey":"pk_live_abcdefghijklmnopqrstuvwx","stripe:version":"2016-07-06"}}}'
request-payer-email>
id="payment"
on-process-payment="_onProcessPayment"
on-error="_onPaymentError"
supported-methods='["visa", "mastercard"]'
android-pay='{"merchantName":"Android Pay Demo","merchantId":"12345678901234567890","environment":"TEST","allowedCardNetworks":["AMEX","DISCOVER","MASTERCARD","VISA"],"paymentMethodTokenizationParameters":{"tokenizationType":"GATEWAY_TOKEN","parameters":{"gateway":"stripe","stripe:publishableKey":"pk_live_abcdefghijklmnopqrstuvwx","stripe:version":"2016-07-06"}}}'>
</shop-payment-request>

<app-header role="navigation" id="header" effects="waterfall" condenses reveals>
Expand Down Expand Up @@ -392,6 +388,11 @@
value: 0
},

currency: {
type: String,
value: 'USD',
},

_shouldShowTabs: {
computed: '_computeShouldShowTabs(page, smallScreen)'
},
Expand All @@ -417,13 +418,13 @@
'add-cart-item': '_onAddCartItem',
'set-cart-item': '_onSetCartItem',
'clear-cart': '_onClearCart',
'buy-item': '_onBuyItem',
'buy-cart': '_onBuyCart',
'change-section': '_onChangeSection',
'announce': '_onAnnounce',
'dom-change': '_domChange',
'show-invalid-url-warning': '_onFallbackSelectionTriggered',
'show-snackbar': '_showSnackbar',
'buy-item': '_onBuyItem',
'buy-cart': '_onBuyCart',
'logout': '_onLogout',
'route-change': '_onRouteChange'
},
Expand Down Expand Up @@ -583,93 +584,71 @@
this._announce('Cart cleared');
},


_onBuyItem: function(event) {
// This only works with PaymentRequest
var item = event.detail.item;
var itemCost = event.detail.quantity * item.price;
var itemDetails = [{
label: item.title + ' ' + event.detail.size + ' x' + event.detail.quantity,
amount: {currency: this.payment.currency, value: itemCost.toFixed(2)}
amount: {currency: this.currency, value: itemCost.toFixed(2)}
}];

var that = this;
this.payment.buyItems(itemDetails, itemCost)
.then(function(instrument) {
return that._processPayment(instrument, false);
}).catch(function(err) {
if (err === 'Request cancelled') {
// Do nothing
} else if (err.name === 'NotSupportedError') {
that._redirectToCheckout();
} else {
console.error('Error while handling PaymentRequest.show(): ' + err);
}
});
this.$.payment.request(itemDetails, itemCost, this.currency, false);
},

_onBuyCart: function(event) {
if ('PaymentRequest' in window) {
var that = this;
var itemDetails = this.payment._computeItemDetails();
// TODO: Calculate total
var total = 60;
this.payment.buyItems(itemDetails, total)
.then(function(instrument) {
return that._processPayment(instrument, true);
}).catch(function(err) {
if (err === 'Request cancelled') {
// Do nothing
} else if (err.name === 'NotSupportedError') {
that._redirectToCheckout();
} else {
console.error('Error while handling PaymentRequest.show(): ' + err);
}
});
} else {
this._redirectToCheckout();
return;
}
},
if ('PaymentRequest' in window && this.cart && this.numItems > 0) {
var itemDetails = [];

for (var i = 0; i < this.cart.length; ++i) {
var entry = this.cart[i];
var itemCost = entry.quantity * entry.item.price;
itemDetails.push({
label: entry.item.title + ' ' + entry.size + ' x' + entry.quantity,
amount: {currency: this.currency, value: itemCost.toFixed(2)}
});
}

_redirectToCheckout: function() {
// prevent reload loop if we're already on /checkout.
if (this.route.path !== 'checkout') {
this.set('route.path', '/checkout');
return;
this.$.payment.request(itemDetails, this.total, this.currency, true);
} else {
this.fire('redirect-to', '/checkout');
}
},

_processPayment: function(instrumentResponse, cartBuy) {
_onProcessPayment: function(event) {
// This is normally where you'd send instrumentResponse to your backend
// or payment processor. For this demo we don't actually do that,
// instead mimicking a processing delay with a 2-second timout.
//
// See the PaymentRequest integration guide for a typical flow:
// https://developers.google.com/web/fundamentals/primers/payment-request/

var instrumentResponse = event.detail.instrument;
var cartBuy = event.detail.cartBuy;
var that = this;
window.setTimeout(function() {
instrumentResponse.complete('success')
.then(function() {
// Proceed to sign-in if the user is not signed up
if (!that.accountData.isSignedIn()) {
that.userEmail = instrumentResponse.payerEmail;
that.set('route.path', '/account/signup');
} else {
if (!that._orderSuccessModal) {
that._orderSuccessModal = document.createElement('shop-order-success-modal');
Polymer.dom(that.root).appendChild(that._orderSuccessModal);
}
that._orderSuccessModal.open();
that._announce('Order processed successfully!');
if (!that._orderSuccessModal) {
that._orderSuccessModal = document.createElement('shop-order-success-modal');
Polymer.dom(that.root).appendChild(that._orderSuccessModal);
}
that._orderSuccessModal.open();
that._announce('Order processed successfully!');

if (cartBuy) {
that.fire('clear-cart');
}
});
}, 2000);
},

_onPaymentError: function(event) {
var err = event.detail;

console.log("Got error calling PR: " + err.message);
},

_autoLogin: function() {
var that = this;
this.accountData = this.$.meta.byKey('account');
Expand Down
7 changes: 6 additions & 1 deletion src/shop-cart-modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
<a href="/cart" on-tap="close" id="viewCartAnchor">View Cart</a>
</shop-button>
<shop-button class="modal-button">
<a href="/checkout" on-tap="close">Checkout</a>
<a href="#" on-click="_checkout">Checkout</a>
</shop-button>
</div>

Expand Down Expand Up @@ -131,6 +131,11 @@
'iron-overlay-canceled': '_onCancel'
},

_checkout: function() {
this.close();
this.fire('buy-cart');
},

_renderOpened: function() {
this.restoreFocusOnClose = true;
this.backdropElement.style.display = 'none';
Expand Down
6 changes: 5 additions & 1 deletion src/shop-cart.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h1>Your Cart</h1>
<div class="checkout-box">
Total: <span class="subtotal">[[_formatTotal(total)]]</span>
<shop-button responsive>
<a href="/checkout">Checkout</a>
<input type="button" on-click="_checkout" value="Checkout">
</shop-button>
</div>
</div>
Expand Down Expand Up @@ -92,6 +92,10 @@ <h1>Your Cart</h1>

},

_checkout: function() {
this.fire('buy-cart');
},

_formatTotal: function(total) {
return isNaN(total) ? '' : '$' + total.toFixed(2);
},
Expand Down
9 changes: 8 additions & 1 deletion src/shop-checkout.html
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,10 @@ <h1>We couldn&acute;t process your order</h1>
/**
* An array containing the items in the cart.
*/
cart: Array,
cart: {
type: Array,
observer: '_cartChanged'
},

/**
* The server's response.
Expand Down Expand Up @@ -493,6 +496,10 @@ <h1>We couldn&acute;t process your order</h1>
}
},

_cartChanged: function() {
this.fire('buy-cart');
},

_submit: function(e) {
if (this._validateForm()) {
// To send the form data to the server:
Expand Down
6 changes: 3 additions & 3 deletions src/shop-detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@

<style include="shop-common-styles shop-button shop-select">

shop-button#buyNow > * {
#buyNow > button {
width: 100%;
}

#buyNow:not([visible]) {
[hidden] {
display: none;
}

Expand Down Expand Up @@ -217,7 +217,7 @@ <h2>Description</h2>
<shop-button responsive id="addToCart" half-size$="[[_hasPaymentRequest()]]">
<button on-tap="_addToCart" aria-label="Add this item to cart">Add to Cart</button>
</shop-button>
<shop-button responsive id="buyNow" visible$="[[_hasPaymentRequest()]]">
<shop-button responsive id="buyNow" hidden$="[[!_hasPaymentRequest()]]">
<button on-tap="_buyNow" aria-label="Buy this item now">Buy Now</button>
</shop-button>
</div>
Expand Down
Loading