Use Stripe Address and email admin on membership creation
This commit is contained in:
parent
896bb5242a
commit
9287b4da1a
142
package-lock.json
generated
142
package-lock.json
generated
@ -29,6 +29,7 @@
|
|||||||
"feed": "^4.2.2",
|
"feed": "^4.2.2",
|
||||||
"next": "13.4.16",
|
"next": "13.4.16",
|
||||||
"next-themes": "^0.2.1",
|
"next-themes": "^0.2.1",
|
||||||
|
"postmark": "4.0.2",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
@ -1300,6 +1301,11 @@
|
|||||||
"astring": "bin/astring"
|
"astring": "bin/astring"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.14",
|
"version": "10.4.14",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
||||||
@ -1353,6 +1359,16 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.0",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/axobject-query": {
|
"node_modules/axobject-query": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
||||||
@ -2085,6 +2101,17 @@
|
|||||||
"simple-swizzle": "^0.2.2"
|
"simple-swizzle": "^0.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"dependencies": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/comma-separated-tokens": {
|
"node_modules/comma-separated-tokens": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
|
||||||
@ -2351,6 +2378,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dequal": {
|
"node_modules/dequal": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||||
@ -3446,6 +3481,25 @@
|
|||||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||||
|
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/for-each": {
|
"node_modules/for-each": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||||
@ -3455,6 +3509,19 @@
|
|||||||
"is-callable": "^1.1.3"
|
"is-callable": "^1.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/form-data": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fraction.js": {
|
"node_modules/fraction.js": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
||||||
@ -6706,7 +6773,6 @@
|
|||||||
"version": "1.52.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@ -6715,7 +6781,6 @@
|
|||||||
"version": "2.1.35",
|
"version": "2.1.35",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mime-db": "1.52.0"
|
"mime-db": "1.52.0"
|
||||||
},
|
},
|
||||||
@ -7721,6 +7786,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/postmark": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/postmark/-/postmark-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-2zlCv+KVVQ0KoamXZHE7d+gXzLlr8tPE+PxQmtUaIZhbHzZAq4D6yH2b+ykhA8wYCc5ISodcx8U1aNLenXBs9g==",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prebuild-install": {
|
"node_modules/prebuild-install": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
|
||||||
@ -7914,6 +7987,11 @@
|
|||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||||
|
},
|
||||||
"node_modules/pseudomap": {
|
"node_modules/pseudomap": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||||
@ -11351,6 +11429,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz",
|
"resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz",
|
||||||
"integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg=="
|
"integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg=="
|
||||||
},
|
},
|
||||||
|
"asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
|
},
|
||||||
"autoprefixer": {
|
"autoprefixer": {
|
||||||
"version": "10.4.14",
|
"version": "10.4.14",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
||||||
@ -11376,6 +11459,16 @@
|
|||||||
"integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==",
|
"integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"axios": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
|
||||||
|
"requires": {
|
||||||
|
"follow-redirects": "^1.15.0",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"axobject-query": {
|
"axobject-query": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
||||||
@ -11883,6 +11976,14 @@
|
|||||||
"simple-swizzle": "^0.2.2"
|
"simple-swizzle": "^0.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"requires": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"comma-separated-tokens": {
|
"comma-separated-tokens": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
|
||||||
@ -12067,6 +12168,11 @@
|
|||||||
"object-keys": "^1.1.1"
|
"object-keys": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||||
|
},
|
||||||
"dequal": {
|
"dequal": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||||
@ -12896,6 +13002,11 @@
|
|||||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"follow-redirects": {
|
||||||
|
"version": "1.15.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||||
|
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q=="
|
||||||
|
},
|
||||||
"for-each": {
|
"for-each": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||||
@ -12905,6 +13016,16 @@
|
|||||||
"is-callable": "^1.1.3"
|
"is-callable": "^1.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"form-data": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||||
|
"requires": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fraction.js": {
|
"fraction.js": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
||||||
@ -15147,14 +15268,12 @@
|
|||||||
"mime-db": {
|
"mime-db": {
|
||||||
"version": "1.52.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"mime-types": {
|
"mime-types": {
|
||||||
"version": "2.1.35",
|
"version": "2.1.35",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"mime-db": "1.52.0"
|
"mime-db": "1.52.0"
|
||||||
}
|
}
|
||||||
@ -15835,6 +15954,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||||
},
|
},
|
||||||
|
"postmark": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/postmark/-/postmark-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-2zlCv+KVVQ0KoamXZHE7d+gXzLlr8tPE+PxQmtUaIZhbHzZAq4D6yH2b+ykhA8wYCc5ISodcx8U1aNLenXBs9g==",
|
||||||
|
"requires": {
|
||||||
|
"axios": "^1.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"prebuild-install": {
|
"prebuild-install": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
|
||||||
@ -15934,6 +16061,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz",
|
||||||
"integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg=="
|
"integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg=="
|
||||||
},
|
},
|
||||||
|
"proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||||
|
},
|
||||||
"pseudomap": {
|
"pseudomap": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
"feed": "^4.2.2",
|
"feed": "^4.2.2",
|
||||||
"next": "13.4.16",
|
"next": "13.4.16",
|
||||||
"next-themes": "^0.2.1",
|
"next-themes": "^0.2.1",
|
||||||
|
"postmark": "4.0.2",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
|
@ -4,7 +4,7 @@ import Stripe from 'stripe';
|
|||||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '');
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '');
|
||||||
|
|
||||||
export async function POST(request: NextRequest): Promise<NextResponse> {
|
export async function POST(request: NextRequest): Promise<NextResponse> {
|
||||||
const { amount, payment_intent_id } = await request.json();
|
const { amount, payment_intent_id, metadata } = await request.json();
|
||||||
|
|
||||||
if (payment_intent_id) {
|
if (payment_intent_id) {
|
||||||
try {
|
try {
|
||||||
@ -18,6 +18,7 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
|
|||||||
payment_intent_id,
|
payment_intent_id,
|
||||||
{
|
{
|
||||||
amount: amount,
|
amount: amount,
|
||||||
|
metadata: metadata || {},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -38,13 +39,14 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Create PaymentIntent
|
// Create PaymentIntent
|
||||||
const params = {
|
const params: Stripe.PaymentIntentCreateParams = {
|
||||||
amount: amount,
|
amount: amount,
|
||||||
currency: 'usd',
|
currency: 'usd',
|
||||||
payment_method_types: ['card'],
|
payment_method_types: ['card'],
|
||||||
automatic_payment_methods: {
|
automatic_payment_methods: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
|
metadata: metadata || {},
|
||||||
};
|
};
|
||||||
const payment_intent = await stripe.paymentIntents.create(params);
|
const payment_intent = await stripe.paymentIntents.create(params);
|
||||||
//Return the payment_intent object
|
//Return the payment_intent object
|
||||||
|
29
src/app/api/stripe_webhook/route.ts
Normal file
29
src/app/api/stripe_webhook/route.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { emailNotification } from '@/lib/email';
|
||||||
|
import { NextRequest } from 'next/server';
|
||||||
|
|
||||||
|
export async function POST(request: NextRequest): Promise<Response> {
|
||||||
|
const body = await request.json();
|
||||||
|
|
||||||
|
if (body.type === 'charge.succeeded') {
|
||||||
|
const data = body.data.object;
|
||||||
|
const billing = data.billing_details;
|
||||||
|
const cityStateZip = `${billing.address.city}, ${billing.address.state} ${billing.address.postal_code}`;
|
||||||
|
const address = billing.address.line2
|
||||||
|
? `${billing.address.line1}\n${cityStateZip}`
|
||||||
|
: `${billing.address.line1}\n${billing.address.line2}\n${cityStateZip}`;
|
||||||
|
|
||||||
|
emailNotification({
|
||||||
|
name: billing.name,
|
||||||
|
type: data.metadata.type,
|
||||||
|
amount: data.amount,
|
||||||
|
email: billing.email,
|
||||||
|
phone: billing.phone,
|
||||||
|
address,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('Another type of event');
|
||||||
|
console.log(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(null, { status: 200 });
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import React, { useEffect, useState, FormEvent } from 'react';
|
import React, { useEffect, useState, FormEvent } from 'react';
|
||||||
import { Elements } from '@stripe/react-stripe-js';
|
import { AddressElement, Elements } from '@stripe/react-stripe-js';
|
||||||
import { Appearance, StripeElementsOptions, loadStripe } from '@stripe/stripe-js';
|
import { Appearance, StripeAddressElementOptions, StripeElementsOptions, loadStripe } from '@stripe/stripe-js';
|
||||||
import {
|
import {
|
||||||
PaymentElement,
|
PaymentElement,
|
||||||
useStripe,
|
useStripe,
|
||||||
@ -12,6 +12,25 @@ import { RadioGroup } from '@headlessui/react'
|
|||||||
|
|
||||||
const stripe = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || '');
|
const stripe = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || '');
|
||||||
|
|
||||||
|
const addressOptions: StripeAddressElementOptions = {
|
||||||
|
mode: 'billing',
|
||||||
|
allowedCountries: ['US'],
|
||||||
|
fields: {
|
||||||
|
phone: 'always',
|
||||||
|
},
|
||||||
|
validation: {
|
||||||
|
phone: {
|
||||||
|
required: 'always'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultValues: {
|
||||||
|
address: {
|
||||||
|
state: 'WA',
|
||||||
|
country: 'US',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const membershipLevels = [
|
const membershipLevels = [
|
||||||
{ id: 1, title: 'Individual', description: 'One vote', price: 20 },
|
{ id: 1, title: 'Individual', description: 'One vote', price: 20 },
|
||||||
{ id: 2, title: 'Household', description: 'Two votes', price: 30 },
|
{ id: 2, title: 'Household', description: 'Two votes', price: 30 },
|
||||||
@ -40,9 +59,7 @@ function CheckoutForm({
|
|||||||
const [selectedAdditionalDonation, setSelectedAdditionalDonation] = useState<number | null>(null);
|
const [selectedAdditionalDonation, setSelectedAdditionalDonation] = useState<number | null>(null);
|
||||||
const [customAmount, setCustomAmount] = useState('');
|
const [customAmount, setCustomAmount] = useState('');
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
const [phone, setPhone] = useState('');
|
const [offsetFees, setOffsetFees] = useState(true);
|
||||||
const [street, setStreet] = useState('');
|
|
||||||
const [zip, setZip] = useState('');
|
|
||||||
const [totalAmount, setTotalAmount] = useState(300);
|
const [totalAmount, setTotalAmount] = useState(300);
|
||||||
const [message, setMessage] = useState<string>('');
|
const [message, setMessage] = useState<string>('');
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
@ -94,6 +111,10 @@ function CheckoutForm({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (offsetFees) {
|
||||||
|
subtotal = Math.ceil(subtotal * 1.03)
|
||||||
|
}
|
||||||
|
|
||||||
setTotalAmount(subtotal);
|
setTotalAmount(subtotal);
|
||||||
|
|
||||||
fetch('api/stripe_intent', {
|
fetch('api/stripe_intent', {
|
||||||
@ -102,9 +123,12 @@ function CheckoutForm({
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
amount: subtotal * 100,
|
amount: subtotal * 100,
|
||||||
payment_intent_id: paymentIntentID,
|
payment_intent_id: paymentIntentID,
|
||||||
|
metadata: {
|
||||||
|
'type': selectedMembershipLevel.title,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}, [paymentIntentID, selectedMembershipLevel, selectedAdditionalDonation, customAmount])
|
}, [paymentIntentID, selectedMembershipLevel, selectedAdditionalDonation, customAmount, offsetFees, email])
|
||||||
|
|
||||||
const handleSubmit = async (e: FormEvent) => {
|
const handleSubmit = async (e: FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -123,7 +147,8 @@ function CheckoutForm({
|
|||||||
receipt_email: email,
|
receipt_email: email,
|
||||||
payment_method_data: {
|
payment_method_data: {
|
||||||
billing_details: {
|
billing_details: {
|
||||||
name: 'Billing user',
|
// Other details are filled automatically by address form.
|
||||||
|
email,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -270,54 +295,7 @@ function CheckoutForm({
|
|||||||
placeholder="you@example.com"
|
placeholder="you@example.com"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="rounded-md mb-3 px-3 pb-1.5 pt-2.5 shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-indigo-600">
|
<AddressElement options={addressOptions} />
|
||||||
<label htmlFor="name" className="block text-xs font-medium text-gray-900">
|
|
||||||
Phone
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="tel"
|
|
||||||
name="phone"
|
|
||||||
id="phone"
|
|
||||||
value={phone}
|
|
||||||
onChange={(e) => setPhone(e.target.value)}
|
|
||||||
className="block w-full border-0 p-0 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
|
|
||||||
placeholder="360-376-XXXX"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<fieldset>
|
|
||||||
<div className="mb-3 -space-y-px rounded-md bg-white shadow-sm">
|
|
||||||
<div className="flex -space-x-px">
|
|
||||||
<div className="w-2/3 min-w-0 flex-1">
|
|
||||||
<label htmlFor="street-address" className="sr-only">
|
|
||||||
Street Address
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
name="street-address"
|
|
||||||
id="street-address"
|
|
||||||
value={street}
|
|
||||||
onChange={(e) => setStreet(e.target.value)}
|
|
||||||
className="relative block w-full rounded-none rounded-l-md border-0 bg-transparent py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
|
||||||
placeholder="Street"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="min-w-0 flex-1">
|
|
||||||
<label htmlFor="zipcode" className="sr-only">
|
|
||||||
Zipcode
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
name="zipcode"
|
|
||||||
id="zipcode"
|
|
||||||
value={zip}
|
|
||||||
onChange={(e) => setZip(e.target.value)}
|
|
||||||
className="relative block w-full rounded-none rounded-r-md border-0 bg-transparent py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
|
||||||
placeholder="98XXX"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
@ -334,6 +312,24 @@ function CheckoutForm({
|
|||||||
|
|
||||||
{/* TODO: Automatically renew toggle? */}
|
{/* TODO: Automatically renew toggle? */}
|
||||||
|
|
||||||
|
<div className="relative flex gap-x-3">
|
||||||
|
<div className="flex h-6 items-center">
|
||||||
|
<input
|
||||||
|
id="offsetFees"
|
||||||
|
name="offsetFees"
|
||||||
|
type="checkbox"
|
||||||
|
checked={offsetFees}
|
||||||
|
onChange={(e) => setOffsetFees(e.target.checked)}
|
||||||
|
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm leading-6">
|
||||||
|
<label htmlFor="offsetFees" className="font-medium text-gray-900">
|
||||||
|
Help offset credit card fees
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="mt-6 w-full rounded-md flex justify-center border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
className="mt-6 w-full rounded-md flex justify-center border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||||
disabled={isLoading || !stripe || !elements}
|
disabled={isLoading || !stripe || !elements}
|
||||||
@ -347,7 +343,7 @@ function CheckoutForm({
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Show any error or success messages */}
|
{/* Show any error or success messages */}
|
||||||
{message && <div id="payment-message">{message}</div>}
|
{message && <div className="text-red-500" id="payment-message">{message}</div>}
|
||||||
</form>
|
</form>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -362,7 +358,7 @@ export function ClubPayment() {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
amount: 30000,
|
amount: 2000,
|
||||||
payment_intent_id: '',
|
payment_intent_id: '',
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
@ -7,7 +7,17 @@ export const metadata: Metadata = {
|
|||||||
description: 'Thanks for becoming a member.',
|
description: 'Thanks for becoming a member.',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ThankYou() {
|
export default async function ThankYou({
|
||||||
|
searchParams
|
||||||
|
}: {
|
||||||
|
searchParams: { [key: string]: string | string[] | undefined }
|
||||||
|
}) {
|
||||||
|
|
||||||
|
const { redirect_status } = searchParams;
|
||||||
|
if (redirect_status !== 'succeeded') {
|
||||||
|
// TODO: Display error
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SimpleLayout
|
<SimpleLayout
|
||||||
title="Thanks for becoming a member."
|
title="Thanks for becoming a member."
|
||||||
|
38
src/lib/email.ts
Normal file
38
src/lib/email.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { ServerClient } from 'postmark';
|
||||||
|
|
||||||
|
const fromAddr = process.env.FROM_ADDRESS || '';
|
||||||
|
const toAddr = process.env.ADMIN_ADDRESS || '';
|
||||||
|
const serverToken = process.env.POSTMARK_SERVER_TOKEN || '';
|
||||||
|
const client = new ServerClient(serverToken);
|
||||||
|
|
||||||
|
export function emailNotification({
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
amount,
|
||||||
|
email,
|
||||||
|
phone,
|
||||||
|
address,
|
||||||
|
}: {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
amount: number;
|
||||||
|
email: string;
|
||||||
|
phone: string;
|
||||||
|
address: string;
|
||||||
|
}) {
|
||||||
|
client.sendEmail({
|
||||||
|
From: fromAddr,
|
||||||
|
To: toAddr,
|
||||||
|
Subject: 'New WSCC Membership',
|
||||||
|
TextBody: [
|
||||||
|
'New WSCC member:',
|
||||||
|
'',
|
||||||
|
'Name: ' + name,
|
||||||
|
'Type: ' + type,
|
||||||
|
'Amount: ' + amount,
|
||||||
|
'Email: ' + email,
|
||||||
|
'Phone: ' + phone,
|
||||||
|
'Address: ' + address,
|
||||||
|
].join('\n'),
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user