Change paypal example to square master
authorNick Downing <nick@ndcode.org>
Mon, 27 Dec 2021 02:26:16 +0000 (13:26 +1100)
committerNick Downing <nick@ndcode.org>
Mon, 27 Dec 2021 06:18:03 +0000 (17:18 +1100)
37 files changed:
_config/config.json
_library/capture_order.jst [deleted file]
_library/create_order.jst [deleted file]
_library/get_access_token.jst [deleted file]
_library/get_oauth.jst [deleted file]
_library/get_order_details.jst [deleted file]
_library/patch_order_details.jst [deleted file]
_library/random_number.jst [deleted file]
_orig/.env [new file with mode: 0644]
_orig/.env.example [new file with mode: 0644]
_orig/PayPalCheckoutServerSideV2_nodejs.zip [deleted file]
_orig/README.md [new file with mode: 0644]
_orig/checkout.php [new file with mode: 0644]
_orig/composer.json [new file with mode: 0644]
_orig/composer.lock [new file with mode: 0644]
_orig/composer.phar [new file with mode: 0755]
_orig/confirmation.php [new file with mode: 0644]
_orig/cucumber_bob.js [new file with mode: 0644]
_orig/index.php [new file with mode: 0644]
_orig/main.css [new file with mode: 0644]
_orig/n.sh [new file with mode: 0755]
_orig/normalize.css [new file with mode: 0644]
api/captureOrder.json.jst [deleted file]
api/createOrder.json.jst [deleted file]
api/getOrderDetails.json.jst [deleted file]
api/patchOrder.json.jst [deleted file]
checkout.html.jst [new file with mode: 0644]
confirmation.html.jst [new file with mode: 0644]
img/camera.jpg [deleted file]
index.html.jst
js/config.js [deleted file]
main.css [new file with mode: 0644]
normalize.css [new file with mode: 0644]
package-lock.json [new file with mode: 0644]
package.json
pages/shipping.html.jst [deleted file]
pages/success.html.jst [deleted file]

index 4d54786..d91c061 100644 (file)
@@ -1,7 +1,6 @@
 {
-    "environment": "sandbox",
-    "sandbox_client_id": "Aa2IfcoEvHnfJRnVQLSFrSs3SmTTkv5N1weMEL66ysqYIeHfAqXpDVkjOv3vLhkhbP4eKB6MpRlQIcJw",
-    "sandbox_secret": "EF6l6PDQJEZbdKTeg35pbBSft6WRdALQC3Xrl5vvG0VNgBUehQyTCQ09QdIauxoccvJOf5Aoy-OGsH5G",
-    "production_client_id": "",
-    "production_secret": ""
-}
\ No newline at end of file
+  "environment": "",
+  "square_application_id": "your-application-id",
+  "square_access_token": "your-access-token",
+  "square_location_id": "your-location-id"
+}
diff --git a/_library/capture_order.jst b/_library/capture_order.jst
deleted file mode 100644 (file)
index 36ac9d0..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-let https = require('https')
-
-return async (env, order_id) => {
-  let config = await env.site.get_json('/_config/config.json')
-  let get_access_token = await _require('get_access_token.jst')
-
-  let access_token = await get_access_token(env)
-  return new Promise(
-    resolve => {
-      let request = https.request(
-        {
-          hostname: 'api.' + (config.environment === 'sandbox' ? 'sandbox.' : '') + 'paypal.com',
-          port: 443,
-          path: '/v2/checkout/orders/' + order_id + '/capture',
-          method: 'POST',
-          headers: {
-            'Content-Type': 'application/json',
-            'Authorization': 'Bearer ' + access_token,
-            'return': 'representation',
-            'PayPal-Partner-Attribution-Id': 'PP-DemoPortal-Checkout-NodeJS-SDK'
-          }
-        },
-        response => {
-          let str = ''
-          response.on('data', chunk => {str += chunk})
-          response.on('end', () => {resolve(JSON.parse(str))})
-        }
-      )
-      request.end()
-    }
-  )
-}
diff --git a/_library/create_order.jst b/_library/create_order.jst
deleted file mode 100644 (file)
index 22bf0fe..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-let https = require('https')
-
-return async (env, item_obj) => {
-  let config = await env.site.get_json('/_config/config.json')
-  let get_access_token = await _require('get_access_token.jst')
-
-  let access_token = await get_access_token(env)
-  return new Promise(
-    resolve => {
-      let request = https.request(
-        {
-          hostname: 'api.' + (config.environment === 'sandbox' ? 'sandbox.' : '') + 'paypal.com',
-          port: 443,
-          path: '/v2/checkout/orders',
-          method: 'POST',
-          headers: {
-            'Content-Type': 'application/json',
-            'Authorization': 'Bearer ' + access_token
-          }
-        },
-        response => {
-          let str = ''
-          response.on('data', chunk => {str += chunk})
-          response.on('end', () => {resolve(JSON.parse(str))})
-        }
-      )
-      request.write(JSON.stringify(item_obj));
-      request.end()
-    }
-  )
-}
diff --git a/_library/get_access_token.jst b/_library/get_access_token.jst
deleted file mode 100644 (file)
index 844bff2..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-let https = require('https')
-
-return async env => {
-  let get_oauth = await _require('get_oauth.jst')
-
-  return (await get_oauth(env)).access_token
-}
-
diff --git a/_library/get_oauth.jst b/_library/get_oauth.jst
deleted file mode 100644 (file)
index 0d54b10..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-let https = require('https')
-
-return async env => {
-  let config = await env.site.get_json('/_config/config.json')
-
-  return new Promise(
-    resolve => {
-      let data = 'grant_type=client_credentials'
-      let request = https.request(
-        {
-          hostname: 'api.' + (config.environment === 'sandbox' ? 'sandbox.' : '') + 'paypal.com',
-          port: 443,
-          path: '/v1/oauth2/token',
-          method: 'POST',
-          headers: {
-            'Content-Type': 'application/x-www-form-urlencoded',
-            'Content-Length': data.length,
-            'Authorization': 'Basic ' + Buffer.from((config.environment === 'sandbox' ? config.sandbox_client_id : config.production_client_id) + ':' + (config.environment === 'sandbox' ? config.sandbox_secret : config.production_secret)).toString('base64')
-          }
-        },
-        response => {
-          let str = ''
-          response.on('data', chunk => {str += chunk})
-          response.on('end', () => {resolve(JSON.parse(str))})
-        }
-      )
-      request.write(data);
-      request.end()
-    }
-  )
-}
diff --git a/_library/get_order_details.jst b/_library/get_order_details.jst
deleted file mode 100644 (file)
index 0d093be..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-let https = require('https')
-
-return async (env, order_id) => {
-  let config = await env.site.get_json('/_config/config.json')
-  let get_access_token = await _require('get_access_token.jst')
-
-  let access_token = await get_access_token(env)
-  return new Promise(
-    resolve => {
-      let request = https.request(
-        {
-          hostname: 'api.' + (config.environment === 'sandbox' ? 'sandbox.' : '') + 'paypal.com',
-          port: 443,
-          path: '/v2/checkout/orders/' + order_id,
-          method: 'GET',
-          headers: {
-            'Content-Type': 'application/json',
-            'Authorization': 'Bearer ' + access_token
-          }
-        },
-        response => {
-          let str = ''
-          response.on('data', chunk => {str += chunk})
-          response.on('end', () => {resolve(JSON.parse(str))})
-        }
-      )
-      request.end()
-    }
-  )
-}
diff --git a/_library/patch_order_details.jst b/_library/patch_order_details.jst
deleted file mode 100644 (file)
index ee68ff3..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-let https = require('https')
-
-return async (env, order_id, patch_details) => {
-  let config = await env.site.get_json('/_config/config.json')
-  let get_access_token = await _require('get_access_token.jst')
-
-  let access_token = await get_access_token(env)
-  return new Promise(
-    resolve => {
-      let request = https.request(
-        {
-          hostname: 'api.' + (config.environment === 'sandbox' ? 'sandbox.' : '') + 'paypal.com',
-          port: 443,
-          path: '/v2/checkout/orders/' + order_id,
-          method: 'PATCH',
-          headers: {
-            'Content-Type': 'application/json',
-            'Authorization': 'Bearer ' + access_token
-          }
-        },
-        response => {resolve(response.statusCode)}
-      )
-      request.write(JSON.stringify(patch_details));
-      request.end()
-    }
-  )
-}
diff --git a/_library/random_number.jst b/_library/random_number.jst
deleted file mode 100644 (file)
index 2152218..0000000
+++ /dev/null
@@ -1 +0,0 @@
-return () => Math.floor(100000 + Math.random() * 900000)
diff --git a/_orig/.env b/_orig/.env
new file mode 100644 (file)
index 0000000..39a80ed
--- /dev/null
@@ -0,0 +1,9 @@
+# Acceptable values are sandbox or production
+ENVIRONMENT=sandbox
+
+# Must match the values found in the corresponding production or sandbox environment
+SQUARE_APPLICATION_ID=sandbox-sq0idb-NWqh-67LhTtIqdvp4978nw
+SQUARE_ACCESS_TOKEN=EAAAEPoF7d_vVakpYQsFACkSNe4XxVF89-KEs2gwtb-tQBF2UGxoS2IIz3KRyQh-
+SQUARE_LOCATION_ID=LP19NHYVKBMB0
+
+
diff --git a/_orig/.env.example b/_orig/.env.example
new file mode 100644 (file)
index 0000000..6b33a32
--- /dev/null
@@ -0,0 +1,9 @@
+# Acceptable values are sandbox or production
+ENVIRONMENT=
+
+# Must match the values found in the corresponding production or sandbox environment
+SQUARE_APPLICATION_ID=your-application-id
+SQUARE_ACCESS_TOKEN=your-access-token
+SQUARE_LOCATION_ID=your-location-id
+
+
diff --git a/_orig/PayPalCheckoutServerSideV2_nodejs.zip b/_orig/PayPalCheckoutServerSideV2_nodejs.zip
deleted file mode 100644 (file)
index 5e2c706..0000000
Binary files a/_orig/PayPalCheckoutServerSideV2_nodejs.zip and /dev/null differ
diff --git a/_orig/README.md b/_orig/README.md
new file mode 100644 (file)
index 0000000..4a956ab
--- /dev/null
@@ -0,0 +1,63 @@
+# Useful Links
+
+* [PHP SDK Page](https://developer.squareup.com/docs/sdks/php)
+* [Checkout API Overview](https://developer.squareup.com/docs/checkout-api/what-it-does)
+* [Checkout in the API Reference](https://developer.squareup.com/reference/square/checkout-api)
+
+Square Checkout Demo
+=========================
+
+This is a simple example application that utilizes Square's Checkout API. This examples does assume you are familiar with PHP development.
+
+It takes a single payment, declared by the user, and creates an order to use in the Checkout API.
+## Setup
+
+
+### Requirements
+
+* PHP >= 7.1
+
+### Install the PHP client library
+
+This sample already includes the `square/square` dependency in its `composer.json`
+file. To install the client library:
+
+1. Make sure you've downloaded Composer, following the instructions
+[here](https://getcomposer.org/download/).
+
+2. Run the following command from the directory containing `composer.json`:
+
+```
+php composer.phar install
+```
+
+### Specify your application credentials
+
+In order for the example to work, you must edit the file called `.env` with your application credentials and environment configuration.
+
+Open your [application dashboard](https://developer.squareup.com/). Now supply either production, sandbox, or both credentials. Open this file and update the following variables:
+* WARNING: never upload .env with your credential/access_token
+
+| Variable               |  Type    |   Description   |
+|------------------------|:---------|-----------------|
+| ENVIRONMENT            | `string` | `production` or `sandbox` depending on what type of endpoint you want to hit. For testing purposes please use the sandbox mode (already configured in the `.env`)   |
+| SQUARE_APPLICATION_ID  | `string` | Application ID found on your Developer App Dashboard, Credentials tab. Must match the corresponding `ENVIRONMENT`.  |
+| SQUARE_ACCESS_TOKEN    | `string` | Access Token found at the Developer App Dashboard, Credentials tab. Must match the corresponding `ENVIRONMENT`.  |
+| SQUARE_LOCATION_ID     | `string` | Location found at the Developer App Dashboard, Location tab. Must match the corresponding `ENVIRONMENT`. |
+
+## Running the sample
+
+From the sample's root directory, run:
+
+    php -S localhost:8888
+
+This will start the server on `localhost:8888`, which you can navigate to in your favorite browser.
+
+
+For more information about Checkout please visit:
+* https://developer.squareup.com/docs/checkout-api-overview
+* https://developer.squareup.com/reference/square/checkout-api
+* https://github.com/square/square-php-sdk/blob/master/docs/Api/CheckoutApi.md
+
+## Feedback
+Rate this sample app [here](https://delighted.com/t/Z1xmKSqy)!
\ No newline at end of file
diff --git a/_orig/checkout.php b/_orig/checkout.php
new file mode 100644 (file)
index 0000000..ee147f8
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+// Note this line needs to change if you don't use Composer:
+// require('square-php-sdk/autoload.php');
+require 'vendor/autoload.php';
+
+use Dotenv\Dotenv;
+use Square\Models\CreateOrderRequest;
+use Square\Models\CreateCheckoutRequest;
+use Square\Models\Order;
+use Square\Models\OrderLineItem;
+use Square\Models\Money;
+use Square\Exceptions\ApiException;
+use Square\SquareClient;
+
+// dotenv is used to read from the '.env' file created
+$dotenv = Dotenv::create(__DIR__);
+$dotenv->load();
+
+// Use the environment and the key name to get the appropriate values from the .env file.
+$access_token = getenv('SQUARE_ACCESS_TOKEN');    
+$location_id =  getenv('SQUARE_LOCATION_ID');
+
+// Initialize the authorization for Square
+$client = new SquareClient([
+  'accessToken' => $access_token,
+  'environment' => getenv('ENVIRONMENT')
+]);
+
+// make sure we actually are on a POST with an amount
+// This example assumes the order information is retrieved and hard coded
+// You can find different ways to retrieve order information and fill in the following lineItems object.
+try {
+  $checkout_api = $client->getCheckoutApi();
+
+  // Monetary amounts are specified in the smallest unit of the applicable currency.
+  // This amount is in cents. It's also hard-coded for $1.00, which isn't very useful.
+  
+  // Set currency to the currency for the location
+  $currency = $client->getLocationsApi()->retrieveLocation(getenv('SQUARE_LOCATION_ID'))->getResult()->getLocation()->getCurrency();
+  $money_A = new Money();
+  $money_A->setCurrency($currency);
+  $money_A->setAmount(500);
+
+  $item_A = new OrderLineItem(1);
+  $item_A->setName('Test Item A');
+  $item_A->setBasePriceMoney($money_A);
+
+  $money_B = new Money();
+  $money_B->setCurrency($currency);
+  $money_B->setAmount(1000);
+  
+  $item_B = new OrderLineItem(3);
+  $item_B->setName('Test Item B');
+  $item_B->setBasePriceMoney($money_B);
+
+  // Create a new order and add the line items as necessary.
+  $order = new Order($location_id);
+  $order->setLineItems([$item_A, $item_B]);
+
+  $create_order_request = new CreateOrderRequest();
+  $create_order_request->setOrder($order);
+
+  // Similar to payments you must have a unique idempotency key.
+  $checkout_request = new CreateCheckoutRequest(uniqid(), $create_order_request);
+  // Set a custom redirect URL, otherwise a default Square confirmation page will be used
+  $checkout_request->setRedirectUrl('http://localhost:8888/confirmation.php');
+
+  $response = $checkout_api->createCheckout($location_id, $checkout_request);
+} catch (ApiException $e) {
+  // If an error occurs, output the message
+  echo 'Caught exception!<br/>';
+  echo '<strong>Response body:</strong><br/>';
+  echo '<pre>'; var_dump($e->getResponseBody()); echo '</pre>';
+  echo '<br/><strong>Context:</strong><br/>';
+  echo '<pre>'; var_dump($e->getContext()); echo '</pre>';
+  exit();
+}
+
+// If there was an error with the request we will
+// print them to the browser screen here
+if ($response->isError()) {
+  echo 'Api response has Errors';
+  $errors = $response->getErrors();
+  echo '<ul>';
+  foreach ($errors as $error) {
+      echo '<li>⌠' . $error->getDetail() . '</li>';
+  }
+  echo '</ul>';
+  exit();
+}
+
+
+// This redirects to the Square hosted checkout page
+header('Location: '.$response->getResult()->getCheckout()->getCheckoutPageUrl());
diff --git a/_orig/composer.json b/_orig/composer.json
new file mode 100644 (file)
index 0000000..4ad4520
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "require": {
+    "square/square": "*",
+    "vlucas/phpdotenv": "^3.3"
+  }
+}
diff --git a/_orig/composer.lock b/_orig/composer.lock
new file mode 100644 (file)
index 0000000..f81e9b8
--- /dev/null
@@ -0,0 +1,417 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "b29806699279afa42ff34d8931ed959c",
+    "packages": [
+        {
+            "name": "apimatic/jsonmapper",
+            "version": "v2.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/apimatic/jsonmapper.git",
+                "reference": "f7588f1ab692c402a9118e65cb9fd42b74e5e0db"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/apimatic/jsonmapper/zipball/f7588f1ab692c402a9118e65cb9fd42b74e5e0db",
+                "reference": "f7588f1ab692c402a9118e65cb9fd42b74e5e0db",
+                "shasum": ""
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+                "squizlabs/php_codesniffer": "^3.0.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "apimatic\\jsonmapper\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "OSL-3.0"
+            ],
+            "authors": [
+                {
+                    "name": "Christian Weiske",
+                    "email": "christian.weiske@netresearch.de",
+                    "homepage": "http://www.netresearch.de/",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Mehdi Jaffery",
+                    "email": "mehdi.jaffery@apimatic.io",
+                    "homepage": "http://apimatic.io/",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Map nested JSON structures onto PHP classes",
+            "support": {
+                "email": "mehdi.jaffery@apimatic.io",
+                "issues": "https://github.com/apimatic/jsonmapper/issues",
+                "source": "https://github.com/apimatic/jsonmapper/tree/v2.0.3"
+            },
+            "time": "2021-07-16T09:02:23+00:00"
+        },
+        {
+            "name": "apimatic/unirest-php",
+            "version": "2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/apimatic/unirest-php.git",
+                "reference": "e07351d5f70b445664e2dc4042bbc237ec7d4c93"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/apimatic/unirest-php/zipball/e07351d5f70b445664e2dc4042bbc237ec7d4c93",
+                "reference": "e07351d5f70b445664e2dc4042bbc237ec7d4c93",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "php": ">=5.6.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5 || ^6 || ^7 || ^8 || ^9"
+            },
+            "suggest": {
+                "ext-json": "Allows using JSON Bodies for sending and parsing requests"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "Unirest\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mashape",
+                    "email": "opensource@mashape.com",
+                    "homepage": "https://www.mashape.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "APIMATIC",
+                    "email": "opensource@apimatic.io",
+                    "homepage": "https://www.apimatic.io",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Unirest PHP",
+            "homepage": "https://github.com/apimatic/unirest-php",
+            "keywords": [
+                "client",
+                "curl",
+                "http",
+                "https",
+                "rest"
+            ],
+            "support": {
+                "email": "opensource@apimatic.io",
+                "issues": "https://github.com/apimatic/unirest-php/issues",
+                "source": "https://github.com/apimatic/unirest-php/tree/2.1.0"
+            },
+            "time": "2021-11-12T05:20:21+00:00"
+        },
+        {
+            "name": "phpoption/phpoption",
+            "version": "1.8.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/schmittjoh/php-option.git",
+                "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15",
+                "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.4.1",
+                "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.8-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PhpOption\\": "src/PhpOption/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Johannes M. Schmitt",
+                    "email": "schmittjoh@gmail.com",
+                    "homepage": "https://github.com/schmittjoh"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                }
+            ],
+            "description": "Option Type for PHP",
+            "keywords": [
+                "language",
+                "option",
+                "php",
+                "type"
+            ],
+            "support": {
+                "issues": "https://github.com/schmittjoh/php-option/issues",
+                "source": "https://github.com/schmittjoh/php-option/tree/1.8.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-12-04T23:24:31+00:00"
+        },
+        {
+            "name": "square/square",
+            "version": "17.0.0.20211215",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/square/square-php-sdk.git",
+                "reference": "b0a35b86cb87154ba448f6265cd4f15a59c1b628"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/square/square-php-sdk/zipball/b0a35b86cb87154ba448f6265cd4f15a59c1b628",
+                "reference": "b0a35b86cb87154ba448f6265cd4f15a59c1b628",
+                "shasum": ""
+            },
+            "require": {
+                "apimatic/jsonmapper": "^2.0.2",
+                "apimatic/unirest-php": "^2.1",
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "php": ">=7.2"
+            },
+            "require-dev": {
+                "phan/phan": "^3.0",
+                "phpunit/phpunit": "^7.5 || ^8.5",
+                "squizlabs/php_codesniffer": "^3.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Square\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Square Developer Platform",
+                    "email": "developers@squareup.com",
+                    "homepage": "https://squareup.com/developers"
+                }
+            ],
+            "description": "Use Square APIs to manage and run business including payment, customer, product, inventory, and employee management.",
+            "homepage": "https://squareup.com/developers",
+            "keywords": [
+                "api",
+                "sdk",
+                "square"
+            ],
+            "support": {
+                "issues": "https://github.com/square/square-php-sdk/issues",
+                "source": "https://github.com/square/square-php-sdk/tree/17.0.0.20211215"
+            },
+            "time": "2021-12-15T00:41:47+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.23.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+                "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-ctype": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-02-19T12:13:01+00:00"
+        },
+        {
+            "name": "vlucas/phpdotenv",
+            "version": "v3.6.10",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/vlucas/phpdotenv.git",
+                "reference": "5b547cdb25825f10251370f57ba5d9d924e6f68e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/5b547cdb25825f10251370f57ba5d9d924e6f68e",
+                "reference": "5b547cdb25825f10251370f57ba5d9d924e6f68e",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.4 || ^7.0 || ^8.0",
+                "phpoption/phpoption": "^1.5.2",
+                "symfony/polyfill-ctype": "^1.17"
+            },
+            "require-dev": {
+                "ext-filter": "*",
+                "ext-pcre": "*",
+                "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.21"
+            },
+            "suggest": {
+                "ext-filter": "Required to use the boolean validator.",
+                "ext-pcre": "Required to use most of the library."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Dotenv\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
+                {
+                    "name": "Vance Lucas",
+                    "email": "vance@vancelucas.com",
+                    "homepage": "https://github.com/vlucas"
+                }
+            ],
+            "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
+            "keywords": [
+                "dotenv",
+                "env",
+                "environment"
+            ],
+            "support": {
+                "issues": "https://github.com/vlucas/phpdotenv/issues",
+                "source": "https://github.com/vlucas/phpdotenv/tree/v3.6.10"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-12-12T23:02:06+00:00"
+        }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": [],
+    "plugin-api-version": "2.2.0"
+}
diff --git a/_orig/composer.phar b/_orig/composer.phar
new file mode 100755 (executable)
index 0000000..cf05b3a
Binary files /dev/null and b/_orig/composer.phar differ
diff --git a/_orig/confirmation.php b/_orig/confirmation.php
new file mode 100644 (file)
index 0000000..7dfefc8
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+require 'vendor/autoload.php';
+
+use Dotenv\Dotenv;
+use Square\SquareClient;
+use Square\Exceptions\ApiException;
+
+// dotenv is used to read from the '.env' file created
+$dotenv = Dotenv::create(__DIR__);
+$dotenv->load();
+
+// Use the environment and the key name to get the appropriate values from the .env file.
+$access_token = getenv('SQUARE_ACCESS_TOKEN');
+$location_id =  getenv('SQUARE_LOCATION_ID');
+
+// Initialize the authorization for Square
+$client = new SquareClient([
+  'accessToken' => $access_token,
+  'environment' => getenv('ENVIRONMENT')
+]);
+
+$transaction_id = $_GET["transactionId"];
+
+try {
+  $orders_api = $client->getOrdersApi();
+  $response = $orders_api->retrieveOrder($transaction_id);
+} catch (ApiException $e) {
+  // If an error occurs, output the message
+  echo 'Caught exception!<br/>';
+  echo '<strong>Response body:</strong><br/>';
+  echo '<pre>';
+  var_dump($e->getResponseBody());
+  echo '</pre>';
+  echo '<br/><strong>Context:</strong><br/>';
+  echo '<pre>';
+  var_dump($e->getContext());
+  echo '</pre>';
+  exit();
+}
+
+// If there was an error with the request we will
+// print them to the browser screen here
+if ($response->isError()) {
+  echo 'Api response has Errors';
+  $errors = $response->getErrors();
+  echo '<ul>';
+  foreach ($errors as $error) {
+    echo '<li>⌠' . $error->getDetail() . '</li>';
+  }
+  echo '</ul>';
+  exit();
+} else {
+  $order = $response->getResult()->getOrder();
+}
+?>
+
+<!DOCTYPE html>
+<html>
+
+<head>
+  <title>Checkout Confirmation</title>
+  <meta name="description" content="An example of Square Checkout on Glitch">
+  <link rel='stylesheet' href='/main.css'>
+  <link rel='stylesheet' href='/normalize.css'>
+  <link id="favicon" rel="icon" href="https://cdn.glitch.com/4c9bc573-ca4c-48de-8afe-501eddad0b79%2Fsquare-logo.svg?1521834224783" type="image/x-icon">
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name='viewport' content='width=device-width, initial-scale=1'>
+</head>
+
+<body>
+  <header class="container">
+    <div id="square-logo"></div>
+    <h1 class="header">Custom Checkout Confirmation</h1>
+  </header>
+
+  <div class="container" id="confirmation">
+    <div>
+      <div>
+        <?php
+        echo ("Order " . $order->getId());
+        ?>
+      </div>
+      <div>
+        <?php
+        echo ("Status: " . $order->getState());
+        ?>
+      </div>
+    </div>
+    <div>
+      <?php
+      foreach ($order->getLineItems() as $line_item) {
+        // Display each line item in the order, you may want to consider formatting the money amount using different currencies
+        echo ("
+          <div class=\"item-line\">
+            <div class=\"item-label\">" . $line_item->getName() . " x " . $line_item->getQuantity() . "</div>
+            <div class=\"item-amount\">$" . number_format((float)$line_item->getTotalMoney()->getAmount() / 100, 2, '.', '') . "</div>
+          </div>");
+      }
+
+      // Display total amount paid for the order, you may want to consider formatting the money amount using different currencies
+      echo ("
+        <div>
+          <div class=\"item-line total-line\">
+            <div class=\"item-label\">Total</div>
+            <div class=\"item-amount\">$" . number_format((float)$order->getTotalMoney()->getAmount() / 100, 2, '.', '') . "</div>
+          </div>
+        </div>
+        ");
+      ?>
+    </div>
+    <div>
+      <span>Payment Successful!</span>
+      <a href="http://localhost:8888">Back to home page</a>
+    </div>
+  </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/_orig/cucumber_bob.js b/_orig/cucumber_bob.js
new file mode 100644 (file)
index 0000000..829f2a3
--- /dev/null
@@ -0,0 +1,57 @@
+// see https://developer.squareup.com/forums/t/404-error-using-node-js-checkoutapi/3220
+
+const uuid = require("uuid");
+
+const { Client, Environment } = require("square");
+
+const locationId = "LV9V6ND34HHBS";
+const squareAccessToken =
+  process.env.squareAccessToken ||
+"redacted"
+const client = new Client({
+  environment: Environment.Sandbox,
+  accessToken: squareAccessToken
+});
+
+app.post("/api/checkout", async (req, res) => {
+  const pizzas = req.body.pizzas;
+  const response = await client.checkoutApi.createCheckout(
+    locationId,
+    convertPizzasToCheckoutRequest(pizzas)
+  );
+  console.log(response.json());
+  return res.status(200).send("OK");
+});
+
+function convertPizzasToCheckoutRequest(pizzas) {
+  const lineItems = pizzas.map((pizza) => {
+    const itemName = { sm: "Small", lg: "Large" }[pizza.size].concat(" Pizza");
+
+    const prunedToppings = pizza.toppings.filter((t) => t !== "Mozzarella");
+
+    //todo fix pluralisation
+    const variation = `With ${prunedToppings.length} toppings`;
+    const note = prunedToppings.reduce((toppingList, topping) => {
+      if (toppingList === "") return topping;
+      return toppingList.concat(`, ${topping}`);
+    }, "");
+
+    const basePrice =
+      { sm: 3, lg: 6 }[pizza.size] +
+      { sm: 0.5, lg: 1 }[pizza.size] * prunedToppings.length;
+
+    return {
+      idempotencyKey: uuid.v4(),
+      quantity: 1,
+      name: itemName,
+      variation_name: variation,
+      note,
+      base_price_money: { amount: basePrice, currency: "GBP" }
+    };
+  });
+  return {
+    order: { locationId, line_items: lineItems },
+    idempotencyKey: uuid.v4(),
+    ask_for_shipping_address: true
+  };
+}
diff --git a/_orig/index.php b/_orig/index.php
new file mode 100644 (file)
index 0000000..92c3579
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Square Checkout</title>
+    <meta name="description" content="An example of Square Checkout on Glitch">
+    <link rel='stylesheet' href='/main.css'>
+    <link rel='stylesheet' href='/normalize.css'>
+    <link id="favicon" rel="icon" href="https://cdn.glitch.com/4c9bc573-ca4c-48de-8afe-501eddad0b79%2Fsquare-logo.svg?1521834224783" type="image/x-icon">
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name='viewport' content='width=device-width, initial-scale=1'>
+  </head>
+  <body>
+    <header class="container">
+      <div id="square-logo"></div>
+      <h1 class="header">Simple Checkout</h1>
+    </header>
+    <div class="container">
+      <form class="form-container" method="post" action="checkout.php">
+        <div class="item-line">
+          <div class="item-label">Test Item A x 1</div>
+          <div class="item-amount">$5.00</div>
+        </div>
+        <div class="item-line">
+          <div class="item-label">Test Item B x 3</div>
+          <div class="item-amount">$30.00</div>
+        </div>
+        <div class="item-line total-line">
+          <div class="item-label">Total</div>
+          <div class="item-amount">$35.00</div>
+        </div>
+        <button type="submit">Pay now!</button>
+      </form>
+    </div>
+  </body>
+</html>
diff --git a/_orig/main.css b/_orig/main.css
new file mode 100644 (file)
index 0000000..0694544
--- /dev/null
@@ -0,0 +1,96 @@
+.container {
+    width: 920px;
+    margin: 0 auto;
+}
+
+#confirmation {
+  width: 500px;
+}
+
+#confirmation > div {
+  margin-top: 20px;
+}
+
+#square-logo {
+    height: 32px;
+    width: 32px;
+    background: url("https://cdn.glitch.com/4c9bc573-ca4c-48de-8afe-501eddad0b79%2Fsquare-logo.svg?1521834224783") center center no-repeat;
+    margin: 0 auto;
+    padding-top: 25px;
+}
+
+.header {
+  text-align: center;
+  margin-top: 0;
+}
+
+.form-container {
+  margin: 0 auto;
+  width: 320px;
+  display: flex;
+  flex-direction: column;
+}
+
+.form-container {
+  margin: 0 auto;
+  width: 320px;
+  display: flex;
+  flex-direction: column;
+}
+
+.item-line {
+  display: flex;
+}
+
+.item-label {
+  flex-grow: 1;
+}
+
+.item-amount {
+  font-weight: bold;
+}
+
+.total-line {
+  font-weight: bold;
+  margin: 5px 0 5px 0;
+  padding-top: 5px;
+  border-top: 1px solid #c2c7cc;
+}
+
+body {
+  background-color: #ececec;
+  font-family: Helvetica, Arial, sans-serif;
+}
+
+
+form {
+  width:100%;
+  margin-top: 25px;
+}
+
+input {
+  border: 1px solid #E0E2E3;
+  border-radius: 4px;
+  outline-offset: -2px;
+  display: inline-block;
+  font-size: 18px;
+  font-family: "HelveticaNeue";
+  padding: 15px;
+  color: #373F4A;
+}
+
+button {
+  background: #0EB00E;
+  box-shadow: 0 0 2px 0 rgba(0,0,0,0.10), 0 2px 2px 0 rgba(0,0,0,0.10);
+  border-radius: 4px;
+  cursor:pointer;
+  font-size: 16px;
+  color: #FFFFFF;
+  letter-spacing: 0;
+  text-align: center;
+  line-height: 24px;
+  padding: 15px;
+  margin-top: 10px;
+  outline: none;
+  font-family: "HelveticaNeue-Bold", Helvetica, Arial, sans-serif;
+}
\ No newline at end of file
diff --git a/_orig/n.sh b/_orig/n.sh
new file mode 100755 (executable)
index 0000000..c2f759b
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+#apt install php php-curl php-mbstring
+#curl -sS https://getcomposer.org/installer |php
+#php composer.phar install
+php -S 127.0.0.1:8888
diff --git a/_orig/normalize.css b/_orig/normalize.css
new file mode 100644 (file)
index 0000000..fa4e73d
--- /dev/null
@@ -0,0 +1,447 @@
+/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+   ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in
+ *    IE on Windows Phone and in iOS.
+ */
+
+html {
+  line-height: 1.15; /* 1 */
+  -ms-text-size-adjust: 100%; /* 2 */
+  -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+   ========================================================================== */
+
+/**
+ * Remove the margin in all browsers (opinionated).
+ */
+
+body {
+  margin: 0;
+}
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+article,
+aside,
+footer,
+header,
+nav,
+section {
+  display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+
+/* Grouping content
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in IE.
+ */
+
+figcaption,
+figure,
+main { /* 1 */
+  display: block;
+}
+
+/**
+ * Add the correct margin in IE 8.
+ */
+
+figure {
+  margin: 1em 40px;
+}
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+  box-sizing: content-box; /* 1 */
+  height: 0; /* 1 */
+  overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+   ========================================================================== */
+
+/**
+ * 1. Remove the gray background on active links in IE 10.
+ * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
+ */
+
+a {
+  background-color: transparent; /* 1 */
+  -webkit-text-decoration-skip: objects; /* 2 */
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+  border-bottom: none; /* 1 */
+  text-decoration: underline; /* 2 */
+  text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
+ */
+
+b,
+strong {
+  font-weight: inherit;
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font style in Android 4.3-.
+ */
+
+dfn {
+  font-style: italic;
+}
+
+/**
+ * Add the correct background and color in IE 9-.
+ */
+
+mark {
+  background-color: #ff0;
+  color: #000;
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+  font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+/* Embedded content
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+audio,
+video {
+  display: inline-block;
+}
+
+/**
+ * Add the correct display in iOS 4-7.
+ */
+
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+
+/**
+ * Remove the border on images inside links in IE 10-.
+ */
+
+img {
+  border-style: none;
+}
+
+/**
+ * Hide the overflow in IE.
+ */
+
+svg:not(:root) {
+  overflow: hidden;
+}
+
+/* Forms
+   ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers (opinionated).
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: sans-serif; /* 1 */
+  font-size: 100%; /* 1 */
+  line-height: 1.15; /* 1 */
+  margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+  overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+  text-transform: none;
+}
+
+/**
+ * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+ *    controls in Android 4.
+ * 2. Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+html [type="button"], /* 1 */
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button; /* 2 */
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+  border-style: none;
+  padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+  outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+  padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ *    `fieldset` elements in all browsers.
+ */
+
+legend {
+  box-sizing: border-box; /* 1 */
+  color: inherit; /* 2 */
+  display: table; /* 1 */
+  max-width: 100%; /* 1 */
+  padding: 0; /* 3 */
+  white-space: normal; /* 1 */
+}
+
+/**
+ * 1. Add the correct display in IE 9-.
+ * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+  display: inline-block; /* 1 */
+  vertical-align: baseline; /* 2 */
+}
+
+/**
+ * Remove the default vertical scrollbar in IE.
+ */
+
+textarea {
+  overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10-.
+ * 2. Remove the padding in IE 10-.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+  box-sizing: border-box; /* 1 */
+  padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+  -webkit-appearance: textfield; /* 1 */
+  outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button; /* 1 */
+  font: inherit; /* 2 */
+}
+
+/* Interactive
+   ========================================================================== */
+
+/*
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in Edge, IE, and Firefox.
+ */
+
+details, /* 1 */
+menu {
+  display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+  display: list-item;
+}
+
+/* Scripting
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+canvas {
+  display: inline-block;
+}
+
+/**
+ * Add the correct display in IE.
+ */
+
+template {
+  display: none;
+}
+
+/* Hidden
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 10-.
+ */
+
+[hidden] {
+  display: none;
+}
diff --git a/api/captureOrder.json.jst b/api/captureOrder.json.jst
deleted file mode 100644 (file)
index 57c092a..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-let cookie = require('cookie')
-
-return async env => {
-  let capture_order = await _require('/_library/capture_order.jst')
-
-  let cookies = cookie.parse(env.request.headers.cookie || '')
-  let response = await capture_order(env, cookies.order_id)
-  console.log('capture_order()', response)
-
-  env.site.serve(
-    env,
-    200,
-    Buffer.from(JSON.stringify(response)),
-    'getOrderDetails.json.jst'
-  )
-}
diff --git a/api/createOrder.json.jst b/api/createOrder.json.jst
deleted file mode 100644 (file)
index dfe3428..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-let querystring = require('querystring')
-let stream_buffers = require('stream-buffers')
-let XDate = require('xdate')
-
-return async env => {
-  let create_order = await _require('/_library/create_order.jst')
-  let random_number = await _require('/_library/random_number.jst')
-
-  let response = null
-  if (env.request.method === 'POST') {
-    let write_stream = new stream_buffers.WritableStreamBuffer()
-    let data = new Promise(
-      (resolve, reject) => {
-        write_stream.
-        on('finish', () => {resolve(write_stream.getContents())}).
-        on('error', () => {reject()})
-      }
-    )
-    env.request.pipe(write_stream)
-    let query = querystring.parse((await data).toString())
-    console.log('received createOrder form:', JSON.stringify(query))
-
-    //Build the PayPal object to create order and populate with POST params from website
-    let item_obj = {
-      "intent" : "CAPTURE",
-      "application_context" : {
-        "return_url" : query.return_url,
-        "cancel_url" : query.cancel_url
-      },
-      "purchase_units" : [ 
-        {
-          "reference_id" : "PU1",
-          "description" : "Camera Shop",
-          "invoice_id" : "INV-CameraShop-" + random_number(),
-          "custom_id" : "CUST-CameraShop",
-          "amount" : {
-            "currency_code" : query.currency,
-            "value" : query.total_amt,
-            "breakdown" : {
-              "item_total" : {
-                "currency_code" : query.currency,
-                "value" : query.item_amt
-              },
-              "shipping" : {
-                "currency_code" : query.currency,
-                "value" : query.shipping_amt
-              },
-              "tax_total" : {
-                "currency_code" : query.currency,
-                "value" : query.tax_amt
-              },
-              "handling" : {
-                "currency_code" : query.currency,
-                "value" : query.handling_fee
-              },
-              "shipping_discount" : {
-                "currency_code" : query.currency,
-                "value" : query.shipping_discount
-              },
-              "insurance" : {
-                "currency_code" : query.currency,
-                "value" : query.insurance_fee
-              }
-            }
-          },
-          "items" : [{
-            "name" : "DSLR Camera",
-            "description" : "Black Camera - Digital SLR",
-            "sku" : "sku01",
-            "unit_amount" : {
-              "currency_code" : query.currency,
-              "value" : query.item_amt
-            },
-            "quantity" : "1",
-            "category" : "PHYSICAL_GOODS"
-          }]
-        }
-      ]
-    }
-    //If order details contain shipping, append shipping and preferences
-    if (query.line1 !== undefined) {
-      item_obj.application_context.shipping_preference = "SET_PROVIDED_ADDRESS"
-      item_obj.application_context.user_action = "PAY_NOW"
-      item_obj.purchase_units[0].shipping = {
-        "address" : {
-        "address_line_1": query.line1,
-        "address_line_2": query.line2,
-        "admin_area_2": query.city,
-        "admin_area_1": query.state,
-        "postal_code": query.zip,
-        "country_code": query.countrySelect
-        }
-      }
-    }
-    console.log('item_obj', item_obj)
-    response = await create_order(env, item_obj)
-    console.log('create_order()', response)
-
-    //sess.order_id = response.id
-    let expires = new XDate()
-    expires.addDays(1)
-    env.response.setHeader(
-      'Set-Cookie',
-      'order_id=' +
-      response.id +
-      '; expires=' +
-      expires +
-      '; path=/;'
-    )
-  }
-
-  env.site.serve(
-    env,
-    200,
-    Buffer.from(JSON.stringify(response)),
-    'createOrder.json.jst'
-  )
-}
diff --git a/api/getOrderDetails.json.jst b/api/getOrderDetails.json.jst
deleted file mode 100644 (file)
index dc6637a..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-let cookie = require('cookie')
-
-return async env => {
-  let get_order_details = await _require('/_library/get_order_details.jst')
-
-  let cookies = cookie.parse(env.request.headers.cookie || '')
-  let response = await get_order_details(env, cookies.order_id)
-  console.log('get_order_details()', response)
-
-  env.site.serve(
-    env,
-    200,
-    Buffer.from(JSON.stringify(response)),
-    'getOrderDetails.json.jst'
-  )
-}
diff --git a/api/patchOrder.json.jst b/api/patchOrder.json.jst
deleted file mode 100644 (file)
index 869b364..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-let cookie = require('cookie')
-let querystring = require('querystring')
-let stream_buffers = require('stream-buffers')
-let XDate = require('xdate')
-
-return async env => {
-  let patch_order_details = await _require('/_library/patch_order_details.jst')
-  let random_number = await _require('/_library/random_number.jst')
-
-  let response = null
-  if (env.request.method === 'POST') {
-    let write_stream = new stream_buffers.WritableStreamBuffer()
-    let data = new Promise(
-      (resolve, reject) => {
-        write_stream.
-        on('finish', () => {resolve(write_stream.getContents())}).
-        on('error', () => {reject()})
-      }
-    )
-    env.request.pipe(write_stream)
-    let query = querystring.parse((await data).toString())
-    console.log('received patchOrder form:', JSON.stringify(query))
-
-    let cookies = cookie.parse(env.request.headers.cookie || '')
-    let patch_details = [
-      {
-        "op" : "replace",
-        "path" : "/purchase_units/@reference_id==\'PU1\'/amount",
-        "value" : {
-          "currency_code" : query.currency,
-          "value" : parseInt(query.total_amt) + parseInt(query.updated_shipping) - parseInt(query.current_shipping),
-          "breakdown" : {
-            "item_total" : {
-              "currency_code" : query.currency,
-              "value" : query.item_amt,
-            },
-            "shipping" : {
-              "currency_code" : query.currency,
-              "value" : query.updated_shipping
-            },
-            "tax_total" : {
-              "currency_code" : query.currency,
-              "value" : query.tax_amt
-            },
-            "shipping_discount" : {
-              "currency_code" : query.currency,
-              "value" : query.shipping_discount
-            },
-            "handling" : {
-              "currency_code" : query.currency,
-              "value" : query.handling_fee
-            },
-            "insurance" : {
-              "currency_code" : query.currency,
-              "value" : query.insurance_fee
-            }
-          }
-        }       
-      }
-    ]
-    response = {
-      http_code:
-        await patch_order_details(env, cookies.order_id, patch_details)
-    }
-    console.log('patch_order_details()', response)
-  }
-
-  env.site.serve(
-    env,
-    200,
-    Buffer.from(JSON.stringify(response)),
-    'patchOrder.json.jst'
-  )
-}
diff --git a/checkout.html.jst b/checkout.html.jst
new file mode 100644 (file)
index 0000000..6fd36f8
--- /dev/null
@@ -0,0 +1,75 @@
+let square = require("square")
+let uuid = require("uuid")
+
+return async env => {
+  let config = await env.site.get_json('/_config/config.json')
+
+  // Initialize the authorization for Square
+  let client = new square.Client(
+    {
+      accessToken: config.square_access_token,
+      environment:
+        config.environment === 'production' ?
+          square.Environment.Production :
+          square.Environment.Sandbox
+    }
+  )
+
+  // Monetary amounts are specified in the smallest unit of the applicable currency.
+  // This amount is in cents. It's also hard-coded for $1.00, which isn't very useful.
+  
+  // Set currency to the currency for the location
+  let currency = (
+    await client.locationsApi.retrieveLocation(config.square_location_id)
+  ).result.location.currency
+
+  let money_A = {currency: currency, amount: 500}
+  let item_A = {quantity: '1', name: 'Test Item A', basePriceMoney: money_A}
+
+  let money_B = {currency: currency, amount: 1000}
+  let item_B = {quantity: '3', name: 'Test Item B', basePriceMoney: money_B}
+
+  // Create a new order and add the line items as necessary.
+  let order = {
+    locationId: config.square_location_id,
+    lineItems: [item_A, item_B]
+  }
+
+  let order_request = {order: order}
+
+  // Similar to payments you must have a unique idempotency key.
+  // Set a custom redirect URL, otherwise a default Square confirmation page will be used
+  let checkout_request = {
+    idempotencyKey: uuid.v4(),
+    order: order_request,
+    redirectUrl: 'http://localhost:8080/confirmation.html'
+  }
+
+  let response = await client.checkoutApi.createCheckout(
+    config.square_location_id,
+    checkout_request
+  )
+  console.log('response', response)
+
+  // If there was an error with the request we will
+  // print them to the browser screen here
+  if (response.isError) {
+    let _out = []
+    _out.push('<!DOCTYPE html>')
+    html {
+      body {
+        'Api response has Errors'
+        ul {
+          for (let i = 0; i < response.errors.length; ++i)
+            li {`⌠${error.detail}`}
+        }
+      }
+    }
+    env.site.serve(env, 200, Buffer.from(_out.join('')), 'checkout.html.jst')
+    return
+  }
+
+  // This redirects to the Square hosted checkout page
+  env.response.setHeader('Location', response.result.checkout.checkoutPageUrl)
+  env.site.serve(env, 301, Buffer.alloc(0), 'checkout.html.jst')
+}
diff --git a/confirmation.html.jst b/confirmation.html.jst
new file mode 100644 (file)
index 0000000..4a28740
--- /dev/null
@@ -0,0 +1,103 @@
+let square = require("square")
+
+return async env => {
+  let config = await env.site.get_json('/_config/config.json')
+
+  // Initialize the authorization for Square
+  let client = new square.Client(
+    {
+      accessToken: config.square_access_token,
+      environment:
+        config.environment === 'production' ?
+          square.Environment.Production :
+          square.Environment.Sandbox
+    }
+  )
+
+  let transaction_id = env.parsed_url.query.transactionId
+  let response = await client.ordersApi.retrieveOrder(transaction_id);
+  console.log('response', response)
+
+  // If there was an error with the request we will
+  // print them to the browser screen here
+  if (response.isError) {
+    let _out = []
+    _out.push('<!DOCTYPE html>')
+    html {
+      body {
+        'Api response has Errors'
+        ul {
+          for (let i = 0; i < response.errors.length; ++i)
+            li {`⌠${error.detail}`}
+        }
+      }
+    }
+    env.site.serve(env, 200, Buffer.from(_out.join('')), 'checkout.html.jst')
+    return
+  }
+
+  let order = response.result.order
+
+  let _out = []
+  _out.push('<!DOCTYPE html>')
+  html {
+    head {
+      title {
+        'Checkout Confirmation'
+      }
+      meta(name="description" content="An example of Square Checkout on Glitch") {}
+      link(rel="stylesheet" href="/main.css") {}
+      link(rel="stylesheet" href="/normalize.css") {}
+      link#favicon(rel="icon" href="https://cdn.glitch.com/4c9bc573-ca4c-48de-8afe-501eddad0b79%2Fsquare-logo.svg?1521834224783" type="image/x-icon") {}
+      meta(charset="utf-8") {}
+      meta(http-equiv="X-UA-Compatible" content="IE=edge") {}
+      meta(name="viewport" content="width=device-width,initial-scale=1") {}
+    }
+    body {
+      header.container {
+        div#square-logo {}
+        h1.header {
+          'Custom Checkout Confirmation'
+        }
+      }
+      div.container#confirmation {
+        div {
+          div {
+            `Order ${order.id}`
+          }
+          div {
+            `Status: ${order.state}`
+          }
+        }
+        div {
+          for (let i = 0; i < order.lineItems.length; ++i) {
+            let line_item = order.lineItems[i]
+            console.log('line_item.totalMoney', line_item.totalMoney)
+            console.log('line_item.totalMoney.amount', line_item.totalMoney.amount)
+            // Display each line item in the order, you may want to consider formatting the money amount using different currencies
+            div.item-line {
+              div.item-label {`${line_item.name} x ${line_item.quantity}`}
+              div.item-amount {`$${line_item.totalMoney.amount / BigInt('100')}.${('0' + line_item.totalMoney.amount % BigInt('100')).slice(-2)}`}
+            }
+          }
+
+          // Display total amount paid for the order, you may want to consider formatting the money amount using different currencies
+          div.item-line.total-line {
+            div.item-label {'Total'}
+            div.item-amount {`$${order.totalMoney.amount / BigInt('100')}.${('0' + order.totalMoney.amount % BigInt('100')).slice(-2)}`}
+          }
+        }
+        div {
+          span {
+            'Payment Successful!'
+          }
+          ' '
+          a(href="http://localhost:8080") {
+            'Back to home page'
+          }
+        }
+      }
+    }
+  }
+  env.site.serve(env, 200, Buffer.from(_out.join('')), 'confirmation.html.jst')
+}
diff --git a/img/camera.jpg b/img/camera.jpg
deleted file mode 100644 (file)
index acfbbf1..0000000
Binary files a/img/camera.jpg and /dev/null differ
index ab4e035..cc4a880 100644 (file)
 return async env => {
-  _out = []
+  let _out = []
   _out.push('<!DOCTYPE html>')
-  html(lang="en") {
+  html {
     head {
-      meta(charset="utf-8") {}
-      meta(http-equiv="x-ua-compatible" content="ie=edge") {}
-      meta(name="viewport" content="width=device-width,initial-scale=1") {}
-      link(href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous") {}
-      script(src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous") {}
       title {
-        'Checkout With PayPal NodeJs Demo'
-      }
-      style {
-        .header-bg-color {
-          color: #fff;
-          background: -moz-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -webkit-gradient(linear,left top,right top,color-stop(0,#004094),color-stop(50%,#0096d9),color-stop(100%,#004094));
-          background: -webkit-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -o-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -ms-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: linear-gradient(90deg,#004094 0,#0096d9 50%,#004094 100%)
-        }
+        'Square Checkout'
       }
+      meta(name="description" content="An example of Square Checkout on Glitch") {}
+      link(rel="stylesheet" href="/main.css") {}
+      link(rel="stylesheet" href="/normalize.css") {}
+      link#favicon(rel="icon" href="https://cdn.glitch.com/4c9bc573-ca4c-48de-8afe-501eddad0b79%2Fsquare-logo.svg?1521834224783" type="image/x-icon") {}
+      meta(charset="utf-8") {}
+      meta(http-equiv="X-UA-Compatible" content="IE=edge") {}
+      meta(name="viewport" content="width=device-width,initial-scale=1") {}
     }
     body {
-      div.container {
-        div.row.header-bg-color.'mb-5'.p-3 {
-          h2.text-center {
-            'Checkout with PayPal Demo'
-          }
-          h4.text-center {
-            'Using Orders v2 REST API with PayPal JavaScript SDK'
-          }
-          h5.text-center {
-            'Server-side Integration'
-          }
+      header.container {
+        div#square-logo {}
+        h1.header {
+          'Simple Checkout'
         }
-        div.row {
-          div.col-sm {
-            div.card {
-              img.card-img-top.img-responsive(src="https://www.paypalobjects.com/web/res/b0b/e9fea36098a7a8192723a8d3b86b2/img/platform/common/merchantStore/cart/camera-lg.jpg") {}
-              div.card-body {
-                h4.text-center {
-                  'Sample Sandbox Buyer Credentials'
-                }
-                table.table.table-striped {
-                  thead {
-                    tr {
-                      th(scope="col") {
-                        'Buyer Email'
-                      }
-                      th(scope="col") {
-                        'Password'
-                      }
-                    }
-                  }
-                  tbody {
-                    tr {
-                      td {
-                        'emily_doe@buyer.com'
-                      }
-                      td {
-                        'qwer1234'
-                      }
-                    }
-                    tr {
-                      td {
-                        'bill_bong@buyer.com'
-                      }
-                      td {
-                        'qwer1234'
-                      }
-                    }
-                    tr {
-                      td {
-                        'jack_potter@buyer.com'
-                      }
-                      td {
-                        '123456789'
-                      }
-                    }
-                    tr {
-                      td {
-                        'harry_doe@buyer.com'
-                      }
-                      td {
-                        '123456789'
-                      }
-                    }
-                    tr {
-                      td {
-                        'ron_brown@buyer.com'
-                      }
-                      td {
-                        'qwer1234'
-                      }
-                    }
-                    tr {
-                      td {
-                        'bella_brown@buyer.com'
-                      }
-                      td {
-                        'qwer1234'
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-          div.col-sm {
-            h3.text-center {
-              'Pricing Details'
+      }
+      div.container {
+        form.form-container(method="post" action="checkout.html") {
+          div.item-line {
+            div.item-label {
+              'Test Item A x 1'
             }
-            hr {}
-            form#camera_form {
-              _out.push('<!-- Cart Details -->')
-              ' '
-              input(name="return_url" type="hidden" value="http://localhost/pages/success.html") {}
-              ' '
-              input(name="cancel_url" type="hidden" value="http://localhost/pages/success.html") {}
-              div.form-group {
-                label.'col-sm-5'.control-label(for="camera_amount") {
-                  'Camera'
-                }
-                div.col-sm {
-                  input.form-control#camera_amount(type="text" name="item_amt" value="300" readonly="") {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(for="tax_amt") {
-                  'Tax'
-                }
-                div.col-sm {
-                  input.form-control#tax_amt(type="text" name="tax_amt" value="5" readonly="") {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(for="insurance_fee") {
-                  'Insurance'
-                }
-                div.col-sm {
-                  input.form-control#insurance_fee(type="text" name="insurance_fee" value="10" readonly="") {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(for="handling_fee") {
-                  'Handling Fee'
-                }
-                div.col-sm {
-                  input.form-control#handling_fee(type="text" name="handling_fee" value="5" readonly="") {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(for="shipping_amt") {
-                  'Estimated Shipping'
-                }
-                div.col-sm {
-                  input.form-control#shipping_amt(type="text" name="shipping_amt" value="2" readonly="") {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(for="shipping_discount") {
-                  'Shipping Discount'
-                }
-                div.col-sm {
-                  input.form-control#shipping_discount(type="text" name="shipping_discount" value="2" readonly="") {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(for="total_amt") {
-                  'Total Amount'
-                }
-                div.col-sm {
-                  input.form-control#total_amt(type="text" name="total_amt" value="320" readonly="") {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(for="currency_Code") {
-                  'Currency'
-                }
-                div.col-sm {
-                  input.form-control#currency_Code(type="text" name="currency" value="USD" readonly="") {}
-                }
-              }
-              hr {}
-              _out.push('<!-- Checkout Options -->')
-              div.form-group {
-                div.'col-sm-offset-5'.col-sm {
-                  _out.push('<!-- Container for PayPal Shortcut Checkout -->')
-                  div#paypalCheckoutContainer {}
-                  _out.push('<!-- Container for PayPal Mark Redirect -->')
-                  div#paypalMarkRedirect {
-                    h4.text-center {
-                      'OR'
-                    }
-                    a.'w-100'.btn.btn-success.btn-block(href="pages/shipping.html" role="button") {
-                      h4 {
-                        'Proceed to Checkout'
-                      }
-                    }
-                  }
-                }
-              }
+            div.item-amount {
+              '$5.00'
             }
           }
-          div.col-sm-4 {
-            hr.m-5 {}
-            h3.text-center {
-              'Readme'
+          div.item-line {
+            div.item-label {
+              'Test Item B x 3'
             }
-            ol {
-              li {
-                'Enter REST API credentials in common/config/config.json. You can get your own REST app credentials by creating a REST app with the steps outlined '
-                i {
-                  a(href="https://developer.paypal.com/docs/api-basics/manage-apps/#create-or-edit-sandbox-and-live-apps" target="_blank") {
-                    'here'
-                  }
-                  ' '
-                }
-                '.'
-              }
-              li {
-                'Click on \'PayPal Checkout’ button and see the experience.'
-              }
-              li {
-                'Checkout with PayPal using a buyer sandbox account provided on this page. And you\'re done!'
-              }
-              li {
-                'In the guest checkout experience, the buyer country can be switched. When switched to one of Germany, Poland, Austria, Netherlands, Italy and Spain, you will be able to choose the alternative payment methods offered in those countries.'
-              }
-              li {
-                'For example: Selecting \'Germany\' in the country drop down will pre-fill the shipping address on the Shipping Information page. For all other countries not mentioned in step 5, the address has to be manually entered.'
-              }
+            div.item-amount {
+              '$30.00'
             }
-            hr {}
-            h3.text-center {
-              'In-Context Checkout integration steps with PayPal JavaScript SDK'
+          }
+          div.item-line.total-line {
+            div.item-label {
+              'Total'
             }
-            ol {
-              li {
-                'Copy the files and folders in the package to the same location where you have your shopping cart page.'
-              }
-              li {
-                'In order to view Alternative Payment Methods as part of the guest checkout flow, you must add query parameters intent=capture, commit=true, vault=false and buyer-country= and you must provide a supported buyer country'
-              }
-              li {
-                'Include the following script on your shopping cart page: (For APMs, the layout must be '
-                code {
-                  'vertical'
-                }
-                ' and setting up the payment in the alternative payment method '
-                a(href="https://developer.paypal.com/docs/checkout/integration-features/alternative-payment-methods/#availability" target="_blank") {
-                  'supported currency'
-                }
-                ' is required for the alternative payment method to render.)'
-                pre {
-                  code {
-                    '\r\n        paypal.Buttons({\r\n        env: \'sandbox\', // sandbox | production\r\n    \r\n            // Set style of buttons\r\n            style: {\r\n                layout: \'vertical\',   // horizontal | vertical <-Must be vertical for APMs\r\n                size:   \'responsive\',   // medium | large | responsive\r\n                shape:  \'pill\',         // pill | rect\r\n                color:  \'gold\',         // gold | blue | silver | black,\r\n                fundingicons: false,    // true | false,\r\n                tagline: false          // true | false,\r\n            },\r\n    \r\n        // payment() is called when the button is clicked\r\n        createOrder: function() {\r\n    \r\n            return fetch(\'/my-server/create-paypal-transaction\')\r\n                .then(function(res) {\r\n                    return res.json();\r\n                }).then(function(data) {\r\n                    return data.orderID;\r\n                });\r\n        },\r\n    \r\n        // onAuthorize() is called when the buyer approves the payment\r\n        onApprove: function(data, actions) {\r\n    \r\n            return fetch(\'/my-server/capture-paypal-transaction\', {\r\n                    body: JSON.stringify({\r\n                    orderID: data.orderID\r\n                    })\r\n                }).then(function(res) {\r\n                    return res.json();\r\n                }).then(function(details) {\r\n                    alert(\'Transaction funds captured from \' + details.payer_given_name);\r\n                });\r\n        }\r\n    }).render(\'#paypal-button-container\');'
-                  }
-                  '\r\n                '
-                }
-              }
-              li {
-                'Open your browser and navigate to your Shopping cart page. Click on \'Checkout with PayPal\' button and complete the flow.'
-              }
-              li {
-                'You can use the sample Buyer Sandbox credentials provided on index/home page.'
-              }
-              li {
-                'Refer to '
-                a(href="https://developer.paypal.com/docs/checkout/" target="_blank") {
-                  'PayPal Developer'
-                }
-                ' site for detailed guidelines.'
-              }
-              li {
-                'Click '
-                a(href="https://developer.paypal.com/docs/api/orders/v2/" target="_blank") {
-                  'here'
-                }
-                ' for the API reference.'
-              }
+            div.item-amount {
+              '$35.00'
             }
           }
+          button(type="submit") {
+            'Pay now!'
+          }
         }
       }
-      _out.push('<!-- Javascript Import -->')
-      script(src="../js/config.js") {}
-      _out.push('<!-- PayPal In-Context Checkout script -->')
-      script(type="text/javascript") {
-        init_smart_buttons = (() => {
-          paypal.Buttons({
-            env: "sandbox",
-            style: {
-              layout: "vertical",
-              size: "responsive",
-              shape: "pill",
-              color: "gold",
-              fundingicons: false,
-              tagline: false
-            },
-            createOrder: function() {
-              return new Promise((resolve, reject) => {
-                $.ajax({
-                  type: "POST",
-                  url: "api/createOrder.json",
-                  data: serialize(document.getElementById("camera_form")),
-                  success: function(response) {
-                    return response;
-                  },
-                  error: function(error) {
-                    reject(error);
-                  }
-                }).then(function(response) {
-                  console.log("Order ID: " + response.id);
-                  resolve(response.id);
-                });
-              });
-            },
-            onApprove: function(data, actions) {
-              return fetch("api/getOrderDetails.json", {
-                method: "GET"
-              }).then(function(res) {
-                return res.json();
-              }).then(function(res) {
-                window.location.href = "pages/success.html";
-              });
-            }
-          }).render("#paypalCheckoutContainer");
-        });
-      }
-      _out.push('<!-- jQuery (necessary for Bootstrap\'s JavaScript plugins) -->')
-      script(src="https://code.jquery.com/jquery.js") {}
     }
   }
   env.site.serve(env, 200, Buffer.from(_out.join('')), 'index.html.jst')
diff --git a/js/config.js b/js/config.js
deleted file mode 100644 (file)
index a5e380b..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-//Helper Functions\r
-function showDom(id) {\r
-    let arr;\r
-    if (!Array.isArray(id)) {\r
-        arr = [id];\r
-    } else {\r
-        arr = id;\r
-    }\r
-    arr.forEach(function (domId) {\r
-        document.getElementById(domId).style.display = "block";\r
-    });\r
-}\r
-\r
-function hideDom(id) {\r
-    let arr;\r
-    if (!Array.isArray(id)) {\r
-        arr = [id];\r
-    } else {\r
-        arr = id;\r
-    }\r
-    arr.forEach(function (domId) {\r
-        document.getElementById(domId).style.display = "none";\r
-    });\r
-}\r
-\r
-function getUrlParams(prop) {\r
-    let params = {},\r
-        search = decodeURIComponent(window.location.href.slice(window.location.href.indexOf("?") + 1)),\r
-        definitions = search.split("&");\r
-\r
-    definitions.forEach(function (val) {\r
-        let parts = val.split("=", 2);\r
-        params[parts[0]] = parts[1];\r
-    });\r
-\r
-    return (prop && prop in params) ? params[prop] : params;\r
-}\r
-\r
-document.addEventListener("input", function (event) {\r
-    if ((event.target.id === "countrySelect") && event.target.id !== null) {\r
-        window.location.href =\r
-            window.location.pathname +\r
-            "?buyer-country=" +\r
-            event.target.options[event.target.selectedIndex].value;\r
-    }\r
-});\r
-\r
-ready = function (fn) {\r
-    if (document.readyState != "loading") {\r
-        fn();\r
-    } else {\r
-        document.addEventListener("DOMContentLoaded", fn);\r
-    }\r
-}\r
-\r
-select_country_dropdown = function () {\r
-    const queryString = window.location.search;\r
-    const urlParams = new URLSearchParams(queryString);\r
-    const buyer_country = urlParams.get("buyer-country")\r
-    //If this param exists in URL\r
-    if (buyer_country) {\r
-        //Build script tag for head based on buyer country\r
-        let head = document.getElementsByTagName("head")[0];\r
-        let paypal_sdk_script = document.createElement("script");\r
-        paypal_sdk_script.type = "text/javascript"; \r
-        paypal_sdk_script.setAttribute("async", "");\r
-        paypal_sdk_script.src = "https://www.paypal.com/sdk/js?intent=capture&vault=false&client-id=Aa2IfcoEvHnfJRnVQLSFrSs3SmTTkv5N1weMEL66ysqYIeHfAqXpDVkjOv3vLhkhbP4eKB6MpRlQIcJw&buyer-country=" + buyer_country;\r
-        paypal_sdk_script.onload = init_smart_buttons; \r
-        head.appendChild(paypal_sdk_script);\r
-        //Pre-populate fields\r
-        for (let i = 0; i < document.getElementById("countrySelect").options.length; i++) {\r
-            if (document.getElementById("countrySelect").options[i].value == buyer_country) {\r
-                document.getElementById("countrySelect").options[i].selected = true;\r
-            }\r
-        }\r
-        apm_country_list = [\r
-            {\r
-                country: "DE", address: {\r
-                    address_line_1: "Bayreuther Straße 42",\r
-                    address_line_2: "",\r
-                    city: "Gmindersdorf",\r
-                    state: "Reutlingen",\r
-                    postal_code: "72760",\r
-                }, recipient_name: "Jane Doe"\r
-            },\r
-            {\r
-                country: "US", address: {\r
-                    address_line_1: "2211 North Street",\r
-                    address_line_2: "",\r
-                    city: "San Jose",\r
-                    state: "CA",\r
-                    postal_code: "95123"\r
-                }, recipient_name: "Jane Doe"\r
-            },\r
-            {\r
-                country: "BE", address: {\r
-                    address_line_1: "Putstraat 478",\r
-                    address_line_2: "",\r
-                    city: "Sint-Pauwels",\r
-                    state: "",\r
-                    postal_code: "9170"\r
-                }, recipient_name: "Marina Beich"\r
-            },\r
-            {\r
-                country: "PL", address: {\r
-                    address_line_1: "ul. Królewska 78",\r
-                    address_line_2: "",\r
-                    city: "Kraków",\r
-                    state: "",\r
-                    postal_code: "30-081"\r
-                }, recipient_name: "August Pedersen"\r
-            },\r
-            {\r
-                country: "AT", address: {\r
-                    address_line_1: "Hauptstrasse 85",\r
-                    address_line_2: "",\r
-                    city: "PULGARN",\r
-                    state: "",\r
-                    postal_code: "4221"\r
-                }, recipient_name: "Berrie Hulstein"\r
-            },\r
-            {\r
-                country: "NL", address: {\r
-                    address_line_1: "Asterstraat 135",\r
-                    address_line_2: "",\r
-                    city: "Almelo",\r
-                    state: "",\r
-                    postal_code: "7601 AK"\r
-                }, recipient_name: "Joos Voorham"\r
-            },\r
-            {\r
-                country: "IT", address: {\r
-                    address_line_1: "Via Longhena, 132",\r
-                    address_line_2: "",\r
-                    city: "Galloro RM",\r
-                    state: "",\r
-                    postal_code: "00040"\r
-                }, recipient_name: "Colette Jalbert"\r
-            },\r
-            {\r
-                country: "ES", address: {\r
-                    address_line_1: "Calle Alcalá 22",\r
-                    address_line_2: "",\r
-                    city: "Madrid",\r
-                    state: "",\r
-                    postal_code: "28055"\r
-                }, recipient_name: "Ana García López"\r
-            },\r
-            {\r
-                country: "AU", address: {\r
-                    address_line_1: "15 Mary Street",\r
-                    address_line_2: "",\r
-                    city: "North Sydney",\r
-                    state: "NSW",\r
-                    postal_code: "2001"\r
-                }, recipient_name: "Jane Doe"\r
-            },\r
-            {\r
-                country: "MX", address: {\r
-                    address_line_1: "Av. Caudillo del Sur 1234, Edificio B-5",\r
-                    address_line_2: "11560, Col. Municipio Libre, D.F.",\r
-                    city: "Mexico City",\r
-                    state: "Morelos",\r
-                    postal_code: "11560"\r
-                }, recipient_name: "Raúl Uriarte, Jr."\r
-            },\r
-            {\r
-                country: "BR", address: {\r
-                    address_line_1: "Rua da Matriz 123",\r
-                    address_line_2: "apto 25 Centro",\r
-                    city: "Rio de Janeiro",\r
-                    state: "Paraná",\r
-                    postal_code: "01000-001"\r
-                }, recipient_name: "João da Silva"\r
-            },\r
-            {\r
-                country: "JP", address: {\r
-                    address_line_1: "123-4567 æ±äº¬éƒ½æ¸¯åŒº",\r
-                    address_line_2: "é’å±± 1-1-1 ãƒšã‚¤ãƒ‘ルビル 1037",\r
-                    city: "港区",\r
-                    state: "æ±äº¬éƒ½",\r
-                    postal_code: "104-0051"\r
-                }, recipient_name: "山田 èŠ±å­"\r
-            },\r
-            {\r
-                country: "GB", address: {\r
-                    address_line_1: "1 Main Terrace",\r
-                    address_line_2: "",\r
-                    city: "Wolverhampton",\r
-                    state: "West Midlands",\r
-                    postal_code: "W12 4LQ"\r
-                }, recipient_name: "Jane Doe"\r
-            }\r
-        ];\r
-        apm_country_check = false;\r
-        apm_country_list.forEach(function (country_object) {\r
-            if (country_object.country === buyer_country) {\r
-                apm_country_check = true;\r
-                document.getElementById("recipient_name").value = country_object.recipient_name;\r
-                document.getElementById("line1").value = country_object.address.address_line_1;\r
-                document.getElementById("line2").value = country_object.address.address_line_2;\r
-                document.getElementById("city").value = country_object.address.city;\r
-                document.getElementById("state").value = country_object.address.state;\r
-                document.getElementById("zip").value = country_object.address.postal_code;\r
-            }\r
-        });\r
-        if (apm_country_check === false && buyer_country !== null) {\r
-            document.getElementById("recipient_name").value = "Jane Doe";\r
-            document.getElementById("line1").value =\r
-                document.getElementById("line2").value =\r
-                document.getElementById("city").value =\r
-                document.getElementById("state").value =\r
-                document.getElementById("zip").value = "";\r
-        }\r
-    } else {\r
-        //Build script tag with no particular buyer country\r
-        let head = document.getElementsByTagName("head")[0];\r
-        let paypal_sdk_script = document.createElement("script");\r
-        paypal_sdk_script.type = "text/javascript"; \r
-        paypal_sdk_script.setAttribute("async", "");\r
-        paypal_sdk_script.src = "https://www.paypal.com/sdk/js?intent=capture&vault=false&client-id=Aa2IfcoEvHnfJRnVQLSFrSs3SmTTkv5N1weMEL66ysqYIeHfAqXpDVkjOv3vLhkhbP4eKB6MpRlQIcJw";\r
-        paypal_sdk_script.onload = init_smart_buttons; \r
-        head.appendChild(paypal_sdk_script);\r
-    }\r
-}\r
-\r
-ready(select_country_dropdown);\r
-\r
-let serialize = function (form) {\r
-\r
-       // Setup our serialized data\r
-       let serialized = [];\r
-\r
-       // Loop through each field in the form\r
-       for (let i = 0; i < form.elements.length; i++) {\r
-\r
-               let field = form.elements[i];\r
-\r
-               // Don't serialize fields without a name, submits, buttons, file and reset inputs, and disabled fields\r
-               if (!field.name || field.disabled || field.type === "file" || field.type === "reset" || field.type === "submit" || field.type === "button") continue;\r
-\r
-               // If a multi-select, get all selections\r
-               if (field.type === "select-multiple") {\r
-                       for (let n = 0; n < field.options.length; n++) {\r
-                               if (!field.options[n].selected) continue;\r
-                               serialized.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.options[n].value));\r
-                       }\r
-               }\r
-\r
-               // Convert field data to a query string\r
-               else if ((field.type !== "checkbox" && field.type !== "radio") || field.checked) {\r
-                       serialized.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));\r
-               }\r
-       }\r
-\r
-       return serialized.join("&");\r
-\r
-};
\ No newline at end of file
diff --git a/main.css b/main.css
new file mode 100644 (file)
index 0000000..0694544
--- /dev/null
+++ b/main.css
@@ -0,0 +1,96 @@
+.container {
+    width: 920px;
+    margin: 0 auto;
+}
+
+#confirmation {
+  width: 500px;
+}
+
+#confirmation > div {
+  margin-top: 20px;
+}
+
+#square-logo {
+    height: 32px;
+    width: 32px;
+    background: url("https://cdn.glitch.com/4c9bc573-ca4c-48de-8afe-501eddad0b79%2Fsquare-logo.svg?1521834224783") center center no-repeat;
+    margin: 0 auto;
+    padding-top: 25px;
+}
+
+.header {
+  text-align: center;
+  margin-top: 0;
+}
+
+.form-container {
+  margin: 0 auto;
+  width: 320px;
+  display: flex;
+  flex-direction: column;
+}
+
+.form-container {
+  margin: 0 auto;
+  width: 320px;
+  display: flex;
+  flex-direction: column;
+}
+
+.item-line {
+  display: flex;
+}
+
+.item-label {
+  flex-grow: 1;
+}
+
+.item-amount {
+  font-weight: bold;
+}
+
+.total-line {
+  font-weight: bold;
+  margin: 5px 0 5px 0;
+  padding-top: 5px;
+  border-top: 1px solid #c2c7cc;
+}
+
+body {
+  background-color: #ececec;
+  font-family: Helvetica, Arial, sans-serif;
+}
+
+
+form {
+  width:100%;
+  margin-top: 25px;
+}
+
+input {
+  border: 1px solid #E0E2E3;
+  border-radius: 4px;
+  outline-offset: -2px;
+  display: inline-block;
+  font-size: 18px;
+  font-family: "HelveticaNeue";
+  padding: 15px;
+  color: #373F4A;
+}
+
+button {
+  background: #0EB00E;
+  box-shadow: 0 0 2px 0 rgba(0,0,0,0.10), 0 2px 2px 0 rgba(0,0,0,0.10);
+  border-radius: 4px;
+  cursor:pointer;
+  font-size: 16px;
+  color: #FFFFFF;
+  letter-spacing: 0;
+  text-align: center;
+  line-height: 24px;
+  padding: 15px;
+  margin-top: 10px;
+  outline: none;
+  font-family: "HelveticaNeue-Bold", Helvetica, Arial, sans-serif;
+}
\ No newline at end of file
diff --git a/normalize.css b/normalize.css
new file mode 100644 (file)
index 0000000..fa4e73d
--- /dev/null
@@ -0,0 +1,447 @@
+/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+   ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in
+ *    IE on Windows Phone and in iOS.
+ */
+
+html {
+  line-height: 1.15; /* 1 */
+  -ms-text-size-adjust: 100%; /* 2 */
+  -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+   ========================================================================== */
+
+/**
+ * Remove the margin in all browsers (opinionated).
+ */
+
+body {
+  margin: 0;
+}
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+article,
+aside,
+footer,
+header,
+nav,
+section {
+  display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+
+/* Grouping content
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in IE.
+ */
+
+figcaption,
+figure,
+main { /* 1 */
+  display: block;
+}
+
+/**
+ * Add the correct margin in IE 8.
+ */
+
+figure {
+  margin: 1em 40px;
+}
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+  box-sizing: content-box; /* 1 */
+  height: 0; /* 1 */
+  overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+   ========================================================================== */
+
+/**
+ * 1. Remove the gray background on active links in IE 10.
+ * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
+ */
+
+a {
+  background-color: transparent; /* 1 */
+  -webkit-text-decoration-skip: objects; /* 2 */
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+  border-bottom: none; /* 1 */
+  text-decoration: underline; /* 2 */
+  text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
+ */
+
+b,
+strong {
+  font-weight: inherit;
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font style in Android 4.3-.
+ */
+
+dfn {
+  font-style: italic;
+}
+
+/**
+ * Add the correct background and color in IE 9-.
+ */
+
+mark {
+  background-color: #ff0;
+  color: #000;
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+  font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+/* Embedded content
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+audio,
+video {
+  display: inline-block;
+}
+
+/**
+ * Add the correct display in iOS 4-7.
+ */
+
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+
+/**
+ * Remove the border on images inside links in IE 10-.
+ */
+
+img {
+  border-style: none;
+}
+
+/**
+ * Hide the overflow in IE.
+ */
+
+svg:not(:root) {
+  overflow: hidden;
+}
+
+/* Forms
+   ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers (opinionated).
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: sans-serif; /* 1 */
+  font-size: 100%; /* 1 */
+  line-height: 1.15; /* 1 */
+  margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+  overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+  text-transform: none;
+}
+
+/**
+ * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+ *    controls in Android 4.
+ * 2. Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+html [type="button"], /* 1 */
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button; /* 2 */
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+  border-style: none;
+  padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+  outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+  padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ *    `fieldset` elements in all browsers.
+ */
+
+legend {
+  box-sizing: border-box; /* 1 */
+  color: inherit; /* 2 */
+  display: table; /* 1 */
+  max-width: 100%; /* 1 */
+  padding: 0; /* 3 */
+  white-space: normal; /* 1 */
+}
+
+/**
+ * 1. Add the correct display in IE 9-.
+ * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+  display: inline-block; /* 1 */
+  vertical-align: baseline; /* 2 */
+}
+
+/**
+ * Remove the default vertical scrollbar in IE.
+ */
+
+textarea {
+  overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10-.
+ * 2. Remove the padding in IE 10-.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+  box-sizing: border-box; /* 1 */
+  padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+  -webkit-appearance: textfield; /* 1 */
+  outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button; /* 1 */
+  font: inherit; /* 2 */
+}
+
+/* Interactive
+   ========================================================================== */
+
+/*
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in Edge, IE, and Firefox.
+ */
+
+details, /* 1 */
+menu {
+  display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+  display: list-item;
+}
+
+/* Scripting
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+canvas {
+  display: inline-block;
+}
+
+/**
+ * Add the correct display in IE.
+ */
+
+template {
+  display: none;
+}
+
+/* Hidden
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 10-.
+ */
+
+[hidden] {
+  display: none;
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644 (file)
index 0000000..c7ec0e0
--- /dev/null
@@ -0,0 +1,151 @@
+{
+  "name": "@ndcode/square_example_site",
+  "version": "0.0.1",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@apimatic/core": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/@apimatic/core/-/core-0.6.2.tgz",
+      "integrity": "sha512-AK96zE9w+cdH9eFUIQUR/GWhSrBFcGtLeCM0SAbpXWn9LLfTYjp9NN1iSdw8E4UqwFfVR3LunSL2vm+t+ECWgQ==",
+      "requires": {
+        "@apimatic/json-bigint": "^1.1.0",
+        "@apimatic/schema": "^0.6.0",
+        "axios": "^0.21.1",
+        "detect-node": "^2.0.4",
+        "form-data": "^3.0.0",
+        "lodash.flatmap": "^4.5.0",
+        "tiny-warning": "^1.0.3",
+        "tslib": "^2.1.0"
+      }
+    },
+    "@apimatic/json-bigint": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@apimatic/json-bigint/-/json-bigint-1.1.0.tgz",
+      "integrity": "sha512-eQ4WC53kBm0JzaO1CWBgmpmc0QzOWLn940L3gPdGDrGbzyuDztzvVhiSUYQZ+FdswxITaBTz+VG05EU5QwRHpg=="
+    },
+    "@apimatic/schema": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@apimatic/schema/-/schema-0.6.0.tgz",
+      "integrity": "sha512-JgG32LQRLphHRWsn64vIt7wD2m+JH46swM6ZrY7g1rdiGiKV5m+A+TBrJKoUUQRmS14azMgePNZY30NauWqzLg==",
+      "requires": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "@types/node": {
+      "version": "14.18.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.3.tgz",
+      "integrity": "sha512-GtTH2crF4MtOIrrAa+jgTV9JX/PfoUCYr6MiZw7O/dkZu5b6gm5dc1nAL0jwGo4ortSBBtGyeVaxdC8X6V+pLg=="
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+    },
+    "axios": {
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+      "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+      "requires": {
+        "follow-redirects": "^1.14.0"
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "cookie": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+    },
+    "detect-node": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
+    },
+    "follow-redirects": {
+      "version": "1.14.6",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz",
+      "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A=="
+    },
+    "form-data": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "lodash.flatmap": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz",
+      "integrity": "sha1-74y/QI9uSCaGYzRTBcaswLd4cC4="
+    },
+    "mime-db": {
+      "version": "1.51.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
+      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
+    },
+    "mime-types": {
+      "version": "2.1.34",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
+      "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
+      "requires": {
+        "mime-db": "1.51.0"
+      }
+    },
+    "querystring": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
+      "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg=="
+    },
+    "square": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/square/-/square-17.0.0.tgz",
+      "integrity": "sha512-16U78woz2hgQnMsz7kAnhNUfCzH7o0vt8vmjzduLUl6hS4jPRz181nn/RdQdxOyX19DQYYKLsKLRDErpwCcg2Q==",
+      "requires": {
+        "@apimatic/core": "^0.6.2",
+        "@apimatic/json-bigint": "^1.1.0",
+        "@apimatic/schema": "^0.6.0",
+        "@types/node": "^14.14.30"
+      }
+    },
+    "stream-buffers": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz",
+      "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ=="
+    },
+    "tiny-warning": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
+      "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+    },
+    "tslib": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+      "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+    },
+    "uuid": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
+    },
+    "xdate": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/xdate/-/xdate-0.8.2.tgz",
+      "integrity": "sha1-17AzwASF0CaVuvAET06s2j/JYaM="
+    }
+  }
+}
index 9a95157..555186f 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "name": "@ndcode/paypal_example_site",
+  "name": "@ndcode/square_example_site",
   "version": "0.0.1",
   "description": "Example website using JavaScript Template system",
   "directories": {},
@@ -7,6 +7,8 @@
     "cookie": "^0.3.1",
     "querystring": "^0.2.0",
     "stream-buffers": "^3.0.2",
+    "square": "^17.0.0",
+    "uuid": "^8.3.2",
     "xdate": "^0.8.2"
   },
   "devDependencies": {},
diff --git a/pages/shipping.html.jst b/pages/shipping.html.jst
deleted file mode 100644 (file)
index adf1164..0000000
+++ /dev/null
@@ -1,960 +0,0 @@
-return async env => {
-  let _out = []
-  _out.push('<!DOCTYPE html>')
-  html(lang="en") {
-    head {
-      meta(charset="utf-8") {}
-      meta(http-equiv="x-ua-compatible" content="ie=edge") {}
-      meta(name="viewport" content="width=device-width,initial-scale=1") {}
-      link(href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous") {}
-      script(src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous") {}
-      title {
-        'Checkout With PayPal NodeJs Demo'
-      }
-      style {
-        .header-bg-color {
-          color: #fff;
-          background: -moz-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -webkit-gradient(linear,left top,right top,color-stop(0,#004094),color-stop(50%,#0096d9),color-stop(100%,#004094));
-          background: -webkit-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -o-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -ms-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: linear-gradient(90deg,#004094 0,#0096d9 50%,#004094 100%)
-        }
-      }
-    }
-    body {
-      div.container {
-        div.row.header-bg-color.'mb-5'.p-3 {
-          h2.text-center {
-            'Checkout with PayPal Demo'
-          }
-          h4.text-center {
-            'Using Orders v2 REST API with PayPal JavaScript SDK'
-          }
-          h5.text-center {
-            'Server-side Integration'
-          }
-        }
-        div.row {
-          div.col-lg-3 {}
-          div.col-lg-6 {
-            h3.text-center {
-              'Shipping Information'
-            }
-            hr {}
-            form#camera_form {
-              input(name="return_url" type="hidden" value="http://localhost/pages/success.html") {}
-              ' '
-              input(name="cancel_url" type="hidden" value="http://localhost/pages/success.html") {}
-              ' '
-              input#item_amt(name="item_amt" type="hidden" value="300") {}
-              ' '
-              input#insurance_fee(name="insurance_fee" type="hidden" value="10") {}
-              ' '
-              input#handling_fee(name="handling_fee" type="hidden" value="5") {}
-              ' '
-              input#tax_amt(name="tax_amt" type="hidden" value="5") {}
-              ' '
-              input#shipping_discount(name="shipping_discount" type="hidden" value="2") {}
-              ' '
-              input#currency(name="currency" type="hidden" value="USD") {}
-              ' '
-              input#total_amt(name="total_amt" type="hidden" value="300") {}
-              _out.push('<!-- Shipping Information -->')
-              div.form-group.row.mb-2 {
-                label.'col-sm-4'.col-form-label(for="recipient_name") {
-                  'Recipient Name'
-                }
-                div.col-sm-8 {
-                  input#recipient_name.form-control(type="text" name="recipient_name" aria-describedby="passwordHelpInline" value="Jane Doe") {}
-                }
-              }
-              div.form-group.row.mb-2 {
-                label.'col-sm-4'.col-form-label(for="line1") {
-                  'Address Line 1'
-                }
-                div.col-sm-8 {
-                  input#line1.form-control(type="text" name="line1" aria-describedby="passwordHelpInline" value="2211 North Street") {}
-                }
-              }
-              div.form-group.row.mb-2 {
-                label.'col-sm-4'.col-form-label(for="line2") {
-                  'Address Line 2'
-                }
-                div.col-sm-8 {
-                  input#line2.form-control(type="text" name="line2" aria-describedby="passwordHelpInline" value="") {}
-                }
-              }
-              div.form-group.row.mb-2 {
-                label.'col-sm-4'.col-form-label(for="city") {
-                  'City'
-                }
-                div.col-sm-8 {
-                  input#city.form-control(type="text" name="city" aria-describedby="passwordHelpInline" value="San Jose") {}
-                }
-              }
-              div.form-group.row.mb-2 {
-                label.'col-sm-4'.col-form-label(for="state") {
-                  'State'
-                }
-                div.col-sm-8 {
-                  input#state.form-control(type="text" name="state" aria-describedby="passwordHelpInline" value="CA") {}
-                }
-              }
-              div.form-group.row.mb-2 {
-                label.'col-sm-4'.col-form-label(for="zip") {
-                  'Postal Code'
-                }
-                div.col-sm-8 {
-                  input#zip.form-control(type="text" name="zip" aria-describedby="passwordHelpInline" value="95123") {}
-                }
-              }
-              div.form-group.row.mb-2 {
-                label.'col-sm-4'.col-form-label(for="countrySelect") {
-                  'Country'
-                }
-                div.col-sm-8 {
-                  select.form-select.mb-2#countrySelect(name="countrySelect" aria-label="Country") {
-                    option(value="AF") {
-                      'Afghanistan'
-                    }
-                    option(value="AX") {
-                      'Aland Islands'
-                    }
-                    option(value="AL") {
-                      'Albania'
-                    }
-                    option(value="DZ") {
-                      'Algeria'
-                    }
-                    option(value="AS") {
-                      'American Samoa'
-                    }
-                    option(value="AD") {
-                      'Andorra'
-                    }
-                    option(value="AO") {
-                      'Angola'
-                    }
-                    option(value="AI") {
-                      'Anguilla'
-                    }
-                    option(value="AQ") {
-                      'Antarctica'
-                    }
-                    option(value="AG") {
-                      'Antigua and Barbuda'
-                    }
-                    option(value="AR") {
-                      'Argentina'
-                    }
-                    option(value="AM") {
-                      'Armenia'
-                    }
-                    option(value="AW") {
-                      'Aruba'
-                    }
-                    option(value="AU") {
-                      'Australia'
-                    }
-                    option(value="AT") {
-                      'Austria'
-                    }
-                    option(value="AZ") {
-                      'Azerbaijan'
-                    }
-                    option(value="BS") {
-                      'Bahamas'
-                    }
-                    option(value="BH") {
-                      'Bahrain'
-                    }
-                    option(value="BD") {
-                      'Bangladesh'
-                    }
-                    option(value="BB") {
-                      'Barbados'
-                    }
-                    option(value="BY") {
-                      'Belarus'
-                    }
-                    option(value="BE") {
-                      'Belgium'
-                    }
-                    option(value="BZ") {
-                      'Belize'
-                    }
-                    option(value="BJ") {
-                      'Benin'
-                    }
-                    option(value="BM") {
-                      'Bermuda'
-                    }
-                    option(value="BT") {
-                      'Bhutan'
-                    }
-                    option(value="BO") {
-                      'Bolivia'
-                    }
-                    option(value="BA") {
-                      'Bosnia and Herzegovina'
-                    }
-                    option(value="BW") {
-                      'Botswana'
-                    }
-                    option(value="BV") {
-                      'Bouvet Island'
-                    }
-                    option(value="BR") {
-                      'Brazil'
-                    }
-                    option(value="IO") {
-                      'British Indian Ocean Territory'
-                    }
-                    option(value="BN") {
-                      'Brunei Darussalam'
-                    }
-                    option(value="BG") {
-                      'Bulgaria'
-                    }
-                    option(value="BF") {
-                      'Burkina Faso'
-                    }
-                    option(value="BI") {
-                      'Burundi'
-                    }
-                    option(value="KH") {
-                      'Cambodia'
-                    }
-                    option(value="CM") {
-                      'Cameroon'
-                    }
-                    option(value="CA") {
-                      'Canada'
-                    }
-                    option(value="CV") {
-                      'Cape Verde'
-                    }
-                    option(value="KY") {
-                      'Cayman Islands'
-                    }
-                    option(value="CF") {
-                      'Central African Republic'
-                    }
-                    option(value="TD") {
-                      'Chad'
-                    }
-                    option(value="CL") {
-                      'Chile'
-                    }
-                    option(value="CN") {
-                      'China'
-                    }
-                    option(value="CX") {
-                      'Christmas Island'
-                    }
-                    option(value="CC") {
-                      'Cocos (Keeling) Islands'
-                    }
-                    option(value="CO") {
-                      'Colombia'
-                    }
-                    option(value="KM") {
-                      'Comoros'
-                    }
-                    option(value="CG") {
-                      'Congo'
-                    }
-                    option(value="CD") {
-                      'Congo, The Democratic Republic of The'
-                    }
-                    option(value="CK") {
-                      'Cook Islands'
-                    }
-                    option(value="CR") {
-                      'Costa Rica'
-                    }
-                    option(value="CI") {
-                      'Cote D\'ivoire'
-                    }
-                    option(value="HR") {
-                      'Croatia'
-                    }
-                    option(value="CU") {
-                      'Cuba'
-                    }
-                    option(value="CY") {
-                      'Cyprus'
-                    }
-                    option(value="CZ") {
-                      'Czech Republic'
-                    }
-                    option(value="DK") {
-                      'Denmark'
-                    }
-                    option(value="DJ") {
-                      'Djibouti'
-                    }
-                    option(value="DM") {
-                      'Dominica'
-                    }
-                    option(value="DO") {
-                      'Dominican Republic'
-                    }
-                    option(value="EC") {
-                      'Ecuador'
-                    }
-                    option(value="EG") {
-                      'Egypt'
-                    }
-                    option(value="SV") {
-                      'El Salvador'
-                    }
-                    option(value="GQ") {
-                      'Equatorial Guinea'
-                    }
-                    option(value="ER") {
-                      'Eritrea'
-                    }
-                    option(value="EE") {
-                      'Estonia'
-                    }
-                    option(value="ET") {
-                      'Ethiopia'
-                    }
-                    option(value="FK") {
-                      'Falkland Islands (Malvinas)'
-                    }
-                    option(value="FO") {
-                      'Faroe Islands'
-                    }
-                    option(value="FJ") {
-                      'Fiji'
-                    }
-                    option(value="FI") {
-                      'Finland'
-                    }
-                    option(value="FR") {
-                      'France'
-                    }
-                    option(value="GF") {
-                      'French Guiana'
-                    }
-                    option(value="PF") {
-                      'French Polynesia'
-                    }
-                    option(value="TF") {
-                      'French Southern Territories'
-                    }
-                    option(value="GA") {
-                      'Gabon'
-                    }
-                    option(value="GM") {
-                      'Gambia'
-                    }
-                    option(value="GE") {
-                      'Georgia'
-                    }
-                    option(value="DE") {
-                      'Germany'
-                    }
-                    option(value="GH") {
-                      'Ghana'
-                    }
-                    option(value="GI") {
-                      'Gibraltar'
-                    }
-                    option(value="GR") {
-                      'Greece'
-                    }
-                    option(value="GL") {
-                      'Greenland'
-                    }
-                    option(value="GD") {
-                      'Grenada'
-                    }
-                    option(value="GP") {
-                      'Guadeloupe'
-                    }
-                    option(value="GU") {
-                      'Guam'
-                    }
-                    option(value="GT") {
-                      'Guatemala'
-                    }
-                    option(value="GG") {
-                      'Guernsey'
-                    }
-                    option(value="GN") {
-                      'Guinea'
-                    }
-                    option(value="GW") {
-                      'Guinea-bissau'
-                    }
-                    option(value="GY") {
-                      'Guyana'
-                    }
-                    option(value="HT") {
-                      'Haiti'
-                    }
-                    option(value="HM") {
-                      'Heard Island and Mcdonald Islands'
-                    }
-                    option(value="VA") {
-                      'Holy See (Vatican City State)'
-                    }
-                    option(value="HN") {
-                      'Honduras'
-                    }
-                    option(value="HK") {
-                      'Hong Kong'
-                    }
-                    option(value="HU") {
-                      'Hungary'
-                    }
-                    option(value="IS") {
-                      'Iceland'
-                    }
-                    option(value="IN") {
-                      'India'
-                    }
-                    option(value="ID") {
-                      'Indonesia'
-                    }
-                    option(value="IR") {
-                      'Iran, Islamic Republic of'
-                    }
-                    option(value="IQ") {
-                      'Iraq'
-                    }
-                    option(value="IE") {
-                      'Ireland'
-                    }
-                    option(value="IM") {
-                      'Isle of Man'
-                    }
-                    option(value="IL") {
-                      'Israel'
-                    }
-                    option(value="IT") {
-                      'Italy'
-                    }
-                    option(value="JM") {
-                      'Jamaica'
-                    }
-                    option(value="JP") {
-                      'Japan'
-                    }
-                    option(value="JE") {
-                      'Jersey'
-                    }
-                    option(value="JO") {
-                      'Jordan'
-                    }
-                    option(value="KZ") {
-                      'Kazakhstan'
-                    }
-                    option(value="KE") {
-                      'Kenya'
-                    }
-                    option(value="KI") {
-                      'Kiribati'
-                    }
-                    option(value="KP") {
-                      'Korea, Democratic People\'s Republic of'
-                    }
-                    option(value="KR") {
-                      'Korea, Republic of'
-                    }
-                    option(value="KW") {
-                      'Kuwait'
-                    }
-                    option(value="KG") {
-                      'Kyrgyzstan'
-                    }
-                    option(value="LA") {
-                      'Lao People\'s Democratic Republic'
-                    }
-                    option(value="LV") {
-                      'Latvia'
-                    }
-                    option(value="LB") {
-                      'Lebanon'
-                    }
-                    option(value="LS") {
-                      'Lesotho'
-                    }
-                    option(value="LR") {
-                      'Liberia'
-                    }
-                    option(value="LY") {
-                      'Libyan Arab Jamahiriya'
-                    }
-                    option(value="LI") {
-                      'Liechtenstein'
-                    }
-                    option(value="LT") {
-                      'Lithuania'
-                    }
-                    option(value="LU") {
-                      'Luxembourg'
-                    }
-                    option(value="MO") {
-                      'Macao'
-                    }
-                    option(value="MK") {
-                      'Macedonia, The Former Yugoslav Republic of'
-                    }
-                    option(value="MG") {
-                      'Madagascar'
-                    }
-                    option(value="MW") {
-                      'Malawi'
-                    }
-                    option(value="MY") {
-                      'Malaysia'
-                    }
-                    option(value="MV") {
-                      'Maldives'
-                    }
-                    option(value="ML") {
-                      'Mali'
-                    }
-                    option(value="MT") {
-                      'Malta'
-                    }
-                    option(value="MH") {
-                      'Marshall Islands'
-                    }
-                    option(value="MQ") {
-                      'Martinique'
-                    }
-                    option(value="MR") {
-                      'Mauritania'
-                    }
-                    option(value="MU") {
-                      'Mauritius'
-                    }
-                    option(value="YT") {
-                      'Mayotte'
-                    }
-                    option(value="MX") {
-                      'Mexico'
-                    }
-                    option(value="FM") {
-                      'Micronesia, Federated States of'
-                    }
-                    option(value="MD") {
-                      'Moldova, Republic of'
-                    }
-                    option(value="MC") {
-                      'Monaco'
-                    }
-                    option(value="MN") {
-                      'Mongolia'
-                    }
-                    option(value="ME") {
-                      'Montenegro'
-                    }
-                    option(value="MS") {
-                      'Montserrat'
-                    }
-                    option(value="MA") {
-                      'Morocco'
-                    }
-                    option(value="MZ") {
-                      'Mozambique'
-                    }
-                    option(value="MM") {
-                      'Myanmar'
-                    }
-                    option(value="NA") {
-                      'Namibia'
-                    }
-                    option(value="NR") {
-                      'Nauru'
-                    }
-                    option(value="NP") {
-                      'Nepal'
-                    }
-                    option(value="NL") {
-                      'Netherlands'
-                    }
-                    option(value="AN") {
-                      'Netherlands Antilles'
-                    }
-                    option(value="NC") {
-                      'New Caledonia'
-                    }
-                    option(value="NZ") {
-                      'New Zealand'
-                    }
-                    option(value="NI") {
-                      'Nicaragua'
-                    }
-                    option(value="NE") {
-                      'Niger'
-                    }
-                    option(value="NG") {
-                      'Nigeria'
-                    }
-                    option(value="NU") {
-                      'Niue'
-                    }
-                    option(value="NF") {
-                      'Norfolk Island'
-                    }
-                    option(value="MP") {
-                      'Northern Mariana Islands'
-                    }
-                    option(value="NO") {
-                      'Norway'
-                    }
-                    option(value="OM") {
-                      'Oman'
-                    }
-                    option(value="PK") {
-                      'Pakistan'
-                    }
-                    option(value="PW") {
-                      'Palau'
-                    }
-                    option(value="PS") {
-                      'Palestinian Territory, Occupied'
-                    }
-                    option(value="PA") {
-                      'Panama'
-                    }
-                    option(value="PG") {
-                      'Papua New Guinea'
-                    }
-                    option(value="PY") {
-                      'Paraguay'
-                    }
-                    option(value="PE") {
-                      'Peru'
-                    }
-                    option(value="PH") {
-                      'Philippines'
-                    }
-                    option(value="PN") {
-                      'Pitcairn'
-                    }
-                    option(value="PL") {
-                      'Poland'
-                    }
-                    option(value="PT") {
-                      'Portugal'
-                    }
-                    option(value="PR") {
-                      'Puerto Rico'
-                    }
-                    option(value="QA") {
-                      'Qatar'
-                    }
-                    option(value="RE") {
-                      'Reunion'
-                    }
-                    option(value="RO") {
-                      'Romania'
-                    }
-                    option(value="RU") {
-                      'Russian Federation'
-                    }
-                    option(value="RW") {
-                      'Rwanda'
-                    }
-                    option(value="SH") {
-                      'Saint Helena'
-                    }
-                    option(value="KN") {
-                      'Saint Kitts and Nevis'
-                    }
-                    option(value="LC") {
-                      'Saint Lucia'
-                    }
-                    option(value="PM") {
-                      'Saint Pierre and Miquelon'
-                    }
-                    option(value="VC") {
-                      'Saint Vincent and The Grenadines'
-                    }
-                    option(value="WS") {
-                      'Samoa'
-                    }
-                    option(value="SM") {
-                      'San Marino'
-                    }
-                    option(value="ST") {
-                      'Sao Tome and Principe'
-                    }
-                    option(value="SA") {
-                      'Saudi Arabia'
-                    }
-                    option(value="SN") {
-                      'Senegal'
-                    }
-                    option(value="RS") {
-                      'Serbia'
-                    }
-                    option(value="SC") {
-                      'Seychelles'
-                    }
-                    option(value="SL") {
-                      'Sierra Leone'
-                    }
-                    option(value="SG") {
-                      'Singapore'
-                    }
-                    option(value="SK") {
-                      'Slovakia'
-                    }
-                    option(value="SI") {
-                      'Slovenia'
-                    }
-                    option(value="SB") {
-                      'Solomon Islands'
-                    }
-                    option(value="SO") {
-                      'Somalia'
-                    }
-                    option(value="ZA") {
-                      'South Africa'
-                    }
-                    option(value="GS") {
-                      'South Georgia and The South Sandwich Islands'
-                    }
-                    option(value="ES") {
-                      'Spain'
-                    }
-                    option(value="LK") {
-                      'Sri Lanka'
-                    }
-                    option(value="SD") {
-                      'Sudan'
-                    }
-                    option(value="SR") {
-                      'Suriname'
-                    }
-                    option(value="SJ") {
-                      'Svalbard and Jan Mayen'
-                    }
-                    option(value="SZ") {
-                      'Swaziland'
-                    }
-                    option(value="SE") {
-                      'Sweden'
-                    }
-                    option(value="CH") {
-                      'Switzerland'
-                    }
-                    option(value="SY") {
-                      'Syrian Arab Republic'
-                    }
-                    option(value="TW") {
-                      'Taiwan, Province of China'
-                    }
-                    option(value="TJ") {
-                      'Tajikistan'
-                    }
-                    option(value="TZ") {
-                      'Tanzania, United Republic of'
-                    }
-                    option(value="TH") {
-                      'Thailand'
-                    }
-                    option(value="TL") {
-                      'Timor-leste'
-                    }
-                    option(value="TG") {
-                      'Togo'
-                    }
-                    option(value="TK") {
-                      'Tokelau'
-                    }
-                    option(value="TO") {
-                      'Tonga'
-                    }
-                    option(value="TT") {
-                      'Trinidad and Tobago'
-                    }
-                    option(value="TN") {
-                      'Tunisia'
-                    }
-                    option(value="TR") {
-                      'Turkey'
-                    }
-                    option(value="TM") {
-                      'Turkmenistan'
-                    }
-                    option(value="TC") {
-                      'Turks and Caicos Islands'
-                    }
-                    option(value="TV") {
-                      'Tuvalu'
-                    }
-                    option(value="UG") {
-                      'Uganda'
-                    }
-                    option(value="UA") {
-                      'Ukraine'
-                    }
-                    option(value="AE") {
-                      'United Arab Emirates'
-                    }
-                    option(value="GB") {
-                      'United Kingdom'
-                    }
-                    option(value="US" selected="") {
-                      'United States'
-                    }
-                    option(value="UM") {
-                      'United States Minor Outlying Islands'
-                    }
-                    option(value="UY") {
-                      'Uruguay'
-                    }
-                    option(value="UZ") {
-                      'Uzbekistan'
-                    }
-                    option(value="VU") {
-                      'Vanuatu'
-                    }
-                    option(value="VE") {
-                      'Venezuela'
-                    }
-                    option(value="VN") {
-                      'Vietnam'
-                    }
-                    option(value="VG") {
-                      'Virgin Islands, British'
-                    }
-                    option(value="VI") {
-                      'Virgin Islands, U.S.'
-                    }
-                    option(value="WF") {
-                      'Wallis and Futuna'
-                    }
-                    option(value="EH") {
-                      'Western Sahara'
-                    }
-                    option(value="YE") {
-                      'Yemen'
-                    }
-                    option(value="ZM") {
-                      'Zambia'
-                    }
-                    option(value="ZW") {
-                      'Zimbabwe'
-                    }
-                  }
-                }
-              }
-              div.row.'g-3'.align-items-center.mb-2 {
-                label.'col-sm-5'.control-label(for="shipping_amt") {
-                  'Shipping Type'
-                }
-                div.col-sm-7 {
-                  select.form-control#shipping_amt(name="shipping_amt") {
-                    optgroup(label="United Parcel Service" style="font-style:normal;") {
-                      option(value="8.00") {
-                        'Worldwide Expedited - $8.00'
-                      }
-                      option(value="4.00") {
-                        'Worldwide Express Saver - $4.00'
-                      }
-                    }
-                    optgroup(label="Flat Rate" style="font-style:normal;") {
-                      option(value="2.00" selected="") {
-                        'Fixed - $2.00'
-                      }
-                    }
-                  }
-                }
-              }
-              _out.push('<!-- Checkout Options -->')
-              div.form-group.mb-2 {
-                div.'col-sm-offset-5'.col-sm-7 {
-                  div.radio {
-                    label {
-                      input#paypalRadio(type="radio" name="paymentMethod" value="paypal" checked="") {}
-                      ' '
-                      img.v-middle(src="https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg" alt="Acceptance Mark") {}
-                      ' '
-                      a(href="https://www.paypal.com/us/cgi-bin/webscr?cmd=xpt/Marketing/popup/OLCWhatIsPayPal-outside" onclick="window.open('https://www.paypal.com/us/cgi-bin/webscr?cmd=xpt/Marketing/popup/OLCWhatIsPayPal-outside','olcwhatispaypal','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, ,left=0, top=0, width=400, height=350'); return false;") {
-                        'What is PayPal?'
-                      }
-                    }
-                  }
-                  div.radio.disabled.mb-2 {
-                    label {
-                      input#cardRadio(type="radio" name="paymentMethod" value="card" disabled="") {}
-                      ' Card'
-                    }
-                  }
-                }
-              }
-              div.row {
-                _out.push('<!-- Container for PayPal Mark Checkout -->')
-                div#paypalCheckoutContainer {}
-              }
-            }
-          }
-          div.col-lg-3 {}
-        }
-      }
-      _out.push('<!-- Javascript Import -->')
-      script(src="../js/config.js") {}
-      _out.push('<!-- PayPal In-Context Checkout script -->')
-      script(type="text/javascript") {
-        init_smart_buttons = (() => {
-          paypal.Buttons({
-            env: "sandbox",
-            style: {
-              layout: "vertical",
-              size: "responsive",
-              shape: "pill",
-              color: "gold"
-            },
-            commit: true,
-            createOrder: function() {
-              let shipping_amtSelect = document.getElementById("shipping_amt"), updatedShipping = shipping_amtSelect.options[shipping_amtSelect.selectedIndex].value, countrySelect = document.getElementById("countrySelect"), total_amt = parseFloat(document.getElementById("item_amt").value) + parseFloat(document.getElementById("tax_amt").value) + parseFloat(document.getElementById("handling_fee").value) + parseFloat(document.getElementById("insurance_fee").value) + parseFloat(updatedShipping) - parseFloat(document.getElementById("shipping_discount").value);
-              document.getElementById("total_amt").value = total_amt;
-              return new Promise((resolve, reject) => {
-                $.ajax({
-                  type: "POST",
-                  url: "/api/createOrder.json",
-                  data: serialize(document.getElementById("camera_form")),
-                  success: function(response) {
-                    return response;
-                  },
-                  error: function(error) {
-                    reject(error);
-                  }
-                }).then(function(response) {
-                  console.log("Order ID: " + response.id);
-                  resolve(response.id);
-                });
-              });
-            },
-            onApprove: function(data, actions) {
-              let postData = new FormData();
-              return fetch("../api/captureOrder.json", {
-                method: "POST",
-                body: postData
-              }).then(function(res) {
-                return res.json();
-              }).then(function() {
-                window.location.href = "success.html?commit=true";
-              });
-            }
-          }).render("#paypalCheckoutContainer");
-        });
-      }
-      _out.push('<!-- jQuery (necessary for Bootstrap\'s JavaScript plugins) -->')
-      script(src="https://code.jquery.com/jquery.js") {}
-    }
-  }
-  env.site.serve(env, 200, Buffer.from(_out.join('')), 'shipping.html.jst')
-}
diff --git a/pages/success.html.jst b/pages/success.html.jst
deleted file mode 100644 (file)
index 4de021c..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-return async env => {
-  let _out = []
-  _out.push('<!DOCTYPE html>')
-  html(lang="en") {
-    head {
-      meta(charset="utf-8") {}
-      meta(http-equiv="x-ua-compatible" content="ie=edge") {}
-      meta(name="viewport" content="width=device-width,initial-scale=1") {}
-      link(href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous") {}
-      script(src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous") {}
-      title {
-        'Checkout With PayPal NodeJs Demo'
-      }
-      style {
-        .header-bg-color {
-          color: #fff;
-          background: -moz-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -webkit-gradient(linear,left top,right top,color-stop(0,#004094),color-stop(50%,#0096d9),color-stop(100%,#004094));
-          background: -webkit-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -o-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: -ms-linear-gradient(0deg,#004094 0,#0096d9 50%,#004094 100%);
-          background: linear-gradient(90deg,#004094 0,#0096d9 50%,#004094 100%)
-        }
-        #orderConfirm p,
-        #orderView p {
-          margin: 0
-        }
-      }
-    }
-    body {
-      div.container {
-        div.row.header-bg-color.'mb-5'.p-3 {
-          h2.text-center {
-            'Checkout with PayPal Demo'
-          }
-          h4.text-center {
-            'Using Orders v2 REST API with PayPal JavaScript SDK'
-          }
-          h5.text-center {
-            'Server-side Integration'
-          }
-        }
-        div.row {
-          div.col-sm {}
-          div.col-sm {
-            div#loadingAlert.card(style="display: none;") {
-              div.card-body {
-                div.alert.alert-info.block(role="alert") {
-                  'Loading....'
-                }
-              }
-            }
-            form#orderConfirm.form-horizontal(style="display: none;") {
-              h3 {
-                'Your payment is authorized.'
-              }
-              h4 {
-                'Confirm the order to execute'
-              }
-              hr {}
-              div.form-group {
-                label.'col-sm-5'.control-label(style="font-weight:bold") {
-                  'Shipping Information'
-                }
-                div.col-sm {
-                  p#confirmRecipient {}
-                  p#confirmAddressLine1 {}
-                  p#confirmAddressLine2 {}
-                  p {
-                    span#confirmCity {}
-                    ', '
-                    span#confirmState {}
-                    ' - '
-                    span#confirmZip {}
-                  }
-                  p#confirmCountry {}
-                }
-              }
-              div.form-group {
-                label.'col-sm-5'.control-label(style="font-weight:bold" for="shippingMethod") {
-                  'Shipping Type'
-                }
-                div.col-sm {
-                  select.form-control#shippingMethod(name="shippingMethod") {
-                    optgroup(label="United Parcel Service" style="font-style:normal;") {
-                      option(value="8.00") {
-                        'Worldwide Expedited - $8.00'
-                      }
-                      option(value="4.00") {
-                        'Worldwide Express Saver - $4.00'
-                      }
-                    }
-                    optgroup(label="Flat Rate" style="font-style:normal;") {
-                      option(value="2.00" selected="selected") {
-                        'Fixed - $2.00'
-                      }
-                    }
-                  }
-                }
-              }
-              hr {}
-              div.form-group {
-                div.'col-sm-offset-5'.col-sm {
-                  label.btn.btn-primary#confirmButton {
-                    'Complete Payment'
-                  }
-                }
-              }
-            }
-            form#orderView.form-horizontal(style="display: none;") {
-              h3 {
-                'Your payment is complete'
-              }
-              h4 {
-                span#viewFirstName {}
-                ' '
-                span#viewLastName {}
-                ', Thank you for your Order'
-              }
-              hr {}
-              div.form-group {
-                div.form-group {
-                  label.'col-sm-5'.control-label(style="font-weight:bold") {
-                    'Shipping Details'
-                  }
-                  div.col-sm {
-                    p#viewRecipientName {}
-                    p#viewAddressLine1 {}
-                    p#viewAddressLine2 {}
-                    p {
-                      span#viewCity {}
-                      ', '
-                      span#viewState {}
-                      ' - '
-                      span#viewPostalCode {}
-                    }
-                    p#confirmCountry {}
-                  }
-                }
-                div.form-group {
-                  label.'col-sm-5'.control-label(style="font-weight:bold") {
-                    'Transaction Details'
-                  }
-                  div.col-sm {
-                    p {
-                      'Transaction ID: '
-                      span#viewTransactionID {}
-                    }
-                    p {
-                      'Payment Total Amount: '
-                      span#viewFinalAmount {}
-                    }
-                    p {
-                      'Currency Code: '
-                      span#viewCurrency {}
-                    }
-                    p {
-                      'Payment Status: '
-                      span#viewPaymentState {}
-                    }
-                    p#transactionType {
-                      'Payment Type: '
-                      span#viewTransactionType {}
-                    }
-                  }
-                }
-              }
-              hr {}
-              h4 {
-                'Click '
-                a(href="/") {
-                  'here '
-                }
-                'to return to Home Page'
-              }
-            }
-          }
-          div.col-sm {}
-        }
-      }
-      _out.push('<!-- Javascript Import -->')
-      script(src="../js/config.js") {}
-      script(type="text/javascript") {
-        showDom("loadingAlert");
-        
-        document.onreadystatechange = function() {
-          if (document.readyState === "complete") {
-            $.ajax({
-              type: "POST",
-              url: "/api/getOrderDetails.json",
-              success: function(response, textStatus, xhr) {
-                hideDom("loadingAlert");
-                if (textStatus === "success") {
-                  console.log("Success Response:\n" + response);
-                  if (getUrlParams("commit") === "true") {
-                    showPaymentExecute(response);
-                  } else {
-                    showPaymentGet(response);
-                  }
-                } else {
-                  alert("Something went wrong");
-                }
-              }
-            });
-          }
-        };
-        
-        function showPaymentGet(res) {
-          let shipping = res.purchase_units[0].shipping;
-          let shipping_address = shipping.address;
-          console.log("Get Order result " + JSON.stringify(res));
-          console.log("shipping add " + JSON.stringify(shipping));
-          document.getElementById("confirmRecipient").innerText = shipping.name.full_name;
-          document.getElementById("confirmAddressLine1").innerText = shipping_address.address_line_1;
-          if (shipping_address.address_line_2) document.getElementById("confirmAddressLine2").innerText = shipping_address.address_line_1; else document.getElementById("confirmAddressLine2").innerText = "";
-          document.getElementById("confirmCity").innerText = shipping_address.admin_area_2;
-          document.getElementById("confirmState").innerText = shipping_address.admin_area_1;
-          document.getElementById("confirmZip").innerText = shipping_address.postal_code;
-          document.getElementById("confirmCountry").innerText = shipping_address.country_code;
-          showDom("orderConfirm");
-          document.querySelector("#confirmButton").addEventListener("click", function() {
-            let shippingMethodSelect = document.getElementById("shippingMethod"), updatedShipping = shippingMethodSelect.options[shippingMethodSelect.selectedIndex].value, currentShipping = res.purchase_units[0].amount.breakdown.shipping.value;
-            let postPatchOrderData = {
-              order_id: res.id,
-              item_amt: res.purchase_units[0].amount.breakdown.item_total.value,
-              tax_amt: res.purchase_units[0].amount.breakdown.tax_total.value,
-              handling_fee: res.purchase_units[0].amount.breakdown.handling.value,
-              insurance_fee: res.purchase_units[0].amount.breakdown.insurance.value,
-              shipping_discount: res.purchase_units[0].amount.breakdown.shipping_discount.value,
-              total_amt: res.purchase_units[0].amount.value,
-              currency: res.purchase_units[0].amount.currency_code,
-              updated_shipping: updatedShipping,
-              current_shipping: currentShipping
-            };
-            console.log("patch data: " + JSON.stringify(postPatchOrderData));
-            hideDom("orderConfirm");
-            hideDom("confirmButton");
-            showDom("loadingAlert");
-            console.log("Current shipping " + currentShipping + " and updated shipping is " + updatedShipping);
-            if (currentShipping == updatedShipping) {
-              return callPaymentCapture();
-            } else {
-              console.log("Trying patch first");
-              $.ajax({
-                type: "POST",
-                url: "/api/patchOrder.json",
-                data: postPatchOrderData,
-                success: function(response) {
-                  console.log("Patch Order Response has no content in V2: " + JSON.stringify(response));
-                  if (response.http_code === 204) return callPaymentCapture();
-                }
-              });
-            }
-          });
-        }
-        
-        function callPaymentCapture() {
-          $.ajax({
-            type: "POST",
-            url: "/api/captureOrder.json",
-            success: function(response) {
-              hideDom("orderConfirm");
-              hideDom("loadingAlert");
-              console.log("Capture Response : " + JSON.stringify(response));
-              showPaymentExecute(response);
-            },
-            error: function(err) {
-              alert("Something went wrong");
-            }
-          });
-        }
-        
-        function showPaymentExecute(result) {
-          console.log("Final Result:\n" + result);
-          document.getElementById("viewFirstName").textContent = result.payer.name.given_name;
-          document.getElementById("viewLastName").textContent = result.payer.name.surname;
-          document.getElementById("viewRecipientName").textContent = result.purchase_units[0].shipping.name.full_name;
-          document.getElementById("viewAddressLine1").textContent = result.purchase_units[0].shipping.address.address_line_1;
-          if (result.purchase_units[0].shipping.address.address_line_2) {
-            document.getElementById("viewAddressLine2").textContent = result.purchase_units[0].shipping.address.address_line_2;
-          } else {
-            document.getElementById("viewAddressLine2").textContent = "";
-          }
-          document.getElementById("viewCity").textContent = result.purchase_units[0].shipping.address.admin_area_2;
-          document.getElementById("viewState").textContent = result.purchase_units[0].shipping.address.admin_area_1;
-          document.getElementById("viewPostalCode").innerHTML = result.purchase_units[0].shipping.address.postal_code;
-          document.getElementById("viewTransactionID").textContent = result.id;
-          if (result.purchase_units[0].payments && result.purchase_units[0].payments.captures) {
-            document.getElementById("viewFinalAmount").textContent = result.purchase_units[0].payments.captures[0].amount.value;
-            document.getElementById("viewCurrency").textContent = result.purchase_units[0].payments.captures[0].amount.currency_code;
-          } else {
-            document.getElementById("viewFinalAmount").textContent = result.purchase_units[0].amount.value;
-            document.getElementById("viewCurrency").textContent = result.purchase_units[0].amount.currency_code;
-          }
-          document.getElementById("viewPaymentState").textContent = result.status;
-          if (result.intent) {
-            document.getElementById("viewTransactionType").textContent = result.intent;
-            document.getElementById("transactionType").style.display = "block";
-          } else {
-            document.getElementById("transactionType").style.display = "none";
-          }
-          hideDom("orderConfirm");
-          hideDom("loadingAlert");
-          showDom("orderView");
-        }
-      }
-      _out.push('<!-- jQuery (necessary for Bootstrap\'s JavaScript plugins) -->')
-      script(src="https://code.jquery.com/jquery.js") {}
-    }
-  }
-  env.site.serve(env, 200, Buffer.from(_out.join('')), 'success.html.jst')
-}