@vandenberghinc/volt 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vrepo +28 -0
- package/.vscode/tasks.json +87 -0
- package/README.md +67 -0
- package/backend/dist/cjs/blacklist.d.ts +10 -0
- package/backend/dist/cjs/blacklist.js +53 -0
- package/backend/dist/cjs/cli.d.ts +2 -0
- package/backend/dist/cjs/cli.js +263 -0
- package/backend/dist/cjs/database.d.ts +364 -0
- package/backend/dist/cjs/database.js +1962 -0
- package/backend/dist/cjs/endpoint.d.ts +57 -0
- package/backend/dist/cjs/endpoint.js +425 -0
- package/backend/dist/cjs/file_watcher.d.ts +44 -0
- package/backend/dist/cjs/file_watcher.js +348 -0
- package/backend/dist/cjs/frontend.d.ts +13 -0
- package/backend/dist/cjs/frontend.js +30 -0
- package/backend/dist/cjs/image_endpoint.d.ts +24 -0
- package/backend/dist/cjs/image_endpoint.js +210 -0
- package/backend/dist/cjs/logger.d.ts +5 -0
- package/backend/dist/cjs/logger.js +16 -0
- package/backend/dist/cjs/meta.d.ts +50 -0
- package/backend/dist/cjs/meta.js +153 -0
- package/backend/dist/cjs/mutex.d.ts +24 -0
- package/backend/dist/cjs/mutex.js +52 -0
- package/backend/dist/cjs/package.json +1 -0
- package/backend/dist/cjs/payments/paddle.d.ts +161 -0
- package/backend/dist/cjs/payments/paddle.js +2301 -0
- package/backend/dist/cjs/plugins/browser.d.ts +36 -0
- package/backend/dist/cjs/plugins/browser.js +183 -0
- package/backend/dist/cjs/plugins/communication.d.ts +70 -0
- package/backend/dist/cjs/plugins/communication.js +177 -0
- package/backend/dist/cjs/plugins/css.d.ts +10 -0
- package/backend/dist/cjs/plugins/css.js +71 -0
- package/backend/dist/cjs/plugins/mail.d.ts +277 -0
- package/backend/dist/cjs/plugins/mail.js +1419 -0
- package/backend/dist/cjs/plugins/pdf.d.ts +757 -0
- package/backend/dist/cjs/plugins/pdf.js +1694 -0
- package/backend/dist/cjs/plugins/thread_monitor.d.ts +18 -0
- package/backend/dist/cjs/plugins/thread_monitor.js +127 -0
- package/backend/dist/cjs/plugins/ts/compiler.d.ts +132 -0
- package/backend/dist/cjs/plugins/ts/compiler.js +944 -0
- package/backend/dist/cjs/plugins/ts/preprocessing.d.ts +14 -0
- package/backend/dist/cjs/plugins/ts/preprocessing.js +762 -0
- package/backend/dist/cjs/rate_limit.d.ts +65 -0
- package/backend/dist/cjs/rate_limit.js +463 -0
- package/backend/dist/cjs/request.deprc.d.ts +48 -0
- package/backend/dist/cjs/request.deprc.js +572 -0
- package/backend/dist/cjs/response.deprc.d.ts +55 -0
- package/backend/dist/cjs/response.deprc.js +275 -0
- package/backend/dist/cjs/server.d.ts +311 -0
- package/backend/dist/cjs/server.js +3475 -0
- package/backend/dist/cjs/splash_screen.d.ts +35 -0
- package/backend/dist/cjs/splash_screen.js +152 -0
- package/backend/dist/cjs/status.d.ts +60 -0
- package/backend/dist/cjs/status.js +199 -0
- package/backend/dist/cjs/stream.d.ts +75 -0
- package/backend/dist/cjs/stream.js +954 -0
- package/backend/dist/cjs/users.d.ts +111 -0
- package/backend/dist/cjs/users.js +1945 -0
- package/backend/dist/cjs/utils.d.ts +27 -0
- package/backend/dist/cjs/utils.js +329 -0
- package/backend/dist/cjs/view.d.ts +52 -0
- package/backend/dist/cjs/view.js +568 -0
- package/backend/dist/cjs/vinc.d.ts +2 -0
- package/backend/dist/cjs/vinc.dev.d.ts +2 -0
- package/backend/dist/cjs/vinc.dev.js +42 -0
- package/backend/dist/cjs/vinc.js +42 -0
- package/backend/dist/cjs/volt.d.ts +15 -0
- package/backend/dist/cjs/volt.js +64 -0
- package/backend/dist/css/adyen.css +92 -0
- package/backend/dist/css/volt.css +65 -0
- package/backend/dist/esm/blacklist.d.ts +10 -0
- package/backend/dist/esm/blacklist.js +49 -0
- package/backend/dist/esm/cli.d.ts +2 -0
- package/backend/dist/esm/cli.js +228 -0
- package/backend/dist/esm/database.d.ts +364 -0
- package/backend/dist/esm/database.js +1957 -0
- package/backend/dist/esm/endpoint.d.ts +57 -0
- package/backend/dist/esm/endpoint.js +421 -0
- package/backend/dist/esm/file_watcher.d.ts +44 -0
- package/backend/dist/esm/file_watcher.js +313 -0
- package/backend/dist/esm/frontend.d.ts +13 -0
- package/backend/dist/esm/frontend.js +27 -0
- package/backend/dist/esm/image_endpoint.d.ts +24 -0
- package/backend/dist/esm/image_endpoint.js +206 -0
- package/backend/dist/esm/logger.d.ts +5 -0
- package/backend/dist/esm/logger.js +13 -0
- package/backend/dist/esm/meta.d.ts +50 -0
- package/backend/dist/esm/meta.js +149 -0
- package/backend/dist/esm/mutex.d.ts +24 -0
- package/backend/dist/esm/mutex.js +48 -0
- package/backend/dist/esm/payments/paddle.d.ts +161 -0
- package/backend/dist/esm/payments/paddle.js +2261 -0
- package/backend/dist/esm/plugins/browser.d.ts +36 -0
- package/backend/dist/esm/plugins/browser.js +176 -0
- package/backend/dist/esm/plugins/communication.d.ts +70 -0
- package/backend/dist/esm/plugins/communication.js +169 -0
- package/backend/dist/esm/plugins/css.d.ts +10 -0
- package/backend/dist/esm/plugins/css.js +64 -0
- package/backend/dist/esm/plugins/mail.d.ts +277 -0
- package/backend/dist/esm/plugins/mail.js +1403 -0
- package/backend/dist/esm/plugins/pdf.d.ts +757 -0
- package/backend/dist/esm/plugins/pdf.js +1694 -0
- package/backend/dist/esm/plugins/thread_monitor.d.ts +18 -0
- package/backend/dist/esm/plugins/thread_monitor.js +120 -0
- package/backend/dist/esm/plugins/ts/compiler.d.ts +132 -0
- package/backend/dist/esm/plugins/ts/compiler.js +907 -0
- package/backend/dist/esm/plugins/ts/preprocessing.d.ts +14 -0
- package/backend/dist/esm/plugins/ts/preprocessing.js +724 -0
- package/backend/dist/esm/rate_limit.d.ts +65 -0
- package/backend/dist/esm/rate_limit.js +425 -0
- package/backend/dist/esm/request.deprc.d.ts +48 -0
- package/backend/dist/esm/request.deprc.js +572 -0
- package/backend/dist/esm/response.deprc.d.ts +55 -0
- package/backend/dist/esm/response.deprc.js +275 -0
- package/backend/dist/esm/server.d.ts +311 -0
- package/backend/dist/esm/server.js +3435 -0
- package/backend/dist/esm/splash_screen.d.ts +35 -0
- package/backend/dist/esm/splash_screen.js +148 -0
- package/backend/dist/esm/status.d.ts +60 -0
- package/backend/dist/esm/status.js +196 -0
- package/backend/dist/esm/stream.d.ts +75 -0
- package/backend/dist/esm/stream.js +947 -0
- package/backend/dist/esm/users.d.ts +111 -0
- package/backend/dist/esm/users.js +1908 -0
- package/backend/dist/esm/utils.d.ts +27 -0
- package/backend/dist/esm/utils.js +324 -0
- package/backend/dist/esm/view.d.ts +52 -0
- package/backend/dist/esm/view.js +561 -0
- package/backend/dist/esm/vinc.d.ts +2 -0
- package/backend/dist/esm/vinc.dev.d.ts +2 -0
- package/backend/dist/esm/vinc.dev.js +6 -0
- package/backend/dist/esm/vinc.js +6 -0
- package/backend/dist/esm/volt.d.ts +15 -0
- package/backend/dist/esm/volt.js +23 -0
- package/backend/dist/esm-dev/blacklist.d.ts +10 -0
- package/backend/dist/esm-dev/blacklist.js +49 -0
- package/backend/dist/esm-dev/cli.d.ts +2 -0
- package/backend/dist/esm-dev/cli.js +228 -0
- package/backend/dist/esm-dev/database.d.ts +364 -0
- package/backend/dist/esm-dev/database.js +1957 -0
- package/backend/dist/esm-dev/endpoint.d.ts +57 -0
- package/backend/dist/esm-dev/endpoint.js +421 -0
- package/backend/dist/esm-dev/file_watcher.d.ts +44 -0
- package/backend/dist/esm-dev/file_watcher.js +313 -0
- package/backend/dist/esm-dev/frontend.d.ts +13 -0
- package/backend/dist/esm-dev/frontend.js +27 -0
- package/backend/dist/esm-dev/image_endpoint.d.ts +24 -0
- package/backend/dist/esm-dev/image_endpoint.js +206 -0
- package/backend/dist/esm-dev/logger.d.ts +5 -0
- package/backend/dist/esm-dev/logger.js +13 -0
- package/backend/dist/esm-dev/meta.d.ts +50 -0
- package/backend/dist/esm-dev/meta.js +149 -0
- package/backend/dist/esm-dev/mutex.d.ts +24 -0
- package/backend/dist/esm-dev/mutex.js +48 -0
- package/backend/dist/esm-dev/payments/paddle.d.ts +161 -0
- package/backend/dist/esm-dev/payments/paddle.js +2261 -0
- package/backend/dist/esm-dev/plugins/browser.d.ts +36 -0
- package/backend/dist/esm-dev/plugins/browser.js +176 -0
- package/backend/dist/esm-dev/plugins/communication.d.ts +70 -0
- package/backend/dist/esm-dev/plugins/communication.js +169 -0
- package/backend/dist/esm-dev/plugins/css.d.ts +10 -0
- package/backend/dist/esm-dev/plugins/css.js +64 -0
- package/backend/dist/esm-dev/plugins/mail.d.ts +277 -0
- package/backend/dist/esm-dev/plugins/mail.js +1403 -0
- package/backend/dist/esm-dev/plugins/pdf.d.ts +757 -0
- package/backend/dist/esm-dev/plugins/pdf.js +1694 -0
- package/backend/dist/esm-dev/plugins/thread_monitor.d.ts +18 -0
- package/backend/dist/esm-dev/plugins/thread_monitor.js +120 -0
- package/backend/dist/esm-dev/plugins/ts/compiler.d.ts +132 -0
- package/backend/dist/esm-dev/plugins/ts/compiler.js +907 -0
- package/backend/dist/esm-dev/plugins/ts/preprocessing.d.ts +14 -0
- package/backend/dist/esm-dev/plugins/ts/preprocessing.js +724 -0
- package/backend/dist/esm-dev/rate_limit.d.ts +65 -0
- package/backend/dist/esm-dev/rate_limit.js +425 -0
- package/backend/dist/esm-dev/request.deprc.d.ts +48 -0
- package/backend/dist/esm-dev/request.deprc.js +572 -0
- package/backend/dist/esm-dev/response.deprc.d.ts +55 -0
- package/backend/dist/esm-dev/response.deprc.js +275 -0
- package/backend/dist/esm-dev/server.d.ts +311 -0
- package/backend/dist/esm-dev/server.js +3435 -0
- package/backend/dist/esm-dev/splash_screen.d.ts +35 -0
- package/backend/dist/esm-dev/splash_screen.js +148 -0
- package/backend/dist/esm-dev/status.d.ts +60 -0
- package/backend/dist/esm-dev/status.js +196 -0
- package/backend/dist/esm-dev/stream.d.ts +75 -0
- package/backend/dist/esm-dev/stream.js +947 -0
- package/backend/dist/esm-dev/users.d.ts +111 -0
- package/backend/dist/esm-dev/users.js +1908 -0
- package/backend/dist/esm-dev/utils.d.ts +27 -0
- package/backend/dist/esm-dev/utils.js +324 -0
- package/backend/dist/esm-dev/view.d.ts +52 -0
- package/backend/dist/esm-dev/view.js +561 -0
- package/backend/dist/esm-dev/vinc.d.ts +2 -0
- package/backend/dist/esm-dev/vinc.dev.d.ts +2 -0
- package/backend/dist/esm-dev/vinc.dev.js +6 -0
- package/backend/dist/esm-dev/vinc.js +6 -0
- package/backend/dist/esm-dev/volt.d.ts +15 -0
- package/backend/dist/esm-dev/volt.js +23 -0
- package/backend/src/blacklist.ts +69 -0
- package/backend/src/cli.js +245 -0
- package/backend/src/database.ts +2241 -0
- package/backend/src/endpoint.ts +494 -0
- package/backend/src/file_watcher.ts +359 -0
- package/backend/src/frontend.ts +35 -0
- package/backend/src/globals.d.ts +8 -0
- package/backend/src/image_endpoint.ts +258 -0
- package/backend/src/logger.ts +18 -0
- package/backend/src/meta.ts +202 -0
- package/backend/src/mutex.ts +51 -0
- package/backend/src/payments/paddle.ts +2659 -0
- package/backend/src/plugins/browser.ts +188 -0
- package/backend/src/plugins/communication.ts +204 -0
- package/backend/src/plugins/css.ts +84 -0
- package/backend/src/plugins/fonts/Menlo-Bold.ttf +0 -0
- package/backend/src/plugins/fonts/Menlo-Regular.ttf +0 -0
- package/backend/src/plugins/mail.ts +1720 -0
- package/backend/src/plugins/pdf.js +1932 -0
- package/backend/src/plugins/thread_monitor.ts +164 -0
- package/backend/src/plugins/ts/compiler.ts +1242 -0
- package/backend/src/plugins/ts/preprocessing.ts +812 -0
- package/backend/src/rate_limit.ts +503 -0
- package/backend/src/request.deprc.js +626 -0
- package/backend/src/response.deprc.js +354 -0
- package/backend/src/server.ts +4149 -0
- package/backend/src/splash_screen.ts +192 -0
- package/backend/src/status.ts +199 -0
- package/backend/src/stream.ts +1070 -0
- package/backend/src/users.ts +2077 -0
- package/backend/src/utils.ts +359 -0
- package/backend/src/view.ts +655 -0
- package/backend/src/vinc.dev.js +6 -0
- package/backend/src/vinc.ts +6 -0
- package/backend/src/volt.js +25 -0
- package/backend/tsconfig.cjs.json +29 -0
- package/backend/tsconfig.esm.dev.json +34 -0
- package/backend/tsconfig.esm.json +30 -0
- package/backend/tsconfig.json +2 -0
- package/frontend/compile.js +436 -0
- package/frontend/dist/elements/base.d.ts +9891 -0
- package/frontend/dist/elements/base.js +8818 -0
- package/frontend/dist/elements/module.d.ts +16 -0
- package/frontend/dist/elements/module.js +178 -0
- package/frontend/dist/modules/array.d.ts +37 -0
- package/frontend/dist/modules/array.js +284 -0
- package/frontend/dist/modules/auth.d.ts +45 -0
- package/frontend/dist/modules/auth.js +138 -0
- package/frontend/dist/modules/colors.d.ts +26 -0
- package/frontend/dist/modules/colors.js +340 -0
- package/frontend/dist/modules/compression.d.ts +6 -0
- package/frontend/dist/modules/compression.js +999 -0
- package/frontend/dist/modules/cookies.d.ts +17 -0
- package/frontend/dist/modules/cookies.js +166 -0
- package/frontend/dist/modules/date.d.ts +142 -0
- package/frontend/dist/modules/date.js +493 -0
- package/frontend/dist/modules/events.d.ts +7 -0
- package/frontend/dist/modules/events.js +90 -0
- package/frontend/dist/modules/google.d.ts +10 -0
- package/frontend/dist/modules/google.js +53 -0
- package/frontend/dist/modules/meta.d.ts +9 -0
- package/frontend/dist/modules/meta.js +45 -0
- package/frontend/dist/modules/mutex.d.ts +8 -0
- package/frontend/dist/modules/mutex.js +52 -0
- package/frontend/dist/modules/number.d.ts +12 -0
- package/frontend/dist/modules/number.js +8 -0
- package/frontend/dist/modules/object.d.ts +50 -0
- package/frontend/dist/modules/object.js +147 -0
- package/frontend/dist/modules/paddle.d.ts +1403 -0
- package/frontend/dist/modules/paddle.js +2641 -0
- package/frontend/dist/modules/scheme.d.ts +207 -0
- package/frontend/dist/modules/scheme.js +649 -0
- package/frontend/dist/modules/settings.d.ts +3 -0
- package/frontend/dist/modules/settings.js +4 -0
- package/frontend/dist/modules/statics.d.ts +4 -0
- package/frontend/dist/modules/statics.js +45 -0
- package/frontend/dist/modules/string.d.ts +163 -0
- package/frontend/dist/modules/string.js +291 -0
- package/frontend/dist/modules/support.d.ts +18 -0
- package/frontend/dist/modules/support.js +102 -0
- package/frontend/dist/modules/themes.d.ts +8 -0
- package/frontend/dist/modules/themes.js +17 -0
- package/frontend/dist/modules/user.d.ts +58 -0
- package/frontend/dist/modules/user.js +279 -0
- package/frontend/dist/modules/utils.d.ts +58 -0
- package/frontend/dist/modules/utils.js +1159 -0
- package/frontend/dist/types/gradient.d.ts +12 -0
- package/frontend/dist/types/gradient.js +79 -0
- package/frontend/dist/ui/border_button.d.ts +177 -0
- package/frontend/dist/ui/border_button.js +235 -0
- package/frontend/dist/ui/button.d.ts +42 -0
- package/frontend/dist/ui/button.js +114 -0
- package/frontend/dist/ui/canvas.d.ts +56 -0
- package/frontend/dist/ui/canvas.js +411 -0
- package/frontend/dist/ui/checkbox.d.ts +72 -0
- package/frontend/dist/ui/checkbox.js +277 -0
- package/frontend/dist/ui/code.d.ts +232 -0
- package/frontend/dist/ui/code.js +977 -0
- package/frontend/dist/ui/color.d.ts +1 -0
- package/frontend/dist/ui/color.js +110 -0
- package/frontend/dist/ui/context_menu.d.ts +30 -0
- package/frontend/dist/ui/context_menu.js +211 -0
- package/frontend/dist/ui/css.d.ts +10 -0
- package/frontend/dist/ui/css.js +44 -0
- package/frontend/dist/ui/divider.d.ts +18 -0
- package/frontend/dist/ui/divider.js +82 -0
- package/frontend/dist/ui/dropdown.d.ts +115 -0
- package/frontend/dist/ui/dropdown.js +446 -0
- package/frontend/dist/ui/for_each.d.ts +38 -0
- package/frontend/dist/ui/for_each.js +97 -0
- package/frontend/dist/ui/form.d.ts +25 -0
- package/frontend/dist/ui/form.js +227 -0
- package/frontend/dist/ui/frame_modes.d.ts +28 -0
- package/frontend/dist/ui/frame_modes.js +116 -0
- package/frontend/dist/ui/google_map.d.ts +31 -0
- package/frontend/dist/ui/google_map.js +111 -0
- package/frontend/dist/ui/gradient.d.ts +24 -0
- package/frontend/dist/ui/gradient.js +115 -0
- package/frontend/dist/ui/image.d.ts +138 -0
- package/frontend/dist/ui/image.js +570 -0
- package/frontend/dist/ui/input.d.ts +316 -0
- package/frontend/dist/ui/input.js +1187 -0
- package/frontend/dist/ui/link.d.ts +39 -0
- package/frontend/dist/ui/link.js +146 -0
- package/frontend/dist/ui/list.d.ts +33 -0
- package/frontend/dist/ui/list.js +161 -0
- package/frontend/dist/ui/loader_button.d.ts +108 -0
- package/frontend/dist/ui/loader_button.js +207 -0
- package/frontend/dist/ui/loaders.d.ts +60 -0
- package/frontend/dist/ui/loaders.js +150 -0
- package/frontend/dist/ui/popup.d.ts +84 -0
- package/frontend/dist/ui/popup.js +331 -0
- package/frontend/dist/ui/pseudo.d.ts +16 -0
- package/frontend/dist/ui/pseudo.js +81 -0
- package/frontend/dist/ui/scroller.d.ts +131 -0
- package/frontend/dist/ui/scroller.js +1251 -0
- package/frontend/dist/ui/slider.d.ts +35 -0
- package/frontend/dist/ui/slider.js +203 -0
- package/frontend/dist/ui/spacer.d.ts +20 -0
- package/frontend/dist/ui/spacer.js +83 -0
- package/frontend/dist/ui/span.d.ts +11 -0
- package/frontend/dist/ui/span.js +75 -0
- package/frontend/dist/ui/stack.d.ts +123 -0
- package/frontend/dist/ui/stack.js +344 -0
- package/frontend/dist/ui/steps.d.ts +72 -0
- package/frontend/dist/ui/steps.js +306 -0
- package/frontend/dist/ui/style.d.ts +12 -0
- package/frontend/dist/ui/style.js +78 -0
- package/frontend/dist/ui/switch.d.ts +44 -0
- package/frontend/dist/ui/switch.js +280 -0
- package/frontend/dist/ui/table.d.ts +118 -0
- package/frontend/dist/ui/table.js +411 -0
- package/frontend/dist/ui/tabs.d.ts +85 -0
- package/frontend/dist/ui/tabs.js +392 -0
- package/frontend/dist/ui/text.d.ts +19 -0
- package/frontend/dist/ui/text.js +88 -0
- package/frontend/dist/ui/theme.d.ts +25 -0
- package/frontend/dist/ui/theme.js +237 -0
- package/frontend/dist/ui/title.d.ts +36 -0
- package/frontend/dist/ui/title.js +127 -0
- package/frontend/dist/ui/ui.d.ts +38 -0
- package/frontend/dist/ui/ui.js +41 -0
- package/frontend/dist/ui/view.d.ts +25 -0
- package/frontend/dist/ui/view.js +93 -0
- package/frontend/dist/volt.d.ts +22 -0
- package/frontend/dist/volt.js +27 -0
- package/frontend/exports.json +1340 -0
- package/frontend/src/css/adyen.css +92 -0
- package/frontend/src/css/volt.css +65 -0
- package/frontend/src/elements/base.ts +16790 -0
- package/frontend/src/elements/module.ts +184 -0
- package/frontend/src/elements/types.d.ts +155 -0
- package/frontend/src/modules/array.ts +366 -0
- package/frontend/src/modules/auth.ts +188 -0
- package/frontend/src/modules/colors.ts +449 -0
- package/frontend/src/modules/compression.ts +67 -0
- package/frontend/src/modules/cookies.ts +182 -0
- package/frontend/src/modules/date.js +535 -0
- package/frontend/src/modules/date.ts +583 -0
- package/frontend/src/modules/events.ts +96 -0
- package/frontend/src/modules/google.ts +60 -0
- package/frontend/src/modules/meta.ts +59 -0
- package/frontend/src/modules/mutex.ts +59 -0
- package/frontend/src/modules/number.ts +20 -0
- package/frontend/src/modules/object.ts +212 -0
- package/frontend/src/modules/paddle.ts +2990 -0
- package/frontend/src/modules/scheme.ts +740 -0
- package/frontend/src/modules/settings.ts +5 -0
- package/frontend/src/modules/statics.ts +47 -0
- package/frontend/src/modules/string.ts +500 -0
- package/frontend/src/modules/support.ts +118 -0
- package/frontend/src/modules/themes.ts +24 -0
- package/frontend/src/modules/user.ts +321 -0
- package/frontend/src/modules/utils.ts +1260 -0
- package/frontend/src/static/admin/admin.png +0 -0
- package/frontend/src/static/admin/password.webp +0 -0
- package/frontend/src/static/icons/copy.webp +0 -0
- package/frontend/src/static/payments/arrow.long.webp +0 -0
- package/frontend/src/static/payments/arrow.long2.webp +0 -0
- package/frontend/src/static/payments/cancelled.webp +0 -0
- package/frontend/src/static/payments/check.sign.webp +0 -0
- package/frontend/src/static/payments/check.webp +0 -0
- package/frontend/src/static/payments/close.webp +0 -0
- package/frontend/src/static/payments/error.webp +0 -0
- package/frontend/src/static/payments/exclamation.webp +0 -0
- package/frontend/src/static/payments/minus.webp +0 -0
- package/frontend/src/static/payments/party.webp +0 -0
- package/frontend/src/static/payments/plus.webp +0 -0
- package/frontend/src/static/payments/shopping_cart.webp +0 -0
- package/frontend/src/static/payments/trash.webp +0 -0
- package/frontend/src/types/global.d.ts +4 -0
- package/frontend/src/types/gradient.ts +87 -0
- package/frontend/src/ui/any_element.d.ts +5 -0
- package/frontend/src/ui/border_button.ts +320 -0
- package/frontend/src/ui/button.ts +62 -0
- package/frontend/src/ui/canvas.ts +431 -0
- package/frontend/src/ui/checkbox.ts +284 -0
- package/frontend/src/ui/code.ts +1049 -0
- package/frontend/src/ui/color.ts +117 -0
- package/frontend/src/ui/context_menu.ts +194 -0
- package/frontend/src/ui/css.ts +57 -0
- package/frontend/src/ui/divider.ts +28 -0
- package/frontend/src/ui/dropdown.ts +503 -0
- package/frontend/src/ui/for_each.ts +71 -0
- package/frontend/src/ui/form.ts +208 -0
- package/frontend/src/ui/frame_modes.ts +140 -0
- package/frontend/src/ui/google_map.ts +70 -0
- package/frontend/src/ui/gradient.ts +73 -0
- package/frontend/src/ui/image.ts +587 -0
- package/frontend/src/ui/input.ts +1284 -0
- package/frontend/src/ui/link.ts +77 -0
- package/frontend/src/ui/list.ts +88 -0
- package/frontend/src/ui/loader_button.ts +192 -0
- package/frontend/src/ui/loaders.ts +126 -0
- package/frontend/src/ui/popup.ts +370 -0
- package/frontend/src/ui/pseudo.ts +33 -0
- package/frontend/src/ui/scroller.ts +1324 -0
- package/frontend/src/ui/slider.ts +215 -0
- package/frontend/src/ui/spacer.ts +29 -0
- package/frontend/src/ui/span.ts +23 -0
- package/frontend/src/ui/stack.ts +238 -0
- package/frontend/src/ui/steps.ts +334 -0
- package/frontend/src/ui/style.ts +26 -0
- package/frontend/src/ui/switch.ts +286 -0
- package/frontend/src/ui/table.ts +323 -0
- package/frontend/src/ui/tabs.ts +441 -0
- package/frontend/src/ui/text.ts +38 -0
- package/frontend/src/ui/theme.ts +279 -0
- package/frontend/src/ui/title.ts +64 -0
- package/frontend/src/ui/ui.ts +47 -0
- package/frontend/src/ui/view.ts +44 -0
- package/frontend/src/volt.ts +31 -0
- package/package.json +58 -0
|
@@ -0,0 +1,2990 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @author: Daan van den Bergh
|
|
3
|
+
* @copyright: © 2022 - 2024 Daan van den Bergh.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Imports.
|
|
7
|
+
import { Utils } from "./utils.js";
|
|
8
|
+
import { User } from "./user.js";
|
|
9
|
+
import { HStack, HStackElement, NullHStack, VStack, VStackElement, } from "../ui/stack"
|
|
10
|
+
import { Text } from "../ui/text"
|
|
11
|
+
import { Title } from "../ui/title"
|
|
12
|
+
import { ForEach } from "../ui/for_each"
|
|
13
|
+
import { Image, ImageMask } from "../ui/image"
|
|
14
|
+
import { RingLoader } from "../ui/loaders"
|
|
15
|
+
import { BorderButton } from "../ui/border_button"
|
|
16
|
+
import { LoaderButton, LoaderButtonElement } from "../ui/loader_button"
|
|
17
|
+
import { Divider } from "../ui/divider"
|
|
18
|
+
import { Input, ExtendedSelect, ExtendedInput, ExtendedInputElement, ExtendedSelectElement } from "../ui/input"
|
|
19
|
+
import { Spacer } from "../ui/spacer"
|
|
20
|
+
import { Link } from "../ui/link"
|
|
21
|
+
import { CheckBox } from "../ui/checkbox"
|
|
22
|
+
import { Form } from "../ui/form"
|
|
23
|
+
import { Popup, PopupElement } from "../ui/popup"
|
|
24
|
+
|
|
25
|
+
// Declare global variables or external libraries if necessary.
|
|
26
|
+
// @todo import paddle here not using scripts
|
|
27
|
+
declare const Paddle: any;
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------
|
|
30
|
+
// Payments Object.
|
|
31
|
+
|
|
32
|
+
const Payments = {
|
|
33
|
+
// ---------------------------------------------------------
|
|
34
|
+
// Private Properties.
|
|
35
|
+
|
|
36
|
+
client_key: "{{PADDLE_CLIENT_KEY}}",
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
sandbox: "{{PADDLE_SANDBOX}}" === "true",
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
tax_inclusive: "{{PADDLE_INCLUSIVE_TAX}}" === "true",
|
|
41
|
+
countries: {
|
|
42
|
+
"AD": { name: "🇦🇩 Andorra", calling_code: "+376" },
|
|
43
|
+
"AE": { name: "🇦🇪 United Arab Emirates", calling_code: "+971" },
|
|
44
|
+
"AF": { name: "🇦🇫 Afghanistan", calling_code: "+93" },
|
|
45
|
+
"AG": { name: "🇦🇬 Antigua and Barbuda", calling_code: "+1-268" },
|
|
46
|
+
"AI": { name: "🇦🇮 Anguilla", calling_code: "+1-264" },
|
|
47
|
+
"AL": { name: "🇦🇱 Albania", calling_code: "+355" },
|
|
48
|
+
"AM": { name: "🇦🇲 Armenia", calling_code: "+374" },
|
|
49
|
+
"AO": { name: "🇦🇴 Angola", calling_code: "+244" },
|
|
50
|
+
"AQ": { name: "🇦🇶 Antarctica", calling_code: "+672" },
|
|
51
|
+
"AR": { name: "🇦🇷 Argentina", calling_code: "+54" },
|
|
52
|
+
"AS": { name: "🇦🇸 American Samoa", calling_code: "+1-684" },
|
|
53
|
+
"AT": { name: "🇦🇹 Austria", calling_code: "+43" },
|
|
54
|
+
"AU": { name: "🇦🇺 Australia", calling_code: "+61" },
|
|
55
|
+
"AW": { name: "🇦🇼 Aruba", calling_code: "+297" },
|
|
56
|
+
"AX": { name: "🇦🇽 Åland Islands", calling_code: "+358-18" },
|
|
57
|
+
"AZ": { name: "🇦🇿 Azerbaijan", calling_code: "+994" },
|
|
58
|
+
"BA": { name: "🇧🇦 Bosnia and Herzegovina", calling_code: "+387" },
|
|
59
|
+
"BB": { name: "🇧🇧 Barbados", calling_code: "+1-246" },
|
|
60
|
+
"BD": { name: "🇧🇩 Bangladesh", calling_code: "+880" },
|
|
61
|
+
"BE": { name: "🇧🇪 Belgium", calling_code: "+32" },
|
|
62
|
+
"BF": { name: "🇧🇫 Burkina Faso", calling_code: "+226" },
|
|
63
|
+
"BG": { name: "🇧🇬 Bulgaria", calling_code: "+359" },
|
|
64
|
+
"BH": { name: "🇧🇭 Bahrain", calling_code: "+973" },
|
|
65
|
+
"BI": { name: "🇧🇮 Burundi", calling_code: "+257" },
|
|
66
|
+
"BJ": { name: "🇧🇯 Benin", calling_code: "+229" },
|
|
67
|
+
"BL": { name: "🇧🇱 Saint Barthélemy", calling_code: "+590" },
|
|
68
|
+
"BM": { name: "🇧🇲 Bermuda", calling_code: "+1-441" },
|
|
69
|
+
"BN": { name: "🇧🇳 Brunei", calling_code: "+673" },
|
|
70
|
+
"BO": { name: "🇧🇴 Bolivia", calling_code: "+591" },
|
|
71
|
+
"BQ": { name: "🇧🇶 Caribbean Netherlands", calling_code: "+599" },
|
|
72
|
+
"BR": { name: "🇧🇷 Brazil", calling_code: "+55" },
|
|
73
|
+
"BS": { name: "🇧🇸 Bahamas", calling_code: "+1-242" },
|
|
74
|
+
"BT": { name: "🇧🇹 Bhutan", calling_code: "+975" },
|
|
75
|
+
"BV": { name: "🇧🇻 Bouvet Island", calling_code: "+47" },
|
|
76
|
+
"BW": { name: "🇧🇼 Botswana", calling_code: "+267" },
|
|
77
|
+
"BY": { name: "🇧🇾 Belarus", calling_code: "+375" },
|
|
78
|
+
"BZ": { name: "🇧🇿 Belize", calling_code: "+501" },
|
|
79
|
+
"CA": { name: "🇨🇦 Canada", calling_code: "+1" },
|
|
80
|
+
"CC": { name: "🇨🇨 Cocos (Keeling) Islands", calling_code: "+61" },
|
|
81
|
+
"CD": { name: "🇨🇩 Congo (DRC)", calling_code: "+243" },
|
|
82
|
+
"CF": { name: "🇨🇫 Central African Republic", calling_code: "+236" },
|
|
83
|
+
"CG": { name: "🇨🇬 Congo (Republic)", calling_code: "+242" },
|
|
84
|
+
"CH": { name: "🇨🇭 Switzerland", calling_code: "+41" },
|
|
85
|
+
"CI": { name: "🇨🇮 Côte d'Ivoire", calling_code: "+225" },
|
|
86
|
+
"CK": { name: "🇨🇰 Cook Islands", calling_code: "+682" },
|
|
87
|
+
"CL": { name: "🇨🇱 Chile", calling_code: "+56" },
|
|
88
|
+
"CM": { name: "🇨🇲 Cameroon", calling_code: "+237" },
|
|
89
|
+
"CN": { name: "🇨🇳 China", calling_code: "+86" },
|
|
90
|
+
"CO": { name: "🇨🇴 Colombia", calling_code: "+57" },
|
|
91
|
+
"CR": { name: "🇨🇷 Costa Rica", calling_code: "+506" },
|
|
92
|
+
"CU": { name: "🇨🇺 Cuba", calling_code: "+53" },
|
|
93
|
+
"CV": { name: "🇨🇻 Cape Verde", calling_code: "+238" },
|
|
94
|
+
"CW": { name: "🇨🇼 Curaçao", calling_code: "+599" },
|
|
95
|
+
"CX": { name: "🇨🇽 Christmas Island", calling_code: "+61" },
|
|
96
|
+
"CY": { name: "🇨🇾 Cyprus", calling_code: "+357" },
|
|
97
|
+
"CZ": { name: "🇨🇿 Czech Republic", calling_code: "+420" },
|
|
98
|
+
"DE": { name: "🇩🇪 Germany", calling_code: "+49" },
|
|
99
|
+
"DJ": { name: "🇩🇯 Djibouti", calling_code: "+253" },
|
|
100
|
+
"DK": { name: "🇩🇰 Denmark", calling_code: "+45" },
|
|
101
|
+
"DM": { name: "🇩🇲 Dominica", calling_code: "+1-767" },
|
|
102
|
+
"DO": { name: "🇩🇴 Dominican Republic", calling_code: "+1-809" },
|
|
103
|
+
"DZ": { name: "🇩🇿 Algeria", calling_code: "+213" },
|
|
104
|
+
"EC": { name: "🇪🇨 Ecuador", calling_code: "+593" },
|
|
105
|
+
"EE": { name: "🇪🇪 Estonia", calling_code: "+372" },
|
|
106
|
+
"EG": { name: "🇪🇬 Egypt", calling_code: "+20" },
|
|
107
|
+
"EH": { name: "🇪🇭 Western Sahara", calling_code: "+212" },
|
|
108
|
+
"ER": { name: "🇪🇷 Eritrea", calling_code: "+291" },
|
|
109
|
+
"ES": { name: "🇪🇸 Spain", calling_code: "+34" },
|
|
110
|
+
"ET": { name: "🇪🇹 Ethiopia", calling_code: "+251" },
|
|
111
|
+
"FI": { name: "🇫🇮 Finland", calling_code: "+358" },
|
|
112
|
+
"FJ": { name: "🇫🇯 Fiji", calling_code: "+679" },
|
|
113
|
+
"FK": { name: "🇫🇰 Falkland Islands (Malvinas)", calling_code: "+500" },
|
|
114
|
+
"FM": { name: "🇫🇲 Micronesia", calling_code: "+691" },
|
|
115
|
+
"FO": { name: "🇫🇴 Faroe Islands", calling_code: "+298" },
|
|
116
|
+
"FR": { name: "🇫🇷 France", calling_code: "+33" },
|
|
117
|
+
"GA": { name: "🇬🇦 Gabon", calling_code: "+241" },
|
|
118
|
+
"GB": { name: "🇬🇧 United Kingdom", calling_code: "+44" },
|
|
119
|
+
"GD": { name: "🇬🇩 Grenada", calling_code: "+1-473" },
|
|
120
|
+
"GE": { name: "🇬🇪 Georgia", calling_code: "+995" },
|
|
121
|
+
"GF": { name: "🇬🇫 French Guiana", calling_code: "+594" },
|
|
122
|
+
"GG": { name: "🇬🇬 Guernsey", calling_code: "+44" },
|
|
123
|
+
"GH": { name: "🇬🇭 Ghana", calling_code: "+233" },
|
|
124
|
+
"GI": { name: "🇬🇮 Gibraltar", calling_code: "+350" },
|
|
125
|
+
"GL": { name: "🇬🇱 Greenland", calling_code: "+299" },
|
|
126
|
+
"GM": { name: "🇬🇲 Gambia", calling_code: "+220" },
|
|
127
|
+
"GN": { name: "🇬🇳 Guinea", calling_code: "+224" },
|
|
128
|
+
"GP": { name: "🇬🇵 Guadeloupe", calling_code: "+590" },
|
|
129
|
+
"GQ": { name: "🇬🇶 Equatorial Guinea", calling_code: "+240" },
|
|
130
|
+
"GR": { name: "🇬🇷 Greece", calling_code: "+30" },
|
|
131
|
+
"GS": { name: "🇬🇸 South Georgia and the South Sandwich Islands", calling_code: "+500" },
|
|
132
|
+
"GT": { name: "🇬🇹 Guatemala", calling_code: "+502" },
|
|
133
|
+
"GU": { name: "🇬🇺 Guam", calling_code: "+1-671" },
|
|
134
|
+
"GW": { name: "🇬🇼 Guinea-Bissau", calling_code: "+245" },
|
|
135
|
+
"GY": { name: "🇬🇾 Guyana", calling_code: "+592" },
|
|
136
|
+
"HK": { name: "🇭🇰 Hong Kong", calling_code: "+852" },
|
|
137
|
+
"HM": { name: "🇭🇲 Heard Island and McDonald Islands", calling_code: "+672" },
|
|
138
|
+
"HN": { name: "🇭🇳 Honduras", calling_code: "+504" },
|
|
139
|
+
"HR": { name: "🇭🇷 Croatia", calling_code: "+385" },
|
|
140
|
+
"HT": { name: "🇭🇹 Haiti", calling_code: "+509" },
|
|
141
|
+
"HU": { name: "🇭🇺 Hungary", calling_code: "+36" },
|
|
142
|
+
"ID": { name: "🇮🇩 Indonesia", calling_code: "+62" },
|
|
143
|
+
"IE": { name: "🇮🇪 Ireland", calling_code: "+353" },
|
|
144
|
+
"IL": { name: "🇮🇱 Israel", calling_code: "+972" },
|
|
145
|
+
"IM": { name: "🇮🇲 Isle of Man", calling_code: "+44" },
|
|
146
|
+
"IN": { name: "🇮🇳 India", calling_code: "+91" },
|
|
147
|
+
"IO": { name: "🇮🇴 British Indian Ocean Territory", calling_code: "+246" },
|
|
148
|
+
"IQ": { name: "🇮🇶 Iraq", calling_code: "+964" },
|
|
149
|
+
"IR": { name: "🇮🇷 Iran", calling_code: "+98" },
|
|
150
|
+
"IS": { name: "🇮🇸 Iceland", calling_code: "+354" },
|
|
151
|
+
"IT": { name: "🇮🇹 Italy", calling_code: "+39" },
|
|
152
|
+
"JE": { name: "🇯🇪 Jersey", calling_code: "+44" },
|
|
153
|
+
"JM": { name: "🇯🇲 Jamaica", calling_code: "+1-876" },
|
|
154
|
+
"JO": { name: "🇯🇴 Jordan", calling_code: "+962" },
|
|
155
|
+
"JP": { name: "🇯🇵 Japan", calling_code: "+81" },
|
|
156
|
+
"KE": { name: "🇰🇪 Kenya", calling_code: "+254" },
|
|
157
|
+
"KG": { name: "🇰🇬 Kyrgyzstan", calling_code: "+996" },
|
|
158
|
+
"KH": { name: "🇰🇭 Cambodia", calling_code: "+855" },
|
|
159
|
+
"KI": { name: "🇰🇮 Kiribati", calling_code: "+686" },
|
|
160
|
+
"KM": { name: "🇰🇲 Comoros", calling_code: "+269" },
|
|
161
|
+
"KN": { name: "🇰🇳 Saint Kitts and Nevis", calling_code: "+1-869" },
|
|
162
|
+
"KP": { name: "🇰🇵 North Korea", calling_code: "+850" },
|
|
163
|
+
"KR": { name: "🇰🇷 South Korea", calling_code: "+82" },
|
|
164
|
+
"KW": { name: "🇰🇼 Kuwait", calling_code: "+965" },
|
|
165
|
+
"KY": { name: "🇰🇾 Cayman Islands", calling_code: "+1-345" },
|
|
166
|
+
"KZ": { name: "🇰🇿 Kazakhstan", calling_code: "+7" },
|
|
167
|
+
"LA": { name: "🇱🇦 Laos", calling_code: "+856" },
|
|
168
|
+
"LB": { name: "🇱🇧 Lebanon", calling_code: "+961" },
|
|
169
|
+
"LC": { name: "🇱🇨 Saint Lucia", calling_code: "+1-758" },
|
|
170
|
+
"LI": { name: "🇱🇮 Liechtenstein", calling_code: "+423" },
|
|
171
|
+
"LK": { name: "🇱🇰 Sri Lanka", calling_code: "+94" },
|
|
172
|
+
"LR": { name: "🇱🇷 Liberia", calling_code: "+231" },
|
|
173
|
+
"LS": { name: "🇱🇸 Lesotho", calling_code: "+266" },
|
|
174
|
+
"LT": { name: "🇱🇹 Lithuania", calling_code: "+370" },
|
|
175
|
+
"LU": { name: "🇱🇺 Luxembourg", calling_code: "+352" },
|
|
176
|
+
"LV": { name: "🇱🇻 Latvia", calling_code: "+371" },
|
|
177
|
+
"LY": { name: "🇱🇾 Libya", calling_code: "+218" },
|
|
178
|
+
"MA": { name: "🇲🇦 Morocco", calling_code: "+212" },
|
|
179
|
+
"MC": { name: "🇲🇨 Monaco", calling_code: "+377" },
|
|
180
|
+
"MD": { name: "🇲🇩 Moldova", calling_code: "+373" },
|
|
181
|
+
"ME": { name: "🇲🇪 Montenegro", calling_code: "+382" },
|
|
182
|
+
"MF": { name: "🇲🇫 Saint Martin", calling_code: "+590" },
|
|
183
|
+
"MG": { name: "🇲🇬 Madagascar", calling_code: "+261" },
|
|
184
|
+
"MH": { name: "🇲🇭 Marshall Islands", calling_code: "+692" },
|
|
185
|
+
"MK": { name: "🇲🇰 North Macedonia", calling_code: "+389" },
|
|
186
|
+
"ML": { name: "🇲🇱 Mali", calling_code: "+223" },
|
|
187
|
+
"MM": { name: "🇲🇲 Myanmar (Burma)", calling_code: "+95" },
|
|
188
|
+
"MN": { name: "🇲🇳 Mongolia", calling_code: "+976" },
|
|
189
|
+
"MO": { name: "🇲🇴 Macao", calling_code: "+853" },
|
|
190
|
+
"MP": { name: "🇲🇵 Northern Mariana Islands", calling_code: "+1-670" },
|
|
191
|
+
"MQ": { name: "🇲🇶 Martinique", calling_code: "+596" },
|
|
192
|
+
"MR": { name: "🇲🇷 Mauritania", calling_code: "+222" },
|
|
193
|
+
"MS": { name: "🇲🇸 Montserrat", calling_code: "+1-664" },
|
|
194
|
+
"MT": { name: "🇲🇹 Malta", calling_code: "+356" },
|
|
195
|
+
"MU": { name: "🇲🇺 Mauritius", calling_code: "+230" },
|
|
196
|
+
"MV": { name: "🇲🇻 Maldives", calling_code: "+960" },
|
|
197
|
+
"MW": { name: "🇲🇼 Malawi", calling_code: "+265" },
|
|
198
|
+
"MX": { name: "🇲🇽 Mexico", calling_code: "+52" },
|
|
199
|
+
"MY": { name: "🇲🇾 Malaysia", calling_code: "+60" },
|
|
200
|
+
"MZ": { name: "🇲🇿 Mozambique", calling_code: "+258" },
|
|
201
|
+
"NA": { name: "🇳🇦 Namibia", calling_code: "+264" },
|
|
202
|
+
"NC": { name: "🇳🇨 New Caledonia", calling_code: "+687" },
|
|
203
|
+
"NE": { name: "🇳🇪 Niger", calling_code: "+227" },
|
|
204
|
+
"NF": { name: "🇳🇫 Norfolk Island", calling_code: "+672" },
|
|
205
|
+
"NG": { name: "🇳🇬 Nigeria", calling_code: "+234" },
|
|
206
|
+
"NI": { name: "🇳🇮 Nicaragua", calling_code: "+505" },
|
|
207
|
+
"NL": { name: "🇳🇱 Netherlands", calling_code: "+31" },
|
|
208
|
+
"NO": { name: "🇳🇴 Norway", calling_code: "+47" },
|
|
209
|
+
"NP": { name: "🇳🇵 Nepal", calling_code: "+977" },
|
|
210
|
+
"NR": { name: "🇳🇷 Nauru", calling_code: "+674" },
|
|
211
|
+
"NU": { name: "🇳🇺 Niue", calling_code: "+683" },
|
|
212
|
+
"NZ": { name: "🇳🇿 New Zealand", calling_code: "+64" },
|
|
213
|
+
"OM": { name: "🇴🇲 Oman", calling_code: "+968" },
|
|
214
|
+
"PA": { name: "🇵🇦 Panama", calling_code: "+507" },
|
|
215
|
+
"PE": { name: "🇵🇪 Peru", calling_code: "+51" },
|
|
216
|
+
"PF": { name: "🇵🇫 French Polynesia", calling_code: "+689" },
|
|
217
|
+
"PG": { name: "🇵🇬 Papua New Guinea", calling_code: "+675" },
|
|
218
|
+
"PH": { name: "🇵🇭 Philippines", calling_code: "+63" },
|
|
219
|
+
"PK": { name: "🇵🇰 Pakistan", calling_code: "+92" },
|
|
220
|
+
"PL": { name: "🇵🇱 Poland", calling_code: "+48" },
|
|
221
|
+
"PM": { name: "🇵🇲 Saint Pierre and Miquelon", calling_code: "+508" },
|
|
222
|
+
"PN": { name: "🇵🇳 Pitcairn Islands", calling_code: "+64" },
|
|
223
|
+
"PR": { name: "🇵🇷 Puerto Rico", calling_code: "+1-787" },
|
|
224
|
+
"PS": { name: "🇵🇸 Palestine", calling_code: "+970" },
|
|
225
|
+
"PT": { name: "🇵🇹 Portugal", calling_code: "+351" },
|
|
226
|
+
"PW": { name: "🇵🇼 Palau", calling_code: "+680" },
|
|
227
|
+
"PY": { name: "🇵🇾 Paraguay", calling_code: "+595" },
|
|
228
|
+
"QA": { name: "🇶🇦 Qatar", calling_code: "+974" },
|
|
229
|
+
"RE": { name: "🇷🇪 Réunion", calling_code: "+262" },
|
|
230
|
+
"RO": { name: "🇷🇴 Romania", calling_code: "+40" },
|
|
231
|
+
"RS": { name: "🇷🇸 Serbia", calling_code: "+381" },
|
|
232
|
+
"RU": { name: "🇷🇺 Russia", calling_code: "+7" },
|
|
233
|
+
"RW": { name: "🇷🇼 Rwanda", calling_code: "+250" },
|
|
234
|
+
"SA": { name: "🇸🇦 Saudi Arabia", calling_code: "+966" },
|
|
235
|
+
"SB": { name: "🇸🇧 Solomon Islands", calling_code: "+677" },
|
|
236
|
+
"SC": { name: "🇸🇨 Seychelles", calling_code: "+248" },
|
|
237
|
+
"SD": { name: "🇸🇩 Sudan", calling_code: "+249" },
|
|
238
|
+
"SE": { name: "🇸🇪 Sweden", calling_code: "+46" },
|
|
239
|
+
"SG": { name: "🇸🇬 Singapore", calling_code: "+65" },
|
|
240
|
+
"SH": { name: "🇸🇭 Saint Helena, Ascension and Tristan da Cunha", calling_code: "+290" },
|
|
241
|
+
"SI": { name: "🇸🇮 Slovenia", calling_code: "+386" },
|
|
242
|
+
"SJ": { name: "🇸🇯 Svalbard and Jan Mayen", calling_code: "+47" },
|
|
243
|
+
"SK": { name: "🇸🇰 Slovakia", calling_code: "+421" },
|
|
244
|
+
"SL": { name: "🇸🇱 Sierra Leone", calling_code: "+232" },
|
|
245
|
+
"SM": { name: "🇸🇲 San Marino", calling_code: "+378" },
|
|
246
|
+
"SN": { name: "🇸🇳 Senegal", calling_code: "+221" },
|
|
247
|
+
"SO": { name: "🇸🇴 Somalia", calling_code: "+252" },
|
|
248
|
+
"SR": { name: "🇸🇷 Suriname", calling_code: "+597" },
|
|
249
|
+
"SS": { name: "🇸🇸 South Sudan", calling_code: "+211" },
|
|
250
|
+
"ST": { name: "🇸🇹 São Tomé and Príncipe", calling_code: "+239" },
|
|
251
|
+
"SV": { name: "🇸🇻 El Salvador", calling_code: "+503" },
|
|
252
|
+
"SX": { name: "🇸🇽 Sint Maarten", calling_code: "+1-721" },
|
|
253
|
+
"SY": { name: "🇸🇾 Syria", calling_code: "+963" },
|
|
254
|
+
"SZ": { name: "🇸🇿 Eswatini", calling_code: "+268" },
|
|
255
|
+
"TC": { name: "🇹🇨 Turks and Caicos Islands", calling_code: "+1-649" },
|
|
256
|
+
"TD": { name: "🇹🇩 Chad", calling_code: "+235" },
|
|
257
|
+
"TF": { name: "🇹🇫 French Southern and Antarctic Lands", calling_code: "+262" },
|
|
258
|
+
"TG": { name: "🇹🇬 Togo", calling_code: "+228" },
|
|
259
|
+
"TH": { name: "🇹🇭 Thailand", calling_code: "+66" },
|
|
260
|
+
"TJ": { name: "🇹🇯 Tajikistan", calling_code: "+992" },
|
|
261
|
+
"TK": { name: "🇹🇰 Tokelau", calling_code: "+690" },
|
|
262
|
+
"TL": { name: "🇹🇱 Timor-Leste", calling_code: "+670" },
|
|
263
|
+
"TM": { name: "🇹🇲 Turkmenistan", calling_code: "+993" },
|
|
264
|
+
"TN": { name: "🇹🇳 Tunisia", calling_code: "+216" },
|
|
265
|
+
"TO": { name: "🇹🇴 Tonga", calling_code: "+676" },
|
|
266
|
+
"TR": { name: "🇹🇷 Turkey", calling_code: "+90" },
|
|
267
|
+
"TT": { name: "🇹🇹 Trinidad and Tobago", calling_code: "+1-868" },
|
|
268
|
+
"TV": { name: "🇹🇻 Tuvalu", calling_code: "+688" },
|
|
269
|
+
"TW": { name: "🇹🇼 Taiwan", calling_code: "+886" },
|
|
270
|
+
"TZ": { name: "🇹🇿 Tanzania", calling_code: "+255" },
|
|
271
|
+
"UA": { name: "🇺🇦 Ukraine", calling_code: "+380" },
|
|
272
|
+
"UG": { name: "🇺🇬 Uganda", calling_code: "+256" },
|
|
273
|
+
"UM": { name: "🇺🇲 U.S. Minor Outlying Islands", calling_code: "+1" },
|
|
274
|
+
"US": { name: "🇺🇸 United States", calling_code: "+1" },
|
|
275
|
+
"UY": { name: "🇺🇾 Uruguay", calling_code: "+598" },
|
|
276
|
+
"UZ": { name: "🇺🇿 Uzbekistan", calling_code: "+998" },
|
|
277
|
+
"VA": { name: "🇻🇦 Vatican City", calling_code: "+379" },
|
|
278
|
+
"VC": { name: "🇻🇨 Saint Vincent and the Grenadines", calling_code: "+1-784" },
|
|
279
|
+
"VE": { name: "🇻🇪 Venezuela", calling_code: "+58" },
|
|
280
|
+
"VG": { name: "🇻🇬 British Virgin Islands", calling_code: "+1-284" },
|
|
281
|
+
"VI": { name: "🇻🇮 U.S. Virgin Islands", calling_code: "+1-340" },
|
|
282
|
+
"VN": { name: "🇻🇳 Vietnam", calling_code: "+84" },
|
|
283
|
+
"VU": { name: "🇻🇺 Vanuatu", calling_code: "+678" },
|
|
284
|
+
"WF": { name: "🇼🇫 Wallis and Futuna", calling_code: "+681" },
|
|
285
|
+
"WS": { name: "🇼🇸 Samoa", calling_code: "+685" },
|
|
286
|
+
"YE": { name: "🇾🇪 Yemen", calling_code: "+967" },
|
|
287
|
+
"YT": { name: "🇾🇹 Mayotte", calling_code: "+262" },
|
|
288
|
+
"ZA": { name: "🇿🇦 South Africa", calling_code: "+27" },
|
|
289
|
+
"ZM": { name: "🇿🇲 Zambia", calling_code: "+260" },
|
|
290
|
+
"ZW": { name: "🇿🇼 Zimbabwe", calling_code: "+263" }
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
_paddle_initialized: false,
|
|
294
|
+
_payment_element: undefined as any, // Replace 'any' with the actual type if known.
|
|
295
|
+
_sign_in_redirect: undefined as string | undefined | null,
|
|
296
|
+
_step: 0 as number,
|
|
297
|
+
_steps_element: undefined as any,
|
|
298
|
+
_steps_container: undefined as any,
|
|
299
|
+
_overview_container: undefined as any,
|
|
300
|
+
_order_container: undefined as any,
|
|
301
|
+
_billing_container: undefined as any,
|
|
302
|
+
_payment_container: undefined as any,
|
|
303
|
+
_processing_container: undefined as any,
|
|
304
|
+
_checkout_button: undefined as any,
|
|
305
|
+
_prev_step_button: undefined as any,
|
|
306
|
+
_style: undefined as any,
|
|
307
|
+
_currency_symbol: undefined as string | undefined,
|
|
308
|
+
_render_payment_element_reject: undefined as undefined | Function,
|
|
309
|
+
_render_payment_element_resolve: undefined as undefined | Function,
|
|
310
|
+
_refunds_element: undefined as any,
|
|
311
|
+
_refunds_container: undefined as any,
|
|
312
|
+
_processing_element: undefined as any,
|
|
313
|
+
_theme: undefined as any,
|
|
314
|
+
_products: undefined as any,
|
|
315
|
+
_days_refundable: 30, // **Added Property**
|
|
316
|
+
|
|
317
|
+
on_error: (data: string | Error) => {},
|
|
318
|
+
|
|
319
|
+
// Additional properties that might be inferred from function bodies:
|
|
320
|
+
_refund_policy: undefined as string | undefined, // Used in commented code
|
|
321
|
+
_cancellation_policy: undefined as string | undefined, // Used in commented code
|
|
322
|
+
|
|
323
|
+
// cart: {
|
|
324
|
+
// items: [] as any[], // Replace 'any' with the actual item type.
|
|
325
|
+
// refresh: function() { /* Implement refresh logic */ },
|
|
326
|
+
// save: function() { /* Implement save logic */ },
|
|
327
|
+
// add: async function(productId: string, quantity: number) { /* Implement add logic */ },
|
|
328
|
+
// remove: async function(productId: string, quantity: number | "all") { /* Implement remove logic */ },
|
|
329
|
+
// },
|
|
330
|
+
|
|
331
|
+
_billing_element: undefined as any, // Replace 'any' with the actual type if known.
|
|
332
|
+
_billing_details: undefined as any, // Replace 'any' with the actual type if known.
|
|
333
|
+
|
|
334
|
+
_overview_subtotal: undefined as any, // Replace 'any' with the actual type if known.
|
|
335
|
+
_overview_total: undefined as any, // Replace 'any' with the actual type if known.
|
|
336
|
+
_overview_subtotal_tax: undefined as any, // Replace 'any' with the actual type if known.
|
|
337
|
+
_overview_tax_container: undefined as any, // Replace 'any' with the actual type if known.
|
|
338
|
+
_overview_incl_excl_tax: undefined as any, // Replace 'any' with the actual type if known.
|
|
339
|
+
_overview_element: undefined as any, // Replace 'any' with the actual type if known.
|
|
340
|
+
_order_element: undefined as any, // Replace 'any' with the actual type if known.
|
|
341
|
+
|
|
342
|
+
// ---------------------------------------------------------
|
|
343
|
+
// Private Methods.
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Initialize Paddle with the provided client key and set up event callbacks.
|
|
347
|
+
*/
|
|
348
|
+
_initialize_paddle: function(): void {
|
|
349
|
+
if (this._paddle_initialized !== true) {
|
|
350
|
+
if (this.sandbox) {
|
|
351
|
+
Paddle.Environment.set("sandbox");
|
|
352
|
+
}
|
|
353
|
+
Paddle.Setup({
|
|
354
|
+
token: this.client_key,
|
|
355
|
+
eventCallback: (data: any) => {
|
|
356
|
+
if (data.name === "checkout.loaded") {
|
|
357
|
+
(this._render_payment_element_resolve as Function)();
|
|
358
|
+
}
|
|
359
|
+
else if (data.name === "checkout.completed") {
|
|
360
|
+
this._show_processing("success");
|
|
361
|
+
}
|
|
362
|
+
else if (data.name === "checkout.payment.initiated") {
|
|
363
|
+
// Uncomment and implement if needed.
|
|
364
|
+
// this._show_processing("processing");
|
|
365
|
+
}
|
|
366
|
+
else if (data.name === "checkout.payment.failed") {
|
|
367
|
+
this._show_processing("error");
|
|
368
|
+
}
|
|
369
|
+
else if (data.type === "checkout.error") {
|
|
370
|
+
if (data.error?.detail) {
|
|
371
|
+
console.error(data);
|
|
372
|
+
this.on_error(data.error.detail);
|
|
373
|
+
} else {
|
|
374
|
+
console.error(data);
|
|
375
|
+
this.on_error(new Error("Unknown error"));
|
|
376
|
+
}
|
|
377
|
+
(this._render_payment_element_reject as Function)(data.detail.split("|")[0]);
|
|
378
|
+
}
|
|
379
|
+
else if (data.type === "checkout.warning") {
|
|
380
|
+
if (this.sandbox) {
|
|
381
|
+
console.log("Checkout warning:", data);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
// Handle other events if necessary.
|
|
386
|
+
// Uncomment for debugging.
|
|
387
|
+
// if (this.sandbox) {
|
|
388
|
+
// console.log("Event", data);
|
|
389
|
+
// }
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
this._paddle_initialized = true;
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Reset the payment element by removing it if it exists.
|
|
399
|
+
*/
|
|
400
|
+
_reset: function(): void {
|
|
401
|
+
if (this._payment_element !== undefined) {
|
|
402
|
+
this._payment_element.remove();
|
|
403
|
+
}
|
|
404
|
+
this._payment_element = undefined;
|
|
405
|
+
},
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Initialize the order by verifying authentication and making a POST request.
|
|
409
|
+
*/
|
|
410
|
+
_init_order: async function (): Promise<void> {
|
|
411
|
+
try {
|
|
412
|
+
if (this._sign_in_redirect != null && !User.is_authenticated()) {
|
|
413
|
+
Utils.redirect(this._sign_in_redirect);
|
|
414
|
+
}
|
|
415
|
+
const response = await Utils.request({
|
|
416
|
+
method: "POST",
|
|
417
|
+
url: "/volt/payments/init",
|
|
418
|
+
data: {
|
|
419
|
+
items: this.cart.items,
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
// Handle response if necessary.
|
|
423
|
+
} catch (err: any) {
|
|
424
|
+
if (typeof err === "object" && err.error != null) {
|
|
425
|
+
err = err.error;
|
|
426
|
+
}
|
|
427
|
+
throw new Error(err);
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Set the current step in the payment process.
|
|
433
|
+
*/
|
|
434
|
+
_set_step: async function (): Promise<void | null> {
|
|
435
|
+
// Switch step.
|
|
436
|
+
switch (this._step) {
|
|
437
|
+
|
|
438
|
+
// Order.
|
|
439
|
+
case 0: {
|
|
440
|
+
// Select the current step.
|
|
441
|
+
this._steps_element.select(this._step);
|
|
442
|
+
|
|
443
|
+
// Show and hide relevant containers.
|
|
444
|
+
this._overview_container.show();
|
|
445
|
+
this._order_container.show();
|
|
446
|
+
this._billing_container.hide();
|
|
447
|
+
this._payment_container.hide();
|
|
448
|
+
this._processing_container.hide();
|
|
449
|
+
this._checkout_button.nodes.text.text("Next");
|
|
450
|
+
// this._policy_checkbox.hide();
|
|
451
|
+
this._prev_step_button.hide();
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Address.
|
|
456
|
+
case 1: {
|
|
457
|
+
// Minimum duration for the loader.
|
|
458
|
+
const min_duration = new Promise(resolve => setTimeout(resolve, 350));
|
|
459
|
+
|
|
460
|
+
// Verify the order.
|
|
461
|
+
try {
|
|
462
|
+
await this._init_order();
|
|
463
|
+
} catch (err) {
|
|
464
|
+
--this._step;
|
|
465
|
+
console.error(err);
|
|
466
|
+
this.on_error(err as Error);
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// Render billing element.
|
|
471
|
+
this._render_billing_element();
|
|
472
|
+
|
|
473
|
+
// Await minimum duration.
|
|
474
|
+
await min_duration;
|
|
475
|
+
|
|
476
|
+
// Select the current step.
|
|
477
|
+
this._steps_element.select(this._step);
|
|
478
|
+
|
|
479
|
+
// Show and hide relevant containers.
|
|
480
|
+
this._overview_container.show();
|
|
481
|
+
this._order_container.hide();
|
|
482
|
+
this._billing_container.show();
|
|
483
|
+
this._payment_container.hide();
|
|
484
|
+
this._processing_container.hide();
|
|
485
|
+
this._checkout_button.nodes.text.text("Next");
|
|
486
|
+
// this._policy_checkbox.hide();
|
|
487
|
+
this._prev_step_button.show();
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Payment.
|
|
492
|
+
case 2: {
|
|
493
|
+
// Check if the billing details are entered correctly.
|
|
494
|
+
try {
|
|
495
|
+
this._billing_details = this._billing_element.data();
|
|
496
|
+
this._billing_details.phone_number = this._billing_details.phone_country_code + this._billing_details.phone_number;
|
|
497
|
+
delete this._billing_details.phone_country_code;
|
|
498
|
+
} catch (error) {
|
|
499
|
+
--this._step;
|
|
500
|
+
console.error(error);
|
|
501
|
+
this.on_error(error as Error);
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Render payment element.
|
|
506
|
+
try {
|
|
507
|
+
await this._render_payment_element();
|
|
508
|
+
} catch (error) {
|
|
509
|
+
--this._step;
|
|
510
|
+
console.error(error);
|
|
511
|
+
this.on_error(error as Error);
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Select the current step.
|
|
516
|
+
this._steps_element.select(this._step);
|
|
517
|
+
|
|
518
|
+
// Show and hide relevant containers.
|
|
519
|
+
this._overview_container.hide();
|
|
520
|
+
this._order_container.hide();
|
|
521
|
+
this._billing_container.hide();
|
|
522
|
+
this._payment_container.show();
|
|
523
|
+
this._processing_container.hide();
|
|
524
|
+
this._checkout_button.nodes.text.text("Checkout");
|
|
525
|
+
// this._policy_checkbox.show();
|
|
526
|
+
this._prev_step_button.show();
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Navigate to the next step in the payment process.
|
|
534
|
+
*/
|
|
535
|
+
_next: async function (): Promise<void | null> {
|
|
536
|
+
if (this._step < 3) {
|
|
537
|
+
++this._step;
|
|
538
|
+
return this._set_step();
|
|
539
|
+
} else if (this._step === 3) {
|
|
540
|
+
return this._set_step();
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Navigate to the previous step in the payment process.
|
|
546
|
+
*/
|
|
547
|
+
_prev: async function (): Promise<void | null> {
|
|
548
|
+
if (this._step > 0) {
|
|
549
|
+
--this._step;
|
|
550
|
+
return this._set_step();
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Render the steps element in the UI.
|
|
556
|
+
*/
|
|
557
|
+
_render_steps_element: function (): void {
|
|
558
|
+
// Shortcuts.
|
|
559
|
+
const style = this._style;
|
|
560
|
+
|
|
561
|
+
// The previous step button.
|
|
562
|
+
this._prev_step_button = HStack(
|
|
563
|
+
ImageMask("/volt_static/payments/arrow.long.webp")
|
|
564
|
+
.frame(15, 15)
|
|
565
|
+
.mask_color(this._style.fg_1)
|
|
566
|
+
.transition_mask("background 300ms ease-in-out")
|
|
567
|
+
.transform("rotate(180deg)")
|
|
568
|
+
.margin_right(10),
|
|
569
|
+
Text("Previous Step")
|
|
570
|
+
.color(this._style.fg_1)
|
|
571
|
+
.transition("color 300ms ease-in-out")
|
|
572
|
+
.padding(0)
|
|
573
|
+
.margin(0)
|
|
574
|
+
.font_size(14)
|
|
575
|
+
)
|
|
576
|
+
.hide()
|
|
577
|
+
.on_mouse_over_out(
|
|
578
|
+
(e: any) => {
|
|
579
|
+
e.child(0).color(this._style.fg);
|
|
580
|
+
e.child(1).color(this._style.fg);
|
|
581
|
+
},
|
|
582
|
+
(e: any) => {
|
|
583
|
+
e.child(0).color(this._style.fg_1);
|
|
584
|
+
e.child(1).color(this._style.fg_1);
|
|
585
|
+
},
|
|
586
|
+
)
|
|
587
|
+
.on_click(() => {
|
|
588
|
+
this._prev()
|
|
589
|
+
.catch((err: any) => console.error(err));
|
|
590
|
+
})
|
|
591
|
+
.center_vertical();
|
|
592
|
+
|
|
593
|
+
// The steps element.
|
|
594
|
+
this._steps_element = HStack(
|
|
595
|
+
ForEach(
|
|
596
|
+
["Order Details", "Billing Details", "Payment Details", "Processing Details"],
|
|
597
|
+
(item: string, index: number) => {
|
|
598
|
+
const stack = HStack(
|
|
599
|
+
VStack((index + 1).toString())
|
|
600
|
+
.font_size(11)
|
|
601
|
+
.padding(0)
|
|
602
|
+
.margin(0)
|
|
603
|
+
.color(index === 0 ? this._style.selected.fg : this._style.fg_1)
|
|
604
|
+
.frame(17.5, 17.5)
|
|
605
|
+
.background(index === 0 ? this._style.selected.bg : this._style.bg_1)
|
|
606
|
+
.transition("color 300ms ease-in-out, background 300ms ease-in-out")
|
|
607
|
+
.border_radius("50%")
|
|
608
|
+
.margin_right(15)
|
|
609
|
+
.flex_shrink(0)
|
|
610
|
+
.center()
|
|
611
|
+
.center_vertical()
|
|
612
|
+
.border(1, this._style.divider_bg),
|
|
613
|
+
Text(item)
|
|
614
|
+
.color(index === 0 ? this._style.fg : this._style.fg_1)
|
|
615
|
+
.transition("color 300ms ease-in-out")
|
|
616
|
+
.padding(0)
|
|
617
|
+
.font_size(14)
|
|
618
|
+
.line_height(16)
|
|
619
|
+
)
|
|
620
|
+
.center_vertical()
|
|
621
|
+
.margin_right(25);
|
|
622
|
+
return stack;
|
|
623
|
+
}
|
|
624
|
+
),
|
|
625
|
+
Spacer().min_frame(10, 1),
|
|
626
|
+
this._prev_step_button,
|
|
627
|
+
)
|
|
628
|
+
.overflow_x("scroll")
|
|
629
|
+
.class("hide_scrollbar")
|
|
630
|
+
.extend(
|
|
631
|
+
{
|
|
632
|
+
selected_index: 0,
|
|
633
|
+
/**
|
|
634
|
+
* Select the current step index and update UI accordingly.
|
|
635
|
+
* @param index - The index of the step to select.
|
|
636
|
+
*/
|
|
637
|
+
select(index) {
|
|
638
|
+
let e = this.child(this.selected_index);
|
|
639
|
+
e.child(0)
|
|
640
|
+
.color(style.fg_1)
|
|
641
|
+
.background(style.bg_1);
|
|
642
|
+
e.child(1)
|
|
643
|
+
.color(style.fg_1);
|
|
644
|
+
|
|
645
|
+
this.selected_index = index;
|
|
646
|
+
|
|
647
|
+
e = this.child(this.selected_index);
|
|
648
|
+
e.child(0)
|
|
649
|
+
.color(style.selected.fg)
|
|
650
|
+
.background(style.selected.bg);
|
|
651
|
+
e.child(1)
|
|
652
|
+
.color(style.fg);
|
|
653
|
+
|
|
654
|
+
return this;
|
|
655
|
+
},
|
|
656
|
+
|
|
657
|
+
} as HStackElement & {
|
|
658
|
+
selected_index: number
|
|
659
|
+
select(index: number);
|
|
660
|
+
}
|
|
661
|
+
);
|
|
662
|
+
|
|
663
|
+
// Append the steps element to the steps container.
|
|
664
|
+
this._steps_container.append(this._steps_element);
|
|
665
|
+
},
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Render the overview element in the UI.
|
|
669
|
+
*/
|
|
670
|
+
_render_overview_element: function (): void {
|
|
671
|
+
// The subtotal price from the overview.
|
|
672
|
+
this._overview_subtotal = Text(`${this._currency_symbol == null ? "$" : this._currency_symbol} 0.00`)
|
|
673
|
+
.color(this._style.fg)
|
|
674
|
+
.font_size(this._style.font_size)
|
|
675
|
+
.flex_shrink(0)
|
|
676
|
+
.margin(0)
|
|
677
|
+
.padding(0);
|
|
678
|
+
|
|
679
|
+
// The total price from the overview.
|
|
680
|
+
this._overview_total = Text(`${this._currency_symbol == null ? "$" : this._currency_symbol} 0.00`)
|
|
681
|
+
.font_weight("bold")
|
|
682
|
+
.color(this._style.fg)
|
|
683
|
+
.font_size(this._style.font_size)
|
|
684
|
+
.flex_shrink(0)
|
|
685
|
+
.margin(0)
|
|
686
|
+
.padding(0);
|
|
687
|
+
|
|
688
|
+
// The subtotal VAT price from the overview.
|
|
689
|
+
this._overview_subtotal_tax = Text(`${this._currency_symbol == null ? "$" : this._currency_symbol} 0.00`)
|
|
690
|
+
.color(this._style.fg)
|
|
691
|
+
.font_size(this._style.font_size)
|
|
692
|
+
.flex_shrink(0)
|
|
693
|
+
.margin(0)
|
|
694
|
+
.padding(0);
|
|
695
|
+
|
|
696
|
+
// The tax stack.
|
|
697
|
+
this._overview_tax_container = HStack(
|
|
698
|
+
Text("Tax:")
|
|
699
|
+
.color(this._style.fg)
|
|
700
|
+
.font_size(this._style.font_size)
|
|
701
|
+
.stretch(true)
|
|
702
|
+
.flex_shrink(0)
|
|
703
|
+
.margin(0, 5, 0, 0)
|
|
704
|
+
.padding(0)
|
|
705
|
+
.wrap(false)
|
|
706
|
+
.overflow("hidden")
|
|
707
|
+
.text_overflow("ellipsis"),
|
|
708
|
+
this._overview_subtotal_tax,
|
|
709
|
+
)
|
|
710
|
+
.margin_top(5);
|
|
711
|
+
|
|
712
|
+
// The incl/excl tax text.
|
|
713
|
+
this._overview_incl_excl_tax = Text(this.tax_inclusive ? "incl. tax" : "excl. tax")
|
|
714
|
+
.color(this._style.fg_2)
|
|
715
|
+
.font_size(this._style.font_size - 6)
|
|
716
|
+
.margin(2.5, 0, 0, 0)
|
|
717
|
+
.padding(0)
|
|
718
|
+
.flex_shrink(0)
|
|
719
|
+
.text_trailing();
|
|
720
|
+
|
|
721
|
+
// The checkout button.
|
|
722
|
+
this._checkout_button = LoaderButton("Next")
|
|
723
|
+
.color(this._style.button.fg)
|
|
724
|
+
.background(this._style.button.bg)
|
|
725
|
+
.border_radius(this._style.button.border_radius)
|
|
726
|
+
.border(this._style.button.border_inset ? `${this._style.button.border_width} inset ${this._style.button.border_color}` : `${this._style.button.border_width} solid ${this._style.button.border_color}`)
|
|
727
|
+
.hover_brightness(...this._style.button.hover_brightness as [any, any])
|
|
728
|
+
.nodes.loader
|
|
729
|
+
.background(this._style.button.fg)
|
|
730
|
+
.update()
|
|
731
|
+
.parent<LoaderButtonElement>()
|
|
732
|
+
.on_click(async () => {
|
|
733
|
+
this._checkout_button.show_loader();
|
|
734
|
+
Payments._next()
|
|
735
|
+
.then(() => {
|
|
736
|
+
this._checkout_button.hide_loader();
|
|
737
|
+
})
|
|
738
|
+
.catch((err: any) => {
|
|
739
|
+
console.error(err);
|
|
740
|
+
this._checkout_button.hide_loader();
|
|
741
|
+
});
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
// Accept agreements (currently commented out).
|
|
745
|
+
// this._policy_checkbox = CheckBox({
|
|
746
|
+
// text: "I agree to the Terms and Conditions and the " +
|
|
747
|
+
// Link("Refund", this._refund_policy) +
|
|
748
|
+
// " and " +
|
|
749
|
+
// Link("Cancellation", this._cancellation_policy) +
|
|
750
|
+
// " policy. I agree that my payment method may be used for recurring subscriptions.",
|
|
751
|
+
// required: true
|
|
752
|
+
// }) // @todo check text.
|
|
753
|
+
// .color(this._style.fg_2)
|
|
754
|
+
// .border_color(this._style.divider_bg)
|
|
755
|
+
// .font_size(this._style.font_size - 6)
|
|
756
|
+
// .focus_color(this._style.theme_fg)
|
|
757
|
+
// .missing_color(this._style.missing_fg)
|
|
758
|
+
// .inner_bg(this._style.bg)
|
|
759
|
+
// .margin_bottom(15)
|
|
760
|
+
// .hide();
|
|
761
|
+
|
|
762
|
+
// The overview element.
|
|
763
|
+
this._overview_element = VStack(
|
|
764
|
+
Title("Overview")
|
|
765
|
+
.color(this._style.fg)
|
|
766
|
+
.width("fit-content")
|
|
767
|
+
.font_size(this._style.font_size - 2)
|
|
768
|
+
.flex_shrink(0)
|
|
769
|
+
.margin(0, 0, 15, 0)
|
|
770
|
+
.letter_spacing("1px")
|
|
771
|
+
.text_transform("uppercase")
|
|
772
|
+
.ellipsis_overflow(true),
|
|
773
|
+
|
|
774
|
+
HStack(
|
|
775
|
+
Text("Subtotal:")
|
|
776
|
+
.color(this._style.fg)
|
|
777
|
+
.font_size(this._style.font_size)
|
|
778
|
+
.stretch(true)
|
|
779
|
+
.flex_shrink(0)
|
|
780
|
+
.margin(0, 5, 0, 0)
|
|
781
|
+
.padding(0)
|
|
782
|
+
.wrap(false)
|
|
783
|
+
.overflow("hidden")
|
|
784
|
+
.text_overflow("ellipsis"),
|
|
785
|
+
this._overview_subtotal,
|
|
786
|
+
),
|
|
787
|
+
// Uncomment and define Shipping if needed.
|
|
788
|
+
// HStack(
|
|
789
|
+
// Text("Shipping:")
|
|
790
|
+
// .color(this._style.fg_1)
|
|
791
|
+
// .font_size(this._style.font_size)
|
|
792
|
+
// .stretch(true)
|
|
793
|
+
// .flex_shrink(0)
|
|
794
|
+
// .margin(0, 5, 0, 0)
|
|
795
|
+
// .padding(0)
|
|
796
|
+
// .wrap(false)
|
|
797
|
+
// .overflow("hidden")
|
|
798
|
+
// .text_overflow("ellipsis"),
|
|
799
|
+
// Text("free")
|
|
800
|
+
// .color(this._style.fg_1)
|
|
801
|
+
// .font_size(this._style.font_size)
|
|
802
|
+
// .flex_shrink(0)
|
|
803
|
+
// .margin(0)
|
|
804
|
+
// .padding(0)
|
|
805
|
+
// .wrap(false)
|
|
806
|
+
// .overflow("hidden")
|
|
807
|
+
// .text_overflow("ellipsis"),
|
|
808
|
+
// )
|
|
809
|
+
// .margin_top(5),
|
|
810
|
+
this._overview_tax_container,
|
|
811
|
+
Divider()
|
|
812
|
+
.margin(20, 0, 20, 0)
|
|
813
|
+
.background(this._style.divider_bg),
|
|
814
|
+
HStack(
|
|
815
|
+
Text("Total:")
|
|
816
|
+
.font_weight("bold")
|
|
817
|
+
.color(this._style.fg)
|
|
818
|
+
.font_size(this._style.font_size)
|
|
819
|
+
.stretch(true)
|
|
820
|
+
.flex_shrink(0)
|
|
821
|
+
.margin(0, 5, 0, 0)
|
|
822
|
+
.padding(0)
|
|
823
|
+
.wrap(false)
|
|
824
|
+
.overflow("hidden")
|
|
825
|
+
.text_overflow("ellipsis"),
|
|
826
|
+
VStack(
|
|
827
|
+
this._overview_total,
|
|
828
|
+
this._overview_incl_excl_tax,
|
|
829
|
+
),
|
|
830
|
+
)
|
|
831
|
+
.margin_bottom(25),
|
|
832
|
+
// this._policy_checkbox,
|
|
833
|
+
this._checkout_button,
|
|
834
|
+
)
|
|
835
|
+
.extend({
|
|
836
|
+
total: 0,
|
|
837
|
+
tax: 0,
|
|
838
|
+
/**
|
|
839
|
+
* Handle unknown tax scenarios by updating the UI accordingly.
|
|
840
|
+
*/
|
|
841
|
+
unknown_tax: () => {
|
|
842
|
+
this._overview_incl_excl_tax.text(this.tax_inclusive ? "incl. tax" : "excl. tax");
|
|
843
|
+
this._overview_tax_container.hide();
|
|
844
|
+
this._overview_element.tax = 0;
|
|
845
|
+
this._overview_total.text(`${this._currency_symbol} ${this._overview_element.total.toFixed(2)}`);
|
|
846
|
+
},
|
|
847
|
+
/**
|
|
848
|
+
* Calculate tax based on the provided country code.
|
|
849
|
+
* @param country - The country code to calculate tax for.
|
|
850
|
+
*/
|
|
851
|
+
calc_tax: async (country: string) => {
|
|
852
|
+
this._initialize_paddle();
|
|
853
|
+
try {
|
|
854
|
+
const result = await Paddle.PricePreview({
|
|
855
|
+
items: this.cart.items.map((item: any) => {
|
|
856
|
+
return { priceId: item.product.price_id, quantity: item.quantity };
|
|
857
|
+
}),
|
|
858
|
+
address: { countryCode: country },
|
|
859
|
+
});
|
|
860
|
+
this._overview_element.tax = 0;
|
|
861
|
+
result.data.details.lineItems.forEach((item: any) => {
|
|
862
|
+
this._overview_element.tax += parseInt(item.totals.tax) / 100;
|
|
863
|
+
});
|
|
864
|
+
this._overview_tax_container.show();
|
|
865
|
+
this._overview_incl_excl_tax.text("incl. tax");
|
|
866
|
+
this._overview_subtotal_tax.text(`${this._currency_symbol} ${this._overview_element.tax.toFixed(2)}`);
|
|
867
|
+
this._overview_total.text(`${this._currency_symbol} ${(this._overview_element.total + this._overview_element.tax).toFixed(2)}`);
|
|
868
|
+
} catch (error: any) {
|
|
869
|
+
if (error?.error?.detail) {
|
|
870
|
+
this.on_error(error.error.detail);
|
|
871
|
+
console.error(error);
|
|
872
|
+
} else {
|
|
873
|
+
console.error(error);
|
|
874
|
+
}
|
|
875
|
+
this._overview_element.unknown_tax();
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
// Append the overview element to the overview container.
|
|
881
|
+
this._overview_container.append(this._overview_element);
|
|
882
|
+
},
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Render the order element in the UI.
|
|
886
|
+
*/
|
|
887
|
+
_render_order_element: function (): void {
|
|
888
|
+
// Render.
|
|
889
|
+
interface Extension extends VStackElement {
|
|
890
|
+
refresh(this: Extension): Extension;
|
|
891
|
+
}
|
|
892
|
+
this._order_element = VStack()
|
|
893
|
+
.extend({
|
|
894
|
+
/**
|
|
895
|
+
* Refresh the order element by updating the cart and UI elements.
|
|
896
|
+
*/
|
|
897
|
+
refresh(this) {
|
|
898
|
+
|
|
899
|
+
// Refresh the cart.
|
|
900
|
+
Payments.cart.refresh();
|
|
901
|
+
|
|
902
|
+
// Shortcuts.
|
|
903
|
+
const style = Payments._style;
|
|
904
|
+
const cart = Payments.cart;
|
|
905
|
+
const cart_items = Payments.cart.items;
|
|
906
|
+
|
|
907
|
+
// Shopping cart view.
|
|
908
|
+
let currency_symbol: string | null = null;
|
|
909
|
+
let subtotal = 0;
|
|
910
|
+
cart_items.forEach((item: any) => {
|
|
911
|
+
if (currency_symbol === null) {
|
|
912
|
+
currency_symbol = Payments.get_currency_symbol(item.product.currency);
|
|
913
|
+
}
|
|
914
|
+
subtotal += item.product.price * item.quantity;
|
|
915
|
+
});
|
|
916
|
+
if (currency_symbol === null) {
|
|
917
|
+
currency_symbol = "$";
|
|
918
|
+
}
|
|
919
|
+
Payments._currency_symbol = currency_symbol;
|
|
920
|
+
|
|
921
|
+
// Set the overview prices.
|
|
922
|
+
Payments._overview_subtotal.text(`${currency_symbol} ${subtotal.toFixed(2)}`);
|
|
923
|
+
Payments._overview_element.total = subtotal;
|
|
924
|
+
Payments._overview_element.unknown_tax();
|
|
925
|
+
|
|
926
|
+
// Add the products.
|
|
927
|
+
this.remove_children();
|
|
928
|
+
if (cart_items.length === 0) {
|
|
929
|
+
this.height(160);
|
|
930
|
+
this.append(
|
|
931
|
+
VStack(
|
|
932
|
+
Title("Empty Shopping Cart")
|
|
933
|
+
.color(style.fg_1)
|
|
934
|
+
.font_size(style.font_size - 2)
|
|
935
|
+
.flex_shrink(0)
|
|
936
|
+
.letter_spacing("1px")
|
|
937
|
+
.text_transform("uppercase")
|
|
938
|
+
.ellipsis_overflow(true)
|
|
939
|
+
.margin(0)
|
|
940
|
+
.padding(0)
|
|
941
|
+
.assign_to_parent_as("title_e"),
|
|
942
|
+
Text(`Your shopping cart is empty.`)
|
|
943
|
+
.color(style.fg_2)
|
|
944
|
+
.font_size(style.font_size - 2)
|
|
945
|
+
.line_height(style.font_size)
|
|
946
|
+
.margin(5, 0, 0, 0)
|
|
947
|
+
.padding(0)
|
|
948
|
+
.assign_to_parent_as("text_e")
|
|
949
|
+
.white_space("pre")
|
|
950
|
+
.line_height("1.4em")
|
|
951
|
+
.center(),
|
|
952
|
+
ImageMask("/volt_static/payments/shopping_cart.webp")
|
|
953
|
+
.frame(35, 35)
|
|
954
|
+
.margin_top(20)
|
|
955
|
+
.mask_color(style.theme_fg),
|
|
956
|
+
)
|
|
957
|
+
.frame("100%", "100%")
|
|
958
|
+
.center()
|
|
959
|
+
.center_vertical()
|
|
960
|
+
);
|
|
961
|
+
} else {
|
|
962
|
+
// Uncomment and adjust height if necessary.
|
|
963
|
+
// this.height("100%");
|
|
964
|
+
this.append(
|
|
965
|
+
Title("Order Details")
|
|
966
|
+
.color(style.fg)
|
|
967
|
+
.width("fit-content")
|
|
968
|
+
.font_size(style.font_size - 2)
|
|
969
|
+
.flex_shrink(0)
|
|
970
|
+
.margin(0, 0, 0, 0)
|
|
971
|
+
.letter_spacing("1px")
|
|
972
|
+
.text_transform("uppercase")
|
|
973
|
+
.ellipsis_overflow(true),
|
|
974
|
+
|
|
975
|
+
Divider()
|
|
976
|
+
.background(style.divider_bg)
|
|
977
|
+
.margin(10, 0, 20, 0),
|
|
978
|
+
|
|
979
|
+
ForEach(cart_items, (item: any, index: number) => {
|
|
980
|
+
let focus = false, mouse_over = false;
|
|
981
|
+
const quantity_input = Input("Quantity")
|
|
982
|
+
.value(item.quantity)
|
|
983
|
+
.font_size(16)
|
|
984
|
+
.color(style.fg_1)
|
|
985
|
+
.font_size(style.font_size - 2)
|
|
986
|
+
.border(1, style.divider_bg)
|
|
987
|
+
// .padding(12.5, 10, 12.5, 10)
|
|
988
|
+
.padding(2.5, 7.5)
|
|
989
|
+
.margin_right(25)
|
|
990
|
+
.flex_shrink(0)
|
|
991
|
+
.width(`calc(${item.quantity.toString().length}ch + 17.5px)`) // add padding.
|
|
992
|
+
.background(style.bg_1)
|
|
993
|
+
.display("inline")
|
|
994
|
+
.transition("color 300ms ease-in-out")
|
|
995
|
+
.center()
|
|
996
|
+
.on_input((_, event: any) => {
|
|
997
|
+
const value = quantity_input.value();
|
|
998
|
+
quantity_input.width(`calc(${value.length}ch + 17.5px)`); // add padding.
|
|
999
|
+
clearTimeout((quantity_input as any)._timeout);
|
|
1000
|
+
(quantity_input as any)._timeout = setTimeout(() => {
|
|
1001
|
+
const quantity = parseInt(value);
|
|
1002
|
+
if (isNaN(quantity)) {
|
|
1003
|
+
console.error(`Specified quantity "${value}" is not a number.`);
|
|
1004
|
+
Payments.on_error(new Error(`Specified quantity "${value}" is not a number.`));
|
|
1005
|
+
quantity_input.value(item.quantity.toString());
|
|
1006
|
+
return null;
|
|
1007
|
+
}
|
|
1008
|
+
item.quantity = quantity;
|
|
1009
|
+
cart.save();
|
|
1010
|
+
this.refresh();
|
|
1011
|
+
}, 500);
|
|
1012
|
+
})
|
|
1013
|
+
.on_mouse_over_out(
|
|
1014
|
+
(e: any) => {
|
|
1015
|
+
e.color(style.fg);
|
|
1016
|
+
mouse_over = true;
|
|
1017
|
+
e.mask_color(style.fg);
|
|
1018
|
+
},
|
|
1019
|
+
(e: any) => {
|
|
1020
|
+
mouse_over = false;
|
|
1021
|
+
if (!mouse_over && !focus) {
|
|
1022
|
+
e.color(style.fg_1);
|
|
1023
|
+
}
|
|
1024
|
+
},
|
|
1025
|
+
)
|
|
1026
|
+
.on_focus((e: any) => {
|
|
1027
|
+
e.color(style.fg);
|
|
1028
|
+
focus = true;
|
|
1029
|
+
})
|
|
1030
|
+
.on_blur((e: any) => {
|
|
1031
|
+
focus = false;
|
|
1032
|
+
if (!mouse_over && !focus) {
|
|
1033
|
+
e.color(style.fg_1);
|
|
1034
|
+
}
|
|
1035
|
+
});
|
|
1036
|
+
|
|
1037
|
+
let per_item = " per item" + (Payments.tax_inclusive ? " incl. tax" : " excl. tax") + ",";
|
|
1038
|
+
let renews_every: string | null = null;
|
|
1039
|
+
if (item.product.interval) {
|
|
1040
|
+
if (item.product.frequency === 1) {
|
|
1041
|
+
renews_every = `renews ${item.product.interval}ly.`;
|
|
1042
|
+
} else {
|
|
1043
|
+
renews_every = `renews every ${item.product.frequency} ${item.product.interval}s.`;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
let trial_text: string | null = null;
|
|
1047
|
+
if (item.product.trial) {
|
|
1048
|
+
if (item.product.trial.frequency === 1) {
|
|
1049
|
+
trial_text = `${item.product.trial.frequency} ${item.product.trial.interval} free`;
|
|
1050
|
+
} else {
|
|
1051
|
+
trial_text = `${item.product.trial.frequency} ${item.product.trial.interval}s free`;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
const stack = HStack(
|
|
1055
|
+
item.product.icon == null ? null :
|
|
1056
|
+
ImageMask(item.product.icon)
|
|
1057
|
+
.frame(30, 30)
|
|
1058
|
+
.flex_shrink(0)
|
|
1059
|
+
.margin(0, 25, 0, 0),
|
|
1060
|
+
VStack(
|
|
1061
|
+
Title(item.product.name)
|
|
1062
|
+
.color(style.fg)
|
|
1063
|
+
.font_size(style.font_size)
|
|
1064
|
+
.margin(0, 10, 0, 0)
|
|
1065
|
+
.padding(0)
|
|
1066
|
+
.wrap(false)
|
|
1067
|
+
.overflow("hidden")
|
|
1068
|
+
.text_overflow("ellipsis"),
|
|
1069
|
+
Text(item.product.description)
|
|
1070
|
+
.color(style.fg_1)
|
|
1071
|
+
.font_size(style.font_size - 2)
|
|
1072
|
+
.line_height(style.font_size)
|
|
1073
|
+
.margin(10, 10, 0, 0)
|
|
1074
|
+
.wrap(true)
|
|
1075
|
+
.padding(0),
|
|
1076
|
+
HStack(
|
|
1077
|
+
Text("Quantity:")
|
|
1078
|
+
.color(style.fg_1)
|
|
1079
|
+
.font_size(style.font_size - 2)
|
|
1080
|
+
// .line_height(style.font_size)
|
|
1081
|
+
.margin(0, 10, 2, 0)
|
|
1082
|
+
.padding(0)
|
|
1083
|
+
.flex_shrink(0),
|
|
1084
|
+
quantity_input,
|
|
1085
|
+
ImageMask("/volt_static/payments/minus.webp")
|
|
1086
|
+
.frame(20, 20)
|
|
1087
|
+
.padding(5)
|
|
1088
|
+
.margin_right(5)
|
|
1089
|
+
.mask_color(style.fg_1)
|
|
1090
|
+
.background(style.bg_1)
|
|
1091
|
+
.border(1, style.divider_bg)
|
|
1092
|
+
.border_radius("50%")
|
|
1093
|
+
.flex_shrink(0)
|
|
1094
|
+
.transition_mask("background 300ms ease-in-out")
|
|
1095
|
+
.on_mouse_over_out(
|
|
1096
|
+
(e: any) => e.mask_color(style.fg),
|
|
1097
|
+
(e: any) => e.mask_color(style.fg_1)
|
|
1098
|
+
)
|
|
1099
|
+
.on_click(async () => {
|
|
1100
|
+
if (item.quantity === 1) {
|
|
1101
|
+
await cart.remove(item.product.id, "all");
|
|
1102
|
+
this.refresh();
|
|
1103
|
+
} else {
|
|
1104
|
+
await cart.remove(item.product.id, 1);
|
|
1105
|
+
this.refresh();
|
|
1106
|
+
}
|
|
1107
|
+
}),
|
|
1108
|
+
ImageMask("/volt_static/payments/plus.webp")
|
|
1109
|
+
.frame(20, 20)
|
|
1110
|
+
.padding(5)
|
|
1111
|
+
.margin_right(5)
|
|
1112
|
+
.mask_color(style.fg_1)
|
|
1113
|
+
.background(style.bg_1)
|
|
1114
|
+
.border(1, style.divider_bg)
|
|
1115
|
+
.border_radius("50%")
|
|
1116
|
+
.flex_shrink(0)
|
|
1117
|
+
.transition_mask("background 300ms ease-in-out")
|
|
1118
|
+
.on_mouse_over_out(
|
|
1119
|
+
(e: any) => e.mask_color(style.fg),
|
|
1120
|
+
(e: any) => e.mask_color(style.fg_1)
|
|
1121
|
+
)
|
|
1122
|
+
.on_click(async () => {
|
|
1123
|
+
await cart.add(item.product.id, 1);
|
|
1124
|
+
this.refresh();
|
|
1125
|
+
}),
|
|
1126
|
+
ImageMask("/volt_static/payments/trash.webp")
|
|
1127
|
+
.frame(20, 20)
|
|
1128
|
+
.padding(5)
|
|
1129
|
+
.margin_right(5)
|
|
1130
|
+
.mask_color(style.fg_1)
|
|
1131
|
+
.background(style.bg_1)
|
|
1132
|
+
.border(1, style.divider_bg)
|
|
1133
|
+
.border_radius("50%")
|
|
1134
|
+
.flex_shrink(0)
|
|
1135
|
+
.transition_mask("background 300ms ease-in-out")
|
|
1136
|
+
.on_mouse_over_out(
|
|
1137
|
+
(e: any) => e.mask_color(style.fg),
|
|
1138
|
+
(e: any) => e.mask_color(style.fg_1)
|
|
1139
|
+
)
|
|
1140
|
+
.on_click(async () => {
|
|
1141
|
+
await cart.remove(item.product.id, "all");
|
|
1142
|
+
this.refresh();
|
|
1143
|
+
}),
|
|
1144
|
+
)
|
|
1145
|
+
.center_vertical()
|
|
1146
|
+
.wrap(true)
|
|
1147
|
+
.margin_top(17.5),
|
|
1148
|
+
)
|
|
1149
|
+
.stretch(true),
|
|
1150
|
+
VStack(
|
|
1151
|
+
Title(trial_text ? trial_text : `${currency_symbol} ${(item.product.price * item.quantity).toFixed(2)}`)
|
|
1152
|
+
.color(style.fg)
|
|
1153
|
+
.font_size(style.font_size)
|
|
1154
|
+
.margin(0)
|
|
1155
|
+
.padding(0)
|
|
1156
|
+
.flex_shrink(0)
|
|
1157
|
+
.wrap(false)
|
|
1158
|
+
.overflow("hidden")
|
|
1159
|
+
.text_overflow("ellipsis"),
|
|
1160
|
+
Text(`${trial_text ? "Then " : ""}${currency_symbol} ${item.product.price} ${per_item}`)
|
|
1161
|
+
.color(style.fg_1)
|
|
1162
|
+
.font_size(style.font_size - 6)
|
|
1163
|
+
.margin(5, 0, 0, 0)
|
|
1164
|
+
.padding(0)
|
|
1165
|
+
.flex_shrink(0),
|
|
1166
|
+
renews_every == null ? null : Text(renews_every)
|
|
1167
|
+
.color(style.fg_1)
|
|
1168
|
+
.font_size(style.font_size - 6)
|
|
1169
|
+
.margin(2.5, 0, 0, 0)
|
|
1170
|
+
.padding(0)
|
|
1171
|
+
.flex_shrink(0),
|
|
1172
|
+
)
|
|
1173
|
+
)
|
|
1174
|
+
.overflow_x("scroll")
|
|
1175
|
+
.class("hide_scrollbar")
|
|
1176
|
+
.width("100%")
|
|
1177
|
+
.media(
|
|
1178
|
+
"width >= 800px",
|
|
1179
|
+
(e: any) => {
|
|
1180
|
+
e.wrap(false);
|
|
1181
|
+
e.child(2).min_width("none")
|
|
1182
|
+
.margin(0);
|
|
1183
|
+
},
|
|
1184
|
+
(e: any) => {
|
|
1185
|
+
e.wrap(true);
|
|
1186
|
+
e.child(2)
|
|
1187
|
+
.min_width("100%")
|
|
1188
|
+
.margin(15, 0, 0, 55);
|
|
1189
|
+
},
|
|
1190
|
+
);
|
|
1191
|
+
return [
|
|
1192
|
+
stack,
|
|
1193
|
+
index === cart_items.length - 1 ? null : Divider()
|
|
1194
|
+
.background(style.divider_bg)
|
|
1195
|
+
.margin(20, 0, 20, 0)
|
|
1196
|
+
];
|
|
1197
|
+
})
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
return this;
|
|
1201
|
+
}
|
|
1202
|
+
} as Extension);
|
|
1203
|
+
|
|
1204
|
+
// Append the order element to the order container.
|
|
1205
|
+
this._order_container.append(this._order_element.refresh());
|
|
1206
|
+
},
|
|
1207
|
+
|
|
1208
|
+
// Render the refunds element.
|
|
1209
|
+
_render_refunds_element: function(): void {
|
|
1210
|
+
// Render.
|
|
1211
|
+
const style = this._style;
|
|
1212
|
+
this._refunds_element = VStack()
|
|
1213
|
+
.extend({
|
|
1214
|
+
/**
|
|
1215
|
+
* Refresh the refunds element by fetching and displaying refundable, refunding, and refunded payments.
|
|
1216
|
+
*/
|
|
1217
|
+
async refresh(this: VStackElement) {
|
|
1218
|
+
// Reset.
|
|
1219
|
+
this.inner_html("");
|
|
1220
|
+
|
|
1221
|
+
// Create containers.
|
|
1222
|
+
let payments = await Payments.get_refundable_payments({
|
|
1223
|
+
days: Payments._days_refundable,
|
|
1224
|
+
});
|
|
1225
|
+
const refundable_container = VStack()
|
|
1226
|
+
.extend({
|
|
1227
|
+
title: "Refundable Payments",
|
|
1228
|
+
payments: payments,
|
|
1229
|
+
is_refundable: true,
|
|
1230
|
+
});
|
|
1231
|
+
payments = await Payments.get_refunding_payments();
|
|
1232
|
+
const refunding_container = VStack()
|
|
1233
|
+
.hide()
|
|
1234
|
+
.extend({
|
|
1235
|
+
title: "Processing Refunds",
|
|
1236
|
+
payments: payments,
|
|
1237
|
+
is_refunding: true,
|
|
1238
|
+
});
|
|
1239
|
+
payments = await Payments.get_refunded_payments();
|
|
1240
|
+
const refunded_container = VStack()
|
|
1241
|
+
.hide()
|
|
1242
|
+
.extend({
|
|
1243
|
+
title: "Refunded Payments",
|
|
1244
|
+
payments: payments,
|
|
1245
|
+
is_refunded: true,
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
// Option bar.
|
|
1249
|
+
const option_bar = HStack(
|
|
1250
|
+
Text("Refundable")
|
|
1251
|
+
.font_size(style.font_size)
|
|
1252
|
+
.color(style.fg_1)
|
|
1253
|
+
.background(style.bg_1)
|
|
1254
|
+
.padding(8, 6)
|
|
1255
|
+
.margin(0)
|
|
1256
|
+
.stretch(true)
|
|
1257
|
+
.text_center()
|
|
1258
|
+
.transition("color 350ms ease, background 350ms ease")
|
|
1259
|
+
.on_mouse_over((e: any) => {
|
|
1260
|
+
if (e.background() === "transparent") {
|
|
1261
|
+
e.color(style.fg);
|
|
1262
|
+
}
|
|
1263
|
+
})
|
|
1264
|
+
.on_mouse_out((e: any) => {
|
|
1265
|
+
if (e.background() === "transparent") {
|
|
1266
|
+
e.color(style.fg_1);
|
|
1267
|
+
}
|
|
1268
|
+
})
|
|
1269
|
+
.on_click((e: any) => {
|
|
1270
|
+
e.color(Payments._style.fg_1);
|
|
1271
|
+
e.background(Payments._style.bg_1);
|
|
1272
|
+
[e.parentElement.child(1), e.parentElement.child(2)].forEach((child: any) => {
|
|
1273
|
+
child.color(Payments._style.fg_1);
|
|
1274
|
+
child.background("none");
|
|
1275
|
+
});
|
|
1276
|
+
|
|
1277
|
+
refundable_container.show();
|
|
1278
|
+
refunding_container.hide();
|
|
1279
|
+
refunded_container.hide();
|
|
1280
|
+
}),
|
|
1281
|
+
Text("Processing")
|
|
1282
|
+
.font_size(style.font_size)
|
|
1283
|
+
.color(style.fg_1)
|
|
1284
|
+
.background("transparent")
|
|
1285
|
+
.padding(8, 6)
|
|
1286
|
+
.margin(0)
|
|
1287
|
+
.stretch(true)
|
|
1288
|
+
.text_center()
|
|
1289
|
+
.transition("color 350ms ease, background 350ms ease")
|
|
1290
|
+
.on_mouse_over((e: any) => {
|
|
1291
|
+
if (e.background() === "transparent") {
|
|
1292
|
+
e.color(style.fg);
|
|
1293
|
+
}
|
|
1294
|
+
})
|
|
1295
|
+
.on_mouse_out((e: any) => {
|
|
1296
|
+
if (e.background() === "transparent") {
|
|
1297
|
+
e.color(style.fg_1);
|
|
1298
|
+
}
|
|
1299
|
+
})
|
|
1300
|
+
.on_click((e: any) => {
|
|
1301
|
+
e.color(Payments._style.fg_1);
|
|
1302
|
+
e.background(Payments._style.bg_1);
|
|
1303
|
+
[e.parentElement.child(0), e.parentElement.child(2)].forEach((child: any) => {
|
|
1304
|
+
child.color(Payments._style.fg_1);
|
|
1305
|
+
child.background("none");
|
|
1306
|
+
});
|
|
1307
|
+
|
|
1308
|
+
refundable_container.hide();
|
|
1309
|
+
refunding_container.show();
|
|
1310
|
+
refunded_container.hide();
|
|
1311
|
+
}),
|
|
1312
|
+
Text("Refunded")
|
|
1313
|
+
.font_size(style.font_size)
|
|
1314
|
+
.color(style.fg_1)
|
|
1315
|
+
.background("transparent")
|
|
1316
|
+
.padding(8, 6)
|
|
1317
|
+
.margin(0)
|
|
1318
|
+
.stretch(true)
|
|
1319
|
+
.text_center()
|
|
1320
|
+
.transition("color 350ms ease, background 350ms ease")
|
|
1321
|
+
.on_mouse_over((e: any) => {
|
|
1322
|
+
if (e.background() === "transparent") {
|
|
1323
|
+
e.color(style.fg);
|
|
1324
|
+
}
|
|
1325
|
+
})
|
|
1326
|
+
.on_mouse_out((e: any) => {
|
|
1327
|
+
if (e.background() === "transparent") {
|
|
1328
|
+
e.color(style.fg_1);
|
|
1329
|
+
}
|
|
1330
|
+
})
|
|
1331
|
+
.on_click((e: any) => {
|
|
1332
|
+
e.color(Payments._style.fg_1);
|
|
1333
|
+
e.background(Payments._style.bg_1);
|
|
1334
|
+
[e.parentElement.child(0), e.parentElement.child(1)].forEach((child: any) => {
|
|
1335
|
+
child.color(Payments._style.fg_1);
|
|
1336
|
+
child.background("none");
|
|
1337
|
+
});
|
|
1338
|
+
|
|
1339
|
+
refundable_container.hide();
|
|
1340
|
+
refunding_container.hide();
|
|
1341
|
+
refunded_container.show();
|
|
1342
|
+
}),
|
|
1343
|
+
)
|
|
1344
|
+
.overflow("hidden")
|
|
1345
|
+
.border(1, style.divider_bg)
|
|
1346
|
+
.border_radius(style.border_radius)
|
|
1347
|
+
.margin_bottom(30)
|
|
1348
|
+
.flex_shrink(0);
|
|
1349
|
+
|
|
1350
|
+
// Assign to parent.
|
|
1351
|
+
const refundable_option = option_bar.child(0);
|
|
1352
|
+
const refunding_option = option_bar.child(1);
|
|
1353
|
+
const refunded_option = option_bar.child(2);
|
|
1354
|
+
|
|
1355
|
+
// Add elements.
|
|
1356
|
+
this.append(
|
|
1357
|
+
option_bar,
|
|
1358
|
+
refundable_container,
|
|
1359
|
+
refunding_container,
|
|
1360
|
+
refunded_container,
|
|
1361
|
+
);
|
|
1362
|
+
|
|
1363
|
+
// Separate payments.
|
|
1364
|
+
let currency_symbol: string | null = null;
|
|
1365
|
+
await Promise.all([refundable_container, refunding_container, refunded_container].map(async (container: any) => {
|
|
1366
|
+
if (container.payments.length === 0) {
|
|
1367
|
+
container.append(
|
|
1368
|
+
VStack(
|
|
1369
|
+
Title("No Payments")
|
|
1370
|
+
.color(style.fg)
|
|
1371
|
+
.font_size(style.font_size - 2)
|
|
1372
|
+
.flex_shrink(0)
|
|
1373
|
+
.letter_spacing("1px")
|
|
1374
|
+
.text_transform("uppercase")
|
|
1375
|
+
.ellipsis_overflow(true)
|
|
1376
|
+
.margin(0)
|
|
1377
|
+
.padding(0)
|
|
1378
|
+
.assign_to_parent_as("title_e"),
|
|
1379
|
+
Text(`There are no ${container.title.toLowerCase()}.`)
|
|
1380
|
+
.color(style.fg_1)
|
|
1381
|
+
.font_size(style.font_size - 2)
|
|
1382
|
+
.line_height(style.font_size)
|
|
1383
|
+
.margin(5, 0, 0, 0)
|
|
1384
|
+
.padding(0)
|
|
1385
|
+
.assign_to_parent_as("text_e")
|
|
1386
|
+
.white_space("pre")
|
|
1387
|
+
.line_height("1.4em")
|
|
1388
|
+
.center(),
|
|
1389
|
+
Image("/volt_static/payments/check.webp")
|
|
1390
|
+
.frame(30, 30)
|
|
1391
|
+
.margin_top(15)
|
|
1392
|
+
.assign_to_parent_as("success_image_e"),
|
|
1393
|
+
)
|
|
1394
|
+
.min_height(160)
|
|
1395
|
+
.frame("100%", "100%")
|
|
1396
|
+
.center()
|
|
1397
|
+
.center_vertical()
|
|
1398
|
+
);
|
|
1399
|
+
} else {
|
|
1400
|
+
await Promise.all(container.payments.map(async (payment: any) => {
|
|
1401
|
+
await Promise.all(payment.line_items.map(async (item: any) => {
|
|
1402
|
+
item.product = await Payments.get_product(item.product);
|
|
1403
|
+
}));
|
|
1404
|
+
}));
|
|
1405
|
+
container.append(
|
|
1406
|
+
Title(container.title)
|
|
1407
|
+
.color(style.fg)
|
|
1408
|
+
.width("fit-content")
|
|
1409
|
+
.font_size(style.font_size - 2)
|
|
1410
|
+
.flex_shrink(0)
|
|
1411
|
+
.margin(0, 0, 0, 0)
|
|
1412
|
+
.letter_spacing("1px")
|
|
1413
|
+
.text_transform("uppercase")
|
|
1414
|
+
.ellipsis_overflow(true),
|
|
1415
|
+
|
|
1416
|
+
Divider()
|
|
1417
|
+
.background(style.divider_bg)
|
|
1418
|
+
.margin(10, 0, 20, 0),
|
|
1419
|
+
|
|
1420
|
+
ForEach(container.payments, (payment: any, index: number) => {
|
|
1421
|
+
// Line items.
|
|
1422
|
+
const items = VStack(
|
|
1423
|
+
ForEach(payment.line_items, (item: any, index: number) => {
|
|
1424
|
+
if (currency_symbol == null) {
|
|
1425
|
+
currency_symbol = Payments.get_currency_symbol(item.product.currency);
|
|
1426
|
+
}
|
|
1427
|
+
return [
|
|
1428
|
+
HStack(
|
|
1429
|
+
item.product.icon == null ? null :
|
|
1430
|
+
Image(item.product.icon)
|
|
1431
|
+
.frame(25, 25)
|
|
1432
|
+
.flex_shrink(0)
|
|
1433
|
+
.margin(0, 20, 0, 0),
|
|
1434
|
+
VStack(
|
|
1435
|
+
Title(item.product.name)
|
|
1436
|
+
.color(style.fg)
|
|
1437
|
+
.font_size(style.font_size - 2)
|
|
1438
|
+
.line_height(style.font_size)
|
|
1439
|
+
.margin(0, 10, 0, 0)
|
|
1440
|
+
.padding(0)
|
|
1441
|
+
.font_weight("bold")
|
|
1442
|
+
.ellipsis_overflow(true),
|
|
1443
|
+
Text(item.product.description)
|
|
1444
|
+
.color(style.fg_1)
|
|
1445
|
+
.font_size(style.font_size - 4)
|
|
1446
|
+
.line_height(style.font_size - 2)
|
|
1447
|
+
.margin(5, 0, 0, 0)
|
|
1448
|
+
.wrap(true)
|
|
1449
|
+
.padding(0),
|
|
1450
|
+
)
|
|
1451
|
+
.stretch(true),
|
|
1452
|
+
VStack(
|
|
1453
|
+
Text(`${currency_symbol} ${(item.total).toFixed(2)}`)
|
|
1454
|
+
.color(style.fg_1)
|
|
1455
|
+
.font_size(style.font_size - 4)
|
|
1456
|
+
.line_height(style.font_size - 2)
|
|
1457
|
+
.margin(0)
|
|
1458
|
+
.padding(0)
|
|
1459
|
+
.flex_shrink(0)
|
|
1460
|
+
.ellipsis_overflow(true),
|
|
1461
|
+
)
|
|
1462
|
+
),
|
|
1463
|
+
index === payment.line_items.length - 1 ? null : Divider()
|
|
1464
|
+
.background(style.divider_bg)
|
|
1465
|
+
.margin(15, 0, 15, 0),
|
|
1466
|
+
];
|
|
1467
|
+
}),
|
|
1468
|
+
)
|
|
1469
|
+
.background(style.bg_1)
|
|
1470
|
+
.border_radius(style.border_radius)
|
|
1471
|
+
.border(1, style.divider_bg)
|
|
1472
|
+
.padding(20);
|
|
1473
|
+
|
|
1474
|
+
// Payment.
|
|
1475
|
+
const stack = VStack(
|
|
1476
|
+
HStack(
|
|
1477
|
+
Title("Payment")
|
|
1478
|
+
.color(style.fg)
|
|
1479
|
+
.font_size(style.font_size)
|
|
1480
|
+
.margin(0, 10, 0, 0)
|
|
1481
|
+
.padding(0)
|
|
1482
|
+
.wrap(false)
|
|
1483
|
+
.overflow("hidden")
|
|
1484
|
+
.text_overflow("ellipsis")
|
|
1485
|
+
.stretch(true),
|
|
1486
|
+
!container.is_refundable ? null : BorderButton("Refund")
|
|
1487
|
+
.font_size(style.font_size - 4)
|
|
1488
|
+
.padding(7.5, 10)
|
|
1489
|
+
.margin(0, 5, 0, 0)
|
|
1490
|
+
.color(style.button.bg)
|
|
1491
|
+
.border_radius(style.button.border_radius)
|
|
1492
|
+
.border_color(style.button.bg)
|
|
1493
|
+
.hover_brightness(...style.button.hover_brightness as [any, any])
|
|
1494
|
+
.font_weight("bold")
|
|
1495
|
+
.on_click(() => {
|
|
1496
|
+
document.body.appendChild(
|
|
1497
|
+
Popup({
|
|
1498
|
+
title: "Request Refund",
|
|
1499
|
+
text: `You are about to request a refund for payment <span style='border-radius: 7px; background: ${style.bg_1}; padding: 1px 4px; font-size: 0.9em;'>${payment.id}</span>, do you wish to proceed?`,
|
|
1500
|
+
no: "No",
|
|
1501
|
+
yes: "Yes",
|
|
1502
|
+
image: "/volt_static/payments/error.webp",
|
|
1503
|
+
blur: 5,
|
|
1504
|
+
animation_duration: 300,
|
|
1505
|
+
on_yes: async () => {
|
|
1506
|
+
try {
|
|
1507
|
+
await Payments.create_refund(payment);
|
|
1508
|
+
} catch(err) {
|
|
1509
|
+
console.error(err);
|
|
1510
|
+
Payments.on_error(err as Error);
|
|
1511
|
+
return null;
|
|
1512
|
+
}
|
|
1513
|
+
(this as any).refresh().then(() => {
|
|
1514
|
+
refunding_option.click();
|
|
1515
|
+
});
|
|
1516
|
+
},
|
|
1517
|
+
})
|
|
1518
|
+
.font(window.getComputedStyle(Payments._refunds_container).font)
|
|
1519
|
+
.widget
|
|
1520
|
+
.background(style.bg)
|
|
1521
|
+
.color(style.fg_1)
|
|
1522
|
+
.border_bottom("4px solid #E8454E")
|
|
1523
|
+
// .leading()
|
|
1524
|
+
.parent<PopupElement>()
|
|
1525
|
+
.title
|
|
1526
|
+
.color(style.fg)
|
|
1527
|
+
// .width("fit-content")
|
|
1528
|
+
.font_size(style.font_size + 2)
|
|
1529
|
+
.flex_shrink(0)
|
|
1530
|
+
.margin(0, 0, 0, 10)
|
|
1531
|
+
// .letter_spacing("1px")
|
|
1532
|
+
// .text_transform("uppercase")
|
|
1533
|
+
// .ellipsis_overflow(true)
|
|
1534
|
+
// .color(style.fg_1)
|
|
1535
|
+
.center()
|
|
1536
|
+
.parent<PopupElement>()
|
|
1537
|
+
.text
|
|
1538
|
+
.color(style.fg_1)
|
|
1539
|
+
.font_size(style.font_size)
|
|
1540
|
+
.margin_left(10)
|
|
1541
|
+
.center()
|
|
1542
|
+
.parent<PopupElement>()
|
|
1543
|
+
.image
|
|
1544
|
+
.padding(10)
|
|
1545
|
+
.mask_color(style.bg)
|
|
1546
|
+
.border_radius("50%")
|
|
1547
|
+
.background("#E8454E")
|
|
1548
|
+
.frame(40, 40)
|
|
1549
|
+
.box_shadow('0 0 0 4px #E8454E50')
|
|
1550
|
+
.parent<PopupElement>()
|
|
1551
|
+
.no_button
|
|
1552
|
+
.padding(10, 0)
|
|
1553
|
+
.font_size(style.font_size)
|
|
1554
|
+
.background(style.bg_1)
|
|
1555
|
+
.color(style.fg_1)
|
|
1556
|
+
.border(1, style.divider_bg)
|
|
1557
|
+
.hover_brightness(...style.button.hover_brightness as [any, any])
|
|
1558
|
+
.box_shadow('0px 0px 5px #00000030')
|
|
1559
|
+
.parent<PopupElement>()
|
|
1560
|
+
.yes_button
|
|
1561
|
+
.padding(10, 0)
|
|
1562
|
+
.font_size(style.font_size)
|
|
1563
|
+
.background("#E8454E")
|
|
1564
|
+
.color(style.fg_1)
|
|
1565
|
+
.border(1, style.divider_bg)
|
|
1566
|
+
.hover_brightness(...style.button.hover_brightness as [any, any])
|
|
1567
|
+
.box_shadow('0px 0px 5px #00000030')
|
|
1568
|
+
.parent<PopupElement>()
|
|
1569
|
+
);
|
|
1570
|
+
}),
|
|
1571
|
+
!container.is_refunding ? null : RingLoader()
|
|
1572
|
+
.frame(20, 20)
|
|
1573
|
+
.background(style.theme_fg)
|
|
1574
|
+
.margin(0, 5, 0, 0)
|
|
1575
|
+
.update(),
|
|
1576
|
+
!container.is_refunded ? null : Image("/volt_static/payments/check.webp")
|
|
1577
|
+
.frame(20, 20)
|
|
1578
|
+
.margin(0, 5, 0, 0),
|
|
1579
|
+
)
|
|
1580
|
+
.min_height(30),
|
|
1581
|
+
Text("")
|
|
1582
|
+
.inner_html(`Purchased at ${Utils.unix_to_date(payment.timestamp/1000)} <span style='font-size: 0.8em'>${payment.id}<span>.`)
|
|
1583
|
+
.color(style.fg_1)
|
|
1584
|
+
.font_size(style.font_size - 6)
|
|
1585
|
+
.line_height(style.font_size - 4)
|
|
1586
|
+
.margin(-5, 0, 10, 0)
|
|
1587
|
+
.wrap(true)
|
|
1588
|
+
.padding(0)
|
|
1589
|
+
.white_space("pre")
|
|
1590
|
+
.line_height("1.4em")
|
|
1591
|
+
.center(),
|
|
1592
|
+
items
|
|
1593
|
+
)
|
|
1594
|
+
.width("100%");
|
|
1595
|
+
|
|
1596
|
+
// Elements.
|
|
1597
|
+
return [
|
|
1598
|
+
stack,
|
|
1599
|
+
index === container.payments.length - 1 ? null : Divider()
|
|
1600
|
+
.background(style.divider_bg)
|
|
1601
|
+
.margin(20, 0, 20, 0),
|
|
1602
|
+
];
|
|
1603
|
+
})
|
|
1604
|
+
);
|
|
1605
|
+
}
|
|
1606
|
+
}));
|
|
1607
|
+
return this;
|
|
1608
|
+
}
|
|
1609
|
+
});
|
|
1610
|
+
|
|
1611
|
+
// Append.
|
|
1612
|
+
this._refunds_element.refresh();
|
|
1613
|
+
this._refunds_container.append(this._refunds_element);
|
|
1614
|
+
},
|
|
1615
|
+
|
|
1616
|
+
// Render the address element.
|
|
1617
|
+
_render_billing_element: function(): void {
|
|
1618
|
+
if (this._billing_element !== undefined) { return ; }
|
|
1619
|
+
|
|
1620
|
+
// Utils.
|
|
1621
|
+
const CreateInput = (args: any) => {
|
|
1622
|
+
return ExtendedInput(args)
|
|
1623
|
+
.color(this._style.fg)
|
|
1624
|
+
.font_size(this._style.font_size)
|
|
1625
|
+
.missing_color(this._style.missing_fg)
|
|
1626
|
+
.focus_color(this._style.theme_fg)
|
|
1627
|
+
.border_color(this._style.divider_bg)
|
|
1628
|
+
.border_radius(this._style.border_radius)
|
|
1629
|
+
.input
|
|
1630
|
+
.color(this._style.fg_1)
|
|
1631
|
+
.parent<ExtendedInputElement>();
|
|
1632
|
+
}
|
|
1633
|
+
const CreateSelect = (args: any) => {
|
|
1634
|
+
return ExtendedSelect(args)
|
|
1635
|
+
.background(this._style.bg)
|
|
1636
|
+
.color(this._style.fg)
|
|
1637
|
+
.font_size(this._style.font_size)
|
|
1638
|
+
.missing_color(this._style.missing_fg)
|
|
1639
|
+
.focus_color(this._style.theme_fg)
|
|
1640
|
+
.border_color(this._style.divider_bg)
|
|
1641
|
+
.border_radius(this._style.border_radius)
|
|
1642
|
+
.dropdown_height(150)
|
|
1643
|
+
.background("transparent")
|
|
1644
|
+
.dropdown
|
|
1645
|
+
.background(this._style.bg_1)
|
|
1646
|
+
.background_blur(20)
|
|
1647
|
+
.parent<ExtendedSelectElement>()
|
|
1648
|
+
.input
|
|
1649
|
+
.white_space("pre")
|
|
1650
|
+
// .border_radius(0)
|
|
1651
|
+
.color(this._style.fg_1)
|
|
1652
|
+
.parent<ExtendedSelectElement>();
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
// Create element.
|
|
1656
|
+
const input_spacing = 15;
|
|
1657
|
+
let country_code: any;
|
|
1658
|
+
this._billing_element = Form(
|
|
1659
|
+
|
|
1660
|
+
Title("Billing Details")
|
|
1661
|
+
.color(this._style.fg)
|
|
1662
|
+
.width("fit-content")
|
|
1663
|
+
.font_size(this._style.font_size - 2)
|
|
1664
|
+
.flex_shrink(0)
|
|
1665
|
+
.margin(0, 0, 0, 0)
|
|
1666
|
+
.letter_spacing("1px")
|
|
1667
|
+
.text_transform("uppercase")
|
|
1668
|
+
.ellipsis_overflow(true),
|
|
1669
|
+
|
|
1670
|
+
Divider()
|
|
1671
|
+
.background(this._style.divider_bg)
|
|
1672
|
+
.margin(10, 0, 10, 0),
|
|
1673
|
+
|
|
1674
|
+
HStack(
|
|
1675
|
+
Text("Personal")
|
|
1676
|
+
.font_size(this._style.font_size)
|
|
1677
|
+
.color(this._style.fg)
|
|
1678
|
+
.background(this._style.bg_1)
|
|
1679
|
+
.padding(8, 6)
|
|
1680
|
+
.margin(0)
|
|
1681
|
+
.stretch(true)
|
|
1682
|
+
.text_center()
|
|
1683
|
+
.transition("color 350ms ease, background 350ms ease")
|
|
1684
|
+
.on_mouse_over((e: any) => {
|
|
1685
|
+
if (e.background() === "transparent") {
|
|
1686
|
+
e.color(this._style.fg);
|
|
1687
|
+
}
|
|
1688
|
+
})
|
|
1689
|
+
.on_mouse_out((e: any) => {
|
|
1690
|
+
if (e.background() === "transparent") {
|
|
1691
|
+
e.color(this._style.fg_1);
|
|
1692
|
+
}
|
|
1693
|
+
})
|
|
1694
|
+
.on_click((e: any) => {
|
|
1695
|
+
|
|
1696
|
+
e.color(this._style.fg_1);
|
|
1697
|
+
e.background(this._style.bg_1)
|
|
1698
|
+
const other = e.parentElement.child(1);
|
|
1699
|
+
other.color(this._style.fg_1);
|
|
1700
|
+
other.background("none");
|
|
1701
|
+
|
|
1702
|
+
this._billing_element.name_input.show();
|
|
1703
|
+
this._billing_element.name_input.required(true);
|
|
1704
|
+
this._billing_element.business_input.hide();
|
|
1705
|
+
this._billing_element.business_input.required(false);
|
|
1706
|
+
this._billing_element.vat_id_input.hide();
|
|
1707
|
+
this._billing_element.vat_id_input.required(false);
|
|
1708
|
+
}),
|
|
1709
|
+
Text("Business")
|
|
1710
|
+
.font_size(this._style.font_size)
|
|
1711
|
+
.color(this._style.fg_1)
|
|
1712
|
+
.background("transparent")
|
|
1713
|
+
.padding(8, 6)
|
|
1714
|
+
.margin(0)
|
|
1715
|
+
.stretch(true)
|
|
1716
|
+
.text_center()
|
|
1717
|
+
.transition("color 350ms ease, background 350ms ease")
|
|
1718
|
+
.on_mouse_over((e: any) => {
|
|
1719
|
+
if (e.background() === "transparent") {
|
|
1720
|
+
e.color(this._style.fg);
|
|
1721
|
+
}
|
|
1722
|
+
})
|
|
1723
|
+
.on_mouse_out((e: any) => {
|
|
1724
|
+
if (e.background() === "transparent") {
|
|
1725
|
+
e.color(this._style.fg_1);
|
|
1726
|
+
}
|
|
1727
|
+
})
|
|
1728
|
+
.on_click((e: any) => {
|
|
1729
|
+
|
|
1730
|
+
e.color(this._style.fg_1);
|
|
1731
|
+
e.background(this._style.bg_1)
|
|
1732
|
+
const other = e.parentElement.child(0);
|
|
1733
|
+
other.color(this._style.fg_1);
|
|
1734
|
+
other.background("transparent");
|
|
1735
|
+
|
|
1736
|
+
this._billing_element.name_input.hide();
|
|
1737
|
+
this._billing_element.name_input.required(false);
|
|
1738
|
+
this._billing_element.business_input.show();
|
|
1739
|
+
this._billing_element.business_input.required(true);
|
|
1740
|
+
this._billing_element.vat_id_input.show();
|
|
1741
|
+
this._billing_element.vat_id_input.required(true);
|
|
1742
|
+
}),
|
|
1743
|
+
)
|
|
1744
|
+
.overflow("hidden")
|
|
1745
|
+
.border(1, this._style.divider_bg)
|
|
1746
|
+
.border_radius(this._style.border_radius)
|
|
1747
|
+
.margin_top(10)
|
|
1748
|
+
.margin_bottom(10)
|
|
1749
|
+
.flex_shrink(0),
|
|
1750
|
+
|
|
1751
|
+
CreateInput({
|
|
1752
|
+
label: "Full Name",
|
|
1753
|
+
placeholder: "John Doe",
|
|
1754
|
+
})
|
|
1755
|
+
.value(User.first_name() === undefined ? "" : (User.first_name() + " " + User.last_name()))
|
|
1756
|
+
.margin_top(input_spacing)
|
|
1757
|
+
.required(true)
|
|
1758
|
+
.id("name")
|
|
1759
|
+
.assign_to_parent_as("name_input"),
|
|
1760
|
+
|
|
1761
|
+
CreateInput({
|
|
1762
|
+
label: "Business Name",
|
|
1763
|
+
placeholder: "Company Inc.",
|
|
1764
|
+
})
|
|
1765
|
+
.margin_top(input_spacing)
|
|
1766
|
+
.required(false)
|
|
1767
|
+
.id("business")
|
|
1768
|
+
.hide()
|
|
1769
|
+
.assign_to_parent_as("business_input"),
|
|
1770
|
+
|
|
1771
|
+
CreateInput({
|
|
1772
|
+
label: "VAT ID",
|
|
1773
|
+
placeholder: "VAT ID",
|
|
1774
|
+
})
|
|
1775
|
+
.margin_top(input_spacing)
|
|
1776
|
+
.required(false)
|
|
1777
|
+
.id("vat_id")
|
|
1778
|
+
.hide()
|
|
1779
|
+
.assign_to_parent_as("vat_id_input"),
|
|
1780
|
+
|
|
1781
|
+
CreateInput({
|
|
1782
|
+
label: "Email",
|
|
1783
|
+
placeholder: "my@email.com",
|
|
1784
|
+
})
|
|
1785
|
+
.value(User.email() ?? "")
|
|
1786
|
+
.margin_top(input_spacing)
|
|
1787
|
+
.required(true)
|
|
1788
|
+
.id("email"),
|
|
1789
|
+
|
|
1790
|
+
CreateInput({
|
|
1791
|
+
label: "Street",
|
|
1792
|
+
placeholder: "123 Park Avenue",
|
|
1793
|
+
})
|
|
1794
|
+
.margin_top(input_spacing)
|
|
1795
|
+
.required(true)
|
|
1796
|
+
.id("street"),
|
|
1797
|
+
|
|
1798
|
+
CreateInput({
|
|
1799
|
+
label: "House Number",
|
|
1800
|
+
placeholder: "Suite 405",
|
|
1801
|
+
})
|
|
1802
|
+
.margin_top(input_spacing)
|
|
1803
|
+
.required(true)
|
|
1804
|
+
.id("house_number"),
|
|
1805
|
+
|
|
1806
|
+
CreateInput({
|
|
1807
|
+
label: "Postal Code",
|
|
1808
|
+
placeholder: "10001",
|
|
1809
|
+
})
|
|
1810
|
+
.margin_top(input_spacing)
|
|
1811
|
+
.required(true)
|
|
1812
|
+
.id("postal_code"),
|
|
1813
|
+
|
|
1814
|
+
CreateInput({
|
|
1815
|
+
label: "City",
|
|
1816
|
+
placeholder: "New York",
|
|
1817
|
+
})
|
|
1818
|
+
.margin_top(input_spacing)
|
|
1819
|
+
.required(true)
|
|
1820
|
+
.id("city"),
|
|
1821
|
+
|
|
1822
|
+
CreateInput({
|
|
1823
|
+
label: "Province",
|
|
1824
|
+
placeholder: "New York",
|
|
1825
|
+
})
|
|
1826
|
+
.margin_top(input_spacing)
|
|
1827
|
+
.required(true)
|
|
1828
|
+
.id("province"),
|
|
1829
|
+
|
|
1830
|
+
CreateSelect({
|
|
1831
|
+
label: "Country",
|
|
1832
|
+
placeholder: "United States",
|
|
1833
|
+
items: Object.fromEntries(Object.entries(Payments.countries).map(([key, value]) => [key, value.name])),
|
|
1834
|
+
})
|
|
1835
|
+
.on_change((_: any, country: string) => {
|
|
1836
|
+
this._overview_element.calc_tax(country);
|
|
1837
|
+
country_code.value(Payments.countries[country].calling_code);
|
|
1838
|
+
})
|
|
1839
|
+
.margin_top(input_spacing)
|
|
1840
|
+
.required(true)
|
|
1841
|
+
.id("country"),
|
|
1842
|
+
|
|
1843
|
+
HStack(
|
|
1844
|
+
country_code = CreateInput({
|
|
1845
|
+
label: "Country Code",
|
|
1846
|
+
placeholder: "+1",
|
|
1847
|
+
type: "tel",
|
|
1848
|
+
})
|
|
1849
|
+
.max_width("fit-content")
|
|
1850
|
+
.margin_top(input_spacing)
|
|
1851
|
+
.margin_right(input_spacing)
|
|
1852
|
+
.required(true)
|
|
1853
|
+
.input
|
|
1854
|
+
.readonly(true)
|
|
1855
|
+
.parent<ExtendedInputElement>()
|
|
1856
|
+
.id("phone_country_code"),
|
|
1857
|
+
|
|
1858
|
+
CreateInput({
|
|
1859
|
+
label: "Phone Number",
|
|
1860
|
+
placeholder: "1234567890",
|
|
1861
|
+
type: "tel",
|
|
1862
|
+
})
|
|
1863
|
+
.margin_top(input_spacing)
|
|
1864
|
+
.stretch(true)
|
|
1865
|
+
.required(true)
|
|
1866
|
+
.id("phone_number"),
|
|
1867
|
+
)
|
|
1868
|
+
.width("100%")
|
|
1869
|
+
);
|
|
1870
|
+
|
|
1871
|
+
// Append.
|
|
1872
|
+
this._billing_container.append(this._billing_element);
|
|
1873
|
+
},
|
|
1874
|
+
|
|
1875
|
+
// Render the payment element.
|
|
1876
|
+
_render_payment_element: async function(): Promise<void> {
|
|
1877
|
+
return new Promise((resolve, reject) => {
|
|
1878
|
+
this._render_payment_element_resolve = resolve;
|
|
1879
|
+
this._render_payment_element_reject = reject;
|
|
1880
|
+
|
|
1881
|
+
// Already rendered.
|
|
1882
|
+
if (this._payment_element !== undefined) {
|
|
1883
|
+
return resolve();
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
// Checks.
|
|
1887
|
+
if (this.client_key == null) {
|
|
1888
|
+
return reject(new Error(`No client key has been assigned to "Payments.client_key".`));
|
|
1889
|
+
}
|
|
1890
|
+
if (this.cart.items.length === 0) {
|
|
1891
|
+
return reject(new Error("Shopping cart is empty."));
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
// Check subscription or one time payment.
|
|
1895
|
+
let is_subscription = false;
|
|
1896
|
+
this.cart.items.forEach((item: any) => {
|
|
1897
|
+
if (item.is_subscription === true) {
|
|
1898
|
+
is_subscription = true;
|
|
1899
|
+
return false;
|
|
1900
|
+
}
|
|
1901
|
+
});
|
|
1902
|
+
|
|
1903
|
+
// Initialize paddle.
|
|
1904
|
+
this._initialize_paddle();
|
|
1905
|
+
|
|
1906
|
+
// Create element.
|
|
1907
|
+
this._payment_element = VStack()
|
|
1908
|
+
.class("checkout-container");
|
|
1909
|
+
|
|
1910
|
+
// Append.
|
|
1911
|
+
this._payment_container.append(this._payment_element);
|
|
1912
|
+
|
|
1913
|
+
// Initialize.
|
|
1914
|
+
let custom_data: any = {
|
|
1915
|
+
customer_name: this._billing_details.name,
|
|
1916
|
+
};
|
|
1917
|
+
if (User.is_authenticated()) {
|
|
1918
|
+
custom_data.uid = User.uid();
|
|
1919
|
+
}
|
|
1920
|
+
try {
|
|
1921
|
+
let business: any = undefined;
|
|
1922
|
+
if (this._billing_details.business !== "") {
|
|
1923
|
+
business = {
|
|
1924
|
+
name: this._billing_details.business,
|
|
1925
|
+
taxIdentifier: this._billing_details.vat_id === "" ? undefined : this._billing_details.vat_id,
|
|
1926
|
+
};
|
|
1927
|
+
}
|
|
1928
|
+
Paddle.Checkout.open({
|
|
1929
|
+
settings: {
|
|
1930
|
+
displayMode: "inline",
|
|
1931
|
+
theme: this._theme,
|
|
1932
|
+
locale: "en",
|
|
1933
|
+
frameTarget: "checkout-container",
|
|
1934
|
+
frameInitialHeight: "450",
|
|
1935
|
+
frameStyle: "width: 100%; min-width: 312px; background-color: transparent; border: none;",
|
|
1936
|
+
// successUrl: this.return_url,
|
|
1937
|
+
// successUrl: "http://test.vandenberghinc.com/checkout?payment_status=success",
|
|
1938
|
+
},
|
|
1939
|
+
items: this.cart.items.map((item: any) => { return { priceId: item.product.price_id, quantity: item.quantity }; }),
|
|
1940
|
+
customer: {
|
|
1941
|
+
email: this._billing_details.email,
|
|
1942
|
+
address: {
|
|
1943
|
+
countryCode: this._billing_details.country,
|
|
1944
|
+
postalCode: this._billing_details.postal_code,
|
|
1945
|
+
region: this._billing_details.province,
|
|
1946
|
+
city: this._billing_details.city,
|
|
1947
|
+
firstLine: `${this._billing_details.street} ${this._billing_details.house_number}`,
|
|
1948
|
+
},
|
|
1949
|
+
business,
|
|
1950
|
+
},
|
|
1951
|
+
customData: custom_data,
|
|
1952
|
+
});
|
|
1953
|
+
} catch (err: any) {
|
|
1954
|
+
return reject(err);
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
// const iframe = this._payment_element.children[0];
|
|
1958
|
+
// iframe.onload = () => {
|
|
1959
|
+
// console.log("ON LOAD");
|
|
1960
|
+
// let doc = iframe.contentDocument || iframe.contentWindow.document;
|
|
1961
|
+
// let elementInsideIframe = doc.getElementById('cardNumber');
|
|
1962
|
+
// elementInsideIframe.style.background = 'red'; // Example of editing an element
|
|
1963
|
+
// }
|
|
1964
|
+
|
|
1965
|
+
});
|
|
1966
|
+
},
|
|
1967
|
+
|
|
1968
|
+
// Render the processing element.
|
|
1969
|
+
_render_processing_element: function(): void {
|
|
1970
|
+
|
|
1971
|
+
// Already defined.
|
|
1972
|
+
if (this._processing_element !== undefined) {
|
|
1973
|
+
this._processing_element.set_processing();
|
|
1974
|
+
return ;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// Create element.
|
|
1978
|
+
this._processing_element = VStack(
|
|
1979
|
+
Title("Processing")
|
|
1980
|
+
.color(this._style.fg)
|
|
1981
|
+
.font_size(this._style.font_size - 2)
|
|
1982
|
+
.flex_shrink(0)
|
|
1983
|
+
.letter_spacing("1px")
|
|
1984
|
+
.text_transform("uppercase")
|
|
1985
|
+
.ellipsis_overflow(true)
|
|
1986
|
+
.margin(0)
|
|
1987
|
+
.padding(0)
|
|
1988
|
+
.assign_to_parent_as("title_e"),
|
|
1989
|
+
Text("Processing your payment, please wait.")
|
|
1990
|
+
.color(this._style.fg_1)
|
|
1991
|
+
.font_size(this._style.font_size - 2)
|
|
1992
|
+
.line_height(this._style.font_size)
|
|
1993
|
+
.margin(5, 0, 0, 0)
|
|
1994
|
+
.padding(0)
|
|
1995
|
+
.assign_to_parent_as("text_e")
|
|
1996
|
+
.white_space("pre")
|
|
1997
|
+
.line_height("1.4em")
|
|
1998
|
+
.center(),
|
|
1999
|
+
ImageMask("/volt_static/payments/error.webp")
|
|
2000
|
+
.hide()
|
|
2001
|
+
.frame(40, 40)
|
|
2002
|
+
.padding(5)
|
|
2003
|
+
.mask_color(this._style.missing_fg)
|
|
2004
|
+
.margin_top(15)
|
|
2005
|
+
.assign_to_parent_as("error_image_e"),
|
|
2006
|
+
Image("/volt_static/payments/party.webp")
|
|
2007
|
+
.hide()
|
|
2008
|
+
.frame(40, 40)
|
|
2009
|
+
.margin_top(15)
|
|
2010
|
+
.assign_to_parent_as("success_image_e"),
|
|
2011
|
+
RingLoader()
|
|
2012
|
+
.background(this._style.theme_fg)
|
|
2013
|
+
.frame(40, 40)
|
|
2014
|
+
.update()
|
|
2015
|
+
.margin_top(15)
|
|
2016
|
+
.assign_to_parent_as("loader_e"),
|
|
2017
|
+
)
|
|
2018
|
+
.padding(15, 0)
|
|
2019
|
+
.center()
|
|
2020
|
+
.center_vertical()
|
|
2021
|
+
.extend({
|
|
2022
|
+
timestamp: Date.now(),
|
|
2023
|
+
/**
|
|
2024
|
+
* Set the processing element to display an error message.
|
|
2025
|
+
* @param message - The error message to display.
|
|
2026
|
+
*/
|
|
2027
|
+
set_error(this: any, message: string = "The payment has failed, please check your information and try again.\n If the problem persists, contact support for assistance.") {
|
|
2028
|
+
this.loader_e.hide();
|
|
2029
|
+
this.error_image_e.src("/volt_static/payments/error.webp");
|
|
2030
|
+
this.error_image_e.show();
|
|
2031
|
+
this.success_image_e.hide();
|
|
2032
|
+
this.title_e.text("Error");
|
|
2033
|
+
this.text_e.text(message);
|
|
2034
|
+
},
|
|
2035
|
+
/**
|
|
2036
|
+
* Set the processing element to display a cancelled message.
|
|
2037
|
+
* @param message - The cancellation message to display.
|
|
2038
|
+
*/
|
|
2039
|
+
set_cancelled(this: any, message: string = "The payment has been cancelled.") {
|
|
2040
|
+
this.loader_e.hide();
|
|
2041
|
+
this.error_image_e.src("/volt_static/payments/cancelled.webp");
|
|
2042
|
+
this.error_image_e.show();
|
|
2043
|
+
this.success_image_e.hide();
|
|
2044
|
+
this.title_e.text("Cancelled");
|
|
2045
|
+
this.text_e.text(message);
|
|
2046
|
+
},
|
|
2047
|
+
/**
|
|
2048
|
+
* Set the processing element to display a success message.
|
|
2049
|
+
* @param message - The success message to display.
|
|
2050
|
+
*/
|
|
2051
|
+
set_success(this: any, message: string = "The payment has succeeded and is currently processing.\n Thank you for your purchase!") {
|
|
2052
|
+
this.loader_e.hide();
|
|
2053
|
+
this.error_image_e.hide();
|
|
2054
|
+
this.success_image_e.show();
|
|
2055
|
+
this.title_e.text("Success");
|
|
2056
|
+
this.text_e.text(message);
|
|
2057
|
+
},
|
|
2058
|
+
/**
|
|
2059
|
+
* Set the processing element to display a processing message.
|
|
2060
|
+
* @param message - The processing message to display.
|
|
2061
|
+
*/
|
|
2062
|
+
set_processing(this: any, message: string = "Processing your payment, please wait.") {
|
|
2063
|
+
this.loader_e.show();
|
|
2064
|
+
this.error_image_e.hide();
|
|
2065
|
+
this.success_image_e.hide();
|
|
2066
|
+
this.title_e.text("Processing");
|
|
2067
|
+
this.text_e.text(message);
|
|
2068
|
+
},
|
|
2069
|
+
});
|
|
2070
|
+
|
|
2071
|
+
// Append.
|
|
2072
|
+
this._processing_container.append(this._processing_element);
|
|
2073
|
+
},
|
|
2074
|
+
|
|
2075
|
+
// Show the processing container.
|
|
2076
|
+
_show_processing: async function(status: string | null = null): Promise<void> {
|
|
2077
|
+
|
|
2078
|
+
// Select step.
|
|
2079
|
+
this._step = 3;
|
|
2080
|
+
this._steps_element.select(this._step);
|
|
2081
|
+
|
|
2082
|
+
// Render the processing element.
|
|
2083
|
+
this._render_processing_element();
|
|
2084
|
+
|
|
2085
|
+
// Set elements.
|
|
2086
|
+
this._order_container.hide();
|
|
2087
|
+
this._billing_container.hide();
|
|
2088
|
+
this._payment_container.hide();
|
|
2089
|
+
this._processing_container.show();
|
|
2090
|
+
this._overview_container.hide();
|
|
2091
|
+
this._prev_step_button.hide();
|
|
2092
|
+
|
|
2093
|
+
// Update.
|
|
2094
|
+
if (status != null) {
|
|
2095
|
+
this._update_processing(status);
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
},
|
|
2099
|
+
|
|
2100
|
+
// Update the processing container.
|
|
2101
|
+
_update_processing: async function(status: string): Promise<void> {
|
|
2102
|
+
|
|
2103
|
+
// Handle result code.
|
|
2104
|
+
switch (status) {
|
|
2105
|
+
case "success":
|
|
2106
|
+
this._processing_element.set_success();
|
|
2107
|
+
break;
|
|
2108
|
+
case "processing":
|
|
2109
|
+
this._processing_element.set_processing();
|
|
2110
|
+
break;
|
|
2111
|
+
case "cancelled":
|
|
2112
|
+
this._processing_element.set_cancelled();
|
|
2113
|
+
break;
|
|
2114
|
+
case "error":
|
|
2115
|
+
this._processing_element.set_error();
|
|
2116
|
+
break;
|
|
2117
|
+
default:
|
|
2118
|
+
console.error(`Unknown session result code "${status}".`);
|
|
2119
|
+
this._processing_element.set_error("An unknown error has occurred.");
|
|
2120
|
+
break;
|
|
2121
|
+
}
|
|
2122
|
+
},
|
|
2123
|
+
|
|
2124
|
+
// Initialize checkout page.
|
|
2125
|
+
style: function({
|
|
2126
|
+
theme = "light", // light or dark
|
|
2127
|
+
font_size = 16,
|
|
2128
|
+
border_radius = 10,
|
|
2129
|
+
bg = "#FFFFFF",
|
|
2130
|
+
bg_1 = "#00000099",
|
|
2131
|
+
divider_bg = "gray",
|
|
2132
|
+
fg = "#687282",
|
|
2133
|
+
fg_1 = "black",
|
|
2134
|
+
fg_2 = "#6D6E77",
|
|
2135
|
+
theme_fg = "#8EB8EB",
|
|
2136
|
+
missing_fg = "#E8454E",
|
|
2137
|
+
selected = {
|
|
2138
|
+
fg: null as null | string,
|
|
2139
|
+
bg: null as null | string,
|
|
2140
|
+
},
|
|
2141
|
+
button = {
|
|
2142
|
+
fg: null as null | string,
|
|
2143
|
+
bg: null as null | string,
|
|
2144
|
+
border_color: null as null | string,
|
|
2145
|
+
border_radius: 25 as null | number,
|
|
2146
|
+
border_width: 1 as null | number | string,
|
|
2147
|
+
border_inset: false,
|
|
2148
|
+
hover_brightness: [1.1, 1.2] as number[],
|
|
2149
|
+
},
|
|
2150
|
+
} = {}): void {
|
|
2151
|
+
// Set selected defaults.
|
|
2152
|
+
if (selected == null) {
|
|
2153
|
+
selected = { fg: null, bg: null };
|
|
2154
|
+
}
|
|
2155
|
+
selected.fg ??= fg;
|
|
2156
|
+
selected.bg ??= theme_fg;
|
|
2157
|
+
|
|
2158
|
+
// Set button defaults.
|
|
2159
|
+
if (button == null) {
|
|
2160
|
+
button = {
|
|
2161
|
+
fg: null,
|
|
2162
|
+
bg: null,
|
|
2163
|
+
border_radius: null,
|
|
2164
|
+
border_color: null,
|
|
2165
|
+
border_width: 1,
|
|
2166
|
+
hover_brightness: [1, 1],
|
|
2167
|
+
border_inset: false,
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2170
|
+
button.fg ??= fg;
|
|
2171
|
+
button.bg ??= bg_1; // Corrected bg_2 to bg_1 as bg_2 is not defined
|
|
2172
|
+
button.border_radius ??= 25;
|
|
2173
|
+
button.border_color ??= fg;
|
|
2174
|
+
button.border_width ??= 1;
|
|
2175
|
+
button.border_inset ??= false;
|
|
2176
|
+
button.hover_brightness ??= [1.1, 1.2];
|
|
2177
|
+
if (typeof button.border_width === "number") { button.border_width = `${button.border_width}px`; }
|
|
2178
|
+
|
|
2179
|
+
// Save style.
|
|
2180
|
+
this._style = {};
|
|
2181
|
+
this._theme = theme;
|
|
2182
|
+
this._style.font_size = font_size;
|
|
2183
|
+
this._style.border_radius = border_radius;
|
|
2184
|
+
this._style.bg = bg;
|
|
2185
|
+
this._style.bg_1 = bg_1;
|
|
2186
|
+
this._style.divider_bg = divider_bg;
|
|
2187
|
+
this._style.fg = fg;
|
|
2188
|
+
this._style.fg_1 = fg_1;
|
|
2189
|
+
this._style.fg_2 = fg_2;
|
|
2190
|
+
this._style.theme_fg = theme_fg;
|
|
2191
|
+
this._style.missing_fg = missing_fg;
|
|
2192
|
+
this._style.selected = selected;
|
|
2193
|
+
this._style.button = button;
|
|
2194
|
+
|
|
2195
|
+
// Set CSS variables.
|
|
2196
|
+
Object.keys(this._style).forEach((key) => {
|
|
2197
|
+
if (typeof this._style[key] === "number") {
|
|
2198
|
+
document.documentElement.style.setProperty(`--vpayments_${key}`, `${this._style[key]}px`);
|
|
2199
|
+
} else {
|
|
2200
|
+
document.documentElement.style.setProperty(`--vpayments_${key}`, this._style[key]);
|
|
2201
|
+
}
|
|
2202
|
+
});
|
|
2203
|
+
document.documentElement.style.setProperty(`--vpayments_theme_fg_80`, `${this._style.theme_fg}80`);
|
|
2204
|
+
document.documentElement.style.setProperty(`--vpayments_missing_fg_80`, `${this._style.missing_fg}80`);
|
|
2205
|
+
},
|
|
2206
|
+
|
|
2207
|
+
// Initialize checkout page.
|
|
2208
|
+
create_checkout_dropin: function({
|
|
2209
|
+
steps_container,
|
|
2210
|
+
order_container,
|
|
2211
|
+
billing_container,
|
|
2212
|
+
payment_container,
|
|
2213
|
+
processing_container,
|
|
2214
|
+
overview_container,
|
|
2215
|
+
sign_in_redirect = null,
|
|
2216
|
+
on_error = (error: string | Error) => {},
|
|
2217
|
+
}: {
|
|
2218
|
+
steps_container: any,
|
|
2219
|
+
order_container: any,
|
|
2220
|
+
billing_container: any,
|
|
2221
|
+
payment_container: any,
|
|
2222
|
+
processing_container: any,
|
|
2223
|
+
overview_container: any,
|
|
2224
|
+
sign_in_redirect?: string | null,
|
|
2225
|
+
on_error?: (error: string | Error) => void,
|
|
2226
|
+
}): void {
|
|
2227
|
+
|
|
2228
|
+
// Check args.
|
|
2229
|
+
if (!(steps_container instanceof Node)) {
|
|
2230
|
+
throw new Error('The "steps_container" must be assigned with a container node.');
|
|
2231
|
+
}
|
|
2232
|
+
if (!(order_container instanceof Node)) {
|
|
2233
|
+
throw new Error('The "order_container" must be assigned with a container node.');
|
|
2234
|
+
}
|
|
2235
|
+
if (!(billing_container instanceof Node)) {
|
|
2236
|
+
throw new Error('The "billing_container" must be assigned with a container node.');
|
|
2237
|
+
}
|
|
2238
|
+
if (!(payment_container instanceof Node)) {
|
|
2239
|
+
throw new Error('The "payment_container" must be assigned with a container node.');
|
|
2240
|
+
}
|
|
2241
|
+
if (!(processing_container instanceof Node)) {
|
|
2242
|
+
throw new Error('The "processing_container" must be assigned with a container node.');
|
|
2243
|
+
}
|
|
2244
|
+
if (!(overview_container instanceof Node)) {
|
|
2245
|
+
throw new Error('The "overview_container" must be assigned with a container node.');
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
// Args.
|
|
2249
|
+
this._steps_container = steps_container;
|
|
2250
|
+
this._order_container = order_container;
|
|
2251
|
+
// @ts-ignore
|
|
2252
|
+
this._billing_container = billing_container.hide();
|
|
2253
|
+
// @ts-ignore
|
|
2254
|
+
this._payment_container = payment_container.hide();
|
|
2255
|
+
// @ts-ignore
|
|
2256
|
+
this._processing_container = processing_container.hide();
|
|
2257
|
+
this._overview_container = overview_container;
|
|
2258
|
+
|
|
2259
|
+
// Settings.
|
|
2260
|
+
this._sign_in_redirect = sign_in_redirect;
|
|
2261
|
+
|
|
2262
|
+
// Events.
|
|
2263
|
+
this.on_error = on_error;
|
|
2264
|
+
|
|
2265
|
+
// Check style.
|
|
2266
|
+
if (this._style === undefined) {
|
|
2267
|
+
this.style();
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
// Other attributes.
|
|
2271
|
+
this._step = 0;
|
|
2272
|
+
|
|
2273
|
+
// Render the steps element.
|
|
2274
|
+
this._render_steps_element();
|
|
2275
|
+
|
|
2276
|
+
// When the user was redirected the URL params are defined, if so only render the processing view.
|
|
2277
|
+
if (Utils.url_param("payment_status", null) != null) {
|
|
2278
|
+
this._show_processing(Utils.url_param("payment_status", null));
|
|
2279
|
+
}
|
|
2280
|
+
// No redirect.
|
|
2281
|
+
else {
|
|
2282
|
+
// Render the overview element.
|
|
2283
|
+
this._render_overview_element();
|
|
2284
|
+
|
|
2285
|
+
// Render the order element.
|
|
2286
|
+
// Must be rendered after the overview element is rendered.
|
|
2287
|
+
this._render_order_element();
|
|
2288
|
+
}
|
|
2289
|
+
},
|
|
2290
|
+
|
|
2291
|
+
// Initialize refund page.
|
|
2292
|
+
create_refunds_dropin: function({
|
|
2293
|
+
// The element containers.
|
|
2294
|
+
refunds_container,
|
|
2295
|
+
|
|
2296
|
+
// Refundable settings.
|
|
2297
|
+
days_refundable = 30,
|
|
2298
|
+
|
|
2299
|
+
// Events.
|
|
2300
|
+
on_error = (error: any) => {},
|
|
2301
|
+
}: {
|
|
2302
|
+
refunds_container: any,
|
|
2303
|
+
days_refundable?: number,
|
|
2304
|
+
on_error?: (error: any) => void,
|
|
2305
|
+
}): void {
|
|
2306
|
+
|
|
2307
|
+
// Check args.
|
|
2308
|
+
if (!(refunds_container instanceof Node)) {
|
|
2309
|
+
throw new Error('The "refunds_container" must be assigned with a container node.');
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
// Args.
|
|
2313
|
+
this._refunds_container = refunds_container;
|
|
2314
|
+
this._days_refundable = days_refundable;
|
|
2315
|
+
|
|
2316
|
+
// Events.
|
|
2317
|
+
this.on_error = on_error;
|
|
2318
|
+
|
|
2319
|
+
// Check style.
|
|
2320
|
+
if (this._style === undefined) {
|
|
2321
|
+
this.style();
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
// Other attributes.
|
|
2325
|
+
this._step = 0;
|
|
2326
|
+
|
|
2327
|
+
// Render the refunds element.
|
|
2328
|
+
this._render_refunds_element();
|
|
2329
|
+
},
|
|
2330
|
+
|
|
2331
|
+
// Backend API.
|
|
2332
|
+
|
|
2333
|
+
// Get the currency symbol for a product currency.
|
|
2334
|
+
// Returns `null` when the currency is not supported.
|
|
2335
|
+
/**
|
|
2336
|
+
* @docs:
|
|
2337
|
+
* @nav: Frontend
|
|
2338
|
+
* @chapter: Payments
|
|
2339
|
+
* @title: Get Currency Symbol
|
|
2340
|
+
* @description: Get the currency symbol for a product currency.
|
|
2341
|
+
* @type: string | null
|
|
2342
|
+
* @return: Returns the currency symbol when the currency is supported, otherwise `null`
|
|
2343
|
+
* @param:
|
|
2344
|
+
* @name: currency
|
|
2345
|
+
* @description: The currency from the product object.
|
|
2346
|
+
*/
|
|
2347
|
+
get_currency_symbol: function(currency: string): string | null {
|
|
2348
|
+
switch (currency.toLowerCase()) {
|
|
2349
|
+
case "aed": return "د.إ";
|
|
2350
|
+
case "afn": return "Af";
|
|
2351
|
+
case "all": return "L";
|
|
2352
|
+
case "amd": return "֏";
|
|
2353
|
+
case "ang": return "ƒ";
|
|
2354
|
+
case "aoa": return "Kz";
|
|
2355
|
+
case "ars": return "$";
|
|
2356
|
+
case "aud": return "$";
|
|
2357
|
+
case "awg": return "ƒ";
|
|
2358
|
+
case "azn": return "₼";
|
|
2359
|
+
case "bam": return "KM";
|
|
2360
|
+
case "bbd": return "Bds$";
|
|
2361
|
+
case "bdt": return "৳";
|
|
2362
|
+
case "bgn": return "лв";
|
|
2363
|
+
case "bhd": return ".د.ب";
|
|
2364
|
+
case "bif": return "FBu";
|
|
2365
|
+
case "bmd": return "BD$";
|
|
2366
|
+
case "bnd": return "B$";
|
|
2367
|
+
case "bob": return "Bs";
|
|
2368
|
+
case "brl": return "R$";
|
|
2369
|
+
case "bsd": return "B$";
|
|
2370
|
+
case "btn": return "Nu.";
|
|
2371
|
+
case "bwp": return "P";
|
|
2372
|
+
case "byn": return "Br";
|
|
2373
|
+
case "bzd": return "BZ$";
|
|
2374
|
+
case "cad": return "$";
|
|
2375
|
+
case "cdf": return "FC";
|
|
2376
|
+
case "chf": return "Fr";
|
|
2377
|
+
case "clf": return "UF";
|
|
2378
|
+
case "clp": return "$";
|
|
2379
|
+
case "cny": return "¥";
|
|
2380
|
+
case "cop": return "$";
|
|
2381
|
+
case "crc": return "₡";
|
|
2382
|
+
case "cuc": return "CUC$";
|
|
2383
|
+
case "cup": return "CUP$";
|
|
2384
|
+
case "cve": return "$";
|
|
2385
|
+
case "czk": return "Kč";
|
|
2386
|
+
case "djf": return "Fdj";
|
|
2387
|
+
case "dkk": return "kr";
|
|
2388
|
+
case "dop": return "RD$";
|
|
2389
|
+
case "dzd": return "دج";
|
|
2390
|
+
case "egp": return "E£";
|
|
2391
|
+
case "ern": return "Nfk";
|
|
2392
|
+
case "etb": return "Br";
|
|
2393
|
+
case "eur": return "€";
|
|
2394
|
+
case "fjd": return "FJ$";
|
|
2395
|
+
case "fkp": return "£";
|
|
2396
|
+
case "fok": return "F$";
|
|
2397
|
+
case "gbp": return "£";
|
|
2398
|
+
case "gel": return "₾";
|
|
2399
|
+
case "ghc": return "₵";
|
|
2400
|
+
case "gip": return "£";
|
|
2401
|
+
case "gmd": return "D";
|
|
2402
|
+
case "gnf": return "FG";
|
|
2403
|
+
case "gtq": return "Q";
|
|
2404
|
+
case "gyd": return "GY$";
|
|
2405
|
+
case "hkd": return "HK$";
|
|
2406
|
+
case "hnl": return "L";
|
|
2407
|
+
case "hrk": return "kn";
|
|
2408
|
+
case "htg": return "G";
|
|
2409
|
+
case "huf": return "Ft";
|
|
2410
|
+
case "idr": return "Rp";
|
|
2411
|
+
case "ils": return "₪";
|
|
2412
|
+
case "inr": return "₹";
|
|
2413
|
+
case "iqd": return "د.ع";
|
|
2414
|
+
case "irr": return "﷼";
|
|
2415
|
+
case "isk": return "kr";
|
|
2416
|
+
case "jmd": return "J$";
|
|
2417
|
+
case "jod": return "JD";
|
|
2418
|
+
case "jpy": return "¥";
|
|
2419
|
+
case "kes": return "Ksh";
|
|
2420
|
+
case "kgs": return "с";
|
|
2421
|
+
case "khr": return "៛";
|
|
2422
|
+
case "kmf": return "CF";
|
|
2423
|
+
case "kpw": return "₩";
|
|
2424
|
+
case "krw": return "₩";
|
|
2425
|
+
case "kwd": return "KD";
|
|
2426
|
+
case "kyd": return "CI$";
|
|
2427
|
+
case "kzt": return "₸";
|
|
2428
|
+
case "lak": return "₭";
|
|
2429
|
+
case "lbp": return "L£";
|
|
2430
|
+
case "lkr": return "Rs";
|
|
2431
|
+
case "lrd": return "L$";
|
|
2432
|
+
case "lsl": return "L";
|
|
2433
|
+
case "lyd": return "ل.د";
|
|
2434
|
+
case "mad": return "د.م.";
|
|
2435
|
+
case "mdl": return "L";
|
|
2436
|
+
case "mnt": return "₮";
|
|
2437
|
+
case "mop": return "MOP$";
|
|
2438
|
+
case "mur": return "Rs";
|
|
2439
|
+
case "mvr": return "Rf";
|
|
2440
|
+
case "mwk": return "MK";
|
|
2441
|
+
case "mxn": return "$";
|
|
2442
|
+
case "myr": return "RM";
|
|
2443
|
+
case "mzn": return "MTn";
|
|
2444
|
+
case "nad": return "N$";
|
|
2445
|
+
case "ngn": return "₦";
|
|
2446
|
+
case "nio": return "C$";
|
|
2447
|
+
case "nok": return "kr";
|
|
2448
|
+
case "npr": return "रू";
|
|
2449
|
+
case "nzd": return "$";
|
|
2450
|
+
case "omr": return "ر.ع.";
|
|
2451
|
+
case "pab": return "B/.";
|
|
2452
|
+
case "pen": return "S/.";
|
|
2453
|
+
case "pgk": return "K";
|
|
2454
|
+
case "php": return "₱";
|
|
2455
|
+
case "pkr": return "Rs";
|
|
2456
|
+
case "pln": return "zł";
|
|
2457
|
+
case "pyg": return "₲";
|
|
2458
|
+
case "qar": return "ر.ق";
|
|
2459
|
+
case "ron": return "lei";
|
|
2460
|
+
case "rsd": return "din.";
|
|
2461
|
+
case "rub": return "₽";
|
|
2462
|
+
case "rwf": return "FRw";
|
|
2463
|
+
case "sar": return "ر.س";
|
|
2464
|
+
case "sbd": return "SI$";
|
|
2465
|
+
case "scr": return "Sr";
|
|
2466
|
+
case "sdg": return "ج.س.";
|
|
2467
|
+
case "sek": return "kr";
|
|
2468
|
+
case "sgd": return "S$";
|
|
2469
|
+
case "shp": return "£";
|
|
2470
|
+
case "sll": return "Le";
|
|
2471
|
+
case "sos": return "S";
|
|
2472
|
+
case "srd": return "SRD$";
|
|
2473
|
+
case "ssp": return "£";
|
|
2474
|
+
case "std": return "Db";
|
|
2475
|
+
case "syp": return "S£";
|
|
2476
|
+
case "szl": return "L";
|
|
2477
|
+
case "thb": return "฿";
|
|
2478
|
+
case "tjs": return "ЅМ";
|
|
2479
|
+
case "tmt": return "m";
|
|
2480
|
+
case "tnd": return "د.ت";
|
|
2481
|
+
case "top": return "T$";
|
|
2482
|
+
case "try": return "₺";
|
|
2483
|
+
case "ttd": return "TT$";
|
|
2484
|
+
case "twd": return "NT$";
|
|
2485
|
+
case "tzs": return "TSh";
|
|
2486
|
+
case "uah": return "₴";
|
|
2487
|
+
case "ugx": return "USh";
|
|
2488
|
+
case "usd": return "$";
|
|
2489
|
+
case "uyu": return "$U";
|
|
2490
|
+
case "uzs": return "лв";
|
|
2491
|
+
case "ves": return "Bs.S.";
|
|
2492
|
+
case "vnd": return "₫";
|
|
2493
|
+
case "vuv": return "VT";
|
|
2494
|
+
case "wst": return "WS$";
|
|
2495
|
+
case "xaf": return "FCFA";
|
|
2496
|
+
case "xcd": return "EC$";
|
|
2497
|
+
case "xof": return "CFA";
|
|
2498
|
+
case "xpf": return "CFP";
|
|
2499
|
+
case "yer": return "﷼";
|
|
2500
|
+
case "zar": return "R";
|
|
2501
|
+
case "zmw": return "ZK";
|
|
2502
|
+
}
|
|
2503
|
+
return null;
|
|
2504
|
+
},
|
|
2505
|
+
|
|
2506
|
+
// Fetch the payment products.
|
|
2507
|
+
/**
|
|
2508
|
+
* @docs:
|
|
2509
|
+
* @nav: Frontend
|
|
2510
|
+
* @chapter: Payments
|
|
2511
|
+
* @title: Payment Products
|
|
2512
|
+
* @description: Get the backend defined payment products asynchronously.
|
|
2513
|
+
* @type: array[object]
|
|
2514
|
+
* @return: Returns the backend defined payment products.
|
|
2515
|
+
*/
|
|
2516
|
+
get_products: async function(): Promise<any[]> {
|
|
2517
|
+
return new Promise((resolve, reject) => {
|
|
2518
|
+
if (this._products !== undefined) {
|
|
2519
|
+
return resolve(this._products);
|
|
2520
|
+
}
|
|
2521
|
+
Utils.request({
|
|
2522
|
+
method: "GET",
|
|
2523
|
+
url: "/volt/payments/products",
|
|
2524
|
+
})
|
|
2525
|
+
.then((products: any[]) => {
|
|
2526
|
+
this._products = products;
|
|
2527
|
+
resolve(this._products);
|
|
2528
|
+
})
|
|
2529
|
+
.catch((err: any) => {
|
|
2530
|
+
reject(err);
|
|
2531
|
+
});
|
|
2532
|
+
});
|
|
2533
|
+
},
|
|
2534
|
+
|
|
2535
|
+
// Fetch a payment product by id.
|
|
2536
|
+
/**
|
|
2537
|
+
* @docs:
|
|
2538
|
+
* @nav: Frontend
|
|
2539
|
+
* @chapter: Payments
|
|
2540
|
+
* @title: Get Payment Product
|
|
2541
|
+
* @description: Get the backend defined payment product by id asynchronously.
|
|
2542
|
+
* @type: object
|
|
2543
|
+
* @return: Returns the backend defined payment product.
|
|
2544
|
+
* @param:
|
|
2545
|
+
* @name: id
|
|
2546
|
+
* @required: true
|
|
2547
|
+
* @type: string
|
|
2548
|
+
* @desc: The id of the payment product.
|
|
2549
|
+
*/
|
|
2550
|
+
get_product: async function(id: string): Promise<any> {
|
|
2551
|
+
return new Promise(async (resolve, reject) => {
|
|
2552
|
+
const products = await this.get_products();
|
|
2553
|
+
let product: any = null;
|
|
2554
|
+
for (const p of products) {
|
|
2555
|
+
if (p.id === id) {
|
|
2556
|
+
product = p;
|
|
2557
|
+
break;
|
|
2558
|
+
}
|
|
2559
|
+
if (p.is_subscription) {
|
|
2560
|
+
for (const plan of p.plans) {
|
|
2561
|
+
if (plan.id === id) {
|
|
2562
|
+
product = plan;
|
|
2563
|
+
break;
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
if (product) break;
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
if (product == null) {
|
|
2570
|
+
return reject(new Error(`Product "${id}" does not exist.`));
|
|
2571
|
+
}
|
|
2572
|
+
resolve(product);
|
|
2573
|
+
});
|
|
2574
|
+
},
|
|
2575
|
+
|
|
2576
|
+
// Fetch a payment object by id.
|
|
2577
|
+
/**
|
|
2578
|
+
* @docs:
|
|
2579
|
+
* @nav: Frontend
|
|
2580
|
+
* @chapter: Payments
|
|
2581
|
+
* @title: Get Payment.
|
|
2582
|
+
* @desc: Get a payment by id.
|
|
2583
|
+
* @param:
|
|
2584
|
+
* @name: id
|
|
2585
|
+
* @required: true
|
|
2586
|
+
* @type: string
|
|
2587
|
+
* @desc: The id of the payment.
|
|
2588
|
+
*/
|
|
2589
|
+
get_payment: async function(id: string): Promise<any> {
|
|
2590
|
+
return Utils.request({
|
|
2591
|
+
method: "GET",
|
|
2592
|
+
url: "/volt/payments/payment",
|
|
2593
|
+
data: {
|
|
2594
|
+
id: id,
|
|
2595
|
+
}
|
|
2596
|
+
});
|
|
2597
|
+
},
|
|
2598
|
+
|
|
2599
|
+
// Get all payments.
|
|
2600
|
+
/**
|
|
2601
|
+
* @docs:
|
|
2602
|
+
* @nav: Frontend
|
|
2603
|
+
* @chapter: Payments
|
|
2604
|
+
* @title: Get Refunded Payments.
|
|
2605
|
+
* @desc:
|
|
2606
|
+
* Get all payments of the authenticated user
|
|
2607
|
+
*
|
|
2608
|
+
* All failed payments are no longer stored in the database.
|
|
2609
|
+
* @param:
|
|
2610
|
+
* @name: days
|
|
2611
|
+
* @type: number
|
|
2612
|
+
* @desc: Retrieve payments from the last amount of days.
|
|
2613
|
+
* @param:
|
|
2614
|
+
* @name: limit
|
|
2615
|
+
* @type: number
|
|
2616
|
+
* @desc: Limit the amount of response payment objects.
|
|
2617
|
+
* @param:
|
|
2618
|
+
* @name: status
|
|
2619
|
+
* @type: string
|
|
2620
|
+
* @desc: Filter the payments by status. Be aware that the line items of a payment also have a status with possible values of `open`, `cancelled`, `refunding` or `refunded.`
|
|
2621
|
+
* @enum:
|
|
2622
|
+
* @value: "open"
|
|
2623
|
+
* @desc: Payments that are still open and unpaid.
|
|
2624
|
+
* @enum:
|
|
2625
|
+
* @value: "paid"
|
|
2626
|
+
* @desc: Payments that are paid.
|
|
2627
|
+
*/
|
|
2628
|
+
get_payments: async function({
|
|
2629
|
+
days = 30,
|
|
2630
|
+
limit = null,
|
|
2631
|
+
status = null,
|
|
2632
|
+
} = {}): Promise<any> {
|
|
2633
|
+
return Utils.request({
|
|
2634
|
+
method: "GET",
|
|
2635
|
+
url: "/volt/payments/payments",
|
|
2636
|
+
data: {
|
|
2637
|
+
days,
|
|
2638
|
+
limit,
|
|
2639
|
+
status,
|
|
2640
|
+
}
|
|
2641
|
+
});
|
|
2642
|
+
},
|
|
2643
|
+
|
|
2644
|
+
// Get refundable payments.
|
|
2645
|
+
/**
|
|
2646
|
+
* @docs:
|
|
2647
|
+
* @nav: Frontend
|
|
2648
|
+
* @chapter: Payments
|
|
2649
|
+
* @title: Get Refundable Payments.
|
|
2650
|
+
* @desc: Get all payments that are refundable for the authenticated user.
|
|
2651
|
+
* @param:
|
|
2652
|
+
* @name: days
|
|
2653
|
+
* @type: number
|
|
2654
|
+
* @desc: Retrieve payments from the last amount of days.
|
|
2655
|
+
* @param:
|
|
2656
|
+
* @name: limit
|
|
2657
|
+
* @type: number
|
|
2658
|
+
* @desc: Limit the amount of response payment objects.
|
|
2659
|
+
*/
|
|
2660
|
+
get_refundable_payments: async function({
|
|
2661
|
+
days = 30,
|
|
2662
|
+
limit = null,
|
|
2663
|
+
} = {}): Promise<any> {
|
|
2664
|
+
return Utils.request({
|
|
2665
|
+
method: "GET",
|
|
2666
|
+
url: "/volt/payments/payments/refundable",
|
|
2667
|
+
data: {
|
|
2668
|
+
days,
|
|
2669
|
+
limit,
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
2672
|
+
},
|
|
2673
|
+
|
|
2674
|
+
// Get refunded payments.
|
|
2675
|
+
/**
|
|
2676
|
+
* @docs:
|
|
2677
|
+
* @nav: Frontend
|
|
2678
|
+
* @chapter: Payments
|
|
2679
|
+
* @title: Get Refunded Payments.
|
|
2680
|
+
* @desc: Get all successfully refunded payments of the authenticated user.
|
|
2681
|
+
* @param:
|
|
2682
|
+
* @name: days
|
|
2683
|
+
* @type: number
|
|
2684
|
+
* @desc: Retrieve payments from the last amount of days.
|
|
2685
|
+
* @param:
|
|
2686
|
+
* @name: limit
|
|
2687
|
+
* @type: number
|
|
2688
|
+
* @desc: Limit the amount of response payment objects.
|
|
2689
|
+
*/
|
|
2690
|
+
get_refunded_payments: async function({
|
|
2691
|
+
days = 30,
|
|
2692
|
+
limit = null,
|
|
2693
|
+
} = {}): Promise<any> {
|
|
2694
|
+
return Utils.request({
|
|
2695
|
+
method: "GET",
|
|
2696
|
+
url: "/volt/payments/payments/refunded",
|
|
2697
|
+
data: {
|
|
2698
|
+
days,
|
|
2699
|
+
limit,
|
|
2700
|
+
}
|
|
2701
|
+
});
|
|
2702
|
+
},
|
|
2703
|
+
|
|
2704
|
+
// Get refunding payments.
|
|
2705
|
+
/**
|
|
2706
|
+
* @docs:
|
|
2707
|
+
* @nav: Frontend
|
|
2708
|
+
* @chapter: Payments
|
|
2709
|
+
* @title: Get Refunding Payments.
|
|
2710
|
+
* @desc: Get all payments that are currently in the refunding process of the authenticated user.
|
|
2711
|
+
* @param:
|
|
2712
|
+
* @name: days
|
|
2713
|
+
* @type: number
|
|
2714
|
+
* @desc: Retrieve payments from the last amount of days.
|
|
2715
|
+
* @param:
|
|
2716
|
+
* @name: limit
|
|
2717
|
+
* @type: number
|
|
2718
|
+
* @desc: Limit the amount of response payment objects.
|
|
2719
|
+
*/
|
|
2720
|
+
get_refunding_payments: async function({
|
|
2721
|
+
days = null,
|
|
2722
|
+
limit = null,
|
|
2723
|
+
} = {}): Promise<any> {
|
|
2724
|
+
return Utils.request({
|
|
2725
|
+
method: "GET",
|
|
2726
|
+
url: "/volt/payments/payments/refunding",
|
|
2727
|
+
data: {
|
|
2728
|
+
days,
|
|
2729
|
+
limit,
|
|
2730
|
+
}
|
|
2731
|
+
});
|
|
2732
|
+
},
|
|
2733
|
+
|
|
2734
|
+
// Create refund.
|
|
2735
|
+
/**
|
|
2736
|
+
* @docs:
|
|
2737
|
+
* @nav: Frontend
|
|
2738
|
+
* @chapter: Payments
|
|
2739
|
+
* @title: Refund Payment.
|
|
2740
|
+
* @desc: Refund a payment based on the payment id for the authenticated user.
|
|
2741
|
+
* @warning: Refunding a subscription will also cancel all other subscriptions that were created by the same payment request.
|
|
2742
|
+
* @param:
|
|
2743
|
+
* @name: payment
|
|
2744
|
+
* @required: true
|
|
2745
|
+
* @type: number | string
|
|
2746
|
+
* @desc: The id of the payment object or the payment object itself.
|
|
2747
|
+
* @param:
|
|
2748
|
+
* @name: line_items
|
|
2749
|
+
* @required: true
|
|
2750
|
+
* @type: array[object]
|
|
2751
|
+
* @desc: The line items to refund, these must be retrieved from the original payment line items otherwise it may cause undefined behaviour. When undefined the entire payment will be refunded.
|
|
2752
|
+
* @param:
|
|
2753
|
+
* @name: reason
|
|
2754
|
+
* @type: string
|
|
2755
|
+
* @desc: The refund reason.
|
|
2756
|
+
*/
|
|
2757
|
+
create_refund: async function(payment: number | string, line_items: any[] | null = null, reason: string = "refund"): Promise<any> {
|
|
2758
|
+
return Utils.request({
|
|
2759
|
+
method: "POST",
|
|
2760
|
+
url: "/volt/payments/refund",
|
|
2761
|
+
data: {
|
|
2762
|
+
payment,
|
|
2763
|
+
line_items,
|
|
2764
|
+
reason,
|
|
2765
|
+
}
|
|
2766
|
+
});
|
|
2767
|
+
},
|
|
2768
|
+
|
|
2769
|
+
// Cancel subscription.
|
|
2770
|
+
/**
|
|
2771
|
+
* @docs:
|
|
2772
|
+
* @nav: Frontend
|
|
2773
|
+
* @chapter: Payments
|
|
2774
|
+
* @title: Cancel Subscription.
|
|
2775
|
+
* @desc: Cancel a subscription based on the product id.
|
|
2776
|
+
* @warning: Cancelling a subscription will also cancel all other subscriptions that were created by the same payment request.
|
|
2777
|
+
* @param:
|
|
2778
|
+
* @name: product
|
|
2779
|
+
* @required: true
|
|
2780
|
+
* @type: string
|
|
2781
|
+
* @desc: The product id.
|
|
2782
|
+
*/
|
|
2783
|
+
cancel_subscription: async function(product: string): Promise<any> {
|
|
2784
|
+
return Utils.request({
|
|
2785
|
+
method: "DELETE",
|
|
2786
|
+
url: "/volt/payments/subscription",
|
|
2787
|
+
data: {
|
|
2788
|
+
product,
|
|
2789
|
+
}
|
|
2790
|
+
});
|
|
2791
|
+
},
|
|
2792
|
+
|
|
2793
|
+
// Is subscribed.
|
|
2794
|
+
/**
|
|
2795
|
+
* @docs:
|
|
2796
|
+
* @nav: Frontend
|
|
2797
|
+
* @chapter: Payments
|
|
2798
|
+
* @title: Is Subscribed.
|
|
2799
|
+
* @desc: Check if the authenticated user is subscribed to a product plan.
|
|
2800
|
+
* @param:
|
|
2801
|
+
* @name: product
|
|
2802
|
+
* @required: true
|
|
2803
|
+
* @type: string
|
|
2804
|
+
* @desc: The product id.
|
|
2805
|
+
*/
|
|
2806
|
+
is_subscribed: async function(product: string): Promise<any> {
|
|
2807
|
+
return Utils.request({
|
|
2808
|
+
method: "GET",
|
|
2809
|
+
url: "/volt/payments/subscribed",
|
|
2810
|
+
data: {
|
|
2811
|
+
product,
|
|
2812
|
+
}
|
|
2813
|
+
});
|
|
2814
|
+
},
|
|
2815
|
+
|
|
2816
|
+
// Get active subscriptions.
|
|
2817
|
+
/**
|
|
2818
|
+
* @docs:
|
|
2819
|
+
* @nav: Frontend
|
|
2820
|
+
* @chapter: Payments
|
|
2821
|
+
* @title: Get active subscriptions
|
|
2822
|
+
* @desc: Get the active subscriptions of the authenticated user.
|
|
2823
|
+
*/
|
|
2824
|
+
get_active_subscriptions: async function(): Promise<any> {
|
|
2825
|
+
return Utils.request({
|
|
2826
|
+
method: "GET",
|
|
2827
|
+
url: "/volt/payments/active_subscriptions",
|
|
2828
|
+
});
|
|
2829
|
+
},
|
|
2830
|
+
|
|
2831
|
+
// Shopping cart.
|
|
2832
|
+
|
|
2833
|
+
// The shopping cart object.
|
|
2834
|
+
cart: {
|
|
2835
|
+
items: [] as any[],
|
|
2836
|
+
|
|
2837
|
+
// Refresh the shopping cart.
|
|
2838
|
+
/**
|
|
2839
|
+
* @docs:
|
|
2840
|
+
* @nav: Frontend
|
|
2841
|
+
* @chapter: Payments
|
|
2842
|
+
* @title: Refresh Cart
|
|
2843
|
+
* @description:
|
|
2844
|
+
* Refresh the shopping cart.
|
|
2845
|
+
*
|
|
2846
|
+
* The current cart items are accessible as `Payments.cart.items`.
|
|
2847
|
+
*/
|
|
2848
|
+
refresh: function(): void {
|
|
2849
|
+
// Load from local storage.
|
|
2850
|
+
try {
|
|
2851
|
+
this.items = JSON.parse(localStorage.getItem("volt_shopping_cart") as string) || [];
|
|
2852
|
+
} catch(err) {
|
|
2853
|
+
this.items = [];
|
|
2854
|
+
}
|
|
2855
|
+
|
|
2856
|
+
// Reset the charge objects.
|
|
2857
|
+
Payments._reset();
|
|
2858
|
+
},
|
|
2859
|
+
|
|
2860
|
+
// Save the shopping cart.
|
|
2861
|
+
/**
|
|
2862
|
+
* @docs:
|
|
2863
|
+
* @nav: Frontend
|
|
2864
|
+
* @chapter: Payments
|
|
2865
|
+
* @title: Save Cart
|
|
2866
|
+
* @description:
|
|
2867
|
+
* Save the shopping cart in the local storage.
|
|
2868
|
+
*
|
|
2869
|
+
* The current cart items are accessible as `Payments.cart.items`.
|
|
2870
|
+
*/
|
|
2871
|
+
save: function(): void {
|
|
2872
|
+
// Save to local storage.
|
|
2873
|
+
localStorage.setItem("volt_shopping_cart", JSON.stringify(this.items));
|
|
2874
|
+
|
|
2875
|
+
// Reset the charge objects.
|
|
2876
|
+
Payments._reset();
|
|
2877
|
+
},
|
|
2878
|
+
|
|
2879
|
+
// Add a product to the shopping cart.
|
|
2880
|
+
/**
|
|
2881
|
+
* @docs:
|
|
2882
|
+
* @nav: Frontend
|
|
2883
|
+
* @chapter: Payments
|
|
2884
|
+
* @title: Add to Cart
|
|
2885
|
+
* @description:
|
|
2886
|
+
* Add a product to the shopping cart.
|
|
2887
|
+
*
|
|
2888
|
+
* When the product was already added to the shopping cart only the quantity will be incremented.
|
|
2889
|
+
*
|
|
2890
|
+
* An error will be thrown if the product id does not exist.
|
|
2891
|
+
*
|
|
2892
|
+
* The current cart items are accessible as `Payments.cart.items`.
|
|
2893
|
+
* @param:
|
|
2894
|
+
* @name: id
|
|
2895
|
+
* @description: The product's id.
|
|
2896
|
+
* @type: string
|
|
2897
|
+
* @param:
|
|
2898
|
+
* @name: quantity
|
|
2899
|
+
* @description: The quantity to add.
|
|
2900
|
+
* @type: number
|
|
2901
|
+
*/
|
|
2902
|
+
add: async function(id: string, quantity: number = 1): Promise<void> {
|
|
2903
|
+
this.refresh(); // Update in case another window has updated the cart.
|
|
2904
|
+
const found = this.items.some((item: any) => {
|
|
2905
|
+
if (item.product.id === id) {
|
|
2906
|
+
item.quantity += quantity;
|
|
2907
|
+
return true;
|
|
2908
|
+
}
|
|
2909
|
+
return false;
|
|
2910
|
+
});
|
|
2911
|
+
if (!found) {
|
|
2912
|
+
try {
|
|
2913
|
+
const product = await Payments.get_product(id);
|
|
2914
|
+
this.items.push({
|
|
2915
|
+
product: product,
|
|
2916
|
+
quantity: quantity,
|
|
2917
|
+
});
|
|
2918
|
+
} catch (error: any) {
|
|
2919
|
+
console.error(error);
|
|
2920
|
+
Payments.on_error(error as Error);
|
|
2921
|
+
throw new Error(`Failed to add product with id "${id}" to the cart.`);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
this.save();
|
|
2925
|
+
},
|
|
2926
|
+
|
|
2927
|
+
// Remove a product from the shopping cart.
|
|
2928
|
+
/**
|
|
2929
|
+
* @docs:
|
|
2930
|
+
* @nav: Frontend
|
|
2931
|
+
* @chapter: Payments
|
|
2932
|
+
* @title: Remove from Cart
|
|
2933
|
+
* @description:
|
|
2934
|
+
* Remove a product from the shopping cart.
|
|
2935
|
+
*
|
|
2936
|
+
* Does not throw an error when the product was not added to the shopping cart.
|
|
2937
|
+
*
|
|
2938
|
+
* The current cart items are accessible as `Payments.cart.items`.
|
|
2939
|
+
* @param:
|
|
2940
|
+
* @name: id
|
|
2941
|
+
* @description: The product's id.
|
|
2942
|
+
* @type: string
|
|
2943
|
+
* @param:
|
|
2944
|
+
* @name: quantity
|
|
2945
|
+
* @description: The quantity to remove. When the quantity value is "all", the entire product will be removed from the shopping cart.
|
|
2946
|
+
* @type: number | "all"
|
|
2947
|
+
*/
|
|
2948
|
+
remove: async function(id: string, quantity: number | "all" = 1): Promise<void> {
|
|
2949
|
+
this.refresh(); // Update in case another window has updated the cart.
|
|
2950
|
+
let new_cart: any[] = [];
|
|
2951
|
+
this.items.forEach((item: any) => {
|
|
2952
|
+
if (item.product.id === id) {
|
|
2953
|
+
if (quantity === "all") {
|
|
2954
|
+
item.quantity = 0;
|
|
2955
|
+
} else {
|
|
2956
|
+
item.quantity -= quantity;
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
if (item.quantity > 0) {
|
|
2960
|
+
new_cart.push(item);
|
|
2961
|
+
}
|
|
2962
|
+
});
|
|
2963
|
+
this.items = new_cart;
|
|
2964
|
+
this.save();
|
|
2965
|
+
},
|
|
2966
|
+
|
|
2967
|
+
// Clear the shopping cart.
|
|
2968
|
+
/**
|
|
2969
|
+
* @docs:
|
|
2970
|
+
* @nav: Frontend
|
|
2971
|
+
* @chapter: Payments
|
|
2972
|
+
* @title: Clear Cart
|
|
2973
|
+
* @description:
|
|
2974
|
+
* Clear the shopping cart.
|
|
2975
|
+
*
|
|
2976
|
+
* Will automatically be called if `Payments.confirm_charge()` finishes without any errors.
|
|
2977
|
+
*
|
|
2978
|
+
* The current cart items are accessible as `Payments.cart.items`.
|
|
2979
|
+
*/
|
|
2980
|
+
clear: async function(): Promise<void> {
|
|
2981
|
+
this.items = [];
|
|
2982
|
+
this.save();
|
|
2983
|
+
}
|
|
2984
|
+
},
|
|
2985
|
+
|
|
2986
|
+
|
|
2987
|
+
};
|
|
2988
|
+
|
|
2989
|
+
// Exports.
|
|
2990
|
+
export { Payments };
|