├── .gitattributes ├── 9781484251836.jpg ├── Ch2 ├── errorhandling │ ├── errorhandling.css │ └── errorhandling.js ├── firstcheckout │ ├── firstcheckout.css │ ├── firstcheckout.html │ └── firstcheckout.js └── setup │ └── index.html ├── Ch3 ├── change order │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment.js │ │ └── scripts.js ├── currencies │ ├── code - finished version │ │ ├── css │ │ │ └── styles.css │ │ ├── index.html │ │ └── js │ │ │ └── payment.js │ ├── css │ │ └── styles.css │ ├── images │ │ ├── chillis.png │ │ ├── united-kingdom.png │ │ └── united-states.png │ ├── index.html │ └── js │ │ ├── payment - finished version.js │ │ └── payment.js ├── discounts │ ├── code - finished version │ │ ├── css │ │ │ └── styles.css │ │ ├── index.html │ │ └── js │ │ │ └── payment.js │ ├── css │ │ └── styles.css │ ├── images │ │ └── chillis.png │ ├── index.html │ └── js │ │ └── payment.js ├── extra info │ ├── code - finished version │ │ ├── css │ │ │ └── styles.css │ │ ├── index.html │ │ └── js │ │ │ ├── payment.js │ │ │ └── scripts.js │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment.js │ │ └── scripts.js ├── iframe │ ├── code - finished version │ │ └── iframe.html │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment.js │ │ └── scripts.js ├── next step │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment - finished version.js │ │ └── scripts.js └── options │ ├── css │ └── styles.css │ ├── favicon.png │ ├── images │ ├── background.png │ ├── black.png │ ├── brown.png │ ├── hamburger.png │ ├── purple.png │ ├── recycling-bin.png │ ├── red.png │ ├── shopping-basket.png │ └── yellow.png │ ├── index.html │ └── js │ ├── payment.js │ └── scripts.js ├── Ch4 ├── basic options │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment - completed version.js │ │ ├── payment.js │ │ └── scripts.js ├── expand options │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment - completed version.js │ │ ├── payment.js │ │ └── scripts.js ├── restrictions │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment - completed version.js │ │ ├── payment.js │ │ └── scripts.js ├── spot errors │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment.js │ │ └── scripts.js └── update shipping │ ├── css │ └── styles.css │ ├── favicon.png │ ├── images │ ├── background.png │ ├── black.png │ ├── brown.png │ ├── hamburger.png │ ├── purple.png │ ├── recycling-bin.png │ ├── red.png │ ├── shopping-basket.png │ └── yellow.png │ ├── index.html │ └── js │ ├── payment - completed version.js │ ├── payment.js │ └── scripts.js ├── Ch5 ├── bobpay │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── all.js │ │ ├── payment.js │ │ └── scripts.js ├── charges │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment.js │ │ └── scripts.js ├── nobob │ ├── css │ │ └── styles.css │ ├── favicon.png │ ├── images │ │ ├── background.png │ │ ├── black.png │ │ ├── bobpay.png │ │ ├── brown.png │ │ ├── hamburger.png │ │ ├── purple.png │ │ ├── recycling-bin.png │ │ ├── red.png │ │ ├── shopping-basket.png │ │ └── yellow.png │ ├── index.html │ └── js │ │ ├── payment.js │ │ └── scripts.js └── stripe │ ├── css │ └── stripe.css │ ├── example index.html │ ├── images │ └── chillis.png │ ├── index.html │ └── js │ ├── all.js │ └── scripts.js ├── Ch6 └── coffee │ ├── css │ ├── dart-sass │ │ ├── dart-sass.bat │ │ ├── sass.bat │ │ └── src │ │ │ ├── DART_LICENSE │ │ │ ├── SASS_LICENSE │ │ │ ├── dart.exe │ │ │ └── sass.dart.snapshot │ ├── styles-BACKUP.css │ ├── styles-sass.scss │ ├── styles.css │ └── styles.css.map │ ├── favicon.png │ ├── images │ ├── black.png │ ├── brown.png │ ├── latte.svg │ ├── long.svg │ ├── purple.png │ ├── recycling-bin.png │ ├── red.png │ ├── shopping-basket.png │ ├── short.svg │ └── yellow.png │ ├── index.html │ └── js │ ├── Examples │ ├── payment - basic.js │ ├── payment - bobpay.js │ ├── payment - charges.js │ ├── payment - errors.js │ └── payment - shipping.js │ ├── payment - completed version.js │ └── scripts.js ├── Ch7 ├── cookies │ ├── css │ │ ├── bootstrap.min.css │ │ └── styles.css │ ├── fonts │ │ └── glyphicons-halflings-regular.woff2 │ ├── images │ │ ├── cbakewell.png │ │ ├── coconut.png │ │ ├── dark-choc.png │ │ ├── double-choc.png │ │ ├── jaffa.png │ │ ├── oatmeal-rasin.png │ │ ├── rasberry-white-choc.png │ │ ├── toffee.png │ │ └── white-choc.png │ ├── index.html │ └── js │ │ ├── bootstrap.min.js │ │ ├── script.js │ │ └── vue.min.js └── geolocate │ ├── css │ ├── bootstrap.min.css │ └── styles.css │ ├── fonts │ └── glyphicons-halflings-regular.woff2 │ ├── images │ ├── cbakewell.png │ ├── coconut.png │ ├── dark-choc.png │ ├── double-choc.png │ ├── jaffa.png │ ├── oatmeal-rasin.png │ ├── rasberry-white-choc.png │ ├── toffee.png │ └── white-choc.png │ ├── index.html │ └── js │ ├── bootstrap.min.js │ ├── jquery.qrcode.min.js │ ├── script.js │ └── vue.min.js ├── Ch8 └── basiccard - completed version │ ├── app.js │ ├── css │ └── style.css │ ├── favicon.ico │ ├── images │ └── coffee.png │ ├── index.html │ ├── installer.js │ ├── manifest.json │ └── testing │ ├── coffee.png │ ├── css │ └── style.css │ ├── favicon.ico │ ├── js │ ├── merchant.js │ └── util.js │ └── test.html ├── Contributing.md ├── LICENSE.txt ├── README.md └── errata.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /9781484251836.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/9781484251836.jpg -------------------------------------------------------------------------------- /Ch2/errorhandling/errorhandling.css: -------------------------------------------------------------------------------- 1 | #message { 2 | float: left; 3 | margin-top: 10px; 4 | width: 320px; 5 | display: none; 6 | padding: 10px; 7 | font-weight: bold; 8 | border-radius: 5px; 9 | } 10 | 11 | #message.success { 12 | background-color: #ace1af; 13 | color: #008000; 14 | display: block; 15 | } 16 | 17 | #message.success > span { 18 | float: left; 19 | font-size: 30px; 20 | color: #008000; 21 | padding: 0px 10px; 22 | } 23 | 24 | #message.failure { 25 | background-color: #FFD1DC; 26 | color: #ff0000; 27 | display: block; 28 | } 29 | 30 | #message.failure > span { 31 | float: left; 32 | font-size: 30px; 33 | color: #ff0000; 34 | padding: 0px 10px; 35 | } 36 | 37 | #message.info { 38 | background-color: #FCF75E; 39 | display: block; 40 | color: #000000; 41 | line-height: 20px; 42 | } 43 | 44 | #message.info > span { 45 | float: left; 46 | font-size: 30px; 47 | color: #000000; 48 | padding: 0px 10px; 49 | } 50 | -------------------------------------------------------------------------------- /Ch2/errorhandling/errorhandling.js: -------------------------------------------------------------------------------- 1 | function displaySuccess() { 2 | document.getElementById("message").classList.add("success"); 3 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; 4 | } 5 | 6 | function displayError() { 7 | document.getElementById("message").classList.add("failure"); 8 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; 9 | } 10 | 11 | function displayCancel() { 12 | document.getElementById("message").classList.add("info"); 13 | document.getElementById("message").innerHTML = "🛈Request has been cancelled"; 14 | } 15 | 16 | function displayMessage(mesg) { 17 | document.getElementById("message").classList.add("info"); 18 | document.getElementById("message").innerHTML = "🛈" + mesg; 19 | } 20 | 21 | // ----------------------------------------------------------------- 22 | 23 | if (request.canMakePayment) { 24 | request.canMakePayment().then(function(result) { 25 | if (result) { 26 | //console.log(request); 27 | request.show().then(function(result) { 28 | result.complete('success').then(function() { 29 | console.log(JSON.stringify(result)); 30 | displaySuccess(); 31 | }); 32 | }).catch(function(err) { 33 | if (err.message == "Request cancelled") { 34 | displayCancel(); 35 | } else { 36 | console.error(err.message); 37 | displayError(); 38 | } 39 | }); 40 | } else { 41 | console.log('Cannot make payment'); 42 | displayMessage("Sorry - no valid payment methods available"); 43 | } 44 | }).catch(function(err) { 45 | console.log(request, err); 46 | }); 47 | } 48 | 49 | // ----------------------------------------------------------------- 50 | 51 | /* time out requests after 20 mins of inactivity */ 52 | var paymentTimeout = window.setTimeout(function() { 53 | window.clearTimeout(paymentTimeout); 54 | request.abort().then(function() { 55 | document.getElementById("message").classList.add("info"); 56 | document.getElementById("message").innerHTML = "🛈 Request has been timed out due to inactivity"; 57 | console.log('Payment timed out after 20 mins.'); 58 | }).catch(function() { 59 | console.log('Unable to abort, because the user is currently in the process of paying.'); 60 | }); 61 | }, 20000 * 60); /* 20 minutes */ 62 | -------------------------------------------------------------------------------- /Ch2/firstcheckout/firstcheckout.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | background-color: #fff; 3 | height: 100%; 4 | width: 335px; 5 | font-family: 'Montserrat', sans-serif; 6 | margin: 0 auto; 7 | } 8 | 9 | img, div { 10 | margin: 0 auto; 11 | display: block; 12 | } 13 | 14 | div { 15 | margin-bottom: 20px; 16 | } 17 | 18 | h1 { 19 | display: block; 20 | border-bottom: 1px solid #c21807; 21 | } 22 | 23 | h3, label { 24 | font-weight: 700; 25 | font-size: 23px; 26 | } 27 | 28 | img { 29 | width: 261px; 30 | } 31 | 32 | input { 33 | width: 50px; 34 | float: right; 35 | } 36 | 37 | span { 38 | float: right; 39 | color: #c21807; 40 | } 41 | 42 | .pay-button { 43 | background-color: white; 44 | border: none; 45 | border-radius: 24px; 46 | cursor: pointer; 47 | font-size: 16px; 48 | padding: 16px 32px; 49 | width: 170px; 50 | background-color: #c21807; 51 | color: #ffffff; 52 | letter-spacing: 2px; 53 | font-weight: 700; 54 | margin: 20px 0 0 170px; 55 | display: block; 56 | } 57 | 58 | .pay-button:hover { 59 | background-color: #f31e09; 60 | } 61 | 62 | .pay-button:focus { 63 | outline: 0; 64 | } 65 | 66 | .currency { 67 | margin-top: -50px; 68 | margin-left: 240px; 69 | position: absolute; 70 | color: #c21807; 71 | } 72 | 73 | #subTotalText { 74 | margin-top: -50px; 75 | float: right; 76 | color: #c21807; 77 | } 78 | 79 | #message { 80 | float: left; 81 | margin-top: 0px; 82 | position: absolute; 83 | display: none; 84 | } -------------------------------------------------------------------------------- /Ch2/firstcheckout/firstcheckout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |

Cart

5 | 6 | 7 |

Product:Bag of red chillis

8 |

Price:$4.99

9 | 10 | 11 |

SubTotal:

12 |

$
0.00

13 | 14 |
15 | -------------------------------------------------------------------------------- /Ch2/firstcheckout/firstcheckout.js: -------------------------------------------------------------------------------- 1 | const methodData = [{ 2 | supportedMethods: 'basic-card', 3 | data: { 4 | supportedNetworks: ['visa', 'mastercard', 'amex'] 5 | } 6 | }]; 7 | 8 | let amount = document.getElementById("amount"); 9 | let subTotalText = document.getElementById("subTotalText"); 10 | let qty = parseFloat(document.getElementById("amount").value); 11 | 12 | amount.addEventListener("click", function() { 13 | let subtotal = Number(document.getElementById("amount").value * 4.99).toFixed(2); 14 | subTotalText.innerText = subtotal; 15 | }); 16 | 17 | document.querySelector('.pay-button').onclick = function (e) { 18 | if(window.PaymentRequest) { 19 | let qty = parseFloat(document.getElementById("amount").value); 20 | let subtotal = Number(qty * 4.99); 21 | let tax = 1.99; 22 | let shipping = 2.99; 23 | 24 | const details = { 25 | total: { 26 | label: 'Total due', 27 | amount: { currency: 'USD', value: (subtotal + tax + shipping).toFixed(2) } 28 | }, 29 | displayItems: [{ 30 | label: 'Sub-total', 31 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 32 | }, { 33 | label: 'Delivery', 34 | amount: { currency: 'USD', value: 3.99 } 35 | }, { 36 | label: 'Sales Tax', 37 | amount: { currency: 'USD', value: tax.toFixed(2) } 38 | }] 39 | }; 40 | 41 | const options = { requestPayerEmail: true }; 42 | const request = new PaymentRequest(methodData, details, options); 43 | 44 | //Show the Native UI 45 | request 46 | .show() 47 | .then(function(result) { 48 | result.complete('success') 49 | .then(console.log(JSON.stringify(result))); 50 | }).catch(function(err) { 51 | console.error(err.message); 52 | }); 53 | } else { 54 | // Fallback to traditional checkout 55 | } 56 | }; -------------------------------------------------------------------------------- /Ch2/setup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testing SSL support 5 | 6 | 7 | Hopefully this page will display correctly under SSL support... 8 | 9 | -------------------------------------------------------------------------------- /Ch3/change order/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/favicon.png -------------------------------------------------------------------------------- /Ch3/change order/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/background.png -------------------------------------------------------------------------------- /Ch3/change order/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/black.png -------------------------------------------------------------------------------- /Ch3/change order/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/brown.png -------------------------------------------------------------------------------- /Ch3/change order/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/hamburger.png -------------------------------------------------------------------------------- /Ch3/change order/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/purple.png -------------------------------------------------------------------------------- /Ch3/change order/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch3/change order/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/red.png -------------------------------------------------------------------------------- /Ch3/change order/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch3/change order/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/change order/images/yellow.png -------------------------------------------------------------------------------- /Ch3/change order/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch3/change order/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let shipping = 2.99; 28 | let discount = 2.00; 29 | let subtotal = Number(document.querySelector(".total-price").innerText - discount); 30 | let tax = (subtotal + shipping) * 0.175; 31 | let total = Number(subtotal) + Number(tax) + Number(shipping); 32 | 33 | const paymentDetails = { 34 | total: { 35 | label: 'Total due', 36 | amount: { currency: 'USD', value: total.toFixed(2) } 37 | }, 38 | displayItems: [{ 39 | label: 'Coffee capsules', 40 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 41 | },{ 42 | label: 'Shipping', 43 | amount: { currency: 'USD', value: 2.99 } 44 | }, { 45 | label: 'Discount', 46 | amount: { currency: 'USD', value: -2.00 } 47 | },{ 48 | label: 'Sales Tax', 49 | amount: { currency: 'USD', value: tax.toFixed(2) } 50 | }] 51 | }; 52 | 53 | const paymentOptions = { requestPayerEmail: true }; 54 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 55 | 56 | if (request.canMakePayment) { 57 | request.canMakePayment().then(function(result) { 58 | if (result) { 59 | request.show().then(function(result) { 60 | result.complete('success').then(function() { 61 | console.log(JSON.stringify(result)); 62 | displaySuccess(); 63 | }); 64 | }).catch(function(err) { 65 | if (err.message == "Request cancelled") { 66 | displayMessage("Request has been cancelled"); 67 | } else { 68 | console.error(err.message); 69 | displayError(); 70 | } 71 | }); 72 | } else { 73 | console.log('Cannot make payment'); 74 | displayMessage("Sorry - no valid payment methods available"); 75 | } 76 | }).catch(function(err) { 77 | console.log(request, err); 78 | }); 79 | } 80 | } 81 | }); 82 | } -------------------------------------------------------------------------------- /Ch3/currencies/code - finished version/css/styles.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | background-color: #fff; 3 | height: 100%; 4 | width: 335px; 5 | font-family: 'Montserrat', sans-serif; 6 | margin: 0 auto; 7 | } 8 | 9 | img, div { 10 | margin: 0 auto; 11 | display: block; 12 | } 13 | 14 | div { 15 | margin-bottom: 20px; 16 | } 17 | 18 | h1 { 19 | display: block; 20 | border-bottom: 1px solid #c21807; 21 | } 22 | 23 | h3, label { 24 | font-weight: 700; 25 | font-size: 23px; 26 | } 27 | 28 | img { 29 | width: 261px; 30 | } 31 | 32 | input { 33 | width: 50px; 34 | float: right; 35 | } 36 | 37 | span { 38 | float: right; 39 | color: #c21807; 40 | } 41 | 42 | .pay-button { 43 | background-color: white; 44 | border: none; 45 | border-radius: 24px; 46 | cursor: pointer; 47 | font-size: 16px; 48 | padding: 16px 32px; 49 | width: 170px; 50 | background-color: #c21807; 51 | color: #ffffff; 52 | letter-spacing: 2px; 53 | font-weight: 700; 54 | margin: 20px 0 0 170px; 55 | display: block; 56 | } 57 | 58 | .pay-button:hover { 59 | background-color: #f31e09; 60 | } 61 | 62 | .pay-button:focus { 63 | outline: 0; 64 | } 65 | 66 | .currency { 67 | margin-top: -50px; 68 | margin-left: 240px; 69 | position: absolute; 70 | color: #c21807; 71 | font-size: 23px; 72 | font-weight: bold; 73 | } 74 | 75 | #subTotalText, #unitcost { 76 | margin-top: -50px; 77 | float: right; 78 | color: #c21807; 79 | font-size: 23px; 80 | font-weight: bold; 81 | } 82 | 83 | #message { 84 | float: left; 85 | margin-top: 10px; 86 | width: 320px; 87 | display: none; 88 | padding: 10px; 89 | font-weight: bold; 90 | border-radius: 5px; 91 | } 92 | 93 | #message.success { 94 | background-color: #ace1af; 95 | color: #008000; 96 | display: block; 97 | } 98 | 99 | #message.success > span { 100 | float: left; 101 | font-size: 30px; 102 | color: #008000; 103 | padding: 0px 10px; 104 | line-height: 40px; 105 | } 106 | 107 | #message.failure { 108 | background-color: #FFD1DC; 109 | color: #ff0000; 110 | display: block; 111 | } 112 | 113 | #message.failure > span { 114 | float: left; 115 | font-size: 30px; 116 | color: red; 117 | padding: 0px 10px; 118 | line-height: 40px; 119 | } 120 | 121 | #message.info { 122 | background-color: #FCF75E; 123 | display: block; 124 | color: #000000; 125 | line-height: 20px; 126 | } 127 | 128 | #message.info > span { 129 | float: left; 130 | font-size: 30px; 131 | color: #000000; 132 | padding: 0px 10px; 133 | line-height: 20px; 134 | } 135 | 136 | /* currencies update */ 137 | #currencies { 138 | float: right; 139 | width: 150px; 140 | display: inline-block; 141 | } 142 | 143 | #gbp:hover, #usd:hover { 144 | cursor: pointer; 145 | } 146 | 147 | #currencies > a { 148 | line-height: 24px; 149 | } 150 | 151 | #currencies > a.selected { 152 | font-weight: bold; 153 | color: #8b0000; 154 | } 155 | 156 | #currencies > a:hover { 157 | color: red; 158 | } 159 | 160 | #currencies > a > img { 161 | width: 24px; 162 | height: auto; 163 | display: inline-block; 164 | padding-right: 5px; 165 | vertical-align: bottom; 166 | } 167 | -------------------------------------------------------------------------------- /Ch3/currencies/code - finished version/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Handling Different Currencies with the Payment Request API 6 | 7 | 8 | 9 | 10 |
11 |

Cart

12 |
USD | GBP
13 | 14 | 15 |

Product:Bag of red chillis

16 |

Price:

17 |
$
4.99
18 | 19 | 20 |

SubTotal:

21 |
$
0.00
22 | 23 |
24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Ch3/currencies/css/styles.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | background-color: #fff; 3 | height: 100%; 4 | width: 335px; 5 | font-family: 'Montserrat', sans-serif; 6 | margin: 0 auto; 7 | } 8 | 9 | img, div { 10 | margin: 0 auto; 11 | display: block; 12 | } 13 | 14 | div { 15 | margin-bottom: 20px; 16 | } 17 | 18 | h1 { 19 | display: block; 20 | border-bottom: 1px solid #c21807; 21 | } 22 | 23 | h3, label { 24 | font-weight: 700; 25 | font-size: 23px; 26 | } 27 | 28 | img { 29 | width: 261px; 30 | } 31 | 32 | input { 33 | width: 50px; 34 | float: right; 35 | } 36 | 37 | span { 38 | float: right; 39 | color: #c21807; 40 | } 41 | 42 | .pay-button { 43 | background-color: white; 44 | border: none; 45 | border-radius: 24px; 46 | cursor: pointer; 47 | font-size: 16px; 48 | padding: 16px 32px; 49 | width: 170px; 50 | background-color: #c21807; 51 | color: #ffffff; 52 | letter-spacing: 2px; 53 | font-weight: 700; 54 | margin: 20px 0 0 170px; 55 | display: block; 56 | } 57 | 58 | .pay-button:hover { 59 | background-color: #f31e09; 60 | } 61 | 62 | .pay-button:focus { 63 | outline: 0; 64 | } 65 | 66 | .currency { 67 | margin-top: -50px; 68 | margin-left: 240px; 69 | position: absolute; 70 | color: #c21807; 71 | font-size: 23px; 72 | font-weight: bold; 73 | } 74 | 75 | #subTotalText, #unitcost { 76 | margin-top: -50px; 77 | float: right; 78 | color: #c21807; 79 | font-size: 23px; 80 | font-weight: bold; 81 | } 82 | 83 | #message { 84 | float: left; 85 | margin-top: 10px; 86 | width: 320px; 87 | display: none; 88 | padding: 10px; 89 | font-weight: bold; 90 | border-radius: 5px; 91 | } 92 | 93 | #message.success { 94 | background-color: #ace1af; 95 | color: #008000; 96 | display: block; 97 | } 98 | 99 | #message.success > span { 100 | float: left; 101 | font-size: 30px; 102 | color: #008000; 103 | padding: 0px 10px; 104 | line-height: 40px; 105 | } 106 | 107 | #message.failure { 108 | background-color: #FFD1DC; 109 | color: #ff0000; 110 | display: block; 111 | } 112 | 113 | #message.failure > span { 114 | float: left; 115 | font-size: 30px; 116 | color: red; 117 | padding: 0px 10px; 118 | line-height: 40px; 119 | } 120 | 121 | #message.info { 122 | background-color: #FCF75E; 123 | display: block; 124 | color: #000000; 125 | line-height: 20px; 126 | } 127 | 128 | #message.info > span { 129 | float: left; 130 | font-size: 30px; 131 | color: #000000; 132 | padding: 0px 10px; 133 | line-height: 20px; 134 | } 135 | -------------------------------------------------------------------------------- /Ch3/currencies/images/chillis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/currencies/images/chillis.png -------------------------------------------------------------------------------- /Ch3/currencies/images/united-kingdom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/currencies/images/united-kingdom.png -------------------------------------------------------------------------------- /Ch3/currencies/images/united-states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/currencies/images/united-states.png -------------------------------------------------------------------------------- /Ch3/currencies/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Handling Different Currencies with the Payment Request API 6 | 7 | 8 | 9 | 10 |
11 |

Cart

12 |
USD | GBP
13 | 14 | 15 |

Product:Bag of red chillis

16 |

Price:

17 |
$
4.99
18 | 19 | 20 |

SubTotal:

21 |
$
0.00
22 | 23 |
24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Ch3/currencies/js/payment - finished version.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 2.99; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | },{ 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: 2.99 } 43 | }, { 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | if (request.canMakePayment) { 53 | request.canMakePayment().then(function(result) { 54 | if (result) { 55 | request.show().then(function(result) { 56 | result.complete('success').then(function() { 57 | console.log(JSON.stringify(result)); 58 | displaySuccess(); 59 | }); 60 | }).catch(function(err) { 61 | if (err.message == "Request cancelled") { 62 | displayMessage("Request has been cancelled"); 63 | } else { 64 | console.error(err.message); 65 | displayError(); 66 | } 67 | }); 68 | } else { 69 | console.log('Cannot make payment'); 70 | displayMessage("Sorry - no valid payment methods available"); 71 | } 72 | }).catch(function(err) { 73 | console.log(request, err); 74 | }); 75 | } 76 | } 77 | }); 78 | } -------------------------------------------------------------------------------- /Ch3/discounts/code - finished version/css/styles.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | background-color: #fff; 3 | height: 100%; 4 | width: 335px; 5 | font-family: 'Montserrat', sans-serif; 6 | margin: 20px auto; 7 | } 8 | 9 | img, div { 10 | margin: 0 auto; 11 | display: block; 12 | } 13 | 14 | div { 15 | margin-bottom: 20px; 16 | } 17 | 18 | h1 { 19 | display: block; 20 | border-bottom: 1px solid #c21807; 21 | } 22 | 23 | h3, label { 24 | font-weight: 700; 25 | font-size: 23px; 26 | } 27 | 28 | img { 29 | width: 261px; 30 | } 31 | 32 | input { 33 | width: 50px; 34 | float: right; 35 | } 36 | 37 | span { 38 | float: right; 39 | color: #c21807; 40 | } 41 | 42 | .pay-button { 43 | background-color: white; 44 | border: none; 45 | border-radius: 24px; 46 | cursor: pointer; 47 | font-size: 16px; 48 | padding: 16px 32px; 49 | width: 170px; 50 | background-color: #c21807; 51 | color: #ffffff; 52 | letter-spacing: 2px; 53 | font-weight: 700; 54 | margin: 20px 0 0 170px; 55 | display: block; 56 | } 57 | 58 | .pay-button:hover { 59 | background-color: #f31e09; 60 | } 61 | 62 | .pay-button:focus { 63 | outline: 0; 64 | } 65 | 66 | .currency { 67 | margin-top: -50px; 68 | margin-left: 240px; 69 | position: absolute; 70 | color: #c21807; 71 | } 72 | 73 | #subTotalText { 74 | margin-top: -50px; 75 | float: right; 76 | color: #c21807; 77 | } 78 | 79 | #message { 80 | float: left; 81 | margin-top: 10px; 82 | width: 320px; 83 | display: none; 84 | padding: 10px; 85 | font-weight: bold; 86 | border-radius: 5px; 87 | } 88 | 89 | #message.success { 90 | background-color: #ace1af; 91 | color: #008000; 92 | display: block; 93 | } 94 | 95 | #message.success > span { 96 | float: left; 97 | font-size: 30px; 98 | color: #008000; 99 | padding: 0px 10px; 100 | line-height: 40px; 101 | } 102 | 103 | #message.failure { 104 | background-color: #FFD1DC; 105 | color: #ff0000; 106 | display: block; 107 | } 108 | 109 | #message.failure > span { 110 | float: left; 111 | font-size: 30px; 112 | color: red; 113 | padding: 0px 10px; 114 | line-height: 40px; 115 | } 116 | 117 | #message.info { 118 | background-color: #FCF75E; 119 | display: block; 120 | color: #000000; 121 | line-height: 20px; 122 | } 123 | 124 | #message.info > span { 125 | float: left; 126 | font-size: 30px; 127 | color: #000000; 128 | padding: 0px 10px; 129 | line-height: 20px; 130 | } 131 | 132 | #discount { 133 | width: 100px; 134 | border: 1px solid #ff0000; 135 | color: #ffffff; 136 | background-color: #ff0000; 137 | padding: 20px; 138 | position: absolute; 139 | margin-top: -70px; 140 | margin-left: 200px; 141 | transform: rotate(10deg); 142 | text-align: center; 143 | font-size: 18px; 144 | } 145 | 146 | #getmore { 147 | float: right; 148 | font-style: italic; 149 | display: none; 150 | font-size: 13px 151 | } 152 | 153 | -------------------------------------------------------------------------------- /Ch3/discounts/code - finished version/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |

Cart

12 |
Buy 10, get 20% off!
13 | 14 | 15 |

Product:Bag of red chillis

16 |

Price:$4.99

17 | 18 | 19 |
Add 2 more to get discount....
20 |

SubTotal:

21 |

$
0.00

22 | 23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /Ch3/discounts/css/styles.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | background-color: #fff; 3 | height: 100%; 4 | width: 335px; 5 | font-family: 'Montserrat', sans-serif; 6 | margin: 20px auto; 7 | } 8 | 9 | img, div { 10 | margin: 0 auto; 11 | display: block; 12 | } 13 | 14 | div { 15 | margin-bottom: 20px; 16 | } 17 | 18 | h1 { 19 | display: block; 20 | border-bottom: 1px solid #c21807; 21 | } 22 | 23 | h3, label { 24 | font-weight: 700; 25 | font-size: 23px; 26 | } 27 | 28 | img { 29 | width: 261px; 30 | } 31 | 32 | input { 33 | width: 50px; 34 | float: right; 35 | } 36 | 37 | span { 38 | float: right; 39 | color: #c21807; 40 | } 41 | 42 | .pay-button { 43 | background-color: white; 44 | border: none; 45 | border-radius: 24px; 46 | cursor: pointer; 47 | font-size: 16px; 48 | padding: 16px 32px; 49 | width: 170px; 50 | background-color: #c21807; 51 | color: #ffffff; 52 | letter-spacing: 2px; 53 | font-weight: 700; 54 | margin: 20px 0 0 170px; 55 | display: block; 56 | } 57 | 58 | .pay-button:hover { 59 | background-color: #f31e09; 60 | } 61 | 62 | .pay-button:focus { 63 | outline: 0; 64 | } 65 | 66 | .currency { 67 | margin-top: -50px; 68 | margin-left: 240px; 69 | position: absolute; 70 | color: #c21807; 71 | } 72 | 73 | #subTotalText { 74 | margin-top: -50px; 75 | float: right; 76 | color: #c21807; 77 | } 78 | 79 | #message { 80 | float: left; 81 | margin-top: 10px; 82 | width: 320px; 83 | display: none; 84 | padding: 10px; 85 | font-weight: bold; 86 | border-radius: 5px; 87 | } 88 | 89 | #message.success { 90 | background-color: #ace1af; 91 | color: #008000; 92 | display: block; 93 | } 94 | 95 | #message.success > span { 96 | float: left; 97 | font-size: 30px; 98 | color: #008000; 99 | padding: 0px 10px; 100 | line-height: 40px; 101 | } 102 | 103 | #message.failure { 104 | background-color: #FFD1DC; 105 | color: #ff0000; 106 | display: block; 107 | } 108 | 109 | #message.failure > span { 110 | float: left; 111 | font-size: 30px; 112 | color: red; 113 | padding: 0px 10px; 114 | line-height: 40px; 115 | } 116 | 117 | #message.info { 118 | background-color: #FCF75E; 119 | display: block; 120 | color: #000000; 121 | line-height: 20px; 122 | } 123 | 124 | #message.info > span { 125 | float: left; 126 | font-size: 30px; 127 | color: #000000; 128 | padding: 0px 10px; 129 | line-height: 20px; 130 | } 131 | -------------------------------------------------------------------------------- /Ch3/discounts/images/chillis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/discounts/images/chillis.png -------------------------------------------------------------------------------- /Ch3/discounts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |

Cart

12 |
Buy 10, get 20% off!
13 | 14 | 15 |

Product:Bag of red chillis

16 |

Price:$4.99

17 | 18 | 19 |
Add 2 more to get discount....
20 |

SubTotal:

21 |

$
0.00

22 | 23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /Ch3/extra info/code - finished version/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 2.99; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | },{ 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: 2.99 } 43 | }, { 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | if (request.canMakePayment) { 53 | request.canMakePayment().then(function(result) { 54 | if (result) { 55 | request.show().then(function(result) { 56 | result.complete('success').then(function() { 57 | console.log(JSON.stringify(result)); 58 | displaySuccess(); 59 | const additionalDetailsContainer = document.getElementById('instructions'); 60 | additionalDetailsContainer.style.display = 'block'; 61 | additionalDetailsContainer.focus(); 62 | }); 63 | }).catch(function(err) { 64 | if (err.message == "Request cancelled") { 65 | displayMessage("Request has been cancelled"); 66 | } else { 67 | console.error(err.message); 68 | displayError(); 69 | } 70 | }); 71 | } else { 72 | console.log('Cannot make payment'); 73 | displayMessage("Sorry - no valid payment methods available"); 74 | } 75 | }).catch(function(err) { 76 | console.log(request, err); 77 | }); 78 | } 79 | } 80 | }); 81 | } -------------------------------------------------------------------------------- /Ch3/extra info/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/favicon.png -------------------------------------------------------------------------------- /Ch3/extra info/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/background.png -------------------------------------------------------------------------------- /Ch3/extra info/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/black.png -------------------------------------------------------------------------------- /Ch3/extra info/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/brown.png -------------------------------------------------------------------------------- /Ch3/extra info/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/hamburger.png -------------------------------------------------------------------------------- /Ch3/extra info/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/purple.png -------------------------------------------------------------------------------- /Ch3/extra info/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch3/extra info/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/red.png -------------------------------------------------------------------------------- /Ch3/extra info/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch3/extra info/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/extra info/images/yellow.png -------------------------------------------------------------------------------- /Ch3/extra info/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch3/extra info/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 2.99; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | },{ 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: 2.99 } 43 | }, { 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | if (request.canMakePayment) { 53 | request.canMakePayment().then(function(result) { 54 | if (result) { 55 | request.show().then(function(result) { 56 | result.complete('success').then(function() { 57 | console.log(JSON.stringify(result)); 58 | displaySuccess(); 59 | }); 60 | }).catch(function(err) { 61 | if (err.message == "Request cancelled") { 62 | displayMessage("Request has been cancelled"); 63 | } else { 64 | console.error(err.message); 65 | displayError(); 66 | } 67 | }); 68 | } else { 69 | console.log('Cannot make payment'); 70 | displayMessage("Sorry - no valid payment methods available"); 71 | } 72 | }).catch(function(err) { 73 | console.log(request, err); 74 | }); 75 | } 76 | } 77 | }); 78 | } -------------------------------------------------------------------------------- /Ch3/iframe/code - finished version/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Viewing Payment Request API via an iframe 5 | 6 | 11 | 12 | 13 |

Viewing a Payment Request API via an iframe

14 | 15 | 16 | -------------------------------------------------------------------------------- /Ch3/iframe/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/favicon.png -------------------------------------------------------------------------------- /Ch3/iframe/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/background.png -------------------------------------------------------------------------------- /Ch3/iframe/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/black.png -------------------------------------------------------------------------------- /Ch3/iframe/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/brown.png -------------------------------------------------------------------------------- /Ch3/iframe/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/hamburger.png -------------------------------------------------------------------------------- /Ch3/iframe/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/purple.png -------------------------------------------------------------------------------- /Ch3/iframe/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch3/iframe/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/red.png -------------------------------------------------------------------------------- /Ch3/iframe/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch3/iframe/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/iframe/images/yellow.png -------------------------------------------------------------------------------- /Ch3/iframe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch3/iframe/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 2.99; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | },{ 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: 2.99 } 43 | }, { 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | if (request.canMakePayment) { 53 | request.canMakePayment().then(function(result) { 54 | if (result) { 55 | request.show().then(function(result) { 56 | result.complete('success').then(function() { 57 | console.log(JSON.stringify(result)); 58 | displaySuccess(); 59 | }); 60 | }).catch(function(err) { 61 | if (err.message == "Request cancelled") { 62 | displayMessage("Request has been cancelled"); 63 | } else { 64 | console.error(err.message); 65 | displayError(); 66 | } 67 | }); 68 | } else { 69 | console.log('Cannot make payment'); 70 | displayMessage("Sorry - no valid payment methods available"); 71 | } 72 | }).catch(function(err) { 73 | console.log(request, err); 74 | }); 75 | } 76 | } 77 | }); 78 | } -------------------------------------------------------------------------------- /Ch3/next step/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/favicon.png -------------------------------------------------------------------------------- /Ch3/next step/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/background.png -------------------------------------------------------------------------------- /Ch3/next step/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/black.png -------------------------------------------------------------------------------- /Ch3/next step/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/brown.png -------------------------------------------------------------------------------- /Ch3/next step/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/hamburger.png -------------------------------------------------------------------------------- /Ch3/next step/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/purple.png -------------------------------------------------------------------------------- /Ch3/next step/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch3/next step/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/red.png -------------------------------------------------------------------------------- /Ch3/next step/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch3/next step/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/next step/images/yellow.png -------------------------------------------------------------------------------- /Ch3/next step/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch3/next step/js/payment - finished version.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 2.99; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | },{ 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: 2.99 } 43 | }, { 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | if (request.canMakePayment) { 53 | request.canMakePayment().then(function(result) { 54 | if (result) { 55 | request.show().then(function(result) { 56 | result.complete('success').then(function() { 57 | console.log(JSON.stringify(result)); 58 | displaySuccess(); 59 | }); 60 | }).catch(function(err) { 61 | if (err.message == "Request cancelled") { 62 | displayMessage("Request has been cancelled"); 63 | } else { 64 | console.error(err.message); 65 | displayError(); 66 | } 67 | }); 68 | } else { 69 | console.log('Cannot make payment'); 70 | displayMessage("Sorry - no valid payment methods available"); 71 | } 72 | }).catch(function(err) { 73 | console.log(request, err); 74 | }); 75 | } 76 | } 77 | }); 78 | } -------------------------------------------------------------------------------- /Ch3/options/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/favicon.png -------------------------------------------------------------------------------- /Ch3/options/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/background.png -------------------------------------------------------------------------------- /Ch3/options/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/black.png -------------------------------------------------------------------------------- /Ch3/options/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/brown.png -------------------------------------------------------------------------------- /Ch3/options/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/hamburger.png -------------------------------------------------------------------------------- /Ch3/options/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/purple.png -------------------------------------------------------------------------------- /Ch3/options/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch3/options/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/red.png -------------------------------------------------------------------------------- /Ch3/options/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch3/options/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch3/options/images/yellow.png -------------------------------------------------------------------------------- /Ch3/options/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch3/options/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 2.99; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | },{ 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: 2.99 } 43 | }, { 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true}; 50 | 51 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 52 | 53 | if (request.canMakePayment) { 54 | request.canMakePayment().then(function(result) { 55 | if (result) { 56 | request.show().then(function(result) { 57 | result.complete('success').then(function() { 58 | console.log(JSON.stringify(result)); 59 | displaySuccess(); 60 | }); 61 | }).catch(function(err) { 62 | if (err.message == "Request cancelled") { 63 | displayMessage("Request has been cancelled"); 64 | } else { 65 | console.error(err.message); 66 | displayError(); 67 | } 68 | }); 69 | } else { 70 | console.log('Cannot make payment'); 71 | displayMessage("Sorry - no valid payment methods available"); 72 | } 73 | }).catch(function(err) { 74 | console.log(request, err); 75 | }); 76 | } 77 | } 78 | }); 79 | } -------------------------------------------------------------------------------- /Ch4/basic options/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/favicon.png -------------------------------------------------------------------------------- /Ch4/basic options/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/background.png -------------------------------------------------------------------------------- /Ch4/basic options/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/black.png -------------------------------------------------------------------------------- /Ch4/basic options/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/brown.png -------------------------------------------------------------------------------- /Ch4/basic options/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/hamburger.png -------------------------------------------------------------------------------- /Ch4/basic options/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/purple.png -------------------------------------------------------------------------------- /Ch4/basic options/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch4/basic options/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/red.png -------------------------------------------------------------------------------- /Ch4/basic options/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch4/basic options/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/basic options/images/yellow.png -------------------------------------------------------------------------------- /Ch4/basic options/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch4/basic options/js/payment - completed version.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 0; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | }, { 41 | label: 'Free worldwide shipping', 42 | amount: { currency: 'USD', value: shipping.toFixed(2) } 43 | },{ 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }], shippingOptions: [{ 47 | id: 'freeShippingOption', 48 | label: 'Free worldwide shipping', 49 | amount: { 50 | currency: 'USD', 51 | value: '0.00' 52 | }, 53 | selected: true 54 | }] 55 | }; 56 | 57 | const paymentOptions = { requestPayerEmail: true, requestShipping: true }; 58 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 59 | 60 | request.addEventListener('shippingaddresschange', function(e) { 61 | e.updateWith(new Promise(function(resolve) { 62 | // No changes in price based on shipping address change. 63 | resolve(paymentDetails); 64 | console.log(request.shippingAddress); 65 | })); 66 | }); 67 | 68 | if (request.canMakePayment) { 69 | request.canMakePayment().then(function(result) { 70 | if (result) { 71 | request.show().then(function(result) { 72 | result.complete('success').then(function() { 73 | console.log(JSON.stringify(result)); 74 | displaySuccess(); 75 | }); 76 | }).catch(function(err) { 77 | if (err.message == "Request cancelled") { 78 | displayMessage("Request has been cancelled"); 79 | } else { 80 | console.error(err.message); 81 | displayError(); 82 | } 83 | }); 84 | } else { 85 | console.log('Cannot make payment'); 86 | displayMessage("Sorry - no valid payment methods available"); 87 | } 88 | }).catch(function(err) { 89 | console.log(request, err); 90 | }); 91 | } 92 | } 93 | }); 94 | } -------------------------------------------------------------------------------- /Ch4/basic options/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 0; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | }, { 41 | label: 'Free worldwide shipping', 42 | amount: { currency: 'USD', value: shipping.toFixed(2) } 43 | },{ 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | if (request.canMakePayment) { 53 | request.canMakePayment().then(function(result) { 54 | if (result) { 55 | request.show().then(function(result) { 56 | result.complete('success').then(function() { 57 | console.log(JSON.stringify(result)); 58 | displaySuccess(); 59 | }); 60 | }).catch(function(err) { 61 | if (err.message == "Request cancelled") { 62 | displayMessage("Request has been cancelled"); 63 | } else { 64 | console.error(err.message); 65 | displayError(); 66 | } 67 | }); 68 | } else { 69 | console.log('Cannot make payment'); 70 | displayMessage("Sorry - no valid payment methods available"); 71 | } 72 | }).catch(function(err) { 73 | console.log(request, err); 74 | }); 75 | } 76 | } 77 | }); 78 | } -------------------------------------------------------------------------------- /Ch4/expand options/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/favicon.png -------------------------------------------------------------------------------- /Ch4/expand options/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/background.png -------------------------------------------------------------------------------- /Ch4/expand options/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/black.png -------------------------------------------------------------------------------- /Ch4/expand options/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/brown.png -------------------------------------------------------------------------------- /Ch4/expand options/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/hamburger.png -------------------------------------------------------------------------------- /Ch4/expand options/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/purple.png -------------------------------------------------------------------------------- /Ch4/expand options/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch4/expand options/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/red.png -------------------------------------------------------------------------------- /Ch4/expand options/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch4/expand options/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/expand options/images/yellow.png -------------------------------------------------------------------------------- /Ch4/expand options/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch4/expand options/js/payment - completed version.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 0; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | }, { 41 | label: 'FREE delivery (3-5 days)', 42 | amount: { currency: 'USD', value: shipping.toFixed(2) } 43 | },{ 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }], shippingOptions: [{ 47 | id: 'standard', 48 | label: 'FREE delivery (3-5 days)', 49 | amount: {currency: 'USD', value: '0.00'}, 50 | selected: true, 51 | }, 52 | { 53 | id: 'express', 54 | label: 'Express delivery (next day)', 55 | amount: {currency: 'USD', value: '3.99'}, 56 | }, 57 | ], 58 | }; 59 | 60 | const paymentOptions = { requestPayerEmail: true, requestShipping: true }; 61 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 62 | 63 | request.addEventListener('shippingaddresschange', function(e) { 64 | e.updateWith(new Promise(function(resolve) { 65 | // No changes in price based on shipping address change. 66 | resolve(paymentDetails); 67 | console.log(request.shippingAddress); 68 | })); 69 | }); 70 | 71 | if (request.canMakePayment) { 72 | request.canMakePayment().then(function(result) { 73 | if (result) { 74 | request.show().then(function(result) { 75 | result.complete('success').then(function() { 76 | console.log(JSON.stringify(result)); 77 | displaySuccess(); 78 | }); 79 | }).catch(function(err) { 80 | if (err.message == "Request cancelled") { 81 | displayMessage("Request has been cancelled"); 82 | } else { 83 | console.error(err.message); 84 | displayError(); 85 | } 86 | }); 87 | } else { 88 | console.log('Cannot make payment'); 89 | displayMessage("Sorry - no valid payment methods available"); 90 | } 91 | }).catch(function(err) { 92 | console.log(request, err); 93 | }); 94 | } 95 | } 96 | }); 97 | } -------------------------------------------------------------------------------- /Ch4/expand options/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 0; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | }, { 41 | label: 'Free worldwide shipping', 42 | amount: { currency: 'USD', value: shipping.toFixed(2) } 43 | },{ 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }], shippingOptions: [{ 47 | id: 'standard', 48 | label: 'Free worldwide shipping', 49 | amount: {currency: 'USD', value: '0.00'}, 50 | selected: true, 51 | }, 52 | ], 53 | }; 54 | 55 | const paymentOptions = { requestPayerEmail: true, requestShipping: true }; 56 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 57 | 58 | request.addEventListener('shippingaddresschange', function(e) { 59 | e.updateWith(new Promise(function(resolve) { 60 | // No changes in price based on shipping address change. 61 | resolve(paymentDetails); 62 | console.log(request.shippingAddress); 63 | })); 64 | }); 65 | 66 | if (request.canMakePayment) { 67 | request.canMakePayment().then(function(result) { 68 | if (result) { 69 | request.show().then(function(result) { 70 | result.complete('success').then(function() { 71 | console.log(JSON.stringify(result)); 72 | displaySuccess(); 73 | }); 74 | }).catch(function(err) { 75 | if (err.message == "Request cancelled") { 76 | displayMessage("Request has been cancelled"); 77 | } else { 78 | console.error(err.message); 79 | displayError(); 80 | } 81 | }); 82 | } else { 83 | console.log('Cannot make payment'); 84 | displayMessage("Sorry - no valid payment methods available"); 85 | } 86 | }).catch(function(err) { 87 | console.log(request, err); 88 | }); 89 | } 90 | } 91 | }); 92 | } -------------------------------------------------------------------------------- /Ch4/restrictions/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/favicon.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/background.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/black.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/brown.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/hamburger.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/purple.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/red.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch4/restrictions/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/restrictions/images/yellow.png -------------------------------------------------------------------------------- /Ch4/restrictions/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch4/restrictions/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 0; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | }, { 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: shipping.toFixed(2) } 43 | },{ 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }] 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true, requestShipping: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | request.addEventListener('shippingaddresschange', function(e) { 53 | e.updateWith(new Promise(function(resolve) { 54 | // No changes in price based on shipping address change. 55 | resolve(paymentDetails); 56 | })); 57 | }); 58 | 59 | if (request.canMakePayment) { 60 | request.canMakePayment().then(function(result) { 61 | if (result) { 62 | request.show().then(function(result) { 63 | result.complete('success').then(function() { 64 | console.log(JSON.stringify(result)); 65 | displaySuccess(); 66 | }); 67 | }).catch(function(err) { 68 | if (err.message == "Request cancelled") { 69 | displayMessage("Request has been cancelled"); 70 | } else { 71 | console.error(err.message); 72 | displayError(); 73 | } 74 | }); 75 | } else { 76 | console.log('Cannot make payment'); 77 | displayMessage("Sorry - no valid payment methods available"); 78 | } 79 | }).catch(function(err) { 80 | console.log(request, err); 81 | }); 82 | } 83 | } 84 | }); 85 | } -------------------------------------------------------------------------------- /Ch4/spot errors/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/favicon.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/background.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/black.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/brown.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/hamburger.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/purple.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/red.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch4/spot errors/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/spot errors/images/yellow.png -------------------------------------------------------------------------------- /Ch4/spot errors/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch4/update shipping/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/favicon.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/background.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/black.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/brown.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/hamburger.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/purple.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/red.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch4/update shipping/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch4/update shipping/images/yellow.png -------------------------------------------------------------------------------- /Ch4/update shipping/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch4/update shipping/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 0; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | }, { 41 | label: 'FREE delivery (3-5 days)', 42 | amount: { currency: 'USD', value: shipping.toFixed(2) } 43 | },{ 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }], shippingOptions: [{ 47 | id: 'standard', 48 | label: 'FREE delivery (3-5 days)', 49 | amount: {currency: 'USD', value: '0.00'}, 50 | selected: true, 51 | }, 52 | { 53 | id: 'express', 54 | label: 'Express delivery (next day)', 55 | amount: {currency: 'USD', value: '3.99'}, 56 | }, 57 | ], 58 | }; 59 | 60 | const paymentOptions = { requestPayerEmail: true, requestShipping: true }; 61 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 62 | 63 | request.addEventListener('shippingaddresschange', function(e) { 64 | e.updateWith(new Promise(function(resolve) { 65 | // No changes in price based on shipping address change. 66 | resolve(paymentDetails); 67 | })); 68 | }); 69 | 70 | if (request.canMakePayment) { 71 | request.canMakePayment().then(function(result) { 72 | if (result) { 73 | request.show().then(function(result) { 74 | result.complete('success').then(function() { 75 | //console.log(JSON.stringify(result)); 76 | displaySuccess(); 77 | }); 78 | }).catch(function(err) { 79 | if (err.message == "Request cancelled") { 80 | displayMessage("Request has been cancelled"); 81 | } else { 82 | console.error(err.message); 83 | displayError(); 84 | } 85 | }); 86 | } else { 87 | console.log('Cannot make payment'); 88 | displayMessage("Sorry - no valid payment methods available"); 89 | } 90 | }).catch(function(err) { 91 | console.log(request, err); 92 | }); 93 | } 94 | } 95 | }); 96 | } -------------------------------------------------------------------------------- /Ch5/bobpay/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/favicon.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/background.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/black.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/brown.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/hamburger.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/purple.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/red.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch5/bobpay/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/bobpay/images/yellow.png -------------------------------------------------------------------------------- /Ch5/bobpay/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displaySuccess() { 10 | document.getElementById("message").classList.add("success"); 11 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 12 | 13 | function displayError() { 14 | document.getElementById("message").classList.add("failure"); 15 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 16 | 17 | function displayMessage(mesg) { 18 | document.getElementById("message").classList.add("info"); 19 | document.getElementById("message").innerHTML = "🛈" + mesg; 20 | } 21 | 22 | // configure payment request API 23 | document.querySelector(".pay-button").addEventListener("click", function(e) { 24 | document.getElementById("message").className = ''; 25 | 26 | if (window.PaymentRequest) { 27 | let subtotal = Number(document.querySelector(".total-price").innerText); 28 | let shipping = 2.99; 29 | let tax = (subtotal + shipping) * 0.175; 30 | let total = Number(subtotal) + Number(tax) + Number(shipping); 31 | 32 | const paymentDetails = { 33 | total: { 34 | label: 'Total due', 35 | amount: { currency: 'USD', value: total.toFixed(2) } 36 | }, 37 | displayItems: [{ 38 | label: 'Coffee capsules', 39 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 40 | },{ 41 | label: 'Shipping', 42 | amount: { currency: 'USD', value: 2.99 } 43 | }, { 44 | label: 'Sales Tax', 45 | amount: { currency: 'USD', value: tax.toFixed(2) } 46 | }], 47 | }; 48 | 49 | const paymentOptions = { requestPayerEmail: true }; 50 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 51 | 52 | if (request.canMakePayment) { 53 | request.canMakePayment().then(function(result) { 54 | if (result) { 55 | request.show().then(function(result) { 56 | result.complete('success').then(function() { 57 | console.log(JSON.stringify(result)); 58 | displaySuccess(); 59 | }); 60 | }).catch(function(err) { 61 | if (err.message == "Request cancelled") { 62 | displayMessage("Request has been cancelled"); 63 | } else { 64 | console.error(err.message); 65 | displayError(); 66 | } 67 | }); 68 | } else { 69 | console.log('Cannot make payment'); 70 | displayMessage("Sorry - no valid payment methods available"); 71 | } 72 | }).catch(function(err) { 73 | console.log(request, err); 74 | }); 75 | } 76 | } 77 | }); 78 | } -------------------------------------------------------------------------------- /Ch5/charges/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/favicon.png -------------------------------------------------------------------------------- /Ch5/charges/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/background.png -------------------------------------------------------------------------------- /Ch5/charges/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/black.png -------------------------------------------------------------------------------- /Ch5/charges/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/brown.png -------------------------------------------------------------------------------- /Ch5/charges/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/hamburger.png -------------------------------------------------------------------------------- /Ch5/charges/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/purple.png -------------------------------------------------------------------------------- /Ch5/charges/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch5/charges/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/red.png -------------------------------------------------------------------------------- /Ch5/charges/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch5/charges/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/charges/images/yellow.png -------------------------------------------------------------------------------- /Ch5/charges/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LoveCoffee.club | The Home of Great Coffee 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 18 |
19 | 20 | 48 | 49 |
50 | 51 |
52 |
53 | 0 54 |
55 | 57 |
58 | Total: $0 59 |
60 |
Checkout securely
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch5/charges/js/payment.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }, { 8 | supportedMethods: 'https://bobpay.xyz/pay' 9 | }, { 10 | supportedMethods: 'interledger' 11 | }]; 12 | 13 | function displaySuccess() { 14 | document.getElementById("message").classList.add("success"); 15 | document.getElementById("message").innerHTML = "\u2714 Payment received - thanks for your order!"; } 16 | 17 | function displayError() { 18 | document.getElementById("message").classList.add("failure"); 19 | document.getElementById("message").innerHTML = "\u2716 There was a problem with payment"; } 20 | 21 | function displayMessage(mesg) { 22 | document.getElementById("message").classList.add("info"); 23 | document.getElementById("message").innerHTML = "🛈" + mesg; 24 | } 25 | 26 | // configure payment request API 27 | document.querySelector(".pay-button").addEventListener("click", function(e) { 28 | document.getElementById("message").className = ''; 29 | 30 | if (window.PaymentRequest) { 31 | let subtotal = Number(document.querySelector(".total-price").innerText); 32 | let shipping = 2.99; 33 | let tax = (subtotal + shipping) * 0.175; 34 | let total = Number(subtotal) + Number(tax) + Number(shipping); 35 | 36 | const paymentDetails = { 37 | total: { 38 | label: 'Total due', 39 | amount: { currency: 'USD', value: total.toFixed(2) } 40 | }, 41 | displayItems: [{ 42 | label: 'Coffee capsules', 43 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 44 | },{ 45 | label: 'Shipping', 46 | amount: { currency: 'USD', value: 2.99 } 47 | }, { 48 | label: 'Sales Tax', 49 | pending: true, 50 | amount: { currency: 'USD', value: tax.toFixed(2) }, 51 | pending: true 52 | }], 53 | modifiers: [{ 54 | supportedMethods: 'https://bobpay.xyz/pay', 55 | additionalDisplayItems: [{ 56 | label: 'Processing fee', 57 | amount: { currency: 'USD', value: '3.00' } 58 | }], 59 | total: { 60 | label: 'Total to pay by card', 61 | amount: {currency: 'USD', value: Number(total + 3).toFixed(2)}} 62 | }], 63 | }; 64 | 65 | const paymentOptions = { requestPayerEmail: true }; 66 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 67 | 68 | if (request.canMakePayment) { 69 | request.canMakePayment().then(function(result) { 70 | if (result) { 71 | request.show().then(function(result) { 72 | result.complete('success').then(function() { 73 | console.log(JSON.stringify(result)); 74 | displaySuccess(); 75 | }); 76 | }).catch(function(err) { 77 | if (err.message == "Request cancelled") { 78 | displayMessage("Request has been cancelled"); 79 | } else { 80 | console.error(err.message); 81 | displayError(); 82 | } 83 | }); 84 | } else { 85 | console.log('Cannot make payment'); 86 | displayMessage("Sorry - no valid payment methods available"); 87 | } 88 | }).catch(function(err) { 89 | console.log(request, err); 90 | }); 91 | } 92 | } 93 | }); 94 | } -------------------------------------------------------------------------------- /Ch5/nobob/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/favicon.png -------------------------------------------------------------------------------- /Ch5/nobob/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/background.png -------------------------------------------------------------------------------- /Ch5/nobob/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/black.png -------------------------------------------------------------------------------- /Ch5/nobob/images/bobpay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/bobpay.png -------------------------------------------------------------------------------- /Ch5/nobob/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/brown.png -------------------------------------------------------------------------------- /Ch5/nobob/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/hamburger.png -------------------------------------------------------------------------------- /Ch5/nobob/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/purple.png -------------------------------------------------------------------------------- /Ch5/nobob/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch5/nobob/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/red.png -------------------------------------------------------------------------------- /Ch5/nobob/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch5/nobob/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/nobob/images/yellow.png -------------------------------------------------------------------------------- /Ch5/stripe/css/stripe.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | background-color: #fff; 3 | height: 100%; 4 | width: 335px; 5 | font-family: 'Montserrat', sans-serif; 6 | margin: 0 auto; 7 | } 8 | 9 | img, div { 10 | margin: 0 auto; 11 | display: block; 12 | } 13 | 14 | div { 15 | margin-bottom: 20px; 16 | } 17 | 18 | h1 { 19 | display: block; 20 | border-bottom: 1px solid #c21807; 21 | } 22 | 23 | h3, label { 24 | font-weight: 700; 25 | font-size: 23px; 26 | } 27 | 28 | img { 29 | width: 261px; 30 | } 31 | 32 | input { 33 | width: 50px; 34 | float: right; 35 | } 36 | 37 | span { 38 | float: right; 39 | } 40 | 41 | span.default { 42 | color: #ffffff; 43 | font-size: 18px; 44 | } 45 | 46 | .currency { 47 | margin-top: -50px; 48 | margin-left: 240px; 49 | position: absolute; 50 | color: #c21807; 51 | } 52 | 53 | #subTotalText { 54 | margin-top: -50px; 55 | float: right; 56 | color: #c21807; 57 | } 58 | 59 | #message { 60 | float: left; 61 | margin-top: 10px; 62 | width: 320px; 63 | display: none; 64 | padding: 10px; 65 | font-weight: bold; 66 | border-radius: 5px; 67 | } 68 | 69 | #message.success { 70 | background-color: #ace1af; 71 | color: #008000; 72 | display: block; 73 | } 74 | 75 | #message.success > span { 76 | float: left; 77 | font-size: 30px; 78 | color: #008000; 79 | padding: 0px 10px; 80 | line-height: 40px; 81 | } 82 | 83 | #message.failure { 84 | background-color: #FFD1DC; 85 | color: #ff0000; 86 | display: block; 87 | } 88 | 89 | #message.failure > span { 90 | float: left; 91 | font-size: 30px; 92 | color: red; 93 | padding: 0px 10px; 94 | line-height: 40px; 95 | } 96 | 97 | #message.info { 98 | background-color: #FCF75E; 99 | display: block; 100 | color: #000000; 101 | line-height: 20px; 102 | } 103 | 104 | #message.info > span { 105 | float: left; 106 | font-size: 30px; 107 | color: #000000; 108 | padding: 0px 10px; 109 | line-height: 20px; 110 | } 111 | 112 | .btn { 113 | display: inline-block; 114 | font-weight: 400; 115 | text-align: center; 116 | white-space: nowrap; 117 | vertical-align: middle; 118 | -webkit-user-select: none; 119 | -moz-user-select: none; 120 | -ms-user-select: none; 121 | user-select: none; 122 | border: 1px solid transparent; 123 | padding: 0.375rem 0.75rem; 124 | font-size: 1rem; 125 | line-height: 1.5; 126 | border-radius: 0.25rem; 127 | transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; 128 | } 129 | 130 | .btn-primary { 131 | color: #fff; 132 | background-color: #c21807; 133 | border-color: #c21807; 134 | display: inline-block; 135 | float: right; 136 | height: 60px; 137 | width: 169px; 138 | text-align: center; 139 | padding: 15px 30px; 140 | border-radius: 30px; 141 | outline: none; 142 | } 143 | 144 | .btn-primary:hover { 145 | color: #fff; 146 | background-color: #f31e09; 147 | border-color: #f31e09; 148 | } 149 | 150 | .btn:hover, .btn:focus { 151 | text-decoration: none; 152 | } 153 | 154 | .btn:not(:disabled):not(.disabled) { 155 | cursor: pointer; 156 | } 157 | -------------------------------------------------------------------------------- /Ch5/stripe/example index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 |
11 | 78 | 79 | -------------------------------------------------------------------------------- /Ch5/stripe/images/chillis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch5/stripe/images/chillis.png -------------------------------------------------------------------------------- /Ch5/stripe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |

Cart

11 | 12 | 13 |

Product:Bag of red chillis

14 |

Price:$4.99

15 | 16 | 17 |

SubTotal:

18 |

$
24.95

19 | 25 |
26 |
27 | 28 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Ch5/stripe/js/scripts.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // Switch out the test key here with your own 3 | let stripe = Stripe(''); 4 | let paymentRequest = stripe.paymentRequest({ 5 | country: 'US', 6 | currency: 'usd', 7 | total: { 8 | label: 'Total to pay', 9 | amount: 2495, 10 | }, 11 | requestPayerName: true, 12 | requestPayerEmail: true, 13 | requestShipping: true, 14 | shippingOptions: [ 15 | { 16 | id: 'free-shipping', 17 | label: 'Free shipping', 18 | detail: 'Arrives in 5 to 7 days', 19 | amount: 0, 20 | }, 21 | ], 22 | }); 23 | 24 | // Check the availability of the Payment Request API first. 25 | paymentRequest.canMakePayment().then(function(result) { 26 | let button = document.getElementById('payment-request-button'); 27 | if (result) { 28 | button.style.display = 'inline-block'; 29 | button.addEventListener('click', paymentRequest.show); 30 | } else { 31 | button.style.display = 'none'; 32 | } 33 | }); 34 | 35 | paymentRequest.on('token', function(ev) { 36 | document.getElementById('payment-token').innerText = ev.token.id; 37 | document.getElementById('payment-token-message').style.display = 'block'; 38 | 39 | ev.complete('success'); 40 | }); 41 | })(); -------------------------------------------------------------------------------- /Ch6/coffee/css/dart-sass/dart-sass.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM Copyright 2016 Google Inc. Use of this source code is governed by an 3 | REM MIT-style license that can be found in the LICENSE file or at 4 | REM https://opensource.org/licenses/MIT. 5 | 6 | REM This script drives the standalone Sass package, which bundles together a 7 | REM Dart executable and a snapshot of Sass. It can be created with `pub run 8 | REM grinder package`. 9 | 10 | echo "WARNING: The dart-sass executable is deprecated, use sass instead." 11 | 12 | set SCRIPTPATH=%~dp0 13 | set arguments=%* 14 | "%SCRIPTPATH%\src\dart.exe" "-Dversion=1.20.3" "%SCRIPTPATH%\src\sass.dart.snapshot" %arguments% 15 | -------------------------------------------------------------------------------- /Ch6/coffee/css/dart-sass/sass.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM Copyright 2016 Google Inc. Use of this source code is governed by an 3 | REM MIT-style license that can be found in the LICENSE file or at 4 | REM https://opensource.org/licenses/MIT. 5 | 6 | REM This script drives the standalone Sass package, which bundles together a 7 | REM Dart executable and a snapshot of Sass. It can be created with `pub run 8 | REM grinder package`. 9 | 10 | set SCRIPTPATH=%~dp0 11 | set arguments=%* 12 | "%SCRIPTPATH%\src\dart.exe" "-Dversion=1.20.3" "%SCRIPTPATH%\src\sass.dart.snapshot" %arguments% 13 | -------------------------------------------------------------------------------- /Ch6/coffee/css/dart-sass/src/DART_LICENSE: -------------------------------------------------------------------------------- 1 | This license applies to all parts of Dart that are not externally 2 | maintained libraries. The external maintained libraries used by 3 | Dart are: 4 | 5 | 7-Zip - in third_party/7zip 6 | JSCRE - in runtime/third_party/jscre 7 | Ant - in third_party/apache_ant 8 | args4j - in third_party/args4j 9 | bzip2 - in third_party/bzip2 10 | Commons IO - in third_party/commons-io 11 | Commons Lang in third_party/commons-lang 12 | Eclipse - in third_party/eclipse 13 | gsutil - in third_party/gsutil 14 | Guava - in third_party/guava 15 | hamcrest - in third_party/hamcrest 16 | Httplib2 - in samples/third_party/httplib2 17 | JSON - in third_party/json 18 | JUnit - in third_party/junit 19 | NSS - in third_party/nss and third_party/net_nss 20 | Oauth - in samples/third_party/oauth2client 21 | SQLite - in third_party/sqlite 22 | weberknecht - in third_party/weberknecht 23 | zlib - in third_party/zlib 24 | fest - in third_party/fest 25 | mockito - in third_party/mockito 26 | 27 | The libraries may have their own licenses; we recommend you read them, 28 | as their terms may differ from the terms below. 29 | 30 | Copyright 2012, the Dart project authors. All rights reserved. 31 | Redistribution and use in source and binary forms, with or without 32 | modification, are permitted provided that the following conditions are 33 | met: 34 | * Redistributions of source code must retain the above copyright 35 | notice, this list of conditions and the following disclaimer. 36 | * Redistributions in binary form must reproduce the above 37 | copyright notice, this list of conditions and the following 38 | disclaimer in the documentation and/or other materials provided 39 | with the distribution. 40 | * Neither the name of Google Inc. nor the names of its 41 | contributors may be used to endorse or promote products derived 42 | from this software without specific prior written permission. 43 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 44 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 45 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 46 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 47 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 49 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 50 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 51 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 52 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 53 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 | -------------------------------------------------------------------------------- /Ch6/coffee/css/dart-sass/src/SASS_LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Google Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Ch6/coffee/css/dart-sass/src/dart.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/css/dart-sass/src/dart.exe -------------------------------------------------------------------------------- /Ch6/coffee/css/dart-sass/src/sass.dart.snapshot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/css/dart-sass/src/sass.dart.snapshot -------------------------------------------------------------------------------- /Ch6/coffee/css/styles.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["styles-sass.scss"],"names":[],"mappings":"AAGA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA,OAXkB;;;AAcpB;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EAAI;;AACJ;EAAU;;AACV;EAAK;EAAa;EAAiB;EAAgB;EAAkC;EACrF;EAAa;EAAmB;;;AAGlC;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAO;;AAEP;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAI;;AACJ;EAAS,OA7FH;EA6FkB;EAAc;EAAc;EAAkB;EACpE;;AACF;EAAS;EAAkB;EAAkC;EAAoB;;;AAGnF;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAQ;EAAc;;;AAItB;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AAKF;EAAU;EAAY;EAAuB;;AAC7C;EAAiB;;AACjB;EAAa;EAAY;EAAuB;;;AAGlD;EACE;EACA;EACA;;AAEA;EAAW;;;AAGb;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAY;EAAa;;;AAG3B;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACG;EACC;EACI;;AAER;EAAY;EAAuB;EAAoB;EAAc;EACnE;;AAEF;EAAoB;;AACpB;EAAU;;AACV;EAAM;EAAa;EAAc;EAAwB;;;AAG3D;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACG;EACC;EACI;EACR;;AAEA;EAAU;;AACV;EAAQ;EAAgB;EAAa;EAAa;;;AAGpD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACC;EACD;EACA;EAEE;EACA;AAA4B;EAC5B;;;AAGJ;EACI;IAAM;;EACN;IAAI;;;AAGR;EACI;IAAM;;EACN;IAAI;;;AAIN;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;;AAKN;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EAAS;EAAkC;EAAqB;;;AAGlE;EAAW;EAAc;;;AAGzB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAU;;;AAGZ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA,OAnaM;EAoaN;EACA;EACA;;AAEA;EAAS;EAA0B;EAA2B;EAChE;;AAEE;EAAa;EAAe;;;AAG9B;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAxbM;EAybN;EACA;EACA;;;AAGF;EACE;EACA","file":"styles.css"} -------------------------------------------------------------------------------- /Ch6/coffee/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/favicon.png -------------------------------------------------------------------------------- /Ch6/coffee/images/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/images/black.png -------------------------------------------------------------------------------- /Ch6/coffee/images/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/images/brown.png -------------------------------------------------------------------------------- /Ch6/coffee/images/latte.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Ch6/coffee/images/long.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Ch6/coffee/images/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/images/purple.png -------------------------------------------------------------------------------- /Ch6/coffee/images/recycling-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/images/recycling-bin.png -------------------------------------------------------------------------------- /Ch6/coffee/images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/images/red.png -------------------------------------------------------------------------------- /Ch6/coffee/images/shopping-basket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/images/shopping-basket.png -------------------------------------------------------------------------------- /Ch6/coffee/images/short.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Ch6/coffee/images/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch6/coffee/images/yellow.png -------------------------------------------------------------------------------- /Ch6/coffee/js/Examples/payment - basic.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | // configure payment request API 10 | document.querySelector(".chkoutbutton").addEventListener("click", function(e) { 11 | if (document.querySelector(".chkoutbutton").classList.contains("enabled")) { 12 | document.getElementById("message").className = ''; 13 | 14 | if (window.PaymentRequest) { 15 | let subtotal = Number(document.querySelector(".total-price").innerText); 16 | let shipping = 2.99; 17 | let tax = (subtotal + shipping) * 0.175; 18 | let total = Number(subtotal) + Number(tax) + Number(shipping); 19 | 20 | const paymentDetails = { 21 | total: { 22 | label: 'Total to pay by card', 23 | amount: { currency: 'USD', value: total.toFixed(2) } 24 | }, 25 | displayItems: [{ 26 | label: 'Coffee capsules', 27 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 28 | }, { 29 | label: 'Sales Tax', 30 | amount: { currency: 'USD', value: tax.toFixed(2) } 31 | }], 32 | }; 33 | 34 | const paymentOptions = { requestPayerEmail: true }; 35 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 36 | 37 | if (request.canMakePayment) { 38 | request.canMakePayment().then(function(result) { 39 | if (result) { 40 | request.show().then(function(result) { 41 | result.complete('success').then(function() { 42 | console.log(JSON.stringify(result)); 43 | }); 44 | }).catch(function(err) { 45 | console.error(err.message); 46 | }); 47 | } else { 48 | console.log('Cannot make payment'); 49 | } 50 | }).catch(function(err) { 51 | console.log(request, err); 52 | }); 53 | } 54 | } 55 | } 56 | }); 57 | }; 58 | -------------------------------------------------------------------------------- /Ch6/coffee/js/Examples/payment - bobpay.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }, { 8 | supportedMethods: 'https://bobpay.xyz/pay' 9 | }, { 10 | supportedMethods: 'interledger' 11 | }]; 12 | 13 | // configure payment request API 14 | document.querySelector(".chkoutbutton").addEventListener("click", function(e) { 15 | if (document.querySelector(".chkoutbutton").classList.contains("enabled")) { 16 | document.getElementById("message").className = ''; 17 | 18 | if (window.PaymentRequest) { 19 | let subtotal = Number(document.querySelector(".total-price").innerText); 20 | let shipping = 2.99; 21 | let tax = (subtotal + shipping) * 0.175; 22 | let total = Number(subtotal) + Number(tax) + Number(shipping); 23 | 24 | const paymentDetails = { 25 | total: { 26 | label: 'Total to pay by card', 27 | amount: { currency: 'USD', value: total.toFixed(2) } 28 | }, 29 | displayItems: [{ 30 | label: 'Coffee capsules', 31 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 32 | },{ 33 | label: 'Standard shipping in US', 34 | amount: { currency: 'USD', value: shipping.toFixed(2) } 35 | }, { 36 | label: 'Sales Tax', 37 | amount: { currency: 'USD', value: tax.toFixed(2) } 38 | }], 39 | }; 40 | 41 | const paymentOptions = { requestPayerEmail: true }; 42 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 43 | 44 | if (request.canMakePayment) { 45 | request.canMakePayment().then(function(result) { 46 | if (result) { 47 | request.show().then(function(result) { 48 | result.complete('success').then(function() { 49 | console.log(JSON.stringify(result)); 50 | }); 51 | }).catch(function(err) { 52 | console.error(err.message); 53 | }); 54 | } else { 55 | console.log('Cannot make payment'); 56 | } 57 | }).catch(function(err) { 58 | console.log(request, err); 59 | }); 60 | } 61 | } 62 | } 63 | }); 64 | }; 65 | -------------------------------------------------------------------------------- /Ch6/coffee/js/Examples/payment - errors.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) { 2 | const paymentMethods = [{ 3 | supportedMethods: 'basic-card', 4 | data: { 5 | supportedNetworks: ['visa', 'mastercard', 'amex'] 6 | } 7 | }]; 8 | 9 | function displayMessage(symbol, state, mesg) { 10 | document.getElementById("message").classList.add(state); 11 | document.getElementById("message").innerHTML = "" + symbol + "" + mesg; 12 | } 13 | 14 | // configure payment request API 15 | document.querySelector(".chkoutbutton").addEventListener("click", function(e) { 16 | if (document.querySelector(".chkoutbutton").classList.contains("enabled")) { 17 | document.getElementById("message").className = ''; 18 | 19 | if (window.PaymentRequest) { 20 | let subtotal = Number(document.querySelector(".total-price").innerText); 21 | let shipping = 2.99; 22 | let tax = (subtotal + shipping) * 0.175; 23 | let total = Number(subtotal) + Number(tax) + Number(shipping); 24 | 25 | const paymentDetails = { 26 | total: { 27 | label: 'Total to pay by card', 28 | amount: { currency: 'USD', value: total.toFixed(2) } 29 | }, 30 | displayItems: [{ 31 | label: 'Coffee capsules', 32 | amount: { currency: 'USD', value: subtotal.toFixed(2) } 33 | },{ 34 | label: 'Standard shipping in US', 35 | amount: { currency: 'USD', value: shipping.toFixed(2) } 36 | }, { 37 | label: 'Sales Tax', 38 | amount: { currency: 'USD', value: tax.toFixed(2) } 39 | }], 40 | }; 41 | 42 | const paymentOptions = { requestPayerEmail: true }; 43 | let request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); 44 | 45 | if (request.canMakePayment) { 46 | request.canMakePayment().then(function(result) { 47 | if (result) { 48 | request.show().then(function(result) { 49 | result.complete('success').then(function() { 50 | console.log(JSON.stringify(result)); 51 | displayMessage("\u2714", "success", "Payment received - thanks for your order!"); 52 | }); 53 | }).catch(function(err) { 54 | if (err.code == DOMException.ABORT_ERR) { 55 | displayMessage("🛈", "info", "Request has been cancelled"); 56 | } else { 57 | console.error(err.message); 58 | displayMessage("\u2716", "error", "There was a problem with payment"); 59 | } 60 | }); 61 | } else { 62 | console.log('Cannot make payment'); 63 | displayMessage("🛈", "info", "Sorry - no valid payment methods available"); 64 | } 65 | }).catch(function(err) { 66 | console.log(request, err); 67 | }); 68 | } 69 | } 70 | } 71 | }); 72 | }; 73 | -------------------------------------------------------------------------------- /Ch7/cookies/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Ch7/cookies/images/cbakewell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/cbakewell.png -------------------------------------------------------------------------------- /Ch7/cookies/images/coconut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/coconut.png -------------------------------------------------------------------------------- /Ch7/cookies/images/dark-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/dark-choc.png -------------------------------------------------------------------------------- /Ch7/cookies/images/double-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/double-choc.png -------------------------------------------------------------------------------- /Ch7/cookies/images/jaffa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/jaffa.png -------------------------------------------------------------------------------- /Ch7/cookies/images/oatmeal-rasin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/oatmeal-rasin.png -------------------------------------------------------------------------------- /Ch7/cookies/images/rasberry-white-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/rasberry-white-choc.png -------------------------------------------------------------------------------- /Ch7/cookies/images/toffee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/toffee.png -------------------------------------------------------------------------------- /Ch7/cookies/images/white-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/cookies/images/white-choc.png -------------------------------------------------------------------------------- /Ch7/cookies/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cookies and More.com | Cookies fresh from our oven ! 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Cookies - fresh from our oven!

13 |

All just 75¢ each

14 |
{{cartItems.length}} item(s) in your basket
15 | 16 |
17 |
18 |
19 |
20 |
{{ item.title }}
21 |

22 |

23 | 24 |

25 |
26 |
27 |
28 | 29 |

Cart

30 | 31 |
32 |
33 |
{{item.title}}
34 |
Quantity:
35 |
${{item.price | formatCurrency}}
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
Cart is empty
Cart Total{{Total | formatCurrency}}
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 |
57 |

Add delivery instructions

58 |

Have any special requirements? You still have time to let us know:

59 | 60 | 61 |
62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Ch7/geolocate/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Ch7/geolocate/images/cbakewell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/cbakewell.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/coconut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/coconut.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/dark-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/dark-choc.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/double-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/double-choc.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/jaffa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/jaffa.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/oatmeal-rasin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/oatmeal-rasin.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/rasberry-white-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/rasberry-white-choc.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/toffee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/toffee.png -------------------------------------------------------------------------------- /Ch7/geolocate/images/white-choc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch7/geolocate/images/white-choc.png -------------------------------------------------------------------------------- /Ch7/geolocate/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cookies and More.com | Cookies fresh from our oven ! 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Cookies - fresh from our oven!

13 |

All just 75¢ each

14 |
{{cartItems.length}} item(s) in your basket
15 | 16 |
17 |
18 |
19 |
20 |
{{ item.title }}
21 |

22 |

23 | 24 |

25 |
26 |
27 |
28 | 29 |

Cart

30 | 31 |
32 |
33 |
{{item.title}}
34 |
Quantity:
35 |
${{item.price | formatCurrency}}
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
Cart is empty
Cart Total{{Total | formatCurrency}}
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 |
57 |

Add delivery instructions

58 |

Have any special requirements? You still have time to let us know:

59 | 60 | 61 |
62 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/app.js: -------------------------------------------------------------------------------- 1 | self.addEventListener('paymentrequest', (evt) => { 2 | evt.respondWith({ 3 | methodName: 'basic-card', 4 | details: { 5 | billingAddress: { 6 | addressLine: [ 7 | '1875 Explorer St #1000', 8 | ], 9 | city: 'Reston', 10 | country: 'US', 11 | dependentLocality: '', 12 | languageCode: '', 13 | organization: 'Google', 14 | phone: '+15555555555', 15 | postalCode: '20190', 16 | recipient: 'Jon Doe', 17 | region: 'VA', 18 | sortingCode: '' 19 | }, 20 | cardNumber: '4111111111111111', 21 | cardSecurityCode: '123', 22 | cardholderName: 'Jon Doe', 23 | expiryMonth: '01', 24 | expiryYear: '2020', 25 | }, 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | font-family: montserrat, sans-serif; 4 | } 5 | 6 | div { 7 | margin-top: 10px; 8 | } 9 | 10 | a { 11 | text-decoration: none; 12 | font-weight: bold; 13 | } 14 | 15 | a:hover { 16 | text-decoration: underline; 17 | } 18 | 19 | h1 { 20 | border-bottom: 1px solid #000000; 21 | margin-top: 0px; 22 | padding: 10px; 23 | background-color: #dcdcdc; 24 | } 25 | 26 | p { 27 | padding-left: 10px; 28 | padding-right: 10px; 29 | } 30 | 31 | img { 32 | width: 50px; 33 | height: auto; 34 | vertical-align: middle; 35 | } 36 | 37 | .error { 38 | animation-duration: 0.5s; 39 | animation-name: popup; 40 | color: red; 41 | } 42 | 43 | @keyframes popup { 44 | from { 45 | margin-top: 20px; 46 | opacity: 0; 47 | } 48 | 50% { 49 | opacity: 1; 50 | } 51 | } 52 | 53 | .error-hide { 54 | animation-duration: 0.5s; 55 | animation-name: popdown; 56 | color: red; 57 | } 58 | 59 | @keyframes popdown { 60 | to { 61 | margin-top: 20px; 62 | opacity: 0; 63 | } 64 | } 65 | 66 | .info { 67 | color: green; 68 | } 69 | 70 | .warning { 71 | background: yellow; 72 | padding: 20px; 73 | font-weight: bold; 74 | text-align: center; 75 | } 76 | 77 | #spinner { 78 | display: none; 79 | } 80 | 81 | #contents { 82 | border: 1px solid #000000; 83 | width: 600px; 84 | margin-left: auto; 85 | margin-right: auto; 86 | margin-top: 30px; 87 | height: 600px; 88 | } 89 | 90 | #contents > b { 91 | padding-left: 10px; 92 | padding-right: 10px; 93 | } 94 | 95 | #msg { 96 | padding-left: 10px; 97 | padding-right: 10px; 98 | width: 550px; 99 | } 100 | 101 | #installed, 102 | #installing, 103 | #uninstalling, 104 | #checking { 105 | display: none; 106 | } 107 | 108 | #not-installed { 109 | display: block; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch8/basiccard - completed version/favicon.ico -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/images/coffee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch8/basiccard - completed version/images/coffee.png -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Payment Handler for "CoffeePay" 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |

Payment Handler for "CoffeePay"

16 |

This is a simple payment handler for "CoffeePay". It does not open a window for user interaction.

17 |

Checking whether the payment handler is installed...

18 |
19 |

The payment handler is installed | Test it out.

20 |
    21 |
  • Scope: N/A
  • 22 |
  • Method: N/A
  • 23 |
  • Capabilities: 24 |
      25 |
    • Network: N/A
    • 26 |
    • Type: N/A
    • 27 |
    28 |
  • 29 |
30 |

31 |
32 | 33 |

Installing...

34 |

Uninstalling...

35 | 36 |
37 |

The payment handler is not installed | Verify.

38 |

39 |
40 | 41 |

42 | 
43 |     
44 |

View the source code:

45 | 50 |
51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pay with CoffeePay", 3 | "icons": [{ 4 | "src": "images/coffee.png", 5 | "sizes": "600x600", 6 | "type": "image/png" 7 | }] 8 | } 9 | -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/testing/coffee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch8/basiccard - completed version/testing/coffee.png -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/testing/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | font-family: montserrat, sans-serif; 4 | } 5 | 6 | div { 7 | margin-top: 10px; 8 | } 9 | 10 | a { 11 | text-decoration: none; 12 | font-weight: bold; 13 | } 14 | 15 | a:hover { 16 | text-decoration: underline; 17 | } 18 | 19 | h1 { 20 | border-bottom: 1px solid #000000; 21 | margin-top: 0px; 22 | padding: 10px; 23 | background-color: #dcdcdc; 24 | } 25 | 26 | p { 27 | padding-left: 10px; 28 | padding-right: 10px; 29 | } 30 | 31 | img { 32 | width: 50px; 33 | height: auto; 34 | vertical-align: middle; 35 | } 36 | 37 | .error { 38 | animation-duration: 0.5s; 39 | animation-name: popup; 40 | color: red; 41 | } 42 | 43 | @keyframes popup { 44 | from { 45 | margin-top: 20px; 46 | opacity: 0; 47 | } 48 | 50% { 49 | opacity: 1; 50 | } 51 | } 52 | 53 | .error { 54 | padding-left: 10px; 55 | padding-right: 10px; 56 | } 57 | 58 | .error-hide { 59 | animation-duration: 0.5s; 60 | animation-name: popdown; 61 | color: red; 62 | } 63 | 64 | @keyframes popdown { 65 | to { 66 | margin-top: 20px; 67 | opacity: 0; 68 | } 69 | } 70 | 71 | .info { 72 | color: green; 73 | } 74 | 75 | .warning { 76 | background: yellow; 77 | padding: 20px; 78 | font-weight: bold; 79 | text-align: center; 80 | } 81 | 82 | #spinner { 83 | display: none; 84 | } 85 | 86 | #contents { 87 | border: 1px solid #000000; 88 | width: 600px; 89 | margin-left: auto; 90 | margin-right: auto; 91 | margin-top: 30px; 92 | height: 600px; 93 | } 94 | 95 | #contents > b { 96 | padding-left: 10px; 97 | padding-right: 10px; 98 | } 99 | 100 | #msg { 101 | padding-left: 10px; 102 | padding-right: 10px; 103 | } 104 | 105 | #installed, 106 | #installing, 107 | #uninstalling, 108 | #checking { 109 | display: none; 110 | } 111 | 112 | #not-installed { 113 | display: block; 114 | } 115 | -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/testing/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/checking-out-with-the-payment-request-API/5044c1034eeddc12bc79d8b9cb5eacf6b9510bd7/Ch8/basiccard - completed version/testing/favicon.ico -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/testing/js/util.js: -------------------------------------------------------------------------------- 1 | var timeoutID1; 2 | var timeoutID2; 3 | 4 | /** 5 | * Prints the given error message. 6 | * @param {string} msg - The error message to print. 7 | */ 8 | function error(msg) { // eslint-disable-line no-unused-vars 9 | if (timeoutID1) { 10 | window.clearTimeout(timeoutID1); 11 | } 12 | if (timeoutID2) { 13 | window.clearTimeout(timeoutID2); 14 | } 15 | let element = document.createElement('pre'); 16 | element.innerHTML = msg; 17 | element.className = 'error'; 18 | document.getElementById('contents').appendChild(element); 19 | timeoutID1 = window.setTimeout(function() { 20 | if (element.className !== 'error') { 21 | return; 22 | } 23 | element.className = 'error-hide'; 24 | timeoutID2 = window.setTimeout(function() { 25 | element.innerHTML = ''; 26 | element.className = ''; 27 | }, 500); 28 | }, 10000); 29 | } 30 | 31 | /** 32 | * Prints the given informational message. 33 | * @param {string} msg - The information message to print. 34 | */ 35 | function info(msg) { 36 | let element = document.createElement('pre'); 37 | element.innerHTML = msg; 38 | element.className = 'info'; 39 | document.getElementById('msg').appendChild(element); 40 | } 41 | 42 | /** 43 | * Converts an address object into a dictionary. 44 | * @param {PaymentAddress} addr - The address to convert. 45 | * @return {object} The resulting dictionary. 46 | */ 47 | function toDictionary(addr) { // eslint-disable-line no-unused-vars 48 | let dict = {}; 49 | if (addr) { 50 | if (addr.toJSON) { 51 | return addr; 52 | } 53 | dict.country = addr.country; 54 | dict.region = addr.region; 55 | dict.city = addr.city; 56 | dict.dependentLocality = addr.dependentLocality; 57 | dict.addressLine = addr.addressLine; 58 | dict.postalCode = addr.postalCode; 59 | dict.sortingCode = addr.sortingCode; 60 | dict.languageCode = addr.languageCode; 61 | dict.organization = addr.organization; 62 | dict.recipient = addr.recipient; 63 | dict.phone = addr.phone; 64 | } 65 | return dict; 66 | } 67 | 68 | /** 69 | * Called when the payment request is complete. 70 | * @param {string} message - The human readable message to display. 71 | * @param {PaymentResponse} resp - The payment response. 72 | */ 73 | function done(message, resp) { // eslint-disable-line no-unused-vars 74 | let element = document.getElementById('contents'); 75 | element.innerHTML = message; 76 | 77 | if (resp.toJSON) { 78 | info(JSON.stringify(resp, undefined, 2)); 79 | return; 80 | } 81 | 82 | let shippingOption = resp.shippingOption ? 83 | 'shipping, delivery, pickup option: ' + resp.shippingOption + '
' : 84 | ''; 85 | 86 | let shippingAddress = resp.shippingAddress ? 87 | 'shipping, delivery, pickup address: ' + 88 | JSON.stringify(toDictionary(resp.shippingAddress), undefined, 2) + 89 | '
' : 90 | ''; 91 | 92 | let instrument = 93 | 'instrument:' + JSON.stringify(resp.details, undefined, 2) + '
'; 94 | 95 | let method = 'method: ' + resp.methodName + '
'; 96 | let email = resp.payerEmail ? 'email: ' + resp.payerEmail + '
' : ''; 97 | let phone = resp.payerPhone ? 'phone: ' + resp.payerPhone + '
' : ''; 98 | let name = resp.payerName ? 'name: ' + resp.payerName + '
' : ''; 99 | 100 | 101 | info(email + phone + name + shippingOption + shippingAddress + method + 102 | instrument); 103 | } 104 | -------------------------------------------------------------------------------- /Ch8/basiccard - completed version/testing/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Credit Card Test 7 | 8 | 9 | 10 | 11 |
12 |

Credit Card Test

13 |

This page can be used to test credit card payments. 14 | No payment will be processed.

15 |

Price: USD $55.00

16 |

17 |
18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Freeware License, some rights reserved 2 | 3 | Copyright (c) 2019 Alex Libby 4 | 5 | Permission is hereby granted, free of charge, to anyone obtaining a copy 6 | of this software and associated documentation files (the "Software"), 7 | to work with the Software within the limits of freeware distribution and fair use. 8 | This includes the rights to use, copy, and modify the Software for personal use. 9 | Users are also allowed and encouraged to submit corrections and modifications 10 | to the Software for the benefit of other users. 11 | 12 | It is not allowed to reuse, modify, or redistribute the Software for 13 | commercial use in any way, or for a user’s educational materials such as books 14 | or blog articles without prior permission from the copyright holder. 15 | 16 | The above copyright notice and this permission notice need to be included 17 | in all copies or substantial portions of the software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Checking Out with the Payment Request API*](http://www.apress.com/9781484251836) by Alex Libby (Apress, 2019). 4 | 5 | [comment]: #cover 6 | ![Cover image](9781484251836.jpg) 7 | 8 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 9 | 10 | ## Releases 11 | 12 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 13 | 14 | ## Contributions 15 | 16 | See the file Contributing.md for more information on how you can contribute to this repository. -------------------------------------------------------------------------------- /errata.md: -------------------------------------------------------------------------------- 1 | # Errata for *Book Title* 2 | 3 | On **page xx** [Summary of error]: 4 | 5 | Details of error here. Highlight key pieces in **bold**. 6 | 7 | *** 8 | 9 | On **page xx** [Summary of error]: 10 | 11 | Details of error here. Highlight key pieces in **bold**. 12 | 13 | *** --------------------------------------------------------------------------------