Change paypal example to stripe
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:21:40 +0000 (17:21 +1100)
25 files changed:
_config/config.json [deleted file]
_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/PayPalCheckoutServerSideV2_nodejs.zip [deleted file]
_orig/stripe-sample-code.zip [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]
cancel.html.jst [new file with mode: 0644]
checkout.html.jst [new file with mode: 0644]
create-checkout-session.html.jst [new file with mode: 0644]
img/camera.jpg [deleted file]
index.html.jst [deleted file]
js/config.js [deleted file]
package.json
pages/shipping.html.jst [deleted file]
pages/success.html.jst [deleted file]
style.css [new file with mode: 0644]
success.html.jst [new file with mode: 0644]

diff --git a/_config/config.json b/_config/config.json
deleted file mode 100644 (file)
index 4d54786..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "environment": "sandbox",
-    "sandbox_client_id": "Aa2IfcoEvHnfJRnVQLSFrSs3SmTTkv5N1weMEL66ysqYIeHfAqXpDVkjOv3vLhkhbP4eKB6MpRlQIcJw",
-    "sandbox_secret": "EF6l6PDQJEZbdKTeg35pbBSft6WRdALQC3Xrl5vvG0VNgBUehQyTCQ09QdIauxoccvJOf5Aoy-OGsH5G",
-    "production_client_id": "",
-    "production_secret": ""
-}
\ No newline at end of file
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/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/stripe-sample-code.zip b/_orig/stripe-sample-code.zip
new file mode 100644 (file)
index 0000000..f92d8b4
Binary files /dev/null and b/_orig/stripe-sample-code.zip differ
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/cancel.html.jst b/cancel.html.jst
new file mode 100644 (file)
index 0000000..49d7868
--- /dev/null
@@ -0,0 +1,20 @@
+return async env => {
+  let _out = []
+  _out.push('<!DOCTYPE html>')
+  html {
+    head {
+      title {
+        'Checkout canceled'
+      }
+      link(rel="stylesheet" href="style.css") {}
+    }
+    body {
+      section {
+        p {
+          'Forgot to add something to your cart? Shop around then come back to pay!'
+        }
+      }
+    }
+  }
+  env.site.serve(env, 200, Buffer.from(_out.join('')), 'cancel.html.jst')
+}
diff --git a/checkout.html.jst b/checkout.html.jst
new file mode 100644 (file)
index 0000000..3561304
--- /dev/null
@@ -0,0 +1,35 @@
+return async env => {
+  let _out = []
+  _out.push('<!DOCTYPE html>')
+  html {
+    head {
+      title {
+        'Buy cool new product'
+      }
+      link(rel="stylesheet" href="style.css") {}
+      script(src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch") {}
+      script(src="https://js.stripe.com/v3/") {}
+    }
+    body {
+      section {
+        div.product {
+          img(src="https://i.imgur.com/EHyR2nP.png" alt="The cover of Stubborn Attachments") {}
+          div.description {
+            h3 {
+              'Stubborn Attachments'
+            }
+            h5 {
+              '$20.00'
+            }
+          }
+        }
+        form(action="/create-checkout-session.html" method="POST") {
+          button#checkout-button(type="submit") {
+            'Checkout'
+          }
+        }
+      }
+    }
+  }
+  env.site.serve(env, 200, Buffer.from(_out.join('')), 'checkout.html.jst')
+}
diff --git a/create-checkout-session.html.jst b/create-checkout-session.html.jst
new file mode 100644 (file)
index 0000000..73386ef
--- /dev/null
@@ -0,0 +1,26 @@
+// This is a public sample test API key.
+// To avoid exposing it, don't submit any personally identifiable information through requests with this API key.
+// Sign in to see your own test API key embedded in code samples.
+const stripe = require('stripe')('sk_test_wsFx86XDJWwmE4dMskBgJYrt')
+
+const YOUR_DOMAIN = 'http://localhost:8080'
+
+return async env => {
+  const session = await stripe.checkout.sessions.create(
+    {
+      line_items: [
+        {
+          // Provide the exact Price ID (for example, pr_1234) of the product you want to sell
+          price: '{{PRICE_ID}}',
+          quantity: 1,
+        },
+      ],
+      mode: 'payment',
+      success_url: `${YOUR_DOMAIN}/success.html`,
+      cancel_url: `${YOUR_DOMAIN}/cancel.html`,
+    }
+  )
+
+  env.response.setHeader('Location', session.url)
+  env.site.serve(env, 303, Buffer.alloc(0), 'create-checkout-session.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
diff --git a/index.html.jst b/index.html.jst
deleted file mode 100644 (file)
index ab4e035..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-return async env => {
-  _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-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'
-            }
-            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.col-sm-4 {
-            hr.m-5 {}
-            h3.text-center {
-              'Readme'
-            }
-            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.'
-              }
-            }
-            hr {}
-            h3.text-center {
-              'In-Context Checkout integration steps with PayPal JavaScript SDK'
-            }
-            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.'
-              }
-            }
-          }
-        }
-      }
-      _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
index 9a95157..cdd9f13 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",
+    "stripe": "^7.1.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')
-}
diff --git a/style.css b/style.css
new file mode 100644 (file)
index 0000000..ad9899f
--- /dev/null
+++ b/style.css
@@ -0,0 +1,80 @@
+body {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: #242d60;
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto',
+  'Helvetica Neue', 'Ubuntu', sans-serif;
+  height: 100vh;
+  margin: 0;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+section {
+  background: #ffffff;
+  display: flex;
+  flex-direction: column;
+  width: 400px;
+  height: 112px;
+  border-radius: 6px;
+  justify-content: space-between;
+}
+.product {
+  display: flex;
+}
+.description {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+p {
+  font-style: normal;
+  font-weight: 500;
+  font-size: 14px;
+  line-height: 20px;
+  letter-spacing: -0.154px;
+  color: #242d60;
+  height: 100%;
+  width: 100%;
+  padding: 0 20px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-sizing: border-box;
+}
+img {
+  border-radius: 6px;
+  margin: 10px;
+  width: 54px;
+  height: 57px;
+}
+h3,
+h5 {
+  font-style: normal;
+  font-weight: 500;
+  font-size: 14px;
+  line-height: 20px;
+  letter-spacing: -0.154px;
+  color: #242d60;
+  margin: 0;
+}
+h5 {
+  opacity: 0.5;
+}
+button {
+  height: 36px;
+  background: #556cd6;
+  color: white;
+  width: 100%;
+  font-size: 14px;
+  border: 0;
+  font-weight: 500;
+  cursor: pointer;
+  letter-spacing: 0.6;
+  border-radius: 0 0 6px 6px;
+  transition: all 0.2s ease;
+  box-shadow: 0px 4px 5.5px 0px rgba(0, 0, 0, 0.07);
+}
+button:hover {
+  opacity: 0.8;
+}
\ No newline at end of file
diff --git a/success.html.jst b/success.html.jst
new file mode 100644 (file)
index 0000000..9c6afe3
--- /dev/null
@@ -0,0 +1,24 @@
+return async env => {
+  let _out = []
+  _out.push('<!DOCTYPE html>')
+  html {
+    head {
+      title {
+        'Thanks for your order!'
+      }
+      link(rel="stylesheet" href="style.css") {}
+    }
+    body {
+      section {
+        p {
+          'We appreciate your business! If you have any questions, please email '
+          a(href="mailto:orders@example.com") {
+            'orders@example.com'
+          }
+          '.'
+        }
+      }
+    }
+  }
+  env.site.serve(env, 200, Buffer.from(_out.join('')), 'success.html.jst')
+}