Add Payment Request demo content.
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Apr 2018 19:51:42 +0000 (19:51 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Apr 2018 19:51:42 +0000 (19:51 +0000)
Rubber-stamped by Zalan Bujtas.

* demos/payment-request/demo.js: Added.
(string_appeared_here.async.applePayButtonClicked):
* demos/payment-request/index.html: Added.
* demos/payment-request/merchant-validation.php: Added.
* demos/payment-request/squirrelfish.png: Added.
* demos/payment-request/style.css: Added.
(@supports (-webkit-appearance: -apple-pay-button)):
(.apple-pay-not-supported::before):
(.hidden):
(#black-buttons > .apple-pay-button):
(#white-buttons > .apple-pay-button):
(#demo):
(#description):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230270 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Websites/webkit.org/ChangeLog
Websites/webkit.org/demos/payment-request/demo.js [new file with mode: 0644]
Websites/webkit.org/demos/payment-request/index.html [new file with mode: 0644]
Websites/webkit.org/demos/payment-request/merchant-validation.php [new file with mode: 0644]
Websites/webkit.org/demos/payment-request/squirrelfish.png [new file with mode: 0644]
Websites/webkit.org/demos/payment-request/style.css [new file with mode: 0644]

index 948df99..868eeca 100644 (file)
@@ -1,3 +1,23 @@
+2018-04-04  Andy Estes  <aestes@apple.com>
+
+        Add Payment Request demo content.
+
+        Rubber-stamped by Zalan Bujtas.
+
+        * demos/payment-request/demo.js: Added.
+        (string_appeared_here.async.applePayButtonClicked):
+        * demos/payment-request/index.html: Added.
+        * demos/payment-request/merchant-validation.php: Added.
+        * demos/payment-request/squirrelfish.png: Added.
+        * demos/payment-request/style.css: Added.
+        (@supports (-webkit-appearance: -apple-pay-button)):
+        (.apple-pay-not-supported::before):
+        (.hidden):
+        (#black-buttons > .apple-pay-button):
+        (#white-buttons > .apple-pay-button):
+        (#demo):
+        (#description):
+
 2018-03-21  Jon Davis  <jond@apple.com>
 
         Add support for an overridable byline in blog posts
diff --git a/Websites/webkit.org/demos/payment-request/demo.js b/Websites/webkit.org/demos/payment-request/demo.js
new file mode 100644 (file)
index 0000000..86fb906
--- /dev/null
@@ -0,0 +1,97 @@
+(() => {
+    "use strict"
+    async function applePayButtonClicked(event)
+    {
+        const applePayMethod = {
+            supportedMethods: "https://apple.com/apple-pay",
+            data: {
+                version: 1,
+                merchantIdentifier: "org.webkit.demo",
+                merchantCapabilities: ["supports3DS", "supportsCredit", "supportsDebit"],
+                supportedNetworks: ["amex", "discover", "masterCard", "visa"],
+                countryCode: "US",
+            },
+        };
+
+        const detailsForShippingOption = selectedShippingOption => {
+            const shippingOptions = [
+                {
+                    id: "ground",
+                    label: "Ground Shipping",
+                    amount: { value: "5.00", currency: "USD" },
+                    overrideTotal: { value: "25.00", currency: "USD" },
+                },
+                {
+                    id: "express",
+                    label: "Express Shipping",
+                    amount: { value: "10.00", currency: "USD" },
+                    overrideTotal: { value: "30.00", currency: "USD" },
+                },
+            ];
+
+            var shippingOptionIndex = null;
+            for (var shippingOption in shippingOptions) {
+                if (shippingOptions[shippingOption].id !== selectedShippingOption)
+                    continue;
+                shippingOptionIndex = shippingOption;
+                break;
+            }
+
+            if (!shippingOptionIndex)
+                return { };
+
+            shippingOptions[shippingOptionIndex].selected = true;
+
+            return {
+                total: {
+                    label: "WebKit",
+                    amount: shippingOptions[shippingOptionIndex].overrideTotal,
+                },
+                displayItems: [
+                    {
+                        label: shippingOptions[shippingOptionIndex].label,
+                        amount: shippingOptions[shippingOptionIndex].amount,
+                    },
+                ],
+                shippingOptions: shippingOptions,
+            };
+        };
+
+        const options = {
+            requestShipping: true,
+        };
+
+        const paymentRequest = new PaymentRequest([applePayMethod], detailsForShippingOption("ground"), options);
+
+        paymentRequest.onmerchantvalidation = event => {
+            fetch("merchant-validation.php", {
+                body: JSON.stringify({ validationURL: event.validationURL }),
+                method: "POST",
+            }).then(response => event.complete(response.json()));
+        };
+
+        paymentRequest.onshippingaddresschange = event => {
+            const detailsUpdate = detailsForShippingOption(paymentRequest.shippingOption);
+            event.updateWith(detailsUpdate);
+        };
+
+        paymentRequest.onshippingoptionchange = event => {
+            const detailsUpdate = detailsForShippingOption(paymentRequest.shippingOption);
+            event.updateWith(detailsUpdate);
+        };
+
+        const response = await paymentRequest.show();
+        response.complete("success");
+    }
+
+    window.addEventListener("DOMContentLoaded", () => {
+        const applePayButton = document.querySelector("#live-button");
+        if (!window.PaymentRequest || !window.ApplePaySession || !ApplePaySession.canMakePayments())
+            applePayButton.classList.add("apple-pay-not-supported");
+        else {
+            applePayButton.classList.add("apple-pay-button");
+            applePayButton.addEventListener("click", applePayButtonClicked);   
+        }
+        applePayButton.classList.remove("hidden");
+    });
+})();
diff --git a/Websites/webkit.org/demos/payment-request/index.html b/Websites/webkit.org/demos/payment-request/index.html
new file mode 100644 (file)
index 0000000..c440d70
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Payment Request Demo</title>
+    <link href="style.css" rel="stylesheet">
+    <script type="text/javascript" src="demo.js"></script>
+</head>
+<body>
+    <div id="demo">
+        <div><img src="squirrelfish.png"></div>
+        <div id="description">Genuine Squirrelfish<br>$20.00 + shipping<br><br></div>
+        <div id="live-button" class="hidden"></div>
+    </div>
+</body>
+</html>
diff --git a/Websites/webkit.org/demos/payment-request/merchant-validation.php b/Websites/webkit.org/demos/payment-request/merchant-validation.php
new file mode 100644 (file)
index 0000000..6d5a99b
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * Download the merchant_id.cer file from developer.apple.com.
+ *
+ * Convert the DER form certificate to PEM and extract the key by
+ * running the following command in Terminal.app:
+ *
+ * openssl x509 -in merchant_id.cer -inform der -outform pem -out merchant_id.pem
+ *
+ * Open the Keychain Access.app on macOS and drag the merchant_id.cer file to your
+ * login keychain. Right-click to the "Apple Pay Merchant Identity:com.example"
+ * certificate and select "Export …". Name the file "merchant_id" and select the
+ * "Personal Information Exchange (.p12)" file format. Choose a password to protect
+ * the private key, then run the following in Terminal.app:
+ *
+ * openssl pkcs12 -in merchant_id.p12 -out merchant_id_key.pem -nocerts
+ **/
+
+$configFilePath = 'payment-request-config.php';
+if (file_exists($configFilePath))
+    include($configFilePath);
+
+if (!defined('MERCHANT_IDENTITY_CERTIFICATE'))
+    define('MERCHANT_IDENTITY_CERTIFICATE', 'merchant_id.pem');
+
+if (!defined('MERCHANT_IDENTITY_KEY'))
+    define('MERCHANT_IDENTITY_KEY', 'merchant_id_key.pem');
+
+if (!defined('MERCHANT_IDENTITY_KEY_PASS'))
+    define('MERCHANT_IDENTITY_KEY_PASS', '');
+
+if (!defined('DISPLAY_NAME'))
+    define('DISPLAY_NAME', 'WebKit.org Demo');
+
+if (!defined('MERCHANT_IDENTIFIER'))
+    define('MERCHANT_IDENTIFIER', openssl_x509_parse(file_get_contents( MERCHANT_IDENTITY_CERTIFICATE ))['subject']['UID'] );
+
+if (!defined('INITIATIVE'))
+    define('INITIATIVE', 'web');
+
+if (!defined('INITIATIVE_CONTEXT'))
+    define('INITIATIVE_CONTEXT', $_SERVER['HTTP_HOST']);
+
+$postedDataString = file_get_contents('php://input');
+
+try {
+    $postedData = json_decode($postedDataString, true);
+} catch (Exception $e) {
+    die('An error occurred parsing the given data in JSON format: ' . $e->getMessage());
+}
+
+$validationURL = isset($postedData['validationURL']) ? $postedData['validationURL'] : '';
+$merchantIdentifier = isset($postedData['merchantIdentifier']) ? $postedData['merchantIdentifier'] : MERCHANT_IDENTIFIER;
+$displayName = isset($postedData['displayName']) ? $postedData['displayName'] : DISPLAY_NAME;
+$intiative = isset($postedData['intiative']) ? $postedData['intiative'] : INITIATIVE;
+$intiativeContext = isset($postedData['intiativeContext']) ? $postedData['intiativeContext'] : INITIATIVE_CONTEXT;
+
+$postData = array(
+    'merchantIdentifier' => $merchantIdentifier,
+    'displayName' => $displayName,
+    'domainName' => $intiativeContext,
+    'initiative' => $intiative,
+    'initiativeContext' => $intiativeContext
+);
+
+$postDataFields = json_encode($postData);
+
+$curlOptions = array(
+    CURLOPT_URL => $validationURL,
+    CURLOPT_POST => true,
+    CURLOPT_POSTFIELDS => $postDataFields,
+    CURLOPT_RETURNTRANSFER => true,
+    CURLOPT_SSLCERT => MERCHANT_IDENTITY_CERTIFICATE,
+    CURLOPT_SSLKEY => MERCHANT_IDENTITY_KEY,
+    CURLOPT_SSLKEYPASSWD => MERCHANT_IDENTITY_KEY_PASS,
+    CURLOPT_SSLKEYPASSWD => MERCHANT_IDENTITY_KEY_PASS,
+    CURLOPT_SSL_VERIFYPEER => true
+);
+
+$curlConnection = curl_init();
+curl_setopt_array($curlConnection, $curlOptions);
+if (!$result = curl_exec($curlConnection))
+    die('An error occurred when connecting to the validation URL: ' . curl_error($curlConnection));
+
+curl_close($curlConnection);
+
+header('Content-Type: application/json');
+echo $result;
+exit();
\ No newline at end of file
diff --git a/Websites/webkit.org/demos/payment-request/squirrelfish.png b/Websites/webkit.org/demos/payment-request/squirrelfish.png
new file mode 100644 (file)
index 0000000..05a6909
Binary files /dev/null and b/Websites/webkit.org/demos/payment-request/squirrelfish.png differ
diff --git a/Websites/webkit.org/demos/payment-request/style.css b/Websites/webkit.org/demos/payment-request/style.css
new file mode 100644 (file)
index 0000000..282526a
--- /dev/null
@@ -0,0 +1,37 @@
+@supports (-webkit-appearance: -apple-pay-button) {
+    .apple-pay-button {
+       display: inline-block;
+        -webkit-appearance: -apple-pay-button;
+        -apple-pay-button-type: buy;
+        width: 50px;
+    }
+}
+
+.apple-pay-not-supported::before {
+    content: "Apple Pay not supported";
+    color: grey;
+}
+
+.hidden {
+    visibility: hidden;
+}
+
+#black-buttons > .apple-pay-button {
+       -apple-pay-button-style: black;
+}
+
+#white-buttons > .apple-pay-button {
+       -apple-pay-button-style: white-outline;
+}
+
+#demo {
+       border: 1px solid black;
+       border-radius: 5px;
+       text-align: center;
+}
+
+#description {
+       font-family: -apple-system;
+       font-style: italic;
+       font-size: 20px;
+}
\ No newline at end of file