@vandenberghinc/volt 1.2.4 → 1.2.6
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/frontend/assets/admin/admin.png +0 -0
- package/frontend/assets/admin/password.webp +0 -0
- package/frontend/assets/icons/arrow.v1.webp +0 -0
- package/frontend/assets/icons/copy.webp +0 -0
- package/frontend/assets/payments/arrow.long.webp +0 -0
- package/frontend/assets/payments/arrow.long2.webp +0 -0
- package/frontend/assets/payments/cancelled.webp +0 -0
- package/frontend/assets/payments/check.sign.webp +0 -0
- package/frontend/assets/payments/check.webp +0 -0
- package/frontend/assets/payments/close.webp +0 -0
- package/frontend/assets/payments/error.webp +0 -0
- package/frontend/assets/payments/exclamation.webp +0 -0
- package/frontend/assets/payments/minus.webp +0 -0
- package/frontend/assets/payments/party.webp +0 -0
- package/frontend/assets/payments/plus.webp +0 -0
- package/frontend/assets/payments/shopping_cart.webp +0 -0
- package/frontend/assets/payments/trash.webp +0 -0
- package/package.json +6 -2
- package/.libris/config.json +0 -82
- package/backend/dist/cjs/backend/src/blacklist.d.ts +0 -12
- package/backend/dist/cjs/backend/src/blacklist.js +0 -78
- package/backend/dist/cjs/backend/src/cli.d.ts +0 -2
- package/backend/dist/cjs/backend/src/cli.js +0 -198
- package/backend/dist/cjs/backend/src/database/collection.d.ts +0 -1765
- package/backend/dist/cjs/backend/src/database/collection.js +0 -3301
- package/backend/dist/cjs/backend/src/database/database.d.ts +0 -92
- package/backend/dist/cjs/backend/src/database/database.js +0 -170
- package/backend/dist/cjs/backend/src/database/document.d.ts +0 -1
- package/backend/dist/cjs/backend/src/database/document.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/filters.d.ts +0 -6
- package/backend/dist/cjs/backend/src/database/filters/filters.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_filter.d.ts +0 -223
- package/backend/dist/cjs/backend/src/database/filters/strict_filter.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_test.d.ts +0 -1
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_test.js +0 -443
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_test_v0.d.ts +0 -1
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_test_v0.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v0.d.ts +0 -50
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v0.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v1.d.ts +0 -76
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v1.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v2.d.ts +0 -75
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v2.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v3.d.ts +0 -219
- package/backend/dist/cjs/backend/src/database/filters/strict_filter_v3.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_update_filter.d.ts +0 -165
- package/backend/dist/cjs/backend/src/database/filters/strict_update_filter.js +0 -15
- package/backend/dist/cjs/backend/src/database/filters/strict_update_filter_test.d.ts +0 -5
- package/backend/dist/cjs/backend/src/database/filters/strict_update_filter_test.js +0 -355
- package/backend/dist/cjs/backend/src/database/flatten.d.ts +0 -78
- package/backend/dist/cjs/backend/src/database/flatten.js +0 -53
- package/backend/dist/cjs/backend/src/database/flatten_test.d.ts +0 -1
- package/backend/dist/cjs/backend/src/database/flatten_test.js +0 -175
- package/backend/dist/cjs/backend/src/database/quota/quoata_v2.d.ts +0 -533
- package/backend/dist/cjs/backend/src/database/quota/quoata_v2.js +0 -1046
- package/backend/dist/cjs/backend/src/database/quota/quota.d.ts +0 -551
- package/backend/dist/cjs/backend/src/database/quota/quota.js +0 -1108
- package/backend/dist/cjs/backend/src/database/quota/quota_v1.d.ts +0 -534
- package/backend/dist/cjs/backend/src/database/quota/quota_v1.js +0 -1087
- package/backend/dist/cjs/backend/src/database/quota/safe_int.d.ts +0 -412
- package/backend/dist/cjs/backend/src/database/quota/safe_int.js +0 -745
- package/backend/dist/cjs/backend/src/endpoint.d.ts +0 -346
- package/backend/dist/cjs/backend/src/endpoint.js +0 -468
- package/backend/dist/cjs/backend/src/errors/index.d.ts +0 -7
- package/backend/dist/cjs/backend/src/errors/index.js +0 -25
- package/backend/dist/cjs/backend/src/errors/internal_external.d.ts +0 -52
- package/backend/dist/cjs/backend/src/errors/internal_external.js +0 -95
- package/backend/dist/cjs/backend/src/errors/invalid_usage_error.d.ts +0 -41
- package/backend/dist/cjs/backend/src/errors/invalid_usage_error.js +0 -47
- package/backend/dist/cjs/backend/src/errors/system_error.d.ts +0 -261
- package/backend/dist/cjs/backend/src/errors/system_error.js +0 -436
- package/backend/dist/cjs/backend/src/events.d.ts +0 -97
- package/backend/dist/cjs/backend/src/events.js +0 -15
- package/backend/dist/cjs/backend/src/frontend.d.ts +0 -11
- package/backend/dist/cjs/backend/src/frontend.js +0 -37
- package/backend/dist/cjs/backend/src/image_endpoint.d.ts +0 -44
- package/backend/dist/cjs/backend/src/image_endpoint.js +0 -185
- package/backend/dist/cjs/backend/src/index.d.ts +0 -23
- package/backend/dist/cjs/backend/src/index.js +0 -70
- package/backend/dist/cjs/backend/src/logger.d.ts +0 -5
- package/backend/dist/cjs/backend/src/logger.js +0 -15
- package/backend/dist/cjs/backend/src/meta.d.ts +0 -112
- package/backend/dist/cjs/backend/src/meta.js +0 -181
- package/backend/dist/cjs/backend/src/payments/paddle.d.ts +0 -329
- package/backend/dist/cjs/backend/src/payments/paddle.js +0 -1996
- package/backend/dist/cjs/backend/src/payments/stripe/checkout.d.ts +0 -113
- package/backend/dist/cjs/backend/src/payments/stripe/checkout.js +0 -295
- package/backend/dist/cjs/backend/src/payments/stripe/customers.d.ts +0 -17
- package/backend/dist/cjs/backend/src/payments/stripe/customers.js +0 -164
- package/backend/dist/cjs/backend/src/payments/stripe/error.d.ts +0 -74
- package/backend/dist/cjs/backend/src/payments/stripe/error.js +0 -64
- package/backend/dist/cjs/backend/src/payments/stripe/events.d.ts +0 -155
- package/backend/dist/cjs/backend/src/payments/stripe/events.js +0 -15
- package/backend/dist/cjs/backend/src/payments/stripe/meters.d.ts +0 -105
- package/backend/dist/cjs/backend/src/payments/stripe/meters.js +0 -230
- package/backend/dist/cjs/backend/src/payments/stripe/payment_methods.d.ts +0 -58
- package/backend/dist/cjs/backend/src/payments/stripe/payment_methods.js +0 -109
- package/backend/dist/cjs/backend/src/payments/stripe/products.d.ts +0 -519
- package/backend/dist/cjs/backend/src/payments/stripe/products.js +0 -650
- package/backend/dist/cjs/backend/src/payments/stripe/stripe.d.ts +0 -215
- package/backend/dist/cjs/backend/src/payments/stripe/stripe.js +0 -468
- package/backend/dist/cjs/backend/src/payments/stripe/subscriptions.d.ts +0 -172
- package/backend/dist/cjs/backend/src/payments/stripe/subscriptions.js +0 -557
- package/backend/dist/cjs/backend/src/payments/stripe/utils.d.ts +0 -63
- package/backend/dist/cjs/backend/src/payments/stripe/utils.js +0 -118
- package/backend/dist/cjs/backend/src/payments/stripe/webhooks.d.ts +0 -105
- package/backend/dist/cjs/backend/src/payments/stripe/webhooks.js +0 -627
- package/backend/dist/cjs/backend/src/plugins/browser.d.ts +0 -1
- package/backend/dist/cjs/backend/src/plugins/browser.js +0 -15
- package/backend/dist/cjs/backend/src/plugins/communication.d.ts +0 -70
- package/backend/dist/cjs/backend/src/plugins/communication.js +0 -196
- package/backend/dist/cjs/backend/src/plugins/mail/mail.d.ts +0 -255
- package/backend/dist/cjs/backend/src/plugins/mail/mail.js +0 -381
- package/backend/dist/cjs/backend/src/plugins/mail/ui.d.ts +0 -297
- package/backend/dist/cjs/backend/src/plugins/mail/ui.js +0 -1370
- package/backend/dist/cjs/backend/src/plugins/pdf.d.ts +0 -1
- package/backend/dist/cjs/backend/src/plugins/pdf.js +0 -1456
- package/backend/dist/cjs/backend/src/plugins/thread_monitor.d.ts +0 -18
- package/backend/dist/cjs/backend/src/plugins/thread_monitor.js +0 -116
- package/backend/dist/cjs/backend/src/rate_limit.d.ts +0 -148
- package/backend/dist/cjs/backend/src/rate_limit.js +0 -543
- package/backend/dist/cjs/backend/src/route.d.ts +0 -39
- package/backend/dist/cjs/backend/src/route.js +0 -172
- package/backend/dist/cjs/backend/src/server.d.ts +0 -502
- package/backend/dist/cjs/backend/src/server.js +0 -1713
- package/backend/dist/cjs/backend/src/server.old.d.ts +0 -594
- package/backend/dist/cjs/backend/src/server.old.js +0 -2058
- package/backend/dist/cjs/backend/src/splash_screen.d.ts +0 -93
- package/backend/dist/cjs/backend/src/splash_screen.js +0 -119
- package/backend/dist/cjs/backend/src/status.d.ts +0 -89
- package/backend/dist/cjs/backend/src/status.js +0 -211
- package/backend/dist/cjs/backend/src/stream.d.ts +0 -494
- package/backend/dist/cjs/backend/src/stream.js +0 -1370
- package/backend/dist/cjs/backend/src/users.d.ts +0 -926
- package/backend/dist/cjs/backend/src/users.js +0 -2223
- package/backend/dist/cjs/backend/src/utils.d.ts +0 -22
- package/backend/dist/cjs/backend/src/utils.js +0 -626
- package/backend/dist/cjs/backend/src/view.d.ts +0 -115
- package/backend/dist/cjs/backend/src/view.js +0 -519
- package/backend/dist/cjs/backend/src/vinc.d.ts +0 -6
- package/backend/dist/cjs/backend/src/vinc.js +0 -40
- package/backend/dist/cjs/backend/src/volt.d.ts +0 -24
- package/backend/dist/cjs/backend/src/volt.js +0 -72
- package/backend/dist/cjs/frontend/src/modules/request.d.ts +0 -70
- package/backend/dist/cjs/frontend/src/modules/request.js +0 -99
- package/backend/dist/cjs/package.json +0 -1
- package/backend/dist/esm/backend/src/blacklist.d.ts +0 -12
- package/backend/dist/esm/backend/src/blacklist.js +0 -52
- package/backend/dist/esm/backend/src/cli.d.ts +0 -2
- package/backend/dist/esm/backend/src/cli.js +0 -211
- package/backend/dist/esm/backend/src/database/collection.d.ts +0 -1765
- package/backend/dist/esm/backend/src/database/collection.js +0 -3779
- package/backend/dist/esm/backend/src/database/database.d.ts +0 -92
- package/backend/dist/esm/backend/src/database/database.js +0 -214
- package/backend/dist/esm/backend/src/database/document.d.ts +0 -1
- package/backend/dist/esm/backend/src/database/document.js +0 -558
- package/backend/dist/esm/backend/src/database/filters/filters.d.ts +0 -6
- package/backend/dist/esm/backend/src/database/filters/filters.js +0 -1
- package/backend/dist/esm/backend/src/database/filters/strict_filter.d.ts +0 -223
- package/backend/dist/esm/backend/src/database/filters/strict_filter.js +0 -3
- package/backend/dist/esm/backend/src/database/filters/strict_filter_test.d.ts +0 -1
- package/backend/dist/esm/backend/src/database/filters/strict_filter_test.js +0 -505
- package/backend/dist/esm/backend/src/database/filters/strict_filter_test_v0.d.ts +0 -1
- package/backend/dist/esm/backend/src/database/filters/strict_filter_test_v0.js +0 -712
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v0.d.ts +0 -50
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v0.js +0 -5
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v1.d.ts +0 -76
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v1.js +0 -44
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v2.d.ts +0 -75
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v2.js +0 -5
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v3.d.ts +0 -219
- package/backend/dist/esm/backend/src/database/filters/strict_filter_v3.js +0 -1
- package/backend/dist/esm/backend/src/database/filters/strict_update_filter.d.ts +0 -165
- package/backend/dist/esm/backend/src/database/filters/strict_update_filter.js +0 -5
- package/backend/dist/esm/backend/src/database/filters/strict_update_filter_test.d.ts +0 -5
- package/backend/dist/esm/backend/src/database/filters/strict_update_filter_test.js +0 -415
- package/backend/dist/esm/backend/src/database/flatten.d.ts +0 -78
- package/backend/dist/esm/backend/src/database/flatten.js +0 -22
- package/backend/dist/esm/backend/src/database/flatten_test.d.ts +0 -1
- package/backend/dist/esm/backend/src/database/flatten_test.js +0 -174
- package/backend/dist/esm/backend/src/database/quota/quoata_v2.d.ts +0 -533
- package/backend/dist/esm/backend/src/database/quota/quoata_v2.js +0 -1155
- package/backend/dist/esm/backend/src/database/quota/quota.d.ts +0 -551
- package/backend/dist/esm/backend/src/database/quota/quota.js +0 -1219
- package/backend/dist/esm/backend/src/database/quota/quota_v1.d.ts +0 -534
- package/backend/dist/esm/backend/src/database/quota/quota_v1.js +0 -1242
- package/backend/dist/esm/backend/src/database/quota/safe_int.d.ts +0 -412
- package/backend/dist/esm/backend/src/database/quota/safe_int.js +0 -810
- package/backend/dist/esm/backend/src/endpoint.d.ts +0 -346
- package/backend/dist/esm/backend/src/endpoint.js +0 -479
- package/backend/dist/esm/backend/src/errors/index.d.ts +0 -7
- package/backend/dist/esm/backend/src/errors/index.js +0 -7
- package/backend/dist/esm/backend/src/errors/internal_external.d.ts +0 -52
- package/backend/dist/esm/backend/src/errors/internal_external.js +0 -86
- package/backend/dist/esm/backend/src/errors/invalid_usage_error.d.ts +0 -41
- package/backend/dist/esm/backend/src/errors/invalid_usage_error.js +0 -33
- package/backend/dist/esm/backend/src/errors/system_error.d.ts +0 -261
- package/backend/dist/esm/backend/src/errors/system_error.js +0 -444
- package/backend/dist/esm/backend/src/events.d.ts +0 -97
- package/backend/dist/esm/backend/src/events.js +0 -5
- package/backend/dist/esm/backend/src/frontend.d.ts +0 -11
- package/backend/dist/esm/backend/src/frontend.js +0 -12
- package/backend/dist/esm/backend/src/image_endpoint.d.ts +0 -44
- package/backend/dist/esm/backend/src/image_endpoint.js +0 -196
- package/backend/dist/esm/backend/src/index.d.ts +0 -23
- package/backend/dist/esm/backend/src/index.js +0 -26
- package/backend/dist/esm/backend/src/logger.d.ts +0 -5
- package/backend/dist/esm/backend/src/logger.js +0 -8
- package/backend/dist/esm/backend/src/meta.d.ts +0 -112
- package/backend/dist/esm/backend/src/meta.js +0 -152
- package/backend/dist/esm/backend/src/payments/paddle.d.ts +0 -329
- package/backend/dist/esm/backend/src/payments/paddle.js +0 -2276
- package/backend/dist/esm/backend/src/payments/stripe/checkout.d.ts +0 -113
- package/backend/dist/esm/backend/src/payments/stripe/checkout.js +0 -356
- package/backend/dist/esm/backend/src/payments/stripe/customers.d.ts +0 -17
- package/backend/dist/esm/backend/src/payments/stripe/customers.js +0 -193
- package/backend/dist/esm/backend/src/payments/stripe/error.d.ts +0 -74
- package/backend/dist/esm/backend/src/payments/stripe/error.js +0 -51
- package/backend/dist/esm/backend/src/payments/stripe/events.d.ts +0 -155
- package/backend/dist/esm/backend/src/payments/stripe/events.js +0 -5
- package/backend/dist/esm/backend/src/payments/stripe/meters.d.ts +0 -105
- package/backend/dist/esm/backend/src/payments/stripe/meters.js +0 -318
- package/backend/dist/esm/backend/src/payments/stripe/payment_methods.d.ts +0 -58
- package/backend/dist/esm/backend/src/payments/stripe/payment_methods.js +0 -135
- package/backend/dist/esm/backend/src/payments/stripe/products.d.ts +0 -519
- package/backend/dist/esm/backend/src/payments/stripe/products.js +0 -896
- package/backend/dist/esm/backend/src/payments/stripe/stripe.d.ts +0 -215
- package/backend/dist/esm/backend/src/payments/stripe/stripe.js +0 -464
- package/backend/dist/esm/backend/src/payments/stripe/subscriptions.d.ts +0 -172
- package/backend/dist/esm/backend/src/payments/stripe/subscriptions.js +0 -754
- package/backend/dist/esm/backend/src/payments/stripe/utils.d.ts +0 -63
- package/backend/dist/esm/backend/src/payments/stripe/utils.js +0 -131
- package/backend/dist/esm/backend/src/payments/stripe/webhooks.d.ts +0 -105
- package/backend/dist/esm/backend/src/payments/stripe/webhooks.js +0 -752
- package/backend/dist/esm/backend/src/plugins/browser.d.ts +0 -1
- package/backend/dist/esm/backend/src/plugins/browser.js +0 -170
- package/backend/dist/esm/backend/src/plugins/communication.d.ts +0 -70
- package/backend/dist/esm/backend/src/plugins/communication.js +0 -169
- package/backend/dist/esm/backend/src/plugins/mail/mail.d.ts +0 -255
- package/backend/dist/esm/backend/src/plugins/mail/mail.js +0 -396
- package/backend/dist/esm/backend/src/plugins/mail/ui.d.ts +0 -297
- package/backend/dist/esm/backend/src/plugins/mail/ui.js +0 -1400
- package/backend/dist/esm/backend/src/plugins/pdf.d.ts +0 -1
- package/backend/dist/esm/backend/src/plugins/pdf.js +0 -1694
- package/backend/dist/esm/backend/src/plugins/thread_monitor.d.ts +0 -18
- package/backend/dist/esm/backend/src/plugins/thread_monitor.js +0 -120
- package/backend/dist/esm/backend/src/rate_limit.d.ts +0 -148
- package/backend/dist/esm/backend/src/rate_limit.js +0 -667
- package/backend/dist/esm/backend/src/route.d.ts +0 -39
- package/backend/dist/esm/backend/src/route.js +0 -222
- package/backend/dist/esm/backend/src/server.d.ts +0 -502
- package/backend/dist/esm/backend/src/server.js +0 -2034
- package/backend/dist/esm/backend/src/server.old.d.ts +0 -594
- package/backend/dist/esm/backend/src/server.old.js +0 -2630
- package/backend/dist/esm/backend/src/splash_screen.d.ts +0 -93
- package/backend/dist/esm/backend/src/splash_screen.js +0 -156
- package/backend/dist/esm/backend/src/status.d.ts +0 -89
- package/backend/dist/esm/backend/src/status.js +0 -213
- package/backend/dist/esm/backend/src/stream.d.ts +0 -494
- package/backend/dist/esm/backend/src/stream.js +0 -1611
- package/backend/dist/esm/backend/src/users.d.ts +0 -926
- package/backend/dist/esm/backend/src/users.js +0 -2423
- package/backend/dist/esm/backend/src/utils.d.ts +0 -22
- package/backend/dist/esm/backend/src/utils.js +0 -463
- package/backend/dist/esm/backend/src/view.d.ts +0 -115
- package/backend/dist/esm/backend/src/view.js +0 -584
- package/backend/dist/esm/backend/src/vinc.d.ts +0 -6
- package/backend/dist/esm/backend/src/vinc.js +0 -6
- package/backend/dist/esm/backend/src/volt.d.ts +0 -24
- package/backend/dist/esm/backend/src/volt.js +0 -27
- package/backend/dist/esm/frontend/src/modules/request.d.ts +0 -70
- package/backend/dist/esm/frontend/src/modules/request.js +0 -117
- package/backend/old/file_watcher.ts +0 -359
- package/backend/old/request.deprc.js +0 -626
- package/backend/old/response.deprc.js +0 -354
- package/frontend/dist/backend/src/database/collection.d.ts +0 -1765
- package/frontend/dist/backend/src/database/collection.js +0 -3779
- package/frontend/dist/backend/src/database/database.d.ts +0 -92
- package/frontend/dist/backend/src/database/database.js +0 -214
- package/frontend/dist/backend/src/database/filters/filters.d.ts +0 -6
- package/frontend/dist/backend/src/database/filters/filters.js +0 -1
- package/frontend/dist/backend/src/database/filters/strict_filter.d.ts +0 -223
- package/frontend/dist/backend/src/database/filters/strict_filter.js +0 -3
- package/frontend/dist/backend/src/database/filters/strict_update_filter.d.ts +0 -165
- package/frontend/dist/backend/src/database/filters/strict_update_filter.js +0 -5
- package/frontend/dist/backend/src/database/flatten.d.ts +0 -78
- package/frontend/dist/backend/src/database/flatten.js +0 -22
- package/frontend/dist/backend/src/endpoint.d.ts +0 -346
- package/frontend/dist/backend/src/endpoint.js +0 -479
- package/frontend/dist/backend/src/errors/index.d.ts +0 -7
- package/frontend/dist/backend/src/errors/index.js +0 -7
- package/frontend/dist/backend/src/errors/internal_external.d.ts +0 -52
- package/frontend/dist/backend/src/errors/internal_external.js +0 -86
- package/frontend/dist/backend/src/errors/invalid_usage_error.d.ts +0 -41
- package/frontend/dist/backend/src/errors/invalid_usage_error.js +0 -33
- package/frontend/dist/backend/src/errors/system_error.d.ts +0 -261
- package/frontend/dist/backend/src/errors/system_error.js +0 -444
- package/frontend/dist/backend/src/events.d.ts +0 -97
- package/frontend/dist/backend/src/events.js +0 -5
- package/frontend/dist/backend/src/frontend.d.ts +0 -11
- package/frontend/dist/backend/src/frontend.js +0 -12
- package/frontend/dist/backend/src/image_endpoint.d.ts +0 -44
- package/frontend/dist/backend/src/image_endpoint.js +0 -196
- package/frontend/dist/backend/src/meta.d.ts +0 -112
- package/frontend/dist/backend/src/meta.js +0 -152
- package/frontend/dist/backend/src/payments/paddle.d.ts +0 -329
- package/frontend/dist/backend/src/payments/paddle.js +0 -2276
- package/frontend/dist/backend/src/payments/stripe/checkout.d.ts +0 -113
- package/frontend/dist/backend/src/payments/stripe/checkout.js +0 -356
- package/frontend/dist/backend/src/payments/stripe/customers.d.ts +0 -17
- package/frontend/dist/backend/src/payments/stripe/customers.js +0 -193
- package/frontend/dist/backend/src/payments/stripe/error.d.ts +0 -74
- package/frontend/dist/backend/src/payments/stripe/error.js +0 -51
- package/frontend/dist/backend/src/payments/stripe/events.d.ts +0 -155
- package/frontend/dist/backend/src/payments/stripe/events.js +0 -5
- package/frontend/dist/backend/src/payments/stripe/meters.d.ts +0 -105
- package/frontend/dist/backend/src/payments/stripe/meters.js +0 -318
- package/frontend/dist/backend/src/payments/stripe/payment_methods.d.ts +0 -58
- package/frontend/dist/backend/src/payments/stripe/payment_methods.js +0 -135
- package/frontend/dist/backend/src/payments/stripe/products.d.ts +0 -519
- package/frontend/dist/backend/src/payments/stripe/products.js +0 -896
- package/frontend/dist/backend/src/payments/stripe/stripe.d.ts +0 -215
- package/frontend/dist/backend/src/payments/stripe/stripe.js +0 -464
- package/frontend/dist/backend/src/payments/stripe/subscriptions.d.ts +0 -172
- package/frontend/dist/backend/src/payments/stripe/subscriptions.js +0 -754
- package/frontend/dist/backend/src/payments/stripe/utils.d.ts +0 -63
- package/frontend/dist/backend/src/payments/stripe/utils.js +0 -131
- package/frontend/dist/backend/src/payments/stripe/webhooks.d.ts +0 -105
- package/frontend/dist/backend/src/payments/stripe/webhooks.js +0 -752
- package/frontend/dist/backend/src/plugins/mail/mail.d.ts +0 -255
- package/frontend/dist/backend/src/plugins/mail/mail.js +0 -396
- package/frontend/dist/backend/src/plugins/mail/ui.d.ts +0 -297
- package/frontend/dist/backend/src/plugins/mail/ui.js +0 -1400
- package/frontend/dist/backend/src/rate_limit.d.ts +0 -148
- package/frontend/dist/backend/src/rate_limit.js +0 -667
- package/frontend/dist/backend/src/route.d.ts +0 -39
- package/frontend/dist/backend/src/route.js +0 -222
- package/frontend/dist/backend/src/server.d.ts +0 -502
- package/frontend/dist/backend/src/server.js +0 -2034
- package/frontend/dist/backend/src/splash_screen.d.ts +0 -93
- package/frontend/dist/backend/src/splash_screen.js +0 -156
- package/frontend/dist/backend/src/status.d.ts +0 -89
- package/frontend/dist/backend/src/status.js +0 -213
- package/frontend/dist/backend/src/stream.d.ts +0 -494
- package/frontend/dist/backend/src/stream.js +0 -1611
- package/frontend/dist/backend/src/users.d.ts +0 -926
- package/frontend/dist/backend/src/users.js +0 -2423
- package/frontend/dist/backend/src/utils.d.ts +0 -22
- package/frontend/dist/backend/src/utils.js +0 -463
- package/frontend/dist/backend/src/view.d.ts +0 -115
- package/frontend/dist/backend/src/view.js +0 -584
- package/frontend/dist/frontend/src/elements/base.d.ts +0 -3743
- package/frontend/dist/frontend/src/elements/base.js +0 -12151
- package/frontend/dist/frontend/src/elements/module.d.ts +0 -95
- package/frontend/dist/frontend/src/elements/module.js +0 -216
- package/frontend/dist/frontend/src/elements/register_element.d.ts +0 -3
- package/frontend/dist/frontend/src/elements/register_element.js +0 -22
- package/frontend/dist/frontend/src/elements/resize_query_manager.d.ts +0 -0
- package/frontend/dist/frontend/src/elements/resize_query_manager.js +0 -150
- package/frontend/dist/frontend/src/elements/types.d.ts +0 -52
- package/frontend/dist/frontend/src/elements/types.js +0 -5
- package/frontend/dist/frontend/src/index.d.ts +0 -21
- package/frontend/dist/frontend/src/index.js +0 -29
- package/frontend/dist/frontend/src/modules/attachment.d.ts +0 -126
- package/frontend/dist/frontend/src/modules/attachment.js +0 -306
- package/frontend/dist/frontend/src/modules/auth.d.ts +0 -44
- package/frontend/dist/frontend/src/modules/auth.js +0 -80
- package/frontend/dist/frontend/src/modules/color.d.ts +0 -160
- package/frontend/dist/frontend/src/modules/color.js +0 -316
- package/frontend/dist/frontend/src/modules/compression.d.ts +0 -39
- package/frontend/dist/frontend/src/modules/compression.js +0 -102
- package/frontend/dist/frontend/src/modules/cookies.d.ts +0 -44
- package/frontend/dist/frontend/src/modules/cookies.js +0 -143
- package/frontend/dist/frontend/src/modules/events.d.ts +0 -31
- package/frontend/dist/frontend/src/modules/events.js +0 -79
- package/frontend/dist/frontend/src/modules/google.d.ts +0 -23
- package/frontend/dist/frontend/src/modules/google.js +0 -52
- package/frontend/dist/frontend/src/modules/meta.d.ts +0 -14
- package/frontend/dist/frontend/src/modules/meta.js +0 -48
- package/frontend/dist/frontend/src/modules/paddle.d.ts +0 -1207
- package/frontend/dist/frontend/src/modules/paddle.js +0 -2594
- package/frontend/dist/frontend/src/modules/request.d.ts +0 -70
- package/frontend/dist/frontend/src/modules/request.js +0 -117
- package/frontend/dist/frontend/src/modules/settings.d.ts +0 -3
- package/frontend/dist/frontend/src/modules/settings.js +0 -5
- package/frontend/dist/frontend/src/modules/statics.d.ts +0 -21
- package/frontend/dist/frontend/src/modules/statics.js +0 -43
- package/frontend/dist/frontend/src/modules/stripe/cart.d.ts +0 -112
- package/frontend/dist/frontend/src/modules/stripe/cart.js +0 -321
- package/frontend/dist/frontend/src/modules/stripe/checkout.d.ts +0 -7
- package/frontend/dist/frontend/src/modules/stripe/checkout.js +0 -37
- package/frontend/dist/frontend/src/modules/stripe/index.m.d.ts +0 -6
- package/frontend/dist/frontend/src/modules/stripe/index.m.js +0 -6
- package/frontend/dist/frontend/src/modules/stripe/payments.d.ts +0 -58
- package/frontend/dist/frontend/src/modules/stripe/payments.js +0 -92
- package/frontend/dist/frontend/src/modules/support.d.ts +0 -30
- package/frontend/dist/frontend/src/modules/support.js +0 -53
- package/frontend/dist/frontend/src/modules/theme.d.ts +0 -133
- package/frontend/dist/frontend/src/modules/theme.js +0 -406
- package/frontend/dist/frontend/src/modules/themes.d.ts +0 -12
- package/frontend/dist/frontend/src/modules/themes.js +0 -22
- package/frontend/dist/frontend/src/modules/user.d.ts +0 -164
- package/frontend/dist/frontend/src/modules/user.js +0 -270
- package/frontend/dist/frontend/src/modules/utils.d.ts +0 -176
- package/frontend/dist/frontend/src/modules/utils.js +0 -569
- package/frontend/dist/frontend/src/types/gradient.d.ts +0 -29
- package/frontend/dist/frontend/src/types/gradient.js +0 -79
- package/frontend/dist/frontend/src/ui/border_button.d.ts +0 -94
- package/frontend/dist/frontend/src/ui/border_button.js +0 -228
- package/frontend/dist/frontend/src/ui/button.d.ts +0 -241
- package/frontend/dist/frontend/src/ui/button.js +0 -682
- package/frontend/dist/frontend/src/ui/canvas.d.ts +0 -138
- package/frontend/dist/frontend/src/ui/canvas.js +0 -444
- package/frontend/dist/frontend/src/ui/checkbox.d.ts +0 -74
- package/frontend/dist/frontend/src/ui/checkbox.js +0 -321
- package/frontend/dist/frontend/src/ui/code.d.ts +0 -235
- package/frontend/dist/frontend/src/ui/code.js +0 -1007
- package/frontend/dist/frontend/src/ui/context_menu.d.ts +0 -36
- package/frontend/dist/frontend/src/ui/context_menu.js +0 -205
- package/frontend/dist/frontend/src/ui/css.d.ts +0 -16
- package/frontend/dist/frontend/src/ui/css.js +0 -48
- package/frontend/dist/frontend/src/ui/divider.d.ts +0 -15
- package/frontend/dist/frontend/src/ui/divider.js +0 -78
- package/frontend/dist/frontend/src/ui/dropdown.d.ts +0 -176
- package/frontend/dist/frontend/src/ui/dropdown.js +0 -481
- package/frontend/dist/frontend/src/ui/for_each.d.ts +0 -37
- package/frontend/dist/frontend/src/ui/for_each.js +0 -92
- package/frontend/dist/frontend/src/ui/form.d.ts +0 -34
- package/frontend/dist/frontend/src/ui/form.js +0 -233
- package/frontend/dist/frontend/src/ui/frame_modes.d.ts +0 -37
- package/frontend/dist/frontend/src/ui/frame_modes.js +0 -108
- package/frontend/dist/frontend/src/ui/google_map.d.ts +0 -24
- package/frontend/dist/frontend/src/ui/google_map.js +0 -106
- package/frontend/dist/frontend/src/ui/gradient.d.ts +0 -25
- package/frontend/dist/frontend/src/ui/gradient.js +0 -131
- package/frontend/dist/frontend/src/ui/image.d.ts +0 -111
- package/frontend/dist/frontend/src/ui/image.js +0 -576
- package/frontend/dist/frontend/src/ui/input.d.ts +0 -392
- package/frontend/dist/frontend/src/ui/input.js +0 -1201
- package/frontend/dist/frontend/src/ui/link.d.ts +0 -25
- package/frontend/dist/frontend/src/ui/link.js +0 -140
- package/frontend/dist/frontend/src/ui/list.d.ts +0 -37
- package/frontend/dist/frontend/src/ui/list.js +0 -170
- package/frontend/dist/frontend/src/ui/loader_button.d.ts +0 -80
- package/frontend/dist/frontend/src/ui/loader_button.js +0 -193
- package/frontend/dist/frontend/src/ui/loaders.d.ts +0 -57
- package/frontend/dist/frontend/src/ui/loaders.js +0 -157
- package/frontend/dist/frontend/src/ui/popup.d.ts +0 -94
- package/frontend/dist/frontend/src/ui/popup.js +0 -510
- package/frontend/dist/frontend/src/ui/pseudo.d.ts +0 -44
- package/frontend/dist/frontend/src/ui/pseudo.js +0 -154
- package/frontend/dist/frontend/src/ui/scroller.d.ts +0 -105
- package/frontend/dist/frontend/src/ui/scroller.js +0 -1253
- package/frontend/dist/frontend/src/ui/slider.d.ts +0 -45
- package/frontend/dist/frontend/src/ui/slider.js +0 -217
- package/frontend/dist/frontend/src/ui/spacer.d.ts +0 -15
- package/frontend/dist/frontend/src/ui/spacer.js +0 -78
- package/frontend/dist/frontend/src/ui/span.d.ts +0 -15
- package/frontend/dist/frontend/src/ui/span.js +0 -73
- package/frontend/dist/frontend/src/ui/stack.d.ts +0 -66
- package/frontend/dist/frontend/src/ui/stack.js +0 -335
- package/frontend/dist/frontend/src/ui/steps.d.ts +0 -131
- package/frontend/dist/frontend/src/ui/steps.js +0 -308
- package/frontend/dist/frontend/src/ui/style.d.ts +0 -17
- package/frontend/dist/frontend/src/ui/style.js +0 -73
- package/frontend/dist/frontend/src/ui/switch.d.ts +0 -69
- package/frontend/dist/frontend/src/ui/switch.js +0 -357
- package/frontend/dist/frontend/src/ui/table.d.ts +0 -100
- package/frontend/dist/frontend/src/ui/table.js +0 -405
- package/frontend/dist/frontend/src/ui/tabs.d.ts +0 -111
- package/frontend/dist/frontend/src/ui/tabs.js +0 -424
- package/frontend/dist/frontend/src/ui/text.d.ts +0 -15
- package/frontend/dist/frontend/src/ui/text.js +0 -83
- package/frontend/dist/frontend/src/ui/title.d.ts +0 -91
- package/frontend/dist/frontend/src/ui/title.js +0 -272
- package/frontend/dist/frontend/src/ui/ui.d.ts +0 -35
- package/frontend/dist/frontend/src/ui/ui.js +0 -38
- package/frontend/dist/frontend/src/ui/view.d.ts +0 -15
- package/frontend/dist/frontend/src/ui/view.js +0 -88
- package/frontend/dist/frontend/src/volt.d.ts +0 -20
- package/frontend/dist/frontend/src/volt.js +0 -27
- package/frontend/examples/theme/theme.ts +0 -58
- package/frontend/tools/bundle_d_ts.js +0 -71
- package/frontend/tools/convert_to_jsdoc_input.txt +0 -9452
- package/frontend/tools/convert_to_jsdoc_output.txt +0 -7626
- package/frontend/tools/convert_to_jsdoc_tmp.js +0 -345
- package/frontend/tools/scan_mixed_imports.js +0 -69
- /package/frontend/{dist/frontend/src/css → css}/adyen.css +0 -0
- /package/frontend/{dist/frontend/src/css → css}/volt.css +0 -0
|
@@ -1,1996 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
var stdin_exports = {};
|
|
29
|
-
__export(stdin_exports, {
|
|
30
|
-
LineItem: () => LineItem,
|
|
31
|
-
Paddle: () => Paddle,
|
|
32
|
-
Payment: () => Payment,
|
|
33
|
-
PaymentStatusValues: () => PaymentStatusValues
|
|
34
|
-
});
|
|
35
|
-
module.exports = __toCommonJS(stdin_exports);
|
|
36
|
-
var https = __toESM(require("https"));
|
|
37
|
-
var PDFDocument = __toESM(require("pdfkit"));
|
|
38
|
-
var libcrypto = __toESM(require("crypto"));
|
|
39
|
-
var vlib = __toESM(require("@vandenberghinc/vlib"));
|
|
40
|
-
var import_errors = require("../errors/index.js");
|
|
41
|
-
var import_status = require("../status.js");
|
|
42
|
-
var import_collection = require("../database/collection.js");
|
|
43
|
-
var import_utils = require("../utils.js");
|
|
44
|
-
var LineItem;
|
|
45
|
-
(function(LineItem2) {
|
|
46
|
-
LineItem2.Schema = {
|
|
47
|
-
product: "string",
|
|
48
|
-
item_id: "string",
|
|
49
|
-
paddle_prod_id: "string",
|
|
50
|
-
quantity: "number",
|
|
51
|
-
tax_rate: "number",
|
|
52
|
-
tax: "number",
|
|
53
|
-
discount: "number",
|
|
54
|
-
subtotal: "number",
|
|
55
|
-
total: "number",
|
|
56
|
-
status: { type: "string", enum: ["paid", "refunded", "refunding"] }
|
|
57
|
-
};
|
|
58
|
-
})(LineItem || (LineItem = {}));
|
|
59
|
-
const PaymentStatusValues = ["open", "paid", "past_due", "unknown"];
|
|
60
|
-
var Payment;
|
|
61
|
-
(function(Payment2) {
|
|
62
|
-
function anonymize(payment) {
|
|
63
|
-
if (!payment.uid || payment.uid === "unauth") {
|
|
64
|
-
const { billing_details, ...rest } = payment;
|
|
65
|
-
return {
|
|
66
|
-
...rest,
|
|
67
|
-
billing_details: void 0
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return payment;
|
|
71
|
-
}
|
|
72
|
-
Payment2.anonymize = anonymize;
|
|
73
|
-
})(Payment || (Payment = {}));
|
|
74
|
-
class Paddle {
|
|
75
|
-
type = "paddle";
|
|
76
|
-
client_key;
|
|
77
|
-
sandbox;
|
|
78
|
-
inclusive_tax;
|
|
79
|
-
products;
|
|
80
|
-
server;
|
|
81
|
-
_host;
|
|
82
|
-
_headers;
|
|
83
|
-
webhook_key;
|
|
84
|
-
_has_create_products_permission;
|
|
85
|
-
_last_products_db;
|
|
86
|
-
_webhook_conf_db;
|
|
87
|
-
_sub_db;
|
|
88
|
-
_active_sub_db;
|
|
89
|
-
_pay_db;
|
|
90
|
-
// private _inv_db: Collection;
|
|
91
|
-
performance;
|
|
92
|
-
constructor({ api_key, client_key, sandbox = false, products = [], inclusive_tax = false, _server }) {
|
|
93
|
-
vlib.schema.validate(arguments[0], {
|
|
94
|
-
unknown: false,
|
|
95
|
-
throw: true,
|
|
96
|
-
parent: "payments",
|
|
97
|
-
schema: {
|
|
98
|
-
type: { type: "string", default: "paddle" },
|
|
99
|
-
api_key: "string",
|
|
100
|
-
client_key: "string",
|
|
101
|
-
sandbox: { type: "boolean", default: false },
|
|
102
|
-
inclusive_tax: { type: "boolean", default: false },
|
|
103
|
-
products: "array",
|
|
104
|
-
_server: "object"
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
this.client_key = client_key;
|
|
108
|
-
this.sandbox = sandbox;
|
|
109
|
-
this.inclusive_tax = inclusive_tax;
|
|
110
|
-
this.products = products;
|
|
111
|
-
this.server = _server;
|
|
112
|
-
this._host = this.sandbox ? "sandbox-api.paddle.com" : "api.paddle.com";
|
|
113
|
-
this._headers = {
|
|
114
|
-
"Content-Type": "application/json",
|
|
115
|
-
"Accept": "application/json",
|
|
116
|
-
"Authorization": "Bearer " + api_key
|
|
117
|
-
};
|
|
118
|
-
this.server.csp["default-src"] += " https://*.paddle.com/";
|
|
119
|
-
this.server.csp["script-src"] += " https://*.paddle.com/ https://*.payments-amazon.com https://*.paypal.com https://*.google.com";
|
|
120
|
-
this.server.csp["style-src"] += " https://*.paddle.com/ https://*.media-amazon.com https://*.paypal.com https://*.google.com";
|
|
121
|
-
this.server.csp["img-src"] += " https://*.paddle.com/ https://*.media-amazon.com https://*.paypal.com https://*.google.com";
|
|
122
|
-
this._last_products_db = this.server.db.collection({
|
|
123
|
-
name: "Volt.Paddle.LastProducts",
|
|
124
|
-
indexes: ["production", "version"]
|
|
125
|
-
});
|
|
126
|
-
this._webhook_conf_db = this.server.db.collection({
|
|
127
|
-
name: "Volt.Paddle.WebhookConfig",
|
|
128
|
-
indexes: ["production", "version"]
|
|
129
|
-
});
|
|
130
|
-
this._sub_db = this.server.db.collection({
|
|
131
|
-
name: "Volt.Paddle.Subscriptions",
|
|
132
|
-
indexes: ["uid", "id"]
|
|
133
|
-
});
|
|
134
|
-
this._active_sub_db = this.server.db.collection({
|
|
135
|
-
name: "Volt.Paddle.ActiveSubscriptions",
|
|
136
|
-
indexes: ["uid", "prod_id"]
|
|
137
|
-
});
|
|
138
|
-
this._pay_db = this.server.db.collection({
|
|
139
|
-
name: "Volt.Paddle.Payments",
|
|
140
|
-
indexes: ["uid", "id", "tran_id"]
|
|
141
|
-
});
|
|
142
|
-
this.performance = new vlib.Performance("Payments performance");
|
|
143
|
-
}
|
|
144
|
-
// ---------------------------------------------------------
|
|
145
|
-
// Products and prices (private).
|
|
146
|
-
// ---------------------------------------------------------
|
|
147
|
-
// Utils (private).
|
|
148
|
-
async _req(method, endpoint, params = null) {
|
|
149
|
-
const promise = new Promise((resolve, reject) => {
|
|
150
|
-
const is_get_like = method === "GET" || method === "HEAD";
|
|
151
|
-
let hostname = this._host;
|
|
152
|
-
let path = endpoint;
|
|
153
|
-
try {
|
|
154
|
-
if (/^https?:\/\//i.test(endpoint)) {
|
|
155
|
-
const u = new URL(endpoint);
|
|
156
|
-
hostname = u.hostname;
|
|
157
|
-
path = u.pathname + u.search;
|
|
158
|
-
} else if (is_get_like && params != null) {
|
|
159
|
-
path = `${endpoint}?${new URLSearchParams(params).toString()}`;
|
|
160
|
-
}
|
|
161
|
-
} catch {
|
|
162
|
-
}
|
|
163
|
-
const options = {
|
|
164
|
-
method,
|
|
165
|
-
hostname,
|
|
166
|
-
path,
|
|
167
|
-
port: 443,
|
|
168
|
-
headers: this._headers
|
|
169
|
-
};
|
|
170
|
-
const request = https.request(options, (response) => {
|
|
171
|
-
let data = "";
|
|
172
|
-
response.on("data", (chunk) => {
|
|
173
|
-
data += chunk;
|
|
174
|
-
});
|
|
175
|
-
response.on("end", () => {
|
|
176
|
-
if (response?.statusCode >= 200 && response?.statusCode < 300) {
|
|
177
|
-
try {
|
|
178
|
-
resolve(data ? JSON.parse(data) : {});
|
|
179
|
-
} catch (error) {
|
|
180
|
-
reject(new Error("Failed to parse response data"));
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
if (data == null || data === "") {
|
|
184
|
-
return reject(new Paddle.RequestError(`${method}:${endpoint}: Request failed [${response.statusCode}].`, response.statusCode));
|
|
185
|
-
}
|
|
186
|
-
try {
|
|
187
|
-
data = JSON.parse(data);
|
|
188
|
-
} catch (e) {
|
|
189
|
-
return reject(new Paddle.RequestError(`${method}:${endpoint}: Request failed [${response.statusCode}].`, response.statusCode));
|
|
190
|
-
}
|
|
191
|
-
if (data.error == null) {
|
|
192
|
-
return reject(new Paddle.RequestError(`${method}:${endpoint}: Request failed [${response.statusCode}].`, response.statusCode));
|
|
193
|
-
}
|
|
194
|
-
data = data.error;
|
|
195
|
-
let errs = "";
|
|
196
|
-
if (data.errors) {
|
|
197
|
-
errs += ". ";
|
|
198
|
-
data.errors.iterate((item) => {
|
|
199
|
-
errs += `Field: "${item.field}" ${item.message}. `;
|
|
200
|
-
});
|
|
201
|
-
errs = errs.substr(0, errs.length - 2);
|
|
202
|
-
}
|
|
203
|
-
return reject(new Paddle.RequestError(`${method}:${endpoint}: ${data.detail} [${response.statusCode}]${errs}.`, response.statusCode));
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
if (!is_get_like && params != null) {
|
|
208
|
-
const requestBody = JSON.stringify(params);
|
|
209
|
-
request.setHeader("Content-Length", Buffer.byteLength(requestBody));
|
|
210
|
-
request.write(requestBody);
|
|
211
|
-
}
|
|
212
|
-
request.on("error", (error) => {
|
|
213
|
-
reject(error);
|
|
214
|
-
});
|
|
215
|
-
request.end();
|
|
216
|
-
});
|
|
217
|
-
try {
|
|
218
|
-
return await promise;
|
|
219
|
-
} catch (e) {
|
|
220
|
-
if (e instanceof Error || e instanceof Paddle.RequestError) {
|
|
221
|
-
throw e;
|
|
222
|
-
}
|
|
223
|
-
throw new Error(e);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
// ---------------------------------------------------------
|
|
227
|
-
// Database (private).
|
|
228
|
-
// Add or remove a subscription to the user's active subscriptions.
|
|
229
|
-
async _add_subscription(uid, prod_id, sub_id) {
|
|
230
|
-
await this._active_sub_db.set({ uid, prod_id }, { prod_id, sub_id });
|
|
231
|
-
}
|
|
232
|
-
async _delete_subscription(uid, prod_id) {
|
|
233
|
-
await this._active_sub_db.delete({ uid, prod_id });
|
|
234
|
-
}
|
|
235
|
-
async _check_subscription(uid, prod_id, load_data = false) {
|
|
236
|
-
try {
|
|
237
|
-
const doc = await this._active_sub_db.load({ uid, prod_id });
|
|
238
|
-
return load_data ? { exists: true, sub_id: doc.sub_id } : true;
|
|
239
|
-
} catch (err) {
|
|
240
|
-
if (err instanceof import_collection.Collection.NotFoundError) {
|
|
241
|
-
return load_data ? { exists: false, sub_id: void 0 } : false;
|
|
242
|
-
}
|
|
243
|
-
throw err;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
async _get_active_subscriptions(uid, detailed = false) {
|
|
247
|
-
const list = await this._active_sub_db.list({ uid });
|
|
248
|
-
if (detailed) {
|
|
249
|
-
return list;
|
|
250
|
-
}
|
|
251
|
-
const products = [];
|
|
252
|
-
for (const doc of list) {
|
|
253
|
-
products.push(doc.prod_id);
|
|
254
|
-
}
|
|
255
|
-
return products;
|
|
256
|
-
}
|
|
257
|
-
async _save_subscription(subscription) {
|
|
258
|
-
await this._sub_db.set({
|
|
259
|
-
uid: subscription.uid == null ? "unauth" : subscription.uid,
|
|
260
|
-
id: subscription.id
|
|
261
|
-
}, subscription);
|
|
262
|
-
}
|
|
263
|
-
async _load_subscription(id) {
|
|
264
|
-
return await this._sub_db.load({ id }, { retry: 3 });
|
|
265
|
-
}
|
|
266
|
-
async _get_subscriptions(uid) {
|
|
267
|
-
if (uid === "unauth" || uid == null) {
|
|
268
|
-
return [];
|
|
269
|
-
}
|
|
270
|
-
const list = await this._sub_db.list({ uid });
|
|
271
|
-
return list;
|
|
272
|
-
}
|
|
273
|
-
// Save and delete payments, all failed payments should be deleted from the database.
|
|
274
|
-
async _save_payment(payment) {
|
|
275
|
-
await this._pay_db.set({
|
|
276
|
-
uid: payment.uid == null ? "unauth" : payment.uid,
|
|
277
|
-
id: payment.id
|
|
278
|
-
}, payment);
|
|
279
|
-
}
|
|
280
|
-
async _load_payment(id) {
|
|
281
|
-
const uid = id.split("_")[1];
|
|
282
|
-
return await this._pay_db.load({ uid, id });
|
|
283
|
-
}
|
|
284
|
-
async _load_payment_for_public(id) {
|
|
285
|
-
return Payment.anonymize(await this._load_payment(id));
|
|
286
|
-
}
|
|
287
|
-
async _load_payment_by_transaction(tran_id) {
|
|
288
|
-
return await this._pay_db.load({ tran_id }, { retry: 3 });
|
|
289
|
-
}
|
|
290
|
-
async _load_payment_by_transaction_for_public(tran_id) {
|
|
291
|
-
return Payment.anonymize(await this._load_payment_by_transaction(tran_id));
|
|
292
|
-
}
|
|
293
|
-
async _delete_payment(id) {
|
|
294
|
-
const uid = id.split("_")[1];
|
|
295
|
-
await this._pay_db.delete({ uid, id });
|
|
296
|
-
}
|
|
297
|
-
// Delete all info of a user.
|
|
298
|
-
async _delete_user(uid) {
|
|
299
|
-
await this._sub_db.delete_many({ uid });
|
|
300
|
-
await this._active_sub_db.delete_many({ uid });
|
|
301
|
-
await this._pay_db.delete_many({ uid });
|
|
302
|
-
}
|
|
303
|
-
// List all active subscriptions.
|
|
304
|
-
async _get_all_active_subscriptions() {
|
|
305
|
-
return await this._active_sub_db.list_all();
|
|
306
|
-
}
|
|
307
|
-
// ---------------------------------------------------------
|
|
308
|
-
// Overall (private).
|
|
309
|
-
// Get product by paddle product id.
|
|
310
|
-
_get_product_by_paddle_prod_id(id, throw_err = false) {
|
|
311
|
-
let product = null;
|
|
312
|
-
for (const p of this.products) {
|
|
313
|
-
if (p.is_subscription) {
|
|
314
|
-
if (p.plans == null) {
|
|
315
|
-
throw Error(`Invalid project "${p.id}" subscription is activated yet no plans are defined.`);
|
|
316
|
-
}
|
|
317
|
-
for (const plan of p.plans) {
|
|
318
|
-
if (plan.paddle_prod_id === id) {
|
|
319
|
-
product = plan;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
if (product != null)
|
|
323
|
-
break;
|
|
324
|
-
} else if (p.paddle_prod_id === id) {
|
|
325
|
-
product = p;
|
|
326
|
-
break;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
if (product == null && throw_err) {
|
|
330
|
-
throw Error(`Unable to find product "${id}".`);
|
|
331
|
-
}
|
|
332
|
-
return product;
|
|
333
|
-
}
|
|
334
|
-
// Get all active products.
|
|
335
|
-
async _get_products() {
|
|
336
|
-
let response, next = null;
|
|
337
|
-
let items = [];
|
|
338
|
-
while (true) {
|
|
339
|
-
if (next == null) {
|
|
340
|
-
response = await this._req("GET", "/products", { status: ["active"], per_page: 100 });
|
|
341
|
-
} else {
|
|
342
|
-
response = await this._req("GET", next);
|
|
343
|
-
}
|
|
344
|
-
items = items.concat(response.data);
|
|
345
|
-
if (response.meta.has_more) {
|
|
346
|
-
next = response.meta.next;
|
|
347
|
-
} else {
|
|
348
|
-
break;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return items;
|
|
352
|
-
}
|
|
353
|
-
// Get all active prices.
|
|
354
|
-
async _get_prices() {
|
|
355
|
-
let response, next = null;
|
|
356
|
-
let items = [];
|
|
357
|
-
while (true) {
|
|
358
|
-
if (next == null) {
|
|
359
|
-
response = await this._req("GET", "/prices", { status: ["active"], per_page: 100 });
|
|
360
|
-
} else {
|
|
361
|
-
response = await this._req("GET", next);
|
|
362
|
-
}
|
|
363
|
-
items = items.concat(response.data);
|
|
364
|
-
if (response.meta.has_more) {
|
|
365
|
-
next = response.meta.next;
|
|
366
|
-
} else {
|
|
367
|
-
break;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
return items;
|
|
371
|
-
}
|
|
372
|
-
// Create or update a product, when existing product is undefined a new product and price will be created.
|
|
373
|
-
async _check_product(product, existing_products = [], existing_prices = []) {
|
|
374
|
-
const has_create_products_permission = async () => {
|
|
375
|
-
if (process.argv.includes("--no-payment-edits")) {
|
|
376
|
-
return false;
|
|
377
|
-
}
|
|
378
|
-
if (this._has_create_products_permission != null) {
|
|
379
|
-
return this._has_create_products_permission;
|
|
380
|
-
}
|
|
381
|
-
const input = await vlib.logging.prompt("Some paddle products have to be edited, do you wish to make these changes? [y/n]: ");
|
|
382
|
-
if (["y", "yes", "ok"].includes(input.toLowerCase())) {
|
|
383
|
-
this._has_create_products_permission = true;
|
|
384
|
-
} else {
|
|
385
|
-
this._has_create_products_permission = false;
|
|
386
|
-
}
|
|
387
|
-
return this._has_create_products_permission;
|
|
388
|
-
};
|
|
389
|
-
let existing_product = null;
|
|
390
|
-
for (const item of existing_products) {
|
|
391
|
-
if (item.custom_data.id === product.id) {
|
|
392
|
-
existing_product = item;
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (existing_product == null) {
|
|
397
|
-
if (!await has_create_products_permission()) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
this.server.log(0, `Creating product ${product.name}.`);
|
|
401
|
-
const created_product = await this._req("POST", "/products", {
|
|
402
|
-
name: product.name,
|
|
403
|
-
description: product.description,
|
|
404
|
-
image_url: product.icon,
|
|
405
|
-
tax_category: product.tax_category,
|
|
406
|
-
custom_data: { id: product.id }
|
|
407
|
-
});
|
|
408
|
-
product.paddle_prod_id = created_product.data.id;
|
|
409
|
-
this.server.log(0, `Creating a price for product ${product.name}.`);
|
|
410
|
-
const created_price = await this._req("POST", "/prices", {
|
|
411
|
-
product_id: product.paddle_prod_id,
|
|
412
|
-
name: product.name,
|
|
413
|
-
description: product.description,
|
|
414
|
-
unit_price: { amount: Math.floor(product.price * 100).toString(), currency_code: product.currency },
|
|
415
|
-
billing_cycle: product.is_subscription ? { interval: product.interval, frequency: product.frequency } : null,
|
|
416
|
-
trial_period: product.is_subscription ? product.trial : null,
|
|
417
|
-
tax_mode: this.inclusive_tax ? "internal" : "external"
|
|
418
|
-
});
|
|
419
|
-
product.price_id = created_price.data.id;
|
|
420
|
-
} else {
|
|
421
|
-
product.paddle_prod_id = existing_product.id;
|
|
422
|
-
const has_trial = product.is_subscription && product.trial != null;
|
|
423
|
-
const update_product = existing_product.name !== product.name || existing_product.description !== product.description || existing_product.image_url !== product.icon || existing_product.tax_category !== product.tax_category || existing_product.status !== "active";
|
|
424
|
-
if (update_product) {
|
|
425
|
-
if (!await has_create_products_permission()) {
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
this.server.log(0, `Updating product ${product.name}.`);
|
|
429
|
-
await this._req("PATCH", `/products/${product.paddle_prod_id}`, {
|
|
430
|
-
name: product.name,
|
|
431
|
-
description: product.description,
|
|
432
|
-
image_url: product.icon,
|
|
433
|
-
tax_category: product.tax_category,
|
|
434
|
-
custom_data: { id: product.id },
|
|
435
|
-
status: "active"
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
let existing_price = null;
|
|
439
|
-
for (const item of existing_prices) {
|
|
440
|
-
if (item.product_id === product.paddle_prod_id) {
|
|
441
|
-
existing_price = item;
|
|
442
|
-
break;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
if (existing_price == null) {
|
|
446
|
-
if (!await has_create_products_permission()) {
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
this.server.log(0, `Creating a price for product ${product.name}.`);
|
|
450
|
-
const price = await this._req("POST", "/prices", {
|
|
451
|
-
product_id: product.paddle_prod_id,
|
|
452
|
-
name: product.name,
|
|
453
|
-
description: product.description,
|
|
454
|
-
unit_price: { amount: Math.floor(product.price * 100).toString(), currency_code: product.currency },
|
|
455
|
-
billing_cycle: product.is_subscription ? { interval: product.interval, frequency: product.frequency } : null,
|
|
456
|
-
trial_period: product.is_subscription ? product.trial : null,
|
|
457
|
-
tax_mode: this.inclusive_tax ? "internal" : "external"
|
|
458
|
-
});
|
|
459
|
-
product.price_id = price.data.id;
|
|
460
|
-
} else {
|
|
461
|
-
product.price_id = existing_price.id;
|
|
462
|
-
const update_price = existing_price.product_id !== product.paddle_prod_id || existing_price.name !== product.name || existing_price.description !== product.description || existing_price.tax_mode !== (this.inclusive_tax ? "internal" : "external") || existing_price.unit_price == null || existing_price.unit_price.amount !== Math.floor(product.price * 100).toString() || existing_price.unit_price.currency_code !== product.currency || product.is_subscription && (existing_price.billing_cycle == null || existing_price.billing_cycle.interval !== product.interval || existing_price.billing_cycle.frequency !== product.frequency) || has_trial && (existing_price.trial_period == null || existing_price.trial_period.interval !== product.trial?.interval || existing_price.trial_period.frequency !== product.trial?.frequency) || existing_price.status !== "active";
|
|
463
|
-
if (update_price) {
|
|
464
|
-
if (!await has_create_products_permission()) {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
this.server.log(0, `Updating the price of product ${product.name}.`);
|
|
468
|
-
await this._req("PATCH", `/prices/${product.price_id}`, {
|
|
469
|
-
// product_id: product.id, // not allowed.
|
|
470
|
-
name: product.name,
|
|
471
|
-
description: product.description,
|
|
472
|
-
unit_price: { amount: Math.floor(product.price * 100).toString(), currency_code: product.currency },
|
|
473
|
-
billing_cycle: product.is_subscription ? { interval: product.interval, frequency: product.frequency } : null,
|
|
474
|
-
trial_period: product.is_subscription ? product.trial : null,
|
|
475
|
-
tax_mode: this.inclusive_tax ? "internal" : "external",
|
|
476
|
-
status: "active"
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
// Cancel subscription by subscription id.
|
|
483
|
-
async _cancel_subscription(id, immediate = false) {
|
|
484
|
-
if (id == null) {
|
|
485
|
-
throw Error(`Define parameter "id".`);
|
|
486
|
-
}
|
|
487
|
-
const subscription = await this._load_subscription(id);
|
|
488
|
-
if (subscription == null) {
|
|
489
|
-
throw Error(`Unable to find subscription "${id}".`);
|
|
490
|
-
}
|
|
491
|
-
if (subscription.status !== "active") {
|
|
492
|
-
throw new import_errors.ExternalError({
|
|
493
|
-
type: "NoActiveSubscriptionError",
|
|
494
|
-
message: `This subscription is already cancelled and will become inactive at the end of the billing period.`,
|
|
495
|
-
status: import_status.Status.bad_request
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
await this._req("POST", `/subscriptions/${subscription.id}/cancel`, {
|
|
499
|
-
effective_from: immediate ? "immediately" : null
|
|
500
|
-
});
|
|
501
|
-
subscription.status = "cancelling";
|
|
502
|
-
await this._save_subscription(subscription);
|
|
503
|
-
}
|
|
504
|
-
// async _cancel_subscription(payment) {
|
|
505
|
-
// if (typeof payment === "string") {
|
|
506
|
-
// payment = await this._load_payment(payment);
|
|
507
|
-
// }
|
|
508
|
-
// if (payment.cus_id == null) {
|
|
509
|
-
// throw Error(`Payment "${payment.id}" does not have an assigned customer id attribute.`);
|
|
510
|
-
// }
|
|
511
|
-
// if (payment.sub_id == null) {
|
|
512
|
-
// throw Error(`Payment "${payment.id}" does not have an assigned subscription id attribute, it may not be a subscription payment.`);
|
|
513
|
-
// }
|
|
514
|
-
// if (payment.line_items.length == 0) {
|
|
515
|
-
// throw Error(`Payment "${payment.id}" does not contain any line items.`);
|
|
516
|
-
// }
|
|
517
|
-
// // Cancel.
|
|
518
|
-
// const cancellable = [];
|
|
519
|
-
// let all_cancelled = null;
|
|
520
|
-
// payment.line_items.iterate((item) => {
|
|
521
|
-
// const product = this.get_product_sync(item.product);
|
|
522
|
-
// if (product.is_subscription) {
|
|
523
|
-
// if (item.status === "cancelled" || item.status === "cancelling") {
|
|
524
|
-
// if (all_cancelled == null) {
|
|
525
|
-
// all_cancelled = true;
|
|
526
|
-
// }
|
|
527
|
-
// } else if (item.status === "paid" || item.status === "refunding" || item.status === "refunded") {
|
|
528
|
-
// all_cancelled = false;
|
|
529
|
-
// cancellable.push(item);
|
|
530
|
-
// }
|
|
531
|
-
// }
|
|
532
|
-
// })
|
|
533
|
-
// if (all_cancelled) {
|
|
534
|
-
// throw new FrontendError(`This subscription is already cancelled and will become inactive at the end of the billing period.`, Status.bad_request);
|
|
535
|
-
// }
|
|
536
|
-
// if (cancellable.length === 0) {
|
|
537
|
-
// throw new FrontendError(`This subscription does not contain any cancellable items, the subscription is likely already cancelled or refunded.`, Status.bad_request);
|
|
538
|
-
// }
|
|
539
|
-
// await this._req("POST", `/subscriptions/${payment.sub_id}/cancel`, {
|
|
540
|
-
// // effective_from: "immediately",
|
|
541
|
-
// });
|
|
542
|
-
// // Update payment.
|
|
543
|
-
// cancellable.iterate((item) => {
|
|
544
|
-
// if (item.status === "paid") {
|
|
545
|
-
// item.status = "cancelling";
|
|
546
|
-
// }
|
|
547
|
-
// })
|
|
548
|
-
// await this._save_payment(payment);
|
|
549
|
-
// /* V1 cancel per product but since the webhook subscription event does not show which sub items are cancelled, this is not possible.
|
|
550
|
-
// // Update the subscription items.
|
|
551
|
-
// const sub = await this._req("GET", `/subscriptions/${payment.sub_id}`);
|
|
552
|
-
// const items = [];
|
|
553
|
-
// const cancelled_line_items = [];
|
|
554
|
-
// let edits = 0;
|
|
555
|
-
// sub.data.items.iterate((sub_item) => {
|
|
556
|
-
// // Only for active subscription items.
|
|
557
|
-
// if (sub_item.recurring && (sub_item.status === "active" || sub_item.status === "trailing")) {
|
|
558
|
-
// // Recurring items.
|
|
559
|
-
// const item = payment.line_items.iterate((item) => {
|
|
560
|
-
// if (item.paddle_prod_id === sub_item.price.product_id) {
|
|
561
|
-
// return item;
|
|
562
|
-
// }
|
|
563
|
-
// })
|
|
564
|
-
// // Item not found, so cancel but do not update status since it is not found.
|
|
565
|
-
// if (item == null) {
|
|
566
|
-
// console.error(`Unable to find subscription item "${sub_item.price.product_id}" while cancelling. Items: ${JSON.stringify(payment.line_items)}`)
|
|
567
|
-
// ++edits;
|
|
568
|
-
// }
|
|
569
|
-
// // Already cancelling.
|
|
570
|
-
// // else if (item.status === "cancelling") {
|
|
571
|
-
// // items.push({
|
|
572
|
-
// // price_id: sub_item.price.id,
|
|
573
|
-
// // quantity: sub_item.quantity,
|
|
574
|
-
// // })
|
|
575
|
-
// // }
|
|
576
|
-
// // Cancel item.
|
|
577
|
-
// else if (products == null || products.includes(item.id)) {
|
|
578
|
-
// item.status = "cancelling";
|
|
579
|
-
// ++edits;
|
|
580
|
-
// cancelled_line_items.push(item);
|
|
581
|
-
// }
|
|
582
|
-
// // Keep item.
|
|
583
|
-
// else {
|
|
584
|
-
// items.push({
|
|
585
|
-
// price_id: sub_item.price.id,
|
|
586
|
-
// quantity: sub_item.quantity,
|
|
587
|
-
// })
|
|
588
|
-
// }
|
|
589
|
-
// }
|
|
590
|
-
// // Keep all non recurring.
|
|
591
|
-
// else if (sub_item.recurring === false) {
|
|
592
|
-
// items.push({
|
|
593
|
-
// price_id: sub_item.price.id,
|
|
594
|
-
// quantity: sub_item.quantity,
|
|
595
|
-
// })
|
|
596
|
-
// }
|
|
597
|
-
// })
|
|
598
|
-
// // No edits.
|
|
599
|
-
// if (edits === 0) {
|
|
600
|
-
// throw Error("This payment does not contain any cancellable subscriptions.");
|
|
601
|
-
// }
|
|
602
|
-
// // Catch certain error.
|
|
603
|
-
// try {
|
|
604
|
-
// // Delete the subscription.
|
|
605
|
-
// if (items.length === 0) {
|
|
606
|
-
// await this._req("POST", `/subscriptions/${payment.sub_id}/cancel`, {});
|
|
607
|
-
// }
|
|
608
|
-
// // Update the subscription.
|
|
609
|
-
// else {
|
|
610
|
-
// await this._req("PATCH", `/subscriptions/${payment.sub_id}`, {
|
|
611
|
-
// items: items,
|
|
612
|
-
// scheduled_change: null,
|
|
613
|
-
// proration_billing_mode: "full_next_billing_period",
|
|
614
|
-
// });
|
|
615
|
-
// }
|
|
616
|
-
// } catch (error) {
|
|
617
|
-
// if (error.message.indexOf("cannot update subscription, pending scheduled changes") === -1) {
|
|
618
|
-
// throw error;
|
|
619
|
-
// }
|
|
620
|
-
// }
|
|
621
|
-
// // Update payment.
|
|
622
|
-
// cancelled_line_items.iterate((item) => {
|
|
623
|
-
// item.status = "cancelling";
|
|
624
|
-
// })
|
|
625
|
-
// await this._save_payment(payment);
|
|
626
|
-
// */
|
|
627
|
-
// }
|
|
628
|
-
// Initialize all products.
|
|
629
|
-
async _initialize_products({ worker = false } = {}) {
|
|
630
|
-
let now = this.performance.start();
|
|
631
|
-
const product_ids = [];
|
|
632
|
-
let product_index = 0;
|
|
633
|
-
const initialize_product = (product) => {
|
|
634
|
-
++product_index;
|
|
635
|
-
if (product.id == null || product.id === "") {
|
|
636
|
-
throw Error(`Product ${product_index} does not have an assigned "id" attribute (string).`);
|
|
637
|
-
} else if (product_ids.includes(product.id)) {
|
|
638
|
-
throw Error(`Product ${product_index} has a non unique name "${product.id}".`);
|
|
639
|
-
}
|
|
640
|
-
product_ids.push(product.id);
|
|
641
|
-
if (typeof product.icon === "string" && product.icon.charAt(0) === "/") {
|
|
642
|
-
product.icon = `${this.server.full_domain}/${product.icon}`;
|
|
643
|
-
}
|
|
644
|
-
if (typeof product.id !== "string" || product.id === "") {
|
|
645
|
-
throw Error(`Product "${product_index}" does not have an assigned "id" attribute (string).`);
|
|
646
|
-
}
|
|
647
|
-
if (typeof product.name !== "string" || product.name === "") {
|
|
648
|
-
throw Error(`Product "${product.id}" does not have an assigned "name" attribute (string).`);
|
|
649
|
-
}
|
|
650
|
-
if (typeof product.description !== "string" || product.description === "") {
|
|
651
|
-
throw Error(`Product "${product.id}" does not have an assigned "description" attribute (string).`);
|
|
652
|
-
}
|
|
653
|
-
if (typeof product.currency !== "string" || product.currency === "") {
|
|
654
|
-
throw Error(`Product "${product.id}" does not have an assigned "currency" attribute (string).`);
|
|
655
|
-
}
|
|
656
|
-
if (typeof product.price !== "number") {
|
|
657
|
-
throw Error(`Product "${product.id}" does not have an assigned "price" attribute (number).`);
|
|
658
|
-
}
|
|
659
|
-
if (typeof product.tax_category !== "string") {
|
|
660
|
-
throw Error(`Product "${product.id}" does not have an assigned "tax_category" attribute (number).`);
|
|
661
|
-
}
|
|
662
|
-
if (product.is_subscription && typeof product.frequency !== "number") {
|
|
663
|
-
throw Error(`Product "${product.id}" does not have an assigned "frequency" attribute (number).`);
|
|
664
|
-
}
|
|
665
|
-
if (product.is_subscription && typeof product.interval !== "string") {
|
|
666
|
-
throw Error(`Product "${product.id}" does not have an assigned "interval" attribute (string).`);
|
|
667
|
-
}
|
|
668
|
-
};
|
|
669
|
-
let sub_products = 0;
|
|
670
|
-
for (const product of this.products) {
|
|
671
|
-
if (product.is_subscription) {
|
|
672
|
-
if (!product.plans || !Array.isArray(product.plans)) {
|
|
673
|
-
throw Error(`Product "${product_index}" has an incorrect value type for attribute "plans", the valid type is "array".`);
|
|
674
|
-
}
|
|
675
|
-
product.id = `sub_${sub_products}`;
|
|
676
|
-
if (product_ids.includes(product.id)) {
|
|
677
|
-
throw Error(`Another product has a reserved name "${product.id}".`);
|
|
678
|
-
}
|
|
679
|
-
product_ids.push(product.id);
|
|
680
|
-
++sub_products;
|
|
681
|
-
product.is_subscription = true;
|
|
682
|
-
for (const plan of product.plans) {
|
|
683
|
-
plan.is_subscription = true;
|
|
684
|
-
plan.subscription_id = product.id;
|
|
685
|
-
if (plan.description == null) {
|
|
686
|
-
plan.description = product.description;
|
|
687
|
-
}
|
|
688
|
-
if (plan.currency == null) {
|
|
689
|
-
plan.currency = product.currency;
|
|
690
|
-
}
|
|
691
|
-
if (plan.frequency == null) {
|
|
692
|
-
plan.frequency = product.frequency;
|
|
693
|
-
}
|
|
694
|
-
if (plan.interval == null) {
|
|
695
|
-
plan.interval = product.interval;
|
|
696
|
-
}
|
|
697
|
-
if (plan.tax_category == null) {
|
|
698
|
-
plan.tax_category = product.tax_category;
|
|
699
|
-
}
|
|
700
|
-
if (plan.icon == null) {
|
|
701
|
-
plan.icon = product.icon;
|
|
702
|
-
}
|
|
703
|
-
initialize_product(plan);
|
|
704
|
-
}
|
|
705
|
-
} else {
|
|
706
|
-
product.is_subscription = false;
|
|
707
|
-
initialize_product(product);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
now = this.performance.end("init-products", now);
|
|
711
|
-
const last_products = await this._last_products_db.load({ production: this.server.production, version: 1 }, { throw: false });
|
|
712
|
-
if (last_products instanceof Error && !(last_products instanceof import_collection.Collection.NotFoundError))
|
|
713
|
-
throw last_products;
|
|
714
|
-
if (!(last_products instanceof import_collection.Collection.NotFoundError) && vlib.Object.deep_eq(last_products.last_products, this.products)) {
|
|
715
|
-
for (const item of last_products.product_ids) {
|
|
716
|
-
const product = this.get_product_sync(item.id);
|
|
717
|
-
if (product != null) {
|
|
718
|
-
product.paddle_prod_id = item.paddle_prod_id;
|
|
719
|
-
product.price_id = item.price_id;
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
now = this.performance.end("assign-product-ids", now);
|
|
723
|
-
} else if (this.server.offline === false) {
|
|
724
|
-
const existing_products = await this._get_products();
|
|
725
|
-
const existing_prices = await this._get_prices();
|
|
726
|
-
now = this.performance.end("get-prices-and-products", now);
|
|
727
|
-
const product_ids2 = [];
|
|
728
|
-
for (const product of this.products) {
|
|
729
|
-
if (product.is_subscription) {
|
|
730
|
-
for (const plan of product.plans) {
|
|
731
|
-
await this._check_product(plan, existing_products, existing_prices);
|
|
732
|
-
product_ids2.append({
|
|
733
|
-
id: plan.id,
|
|
734
|
-
paddle_prod_id: plan.paddle_prod_id,
|
|
735
|
-
price_id: plan.price_id
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
;
|
|
739
|
-
} else {
|
|
740
|
-
await this._check_product(product, existing_products, existing_prices);
|
|
741
|
-
product_ids2.append({
|
|
742
|
-
id: product.id,
|
|
743
|
-
paddle_prod_id: product.paddle_prod_id,
|
|
744
|
-
price_id: product.price_id
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
;
|
|
749
|
-
now = this.performance.end("check-products", now);
|
|
750
|
-
await this._last_products_db.set({ production: this.server.production, version: 1 }, {
|
|
751
|
-
last_products: vlib.Object.delete_recursively(vlib.Object.deep_copy(this.products), ["paddle_prod_id", "price_id"]),
|
|
752
|
-
product_ids: product_ids2
|
|
753
|
-
});
|
|
754
|
-
now = this.performance.end("save-products-to-db", now);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
// Initialize the payments.
|
|
758
|
-
async _initialize({ worker = false } = {}) {
|
|
759
|
-
await this._initialize_products({ worker });
|
|
760
|
-
let now = this.performance.start();
|
|
761
|
-
if (!worker) {
|
|
762
|
-
this.server.endpoint({
|
|
763
|
-
method: "POST",
|
|
764
|
-
endpoint: "/volt/api/v1/payments/init",
|
|
765
|
-
content_type: "application/json",
|
|
766
|
-
rate_limit: "global",
|
|
767
|
-
params: {
|
|
768
|
-
items: { type: "array", required: true, value_schema: "object" }
|
|
769
|
-
// add schema for items
|
|
770
|
-
},
|
|
771
|
-
callback: async (stream, params) => {
|
|
772
|
-
if (params.items.length === 0) {
|
|
773
|
-
return stream.error({ status: import_status.Status.bad_request, message: "Shopping cart is empty." });
|
|
774
|
-
}
|
|
775
|
-
let sub_plan_count = {};
|
|
776
|
-
let error = void 0;
|
|
777
|
-
for (const item of params.items) {
|
|
778
|
-
if (item.product.is_subscription) {
|
|
779
|
-
if (stream.uid == null) {
|
|
780
|
-
error = "You must be signed-in to purchase a subscription.";
|
|
781
|
-
break;
|
|
782
|
-
}
|
|
783
|
-
if (item.quantity != null && item.quantity > 1) {
|
|
784
|
-
error = "Subscriptions have a max quantity of 1.";
|
|
785
|
-
break;
|
|
786
|
-
}
|
|
787
|
-
if (sub_plan_count[item.product.subscription_id] == null) {
|
|
788
|
-
sub_plan_count[item.product.subscription_id] = 1;
|
|
789
|
-
} else {
|
|
790
|
-
error = "You can not charge two different subscription plans from the same subscription product.";
|
|
791
|
-
break;
|
|
792
|
-
}
|
|
793
|
-
if (await this._check_subscription(stream.uid, item.product.id, false)) {
|
|
794
|
-
error = `You are already subscribed to product "${item.product.name}".`;
|
|
795
|
-
break;
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
if (error) {
|
|
800
|
-
return stream.error({ status: import_status.Status.bad_request, message: error });
|
|
801
|
-
}
|
|
802
|
-
return stream.success({ data: { message: "Successfully initialized the order." } });
|
|
803
|
-
}
|
|
804
|
-
});
|
|
805
|
-
this.server.endpoint({
|
|
806
|
-
method: "GET",
|
|
807
|
-
endpoint: "/volt/api/v1/payments/products",
|
|
808
|
-
content_type: "application/json",
|
|
809
|
-
rate_limit: "global",
|
|
810
|
-
callback: (stream) => {
|
|
811
|
-
return stream.success({ data: this.products });
|
|
812
|
-
}
|
|
813
|
-
});
|
|
814
|
-
this.server.endpoint({
|
|
815
|
-
method: "GET",
|
|
816
|
-
endpoint: "/volt/api/v1/payments/payment",
|
|
817
|
-
content_type: "application/json",
|
|
818
|
-
rate_limit: "global",
|
|
819
|
-
params: {
|
|
820
|
-
id: "string"
|
|
821
|
-
},
|
|
822
|
-
callback: async (stream, params) => {
|
|
823
|
-
return stream.success({
|
|
824
|
-
data: await this._load_payment_for_public(params.id)
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
});
|
|
828
|
-
this.server.endpoint({
|
|
829
|
-
method: "GET",
|
|
830
|
-
endpoint: "/volt/api/v1/payments/payments",
|
|
831
|
-
content_type: "application/json",
|
|
832
|
-
authenticated: true,
|
|
833
|
-
rate_limit: "global",
|
|
834
|
-
params: {
|
|
835
|
-
days: { type: "number", default: 30 },
|
|
836
|
-
limit: { type: "number", required: false },
|
|
837
|
-
status: { type: "string", required: false, enum: PaymentStatusValues }
|
|
838
|
-
},
|
|
839
|
-
callback: async (stream, params) => {
|
|
840
|
-
return stream.success({
|
|
841
|
-
data: await this.get_payments({
|
|
842
|
-
uid: stream.uid,
|
|
843
|
-
days: params.days,
|
|
844
|
-
limit: params.limit,
|
|
845
|
-
status: params.status
|
|
846
|
-
})
|
|
847
|
-
});
|
|
848
|
-
}
|
|
849
|
-
});
|
|
850
|
-
this.server.endpoint({
|
|
851
|
-
method: "GET",
|
|
852
|
-
endpoint: "/volt/api/v1/payments/payments/refundable",
|
|
853
|
-
content_type: "application/json",
|
|
854
|
-
authenticated: true,
|
|
855
|
-
rate_limit: "global",
|
|
856
|
-
params: {
|
|
857
|
-
days: { type: "number", default: 30 },
|
|
858
|
-
limit: { type: "number", required: false }
|
|
859
|
-
},
|
|
860
|
-
callback: async (stream, params) => {
|
|
861
|
-
return stream.success({
|
|
862
|
-
data: await this.get_refundable_payments({
|
|
863
|
-
uid: stream.uid,
|
|
864
|
-
days: params.days,
|
|
865
|
-
limit: params.limit,
|
|
866
|
-
for_public: true
|
|
867
|
-
})
|
|
868
|
-
});
|
|
869
|
-
}
|
|
870
|
-
});
|
|
871
|
-
this.server.endpoint({
|
|
872
|
-
method: "GET",
|
|
873
|
-
endpoint: "/volt/api/v1/payments/payments/refunded",
|
|
874
|
-
content_type: "application/json",
|
|
875
|
-
authenticated: true,
|
|
876
|
-
rate_limit: "global",
|
|
877
|
-
params: {
|
|
878
|
-
days: { type: "number", default: 30 },
|
|
879
|
-
limit: { type: "number", required: false }
|
|
880
|
-
},
|
|
881
|
-
callback: async (stream, params) => {
|
|
882
|
-
return stream.success({
|
|
883
|
-
data: await this.get_refunded_payments({
|
|
884
|
-
uid: stream.uid,
|
|
885
|
-
days: params.days,
|
|
886
|
-
limit: params.limit,
|
|
887
|
-
for_public: true
|
|
888
|
-
})
|
|
889
|
-
});
|
|
890
|
-
}
|
|
891
|
-
});
|
|
892
|
-
this.server.endpoint({
|
|
893
|
-
method: "GET",
|
|
894
|
-
endpoint: "/volt/api/v1/payments/payments/refunding",
|
|
895
|
-
content_type: "application/json",
|
|
896
|
-
authenticated: true,
|
|
897
|
-
rate_limit: "global",
|
|
898
|
-
params: {
|
|
899
|
-
days: { type: "number", default: 30 },
|
|
900
|
-
limit: { type: "number", required: false }
|
|
901
|
-
},
|
|
902
|
-
callback: async (stream, params) => {
|
|
903
|
-
return stream.success({
|
|
904
|
-
data: await this.get_refunding_payments({
|
|
905
|
-
uid: stream.uid,
|
|
906
|
-
days: params.days,
|
|
907
|
-
limit: params.limit,
|
|
908
|
-
for_public: true
|
|
909
|
-
})
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
});
|
|
913
|
-
this.server.endpoint({
|
|
914
|
-
method: "POST",
|
|
915
|
-
endpoint: "/volt/api/v1/payments/refund",
|
|
916
|
-
content_type: "application/json",
|
|
917
|
-
authenticated: true,
|
|
918
|
-
rate_limit: "global",
|
|
919
|
-
params: {
|
|
920
|
-
payment: { type: ["string", "object"], schema: { id: "string" } },
|
|
921
|
-
line_items: { type: "array", required: false, value_schema: {
|
|
922
|
-
type: "object",
|
|
923
|
-
schema: LineItem.Schema
|
|
924
|
-
} },
|
|
925
|
-
reason: { type: "string", default: "refund" }
|
|
926
|
-
},
|
|
927
|
-
callback: async (stream, params) => {
|
|
928
|
-
await this.create_refund(typeof params.payment === "string" ? params.payment : params.payment.id, params.line_items, params.reason);
|
|
929
|
-
return stream.success();
|
|
930
|
-
}
|
|
931
|
-
});
|
|
932
|
-
this.server.endpoint({
|
|
933
|
-
method: "DELETE",
|
|
934
|
-
endpoint: "/volt/api/v1/payments/subscription",
|
|
935
|
-
content_type: "application/json",
|
|
936
|
-
authenticated: true,
|
|
937
|
-
rate_limit: "global",
|
|
938
|
-
params: {
|
|
939
|
-
product: "string"
|
|
940
|
-
},
|
|
941
|
-
callback: async (stream, params) => {
|
|
942
|
-
await this.cancel_subscription(stream.uid, params.product);
|
|
943
|
-
return stream.success();
|
|
944
|
-
}
|
|
945
|
-
});
|
|
946
|
-
this.server.endpoint({
|
|
947
|
-
method: "GET",
|
|
948
|
-
endpoint: "/volt/api/v1/payments/active_subscriptions",
|
|
949
|
-
content_type: "application/json",
|
|
950
|
-
authenticated: true,
|
|
951
|
-
rate_limit: "global",
|
|
952
|
-
callback: async (stream) => {
|
|
953
|
-
return stream.success({
|
|
954
|
-
data: {
|
|
955
|
-
subscriptions: await this.get_active_subscriptions(stream.uid)
|
|
956
|
-
}
|
|
957
|
-
});
|
|
958
|
-
}
|
|
959
|
-
});
|
|
960
|
-
this.server.endpoint({
|
|
961
|
-
method: "GET",
|
|
962
|
-
endpoint: "/volt/api/v1/payments/subscribed",
|
|
963
|
-
content_type: "application/json",
|
|
964
|
-
authenticated: true,
|
|
965
|
-
rate_limit: "global",
|
|
966
|
-
params: {
|
|
967
|
-
product: "string"
|
|
968
|
-
},
|
|
969
|
-
callback: async (stream, params) => {
|
|
970
|
-
return stream.success({
|
|
971
|
-
data: {
|
|
972
|
-
is_subscribed: await this.is_subscribed(stream.uid, params.product)
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
}
|
|
976
|
-
});
|
|
977
|
-
if (!this.server.offline) {
|
|
978
|
-
this.server.endpoint(await this._create_webhook());
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
now = this.performance.end("init-endpoints", now);
|
|
982
|
-
}
|
|
983
|
-
// ---------------------------------------------------------
|
|
984
|
-
// Webhook (private).
|
|
985
|
-
// Execute a webhook user defined callback.
|
|
986
|
-
async _exec_user_callback(callback, args) {
|
|
987
|
-
if (callback != null) {
|
|
988
|
-
try {
|
|
989
|
-
let res = callback(args);
|
|
990
|
-
if (res instanceof Promise) {
|
|
991
|
-
res = await res;
|
|
992
|
-
}
|
|
993
|
-
} catch (error) {
|
|
994
|
-
console.error(error);
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
// Send a payment mail.
|
|
999
|
-
// async _send_payment_mail({payment, subject, attachments = [], mail}) {
|
|
1000
|
-
// await this.server.send_mail({
|
|
1001
|
-
// recipients: [payment.billing_details.name == null ? payment.billing_details.email : [payment.billing_details.name, payment.billing_details.email]],
|
|
1002
|
-
// subject,
|
|
1003
|
-
// body: mail.html(),
|
|
1004
|
-
// attachments,
|
|
1005
|
-
// })
|
|
1006
|
-
// }
|
|
1007
|
-
// On a successfull payment webhook event.
|
|
1008
|
-
async _payment_webhook(data) {
|
|
1009
|
-
let obj = (await this._req("GET", `/transactions/${data.id}`, { include: ["address", "adjustments", "business", "customer"] })).data;
|
|
1010
|
-
const id = `pay_${obj.custom_data.uid == null ? "unauth" : obj.custom_data.uid}_${vlib.String.random(4)}${Date.now()}`;
|
|
1011
|
-
const payment = {
|
|
1012
|
-
id,
|
|
1013
|
-
// payment id.
|
|
1014
|
-
uid: obj.custom_data.uid,
|
|
1015
|
-
// user id,
|
|
1016
|
-
cus_id: obj.customer_id,
|
|
1017
|
-
// customer id.
|
|
1018
|
-
tran_id: obj.id,
|
|
1019
|
-
// transaction id.
|
|
1020
|
-
timestamp: Date.now(),
|
|
1021
|
-
status: "unknown",
|
|
1022
|
-
// payment status, possible values are "open" or "paid".
|
|
1023
|
-
line_items: [],
|
|
1024
|
-
// cart line items as {quantity: 1, product: "prod_xxx"}.
|
|
1025
|
-
billing_details: {
|
|
1026
|
-
name: void 0,
|
|
1027
|
-
email: void 0,
|
|
1028
|
-
business: void 0,
|
|
1029
|
-
vat_id: void 0,
|
|
1030
|
-
address: void 0,
|
|
1031
|
-
city: void 0,
|
|
1032
|
-
postal_code: void 0,
|
|
1033
|
-
province: void 0,
|
|
1034
|
-
country: void 0,
|
|
1035
|
-
tax_identifier: void 0
|
|
1036
|
-
}
|
|
1037
|
-
};
|
|
1038
|
-
if (obj.business != null) {
|
|
1039
|
-
const b = obj.business;
|
|
1040
|
-
if (b != null && b.name != null && b.name.length > 0) {
|
|
1041
|
-
payment.billing_details.business = b.name;
|
|
1042
|
-
}
|
|
1043
|
-
if (b.tax_identifier != null && b.tax_identifier.length > 0) {
|
|
1044
|
-
payment.billing_details.tax_identifier = b.tax_identifier;
|
|
1045
|
-
}
|
|
1046
|
-
if (b.contacts.length > 0) {
|
|
1047
|
-
const contact = b.contacts[0];
|
|
1048
|
-
payment.billing_details.name = contact.name;
|
|
1049
|
-
payment.billing_details.email = contact.email;
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
if (payment.billing_details.email == null && obj.customer != null && obj.customer.email != null && obj.customer.email.length > 0) {
|
|
1053
|
-
payment.billing_details.email = obj.customer.email;
|
|
1054
|
-
}
|
|
1055
|
-
if (payment.billing_details.name == null && obj.custom_data.customer_name != null && obj.custom_data.customer_name != null && obj.custom_data.customer_name.length > 0) {
|
|
1056
|
-
payment.billing_details.name = obj.custom_data.customer_name;
|
|
1057
|
-
}
|
|
1058
|
-
if (obj.address != null) {
|
|
1059
|
-
const a = obj.address;
|
|
1060
|
-
if (a.first_line != null && a.first_line.length > 0) {
|
|
1061
|
-
payment.billing_details.address = a.first_line;
|
|
1062
|
-
}
|
|
1063
|
-
if (a.city != null && a.city.length > 0) {
|
|
1064
|
-
payment.billing_details.city = a.city;
|
|
1065
|
-
}
|
|
1066
|
-
if (a.postal_code != null && a.postal_code.length > 0) {
|
|
1067
|
-
payment.billing_details.postal_code = a.postal_code;
|
|
1068
|
-
}
|
|
1069
|
-
if (a.region != null && a.region.length > 0) {
|
|
1070
|
-
payment.billing_details.province = a.region;
|
|
1071
|
-
}
|
|
1072
|
-
if (a.country_code != null && a.country_code.length > 0) {
|
|
1073
|
-
payment.billing_details.country = a.country_code;
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
switch (obj.status) {
|
|
1077
|
-
case "draft":
|
|
1078
|
-
case "ready":
|
|
1079
|
-
payment.status = "open";
|
|
1080
|
-
break;
|
|
1081
|
-
case "billed":
|
|
1082
|
-
case "paid":
|
|
1083
|
-
case "completed":
|
|
1084
|
-
payment.status = "paid";
|
|
1085
|
-
break;
|
|
1086
|
-
case "past_due":
|
|
1087
|
-
payment.status = "past_due";
|
|
1088
|
-
break;
|
|
1089
|
-
default:
|
|
1090
|
-
this.server.log.error(`Payment Webhook: Unknown payment status "${obj.status}".`);
|
|
1091
|
-
payment.status = "unknown";
|
|
1092
|
-
break;
|
|
1093
|
-
}
|
|
1094
|
-
obj.details.line_items.iterate((item) => {
|
|
1095
|
-
payment.line_items.push({
|
|
1096
|
-
product: item.product.custom_data.id,
|
|
1097
|
-
// product id, keep as id since we do not want to save the product object to the database since this can change.
|
|
1098
|
-
item_id: item.id,
|
|
1099
|
-
// transaction item id.
|
|
1100
|
-
paddle_prod_id: item.product.id,
|
|
1101
|
-
// paddle product id.
|
|
1102
|
-
quantity: item.quantity,
|
|
1103
|
-
tax_rate: parseFloat(item.tax_rate),
|
|
1104
|
-
tax: item.totals.tax / 100,
|
|
1105
|
-
// should not be changed to unit totals, since mails and invoices depend on this behaviour, just divide by quantity.
|
|
1106
|
-
discount: item.totals.discount / 100,
|
|
1107
|
-
// should not be changed to unit totals, since mails and invoices depend on this behaviour, just divide by quantity.
|
|
1108
|
-
subtotal: item.totals.subtotal / 100,
|
|
1109
|
-
// should not be changed to unit totals, since mails and invoices depend on this behaviour, just divide by quantity.
|
|
1110
|
-
total: item.totals.total / 100,
|
|
1111
|
-
// should not be changed to unit totals, since mails and invoices depend on this behaviour, just divide by quantity.
|
|
1112
|
-
status: "paid"
|
|
1113
|
-
// can be "paid", "refunded", "refunding".
|
|
1114
|
-
});
|
|
1115
|
-
});
|
|
1116
|
-
if (obj.adustments != null) {
|
|
1117
|
-
obj.adustments.iterate((adj) => {
|
|
1118
|
-
switch (adj.action) {
|
|
1119
|
-
case "refund":
|
|
1120
|
-
case "chargeback":
|
|
1121
|
-
for (const adj_item of adj.items) {
|
|
1122
|
-
for (const item of payment.line_items) {
|
|
1123
|
-
if (adj_item.item_id === item.item_id) {
|
|
1124
|
-
item.status = "refunded";
|
|
1125
|
-
break;
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
break;
|
|
1130
|
-
case "chargeback_reversal":
|
|
1131
|
-
for (const adj_item of adj.items) {
|
|
1132
|
-
for (const item of payment.line_items) {
|
|
1133
|
-
if (adj_item.item_id === item.item_id) {
|
|
1134
|
-
item.status = "paid";
|
|
1135
|
-
break;
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
break;
|
|
1140
|
-
default:
|
|
1141
|
-
break;
|
|
1142
|
-
}
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
|
-
await this._save_payment(payment);
|
|
1146
|
-
const { uid } = payment;
|
|
1147
|
-
for (const item of payment.line_items) {
|
|
1148
|
-
const product = this.get_product_sync(item.product, false);
|
|
1149
|
-
if (product == null) {
|
|
1150
|
-
continue;
|
|
1151
|
-
} else if (product.is_subscription) {
|
|
1152
|
-
const subscription = await this.get_product(product.subscription_id, true);
|
|
1153
|
-
for (const plan of subscription?.plans ?? []) {
|
|
1154
|
-
if (plan.id != product.id) {
|
|
1155
|
-
const { exists, sub_id } = await this._check_subscription(uid, plan.id);
|
|
1156
|
-
if (exists) {
|
|
1157
|
-
this.server.log(0, `Cancelling subscription "${plan.id}" due too downgrade/upgrade to "${product.id}" of user "${payment.uid}".`);
|
|
1158
|
-
await this._cancel_subscription(sub_id);
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
} else {
|
|
1163
|
-
await this._exec_user_callback(this.server.on_payment, { product, payment });
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
// On subscription activated webhook event.
|
|
1168
|
-
// Even though the payment webhook could take care of this, still keep it seperated for customization, and possibly a new activation in certain scenerario's perhaps past due invoice, not sure just in case.
|
|
1169
|
-
async _subscription_webhook(data) {
|
|
1170
|
-
const uid = data.custom_data.uid;
|
|
1171
|
-
const subscription = {
|
|
1172
|
-
uid,
|
|
1173
|
-
id: data.id,
|
|
1174
|
-
cus_id: data.customer_id,
|
|
1175
|
-
// customer id.
|
|
1176
|
-
status: "active",
|
|
1177
|
-
// can be "active", "cancelling", "cancelled".
|
|
1178
|
-
plans: []
|
|
1179
|
-
};
|
|
1180
|
-
for (const item of data.items) {
|
|
1181
|
-
const product = this._get_product_by_paddle_prod_id(item.price.product_id, false);
|
|
1182
|
-
if (product == null) {
|
|
1183
|
-
this.server.log.error(`Subscription webhook [#sub1]: Unable to find product with id ${item.price.product_id}. This is a serious error which causes a non activated subscription for a paid transaction. You should manually cancel the subscription. Event: ${JSON.stringify(data, null, 4)}.`);
|
|
1184
|
-
continue;
|
|
1185
|
-
} else if (product.is_subscription) {
|
|
1186
|
-
subscription.plans.append(product.id);
|
|
1187
|
-
this.server.log(0, `Activating subscription "${product.id}" of user "${subscription.uid}".`);
|
|
1188
|
-
await this._add_subscription(uid, product.id, subscription.id);
|
|
1189
|
-
await this._exec_user_callback(this.server.on_subscription, { product, subscription });
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
await this._save_subscription(subscription);
|
|
1193
|
-
}
|
|
1194
|
-
// On a subscription cancelled webhook event.
|
|
1195
|
-
async _subscription_cancelled_webhook(data) {
|
|
1196
|
-
const subscription = await this._load_subscription(data.id);
|
|
1197
|
-
for (const plan_id of subscription.plans) {
|
|
1198
|
-
await this._delete_subscription(subscription.uid, plan_id);
|
|
1199
|
-
this.server.log(0, `Deactivating subscription "${plan_id}" of user "${subscription.uid}".`);
|
|
1200
|
-
}
|
|
1201
|
-
subscription.status = "cancelled";
|
|
1202
|
-
await this._save_subscription(subscription);
|
|
1203
|
-
await this._exec_user_callback(this.server.on_cancellation, { subscription });
|
|
1204
|
-
}
|
|
1205
|
-
// On a adjustment (refunds) updated webhook event.
|
|
1206
|
-
async _adjustment_webhook(data) {
|
|
1207
|
-
const is_refund = data.action === "refund";
|
|
1208
|
-
const is_chargeback = data.action === "chargeback";
|
|
1209
|
-
if (is_refund || is_chargeback) {
|
|
1210
|
-
if (data.status === "pending_approval") {
|
|
1211
|
-
return;
|
|
1212
|
-
}
|
|
1213
|
-
const is_approved = data.status === "approved";
|
|
1214
|
-
const payment = await this._load_payment_by_transaction(data.transaction_id);
|
|
1215
|
-
const line_items = [], cancel_products = [];
|
|
1216
|
-
for (const adj_item of data.items) {
|
|
1217
|
-
for (const item of payment.line_items) {
|
|
1218
|
-
if (item.item_id === adj_item.item_id) {
|
|
1219
|
-
item.status = is_approved ? "refunded" : "paid";
|
|
1220
|
-
cancel_products.push(item.product);
|
|
1221
|
-
line_items.push(item);
|
|
1222
|
-
break;
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
if (payment.sub_id != null && is_approved) {
|
|
1227
|
-
await this._cancel_subscription(payment.sub_id, true);
|
|
1228
|
-
}
|
|
1229
|
-
if (line_items.length > 0) {
|
|
1230
|
-
await this._save_payment(payment);
|
|
1231
|
-
}
|
|
1232
|
-
if (is_approved) {
|
|
1233
|
-
this.server.log(0, `Refunded items of payment "${payment.id}" of user "${payment.uid}".`);
|
|
1234
|
-
await this._exec_user_callback(is_refund ? this.server.on_refund : this.server.on_chargeback, { payment, line_items });
|
|
1235
|
-
} else {
|
|
1236
|
-
this.server.log(0, `Refund denied for items of payment ${payment.id} of user "${payment.uid}".`);
|
|
1237
|
-
await this._exec_user_callback(is_refund ? this.server.on_failed_refund : this.server.on_failed_chargeback, { payment, line_items });
|
|
1238
|
-
}
|
|
1239
|
-
} else if (data.action === "chargeback_reverse" && data.status === "reversed") {
|
|
1240
|
-
const payment = await this._load_payment_by_transaction(data.transaction_id);
|
|
1241
|
-
if (payment.sub_id != null) {
|
|
1242
|
-
this.server.log(0, `Chargeback reversed for payment ${payment.id} from user "${payment.uid}".`);
|
|
1243
|
-
}
|
|
1244
|
-
let line_items = [];
|
|
1245
|
-
for (const adj_item of data.items) {
|
|
1246
|
-
for (const item of payment.line_items) {
|
|
1247
|
-
if (item.item_id === adj_item.item_id) {
|
|
1248
|
-
item.status = "paid";
|
|
1249
|
-
line_items.push(item);
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
if (line_items.length > 0) {
|
|
1254
|
-
await this._save_payment(payment);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
// Create and register the webhook endpoint.
|
|
1259
|
-
async _create_webhook() {
|
|
1260
|
-
const now = this.performance.start();
|
|
1261
|
-
const webhook_settings = {
|
|
1262
|
-
description: "volt webhook",
|
|
1263
|
-
destination: `${this.server.full_domain}/volt/payments/webhook`,
|
|
1264
|
-
type: "url",
|
|
1265
|
-
subscribed_events: [
|
|
1266
|
-
// "transaction.billed",
|
|
1267
|
-
// "transaction.canceled",
|
|
1268
|
-
// "transaction.completed",
|
|
1269
|
-
// "transaction.created",
|
|
1270
|
-
"transaction.paid",
|
|
1271
|
-
// "transaction.past_due",
|
|
1272
|
-
// "transaction.payment_failed",
|
|
1273
|
-
// "transaction.ready",
|
|
1274
|
-
// "transaction.updated",
|
|
1275
|
-
"subscription.activated",
|
|
1276
|
-
"subscription.canceled",
|
|
1277
|
-
// "subscription.created",
|
|
1278
|
-
// "subscription.imported",
|
|
1279
|
-
// "subscription.past_due",
|
|
1280
|
-
"subscription.paused",
|
|
1281
|
-
"subscription.resumed",
|
|
1282
|
-
"subscription.trialing",
|
|
1283
|
-
// "subscription.updated",
|
|
1284
|
-
"adjustment.updated"
|
|
1285
|
-
]
|
|
1286
|
-
};
|
|
1287
|
-
const hashed_webhook_settings = this.server.hash(webhook_settings);
|
|
1288
|
-
const register_webhook = async () => {
|
|
1289
|
-
this.server.log(0, "Registering payments webhook.");
|
|
1290
|
-
const response = await this._req("POST", "/notification-settings", webhook_settings);
|
|
1291
|
-
this.webhook_key = response.data.endpoint_secret_key;
|
|
1292
|
-
await this._webhook_conf_db.set({ production: this.server.production, version: 1 }, {
|
|
1293
|
-
id: response.data.id,
|
|
1294
|
-
key: this.webhook_key,
|
|
1295
|
-
hash: this.server.hash(webhook_settings)
|
|
1296
|
-
});
|
|
1297
|
-
};
|
|
1298
|
-
const home_dir = vlib.Path.home().join(".volt/cache");
|
|
1299
|
-
if (!home_dir.exists()) {
|
|
1300
|
-
home_dir.mkdir({ recursive: true });
|
|
1301
|
-
}
|
|
1302
|
-
const cached_local_hash_file = home_dir.join(`paddle_webhook_${this.server.production ? "live" : "sandbox"}.hash`);
|
|
1303
|
-
const cached_local_hash = cached_local_hash_file.exists() ? await cached_local_hash_file.load() : null;
|
|
1304
|
-
if (cached_local_hash !== hashed_webhook_settings) {
|
|
1305
|
-
const webhook_doc = await this._webhook_conf_db.load({ production: this.server.production, version: 1 }, { throw: false });
|
|
1306
|
-
if (webhook_doc instanceof Error && !(webhook_doc instanceof import_collection.Collection.NotFoundError)) {
|
|
1307
|
-
throw webhook_doc;
|
|
1308
|
-
}
|
|
1309
|
-
if (!(webhook_doc instanceof import_collection.Collection.NotFoundError)) {
|
|
1310
|
-
this.webhook_key = webhook_doc.key;
|
|
1311
|
-
if (webhook_doc.hash !== hashed_webhook_settings) {
|
|
1312
|
-
this.server.log(0, `Checking payments webhook.`);
|
|
1313
|
-
const webhook_id = webhook_doc.id;
|
|
1314
|
-
let registered;
|
|
1315
|
-
try {
|
|
1316
|
-
registered = await this._req("GET", `/notification-settings/${webhook_id}`);
|
|
1317
|
-
} catch (error) {
|
|
1318
|
-
if (error.status === 404 || error.status_code === 404) {
|
|
1319
|
-
registered = void 0;
|
|
1320
|
-
await register_webhook();
|
|
1321
|
-
} else {
|
|
1322
|
-
throw error;
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
if (registered) {
|
|
1326
|
-
const item = registered.data;
|
|
1327
|
-
const patch = (() => {
|
|
1328
|
-
if (item.active !== true || item.destination !== webhook_settings.destination || item.type !== webhook_settings.type || item.description !== webhook_settings.description || item.subscribed_events.length != webhook_settings.subscribed_events.length) {
|
|
1329
|
-
return true;
|
|
1330
|
-
}
|
|
1331
|
-
let has_subscribed_event_missing = false;
|
|
1332
|
-
for (const x of webhook_settings.subscribed_events) {
|
|
1333
|
-
let found = false;
|
|
1334
|
-
for (const y of item.subscribed_events) {
|
|
1335
|
-
if (x === y.name) {
|
|
1336
|
-
found = true;
|
|
1337
|
-
break;
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
if (found === false) {
|
|
1341
|
-
has_subscribed_event_missing = true;
|
|
1342
|
-
break;
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
return has_subscribed_event_missing;
|
|
1346
|
-
})();
|
|
1347
|
-
if (patch === true) {
|
|
1348
|
-
this.server.log(0, "Updating payments webhook.");
|
|
1349
|
-
await this._req("PATCH", `/notification-settings/${webhook_id}`, { ...webhook_settings, active: true });
|
|
1350
|
-
}
|
|
1351
|
-
await this._webhook_conf_db.set({ production: this.server.production, version: 1 }, { hash: this.server.hash(webhook_settings) });
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
} else {
|
|
1355
|
-
await register_webhook();
|
|
1356
|
-
}
|
|
1357
|
-
await cached_local_hash_file.save(hashed_webhook_settings);
|
|
1358
|
-
}
|
|
1359
|
-
const ip_whitelist = [
|
|
1360
|
-
// Live.
|
|
1361
|
-
"34.232.58.13",
|
|
1362
|
-
"34.195.105.136",
|
|
1363
|
-
"34.237.3.244",
|
|
1364
|
-
"35.155.119.135",
|
|
1365
|
-
"52.11.166.252",
|
|
1366
|
-
"34.212.5.7",
|
|
1367
|
-
// Sandbox.
|
|
1368
|
-
"34.194.127.46",
|
|
1369
|
-
"54.234.237.108",
|
|
1370
|
-
"3.208.120.145",
|
|
1371
|
-
"44.226.236.210",
|
|
1372
|
-
"44.241.183.62",
|
|
1373
|
-
"100.20.172.113"
|
|
1374
|
-
];
|
|
1375
|
-
this.server.performance.end("create-payments-webhook", now);
|
|
1376
|
-
return {
|
|
1377
|
-
method: "POST",
|
|
1378
|
-
endpoint: "/volt/api/v1/payments/webhook",
|
|
1379
|
-
content_type: "application/json",
|
|
1380
|
-
rate_limit: void 0,
|
|
1381
|
-
callback: async (stream) => {
|
|
1382
|
-
if (ip_whitelist.includes(stream.ip) === false) {
|
|
1383
|
-
this.server.log(0, `POST:/volt/payments/webhook: Warning: Blocking non whitelisted ip "${stream.ip}".`);
|
|
1384
|
-
return stream.error({ status: import_status.Status.unauthorized });
|
|
1385
|
-
}
|
|
1386
|
-
const full_signature = stream.headers["paddle-signature"];
|
|
1387
|
-
if (full_signature == null) {
|
|
1388
|
-
this.server.log(0, "POST:/volt/payments/webhook: Error: No paddle signature found in the request headers.");
|
|
1389
|
-
return stream.error({ status: import_status.Status.unauthorized, data: { error: "Webhook signature verification failed." } });
|
|
1390
|
-
}
|
|
1391
|
-
const ts_index = full_signature.indexOf(";");
|
|
1392
|
-
const ts = full_signature.substr(3, ts_index - 3);
|
|
1393
|
-
const signature = full_signature.substr(ts_index + 4);
|
|
1394
|
-
const digest = libcrypto.createHmac("sha256", this.webhook_key).update(`${ts}:${stream.body}`).digest("hex");
|
|
1395
|
-
if (libcrypto.timingSafeEqual(Buffer.from(digest, "hex"), Buffer.from(signature, "hex")) !== true) {
|
|
1396
|
-
this.server.log(0, "POST:/volt/payments/webhook: Error: Webhook signature verification failed.");
|
|
1397
|
-
return stream.error({ status: import_status.Status.unauthorized, data: { error: "Webhook signature verification failed." } });
|
|
1398
|
-
}
|
|
1399
|
-
const event = JSON.parse(stream.body);
|
|
1400
|
-
switch (event.event_type) {
|
|
1401
|
-
// Paid transaction.
|
|
1402
|
-
// https://developer.paddle.com/webhooks/transactions/transaction-paid
|
|
1403
|
-
case "transaction.paid":
|
|
1404
|
-
await this._payment_webhook(event.data);
|
|
1405
|
-
break;
|
|
1406
|
-
// Subscription activated.
|
|
1407
|
-
// https://developer.paddle.com/webhooks/subscriptions/subscription-activated
|
|
1408
|
-
case "subscription.activated":
|
|
1409
|
-
case "subscription.trialing":
|
|
1410
|
-
case "subscription.resumed":
|
|
1411
|
-
await this._subscription_webhook(event.data);
|
|
1412
|
-
break;
|
|
1413
|
-
// Subscription canceled.
|
|
1414
|
-
// https://developer.paddle.com/webhooks/subscriptions/subscription-canceled
|
|
1415
|
-
case "subscription.canceled":
|
|
1416
|
-
case "subscription.paused":
|
|
1417
|
-
await this._subscription_cancelled_webhook(event.data);
|
|
1418
|
-
break;
|
|
1419
|
-
// Adjustment updated (refunds).
|
|
1420
|
-
// https://developer.paddle.com/webhooks/subscriptions/subscription-canceled
|
|
1421
|
-
case "adjustment.updated":
|
|
1422
|
-
await this._adjustment_webhook(event.data);
|
|
1423
|
-
break;
|
|
1424
|
-
// Default.
|
|
1425
|
-
default:
|
|
1426
|
-
break;
|
|
1427
|
-
}
|
|
1428
|
-
stream.success({ data: { message: "OK" } });
|
|
1429
|
-
}
|
|
1430
|
-
};
|
|
1431
|
-
}
|
|
1432
|
-
async get_product(id, throw_err = false) {
|
|
1433
|
-
return this.get_product_sync(id, throw_err);
|
|
1434
|
-
}
|
|
1435
|
-
get_product_sync(id, throw_err = false) {
|
|
1436
|
-
let product = null;
|
|
1437
|
-
for (const p of this.products) {
|
|
1438
|
-
if (p.is_subscription) {
|
|
1439
|
-
if (p.id === id) {
|
|
1440
|
-
product = p;
|
|
1441
|
-
break;
|
|
1442
|
-
}
|
|
1443
|
-
for (const plan of p.plans) {
|
|
1444
|
-
if (plan.id === id) {
|
|
1445
|
-
product = plan;
|
|
1446
|
-
break;
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
} else if (p.id === id) {
|
|
1450
|
-
product = p;
|
|
1451
|
-
break;
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
if (product == null && throw_err) {
|
|
1455
|
-
throw Error(`Unable to find product "${id}".`);
|
|
1456
|
-
}
|
|
1457
|
-
return product;
|
|
1458
|
-
}
|
|
1459
|
-
/* @docs:
|
|
1460
|
-
@title: Get Payment.
|
|
1461
|
-
@desc: Get a payment by id.
|
|
1462
|
-
@param:
|
|
1463
|
-
@name: id
|
|
1464
|
-
@required: true
|
|
1465
|
-
@type: string
|
|
1466
|
-
@desc: The id of the payment.
|
|
1467
|
-
*/
|
|
1468
|
-
async get_payment(id, opts) {
|
|
1469
|
-
if (opts?.for_public) {
|
|
1470
|
-
return await this._load_payment_for_public(id);
|
|
1471
|
-
}
|
|
1472
|
-
return await this._load_payment(id);
|
|
1473
|
-
}
|
|
1474
|
-
/* @docs:
|
|
1475
|
-
@title: Get Refunded Payments.
|
|
1476
|
-
@desc:
|
|
1477
|
-
Get all payments.
|
|
1478
|
-
|
|
1479
|
-
All failed payments are no longer stored in the database.
|
|
1480
|
-
@param:
|
|
1481
|
-
@name: uid
|
|
1482
|
-
@cached: Users:uid:param
|
|
1483
|
-
@param:
|
|
1484
|
-
@name: days
|
|
1485
|
-
@type: number
|
|
1486
|
-
@desc: Retrieve payments from the last amount of days.
|
|
1487
|
-
@param:
|
|
1488
|
-
@name: limit
|
|
1489
|
-
@type: number
|
|
1490
|
-
@desc: Limit the amount of response payment objects.
|
|
1491
|
-
@param:
|
|
1492
|
-
@name: status
|
|
1493
|
-
@type: string, array[string]
|
|
1494
|
-
@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.`
|
|
1495
|
-
@enum:
|
|
1496
|
-
@value: "open"
|
|
1497
|
-
@desc: Payments that are still open and unpaid.
|
|
1498
|
-
@enum:
|
|
1499
|
-
@value: "paid"
|
|
1500
|
-
@desc: Payments that are paid.
|
|
1501
|
-
*/
|
|
1502
|
-
async get_payments({ uid, days = 30, limit = 1e4, status = void 0, for_public }) {
|
|
1503
|
-
const query = {
|
|
1504
|
-
uid
|
|
1505
|
-
};
|
|
1506
|
-
if (days != null) {
|
|
1507
|
-
const since = /* @__PURE__ */ new Date();
|
|
1508
|
-
since.setHours(0, 0, 0, 0);
|
|
1509
|
-
query.timestamp = { $gte: Math.floor(since.getTime() - 3600 * 24 * 1e3 * days) };
|
|
1510
|
-
}
|
|
1511
|
-
if (Array.isArray(status)) {
|
|
1512
|
-
query.status = { $in: status };
|
|
1513
|
-
} else if (typeof status === "string") {
|
|
1514
|
-
query.status = status;
|
|
1515
|
-
}
|
|
1516
|
-
const payments = await this._pay_db.list(query, { limit });
|
|
1517
|
-
payments.sort((a, b) => b.timestamp - a.timestamp);
|
|
1518
|
-
return for_public ? payments.map((p) => Payment.anonymize(p)) : payments;
|
|
1519
|
-
}
|
|
1520
|
-
/* @docs:
|
|
1521
|
-
@title: Get Refundable Payments.
|
|
1522
|
-
@desc: Get all payments that are refundable.
|
|
1523
|
-
@param:
|
|
1524
|
-
@name: uid
|
|
1525
|
-
@cached: Users:uid:param
|
|
1526
|
-
@param:
|
|
1527
|
-
@name: days
|
|
1528
|
-
@type: number
|
|
1529
|
-
@desc: Retrieve payments from the last amount of days.
|
|
1530
|
-
@param:
|
|
1531
|
-
@name: limit
|
|
1532
|
-
@type: number
|
|
1533
|
-
@desc: Limit the amount of response payment objects.
|
|
1534
|
-
*/
|
|
1535
|
-
async get_refundable_payments({ uid, days = 30, limit = void 0, for_public }) {
|
|
1536
|
-
const out = [];
|
|
1537
|
-
const all_payments = await this.get_payments({ uid, days, limit, status: "paid", for_public });
|
|
1538
|
-
for (const pmt of all_payments) {
|
|
1539
|
-
const refundable = pmt.line_items.filter((li) => li.status === "paid" && li.total > 0);
|
|
1540
|
-
if (refundable.length > 0) {
|
|
1541
|
-
out.push({ ...pmt, line_items: refundable });
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
return out;
|
|
1545
|
-
}
|
|
1546
|
-
/* @docs:
|
|
1547
|
-
@title: Get Refunded Payments.
|
|
1548
|
-
@desc: Get all payments that are successfully refunded.
|
|
1549
|
-
@param:
|
|
1550
|
-
@name: uid
|
|
1551
|
-
@cached: Users:uid:param
|
|
1552
|
-
@param:
|
|
1553
|
-
@name: days
|
|
1554
|
-
@type: number
|
|
1555
|
-
@desc: Retrieve payments from the last amount of days.
|
|
1556
|
-
@param:
|
|
1557
|
-
@name: limit
|
|
1558
|
-
@type: number
|
|
1559
|
-
@desc: Limit the amount of response payment objects.
|
|
1560
|
-
*/
|
|
1561
|
-
async get_refunded_payments({ uid, days = 30, limit = void 0, for_public }) {
|
|
1562
|
-
const out = [];
|
|
1563
|
-
const all_payments = await this.get_payments({ uid, days, limit, status: "paid", for_public });
|
|
1564
|
-
for (const pmt of all_payments) {
|
|
1565
|
-
const refundable = pmt.line_items.filter((li) => li.status === "refunded" && li.total > 0);
|
|
1566
|
-
if (refundable.length > 0) {
|
|
1567
|
-
out.push({ ...pmt, line_items: refundable });
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
return out;
|
|
1571
|
-
}
|
|
1572
|
-
/* @docs:
|
|
1573
|
-
@title: Get Refunding Payments.
|
|
1574
|
-
@desc: Get all payments that are currently in the refunding process.
|
|
1575
|
-
@param:
|
|
1576
|
-
@name: uid
|
|
1577
|
-
@cached: Users:uid:param
|
|
1578
|
-
@param:
|
|
1579
|
-
@name: days
|
|
1580
|
-
@type: number
|
|
1581
|
-
@desc: Retrieve payments from the last amount of days.
|
|
1582
|
-
@param:
|
|
1583
|
-
@name: limit
|
|
1584
|
-
@type: number
|
|
1585
|
-
@desc: Limit the amount of response payment objects.
|
|
1586
|
-
*/
|
|
1587
|
-
async get_refunding_payments({ uid, days = void 0, limit = void 0, for_public }) {
|
|
1588
|
-
const out = [];
|
|
1589
|
-
const all_payments = await this.get_payments({ uid, days, limit, status: "paid", for_public });
|
|
1590
|
-
for (const pmt of all_payments) {
|
|
1591
|
-
const refundable = pmt.line_items.filter((li) => li.status === "refunding" && li.total > 0);
|
|
1592
|
-
if (refundable.length > 0) {
|
|
1593
|
-
out.push({ ...pmt, line_items: refundable });
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
return out;
|
|
1597
|
-
}
|
|
1598
|
-
/* @docs:
|
|
1599
|
-
@title: Refund Payment.
|
|
1600
|
-
@desc: Refund a payment based on the payment id.
|
|
1601
|
-
@warning: Refunding a subscription will also cancel all other subscriptions that were created by the same payment request.
|
|
1602
|
-
@param:
|
|
1603
|
-
@name: payment
|
|
1604
|
-
@required: true
|
|
1605
|
-
@type: number
|
|
1606
|
-
@desc: The id of the payment object or the payment object itself.
|
|
1607
|
-
@param:
|
|
1608
|
-
@name: line_items
|
|
1609
|
-
@type: array[object]
|
|
1610
|
-
@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.
|
|
1611
|
-
@param:
|
|
1612
|
-
@name: reason
|
|
1613
|
-
@type: string
|
|
1614
|
-
@desc: The refund reason for internal analytics.
|
|
1615
|
-
*/
|
|
1616
|
-
async create_refund(payment, line_items = void 0, reason = "refund") {
|
|
1617
|
-
if (typeof payment === "string") {
|
|
1618
|
-
payment = await this._load_payment(payment);
|
|
1619
|
-
} else {
|
|
1620
|
-
payment = await this._load_payment(payment.id);
|
|
1621
|
-
}
|
|
1622
|
-
if (line_items == null) {
|
|
1623
|
-
line_items = payment.line_items;
|
|
1624
|
-
}
|
|
1625
|
-
if (line_items.length === 0) {
|
|
1626
|
-
throw Error("No refund line items array is empty.");
|
|
1627
|
-
}
|
|
1628
|
-
const items = [];
|
|
1629
|
-
const item_ids = [];
|
|
1630
|
-
for (const item of line_items) {
|
|
1631
|
-
if (item.status === "refunded" || item.status === "refunding") {
|
|
1632
|
-
continue;
|
|
1633
|
-
}
|
|
1634
|
-
item_ids.push(item.item_id);
|
|
1635
|
-
items.push({
|
|
1636
|
-
item_id: item.item_id,
|
|
1637
|
-
type: "full"
|
|
1638
|
-
// partial refudings are not supported per line item since there is no convenient way to keep track of how much is refunded.
|
|
1639
|
-
});
|
|
1640
|
-
}
|
|
1641
|
-
if (items.length === 0) {
|
|
1642
|
-
throw Error("This payment no longer has any refundable line items.");
|
|
1643
|
-
}
|
|
1644
|
-
const response = await this._req("POST", `/adjustments`, {
|
|
1645
|
-
action: "refund",
|
|
1646
|
-
transaction_id: payment.tran_id,
|
|
1647
|
-
reason,
|
|
1648
|
-
items,
|
|
1649
|
-
custom_data: {
|
|
1650
|
-
uid: payment.uid
|
|
1651
|
-
}
|
|
1652
|
-
});
|
|
1653
|
-
if (response.data.status === "rejected") {
|
|
1654
|
-
throw Error("This payment is no longer refundable.");
|
|
1655
|
-
} else if (response.data.status === "approved") {
|
|
1656
|
-
for (const item of payment.line_items) {
|
|
1657
|
-
if (line_items.find((i) => i.item_id === item.item_id)) {
|
|
1658
|
-
item.status = "refunded";
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
} else {
|
|
1662
|
-
for (const item of payment.line_items) {
|
|
1663
|
-
if (line_items.find((i) => i.item_id === item.item_id)) {
|
|
1664
|
-
item.status = "refunding";
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
await this._save_payment(payment);
|
|
1669
|
-
}
|
|
1670
|
-
/* @docs:
|
|
1671
|
-
@title: Cancel Subscription.
|
|
1672
|
-
@desc: Cancel a subscription based on the retrieved payment object or id.
|
|
1673
|
-
@warning: Cancelling a subscription will also cancel all other subscriptions that were created by the same payment request.
|
|
1674
|
-
@param:
|
|
1675
|
-
@name: uid
|
|
1676
|
-
@cached: Users:uid:param
|
|
1677
|
-
@param:
|
|
1678
|
-
@name: products
|
|
1679
|
-
@required: true
|
|
1680
|
-
@type: string, array[string, object]
|
|
1681
|
-
@desc: The product to cancel, the product ids to cancel or the product objects to cancel.
|
|
1682
|
-
*/
|
|
1683
|
-
async cancel_subscription(uid, products, _throw_no_cancelled_err = true) {
|
|
1684
|
-
if (products == null) {
|
|
1685
|
-
throw new Error('Parameter "products" should be a defined value of type "array[string, object]".');
|
|
1686
|
-
}
|
|
1687
|
-
if (typeof products === "string") {
|
|
1688
|
-
products = [products];
|
|
1689
|
-
}
|
|
1690
|
-
let cancelled = [];
|
|
1691
|
-
for (let product of products) {
|
|
1692
|
-
if (typeof product === "object") {
|
|
1693
|
-
product = product.id;
|
|
1694
|
-
}
|
|
1695
|
-
const { exists, sub_id } = await this._check_subscription(uid, product);
|
|
1696
|
-
if (exists && cancelled.includes(sub_id) === false) {
|
|
1697
|
-
await this._cancel_subscription(sub_id);
|
|
1698
|
-
cancelled.push(sub_id);
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1701
|
-
;
|
|
1702
|
-
if (_throw_no_cancelled_err && cancelled.length === 0) {
|
|
1703
|
-
throw new import_errors.ExternalError({
|
|
1704
|
-
type: "NoCancellableSubscriptions",
|
|
1705
|
-
message: "No cancellable subscriptions found.",
|
|
1706
|
-
status: import_status.Status.bad_request
|
|
1707
|
-
});
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
/* @docs:
|
|
1711
|
-
@title: Cancel subscription by subscription id.
|
|
1712
|
-
@desc: Cancel a subscription based on the retrieved subscription object or id.
|
|
1713
|
-
@warning: Cancelling a subscription will also cancel all other subscriptions that were created by the same payment request.
|
|
1714
|
-
@param:
|
|
1715
|
-
@name: subscription
|
|
1716
|
-
@required: true
|
|
1717
|
-
@type: string, object
|
|
1718
|
-
@desc: The retrieved subscription object or the subscription's id.
|
|
1719
|
-
@param:
|
|
1720
|
-
@name: immediate
|
|
1721
|
-
@type: boolean
|
|
1722
|
-
@desc: Immediately cancel the subscription, or wait till the end of the billing cycle.
|
|
1723
|
-
*/
|
|
1724
|
-
async cancel_subscription_by_id(subscription, immediate = false) {
|
|
1725
|
-
if (typeof subscription === "object") {
|
|
1726
|
-
subscription = subscription.id;
|
|
1727
|
-
}
|
|
1728
|
-
return await this._cancel_subscription(subscription, immediate);
|
|
1729
|
-
}
|
|
1730
|
-
/* @docs:
|
|
1731
|
-
@title: Get active subscriptions
|
|
1732
|
-
@desc: Get the active subscriptions of a user.
|
|
1733
|
-
@param:
|
|
1734
|
-
@name: uid
|
|
1735
|
-
@cached: Users:uid:param
|
|
1736
|
-
*/
|
|
1737
|
-
async get_active_subscriptions(uid) {
|
|
1738
|
-
return await this._get_active_subscriptions(uid);
|
|
1739
|
-
}
|
|
1740
|
-
/* @docs:
|
|
1741
|
-
@title: Get all subscriptions
|
|
1742
|
-
@desc: Get all subscriptions of a user, active and inactive.
|
|
1743
|
-
@param:
|
|
1744
|
-
@name: uid
|
|
1745
|
-
@cached: Users:uid:param
|
|
1746
|
-
*/
|
|
1747
|
-
async get_subscriptions(uid) {
|
|
1748
|
-
return await this._get_subscriptions(uid);
|
|
1749
|
-
}
|
|
1750
|
-
/* @docs:
|
|
1751
|
-
@title: Is Subscribed
|
|
1752
|
-
@desc: Check if a user is subscribed to a product.
|
|
1753
|
-
@param:
|
|
1754
|
-
@name: uid
|
|
1755
|
-
@cached: Users:uid:param
|
|
1756
|
-
@param:
|
|
1757
|
-
@name: product
|
|
1758
|
-
@required: true
|
|
1759
|
-
@type: string
|
|
1760
|
-
@desc: The product id.
|
|
1761
|
-
*/
|
|
1762
|
-
async is_subscribed(uid, product) {
|
|
1763
|
-
return await this._check_subscription(uid, product, false);
|
|
1764
|
-
}
|
|
1765
|
-
/* @docs:
|
|
1766
|
-
@title: Generate Invoice
|
|
1767
|
-
@desc:
|
|
1768
|
-
Generate an invoice for a paid payment.
|
|
1769
|
-
|
|
1770
|
-
By default an invoice is already generated when a payment has been paid.
|
|
1771
|
-
@param:
|
|
1772
|
-
@name: payment
|
|
1773
|
-
@required: true
|
|
1774
|
-
@type: object
|
|
1775
|
-
@desc: The payment object.
|
|
1776
|
-
@return:
|
|
1777
|
-
@type: Promise
|
|
1778
|
-
@desc: This function returns a promise to the invoice pdf in bytes.
|
|
1779
|
-
*/
|
|
1780
|
-
async generate_invoice(payment) {
|
|
1781
|
-
if (payment == null || typeof payment !== "object") {
|
|
1782
|
-
throw Error(`Parameter "payment" should be a defined value of type "object".`);
|
|
1783
|
-
}
|
|
1784
|
-
let currency;
|
|
1785
|
-
let subtotal = 0;
|
|
1786
|
-
let subtotal_tax = 0;
|
|
1787
|
-
let total = 0;
|
|
1788
|
-
for (const item of payment.line_items) {
|
|
1789
|
-
if (typeof item.product === "string") {
|
|
1790
|
-
item.product = this.get_product_sync(item.product, true);
|
|
1791
|
-
}
|
|
1792
|
-
if (currency == null) {
|
|
1793
|
-
const c = import_utils.Utils.get_currency_symbol(item.product.currency);
|
|
1794
|
-
if (c == null) {
|
|
1795
|
-
throw new Error(`Unable to determine the currency symbol for "${item.product.currency}".`);
|
|
1796
|
-
}
|
|
1797
|
-
currency = c;
|
|
1798
|
-
}
|
|
1799
|
-
subtotal += item.subtotal;
|
|
1800
|
-
subtotal_tax += item.tax;
|
|
1801
|
-
total += item.total;
|
|
1802
|
-
}
|
|
1803
|
-
let total_due = payment.status === "open" ? total : 0;
|
|
1804
|
-
let doc = new PDFDocument({ size: "A4", margin: 50 });
|
|
1805
|
-
let expanded_payment = payment;
|
|
1806
|
-
let top_offset = 57;
|
|
1807
|
-
let spacing = 10;
|
|
1808
|
-
const gen_text = (text, x, y = null, opts = null, _spacing = null) => {
|
|
1809
|
-
if (y == null) {
|
|
1810
|
-
y = top_offset;
|
|
1811
|
-
} else {
|
|
1812
|
-
top_offset = y;
|
|
1813
|
-
}
|
|
1814
|
-
if (_spacing == null) {
|
|
1815
|
-
_spacing = spacing;
|
|
1816
|
-
}
|
|
1817
|
-
doc.text(text, x, y, opts);
|
|
1818
|
-
top_offset += doc.heightOfString(text, x, y, opts) + (_spacing == null ? spacing : _spacing);
|
|
1819
|
-
};
|
|
1820
|
-
const gen_col_text = (text, x, opts = null, is_last = false, _spacing = 2) => {
|
|
1821
|
-
doc.text(text, x, top_offset, opts);
|
|
1822
|
-
if (is_last) {
|
|
1823
|
-
top_offset += doc.heightOfString(text, x, top_offset, opts) + (_spacing == null ? spacing : _spacing);
|
|
1824
|
-
} else {
|
|
1825
|
-
return doc.heightOfString(text, x, top_offset, opts);
|
|
1826
|
-
}
|
|
1827
|
-
};
|
|
1828
|
-
const gen_divider = (_spacing = null) => {
|
|
1829
|
-
doc.strokeColor("#aaaaaa").lineWidth(1).moveTo(50, top_offset).lineTo(550, top_offset).stroke();
|
|
1830
|
-
top_offset += 1 + (_spacing == null ? spacing : _spacing);
|
|
1831
|
-
};
|
|
1832
|
-
const gen_line_item = ({ name = "", desc = "", unit_cost = "", quantity = "", total_cost = "" }) => {
|
|
1833
|
-
const items = [
|
|
1834
|
-
[0.25, name],
|
|
1835
|
-
[0.35, desc],
|
|
1836
|
-
[0.4 / 3, unit_cost],
|
|
1837
|
-
[0.4 / 3, quantity],
|
|
1838
|
-
[0.4 / 3, total_cost]
|
|
1839
|
-
];
|
|
1840
|
-
let x = 50;
|
|
1841
|
-
let max_height = 0;
|
|
1842
|
-
const full_width = 550 - 50 - 10 * 4;
|
|
1843
|
-
for (const item of items) {
|
|
1844
|
-
max_height = Math.max(max_height, doc.heightOfString(item[1], x, top_offset, { width: full_width * item[0], align: "left" }));
|
|
1845
|
-
x += full_width * item[0] + 10;
|
|
1846
|
-
}
|
|
1847
|
-
if (top_offset + max_height + 10 > doc.page.height - 50) {
|
|
1848
|
-
doc.addPage();
|
|
1849
|
-
top_offset = 50;
|
|
1850
|
-
}
|
|
1851
|
-
x = 50;
|
|
1852
|
-
for (const item of items) {
|
|
1853
|
-
gen_col_text(item[1], x, { width: full_width * item[0], align: "left" });
|
|
1854
|
-
x += full_width * item[0] + 10;
|
|
1855
|
-
}
|
|
1856
|
-
top_offset += max_height + spacing;
|
|
1857
|
-
};
|
|
1858
|
-
const format_date = (date) => {
|
|
1859
|
-
return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`;
|
|
1860
|
-
};
|
|
1861
|
-
doc.fillColor("#444444");
|
|
1862
|
-
doc.fontSize(20);
|
|
1863
|
-
if (this.server.company.stroke_icon_path != null) {
|
|
1864
|
-
doc.image(this.server.company.stroke_icon_path, 50, top_offset - 2, { width: 60 });
|
|
1865
|
-
} else {
|
|
1866
|
-
if (this.server.company.icon_path != null) {
|
|
1867
|
-
doc.image(this.server.company.icon_path, 50, top_offset - 2, { width: 18 });
|
|
1868
|
-
}
|
|
1869
|
-
gen_text(this.server.company.legal_name, 50 + 18 + 10);
|
|
1870
|
-
}
|
|
1871
|
-
top_offset += 15;
|
|
1872
|
-
const start_top_offset = top_offset;
|
|
1873
|
-
doc.fillColor("#444444");
|
|
1874
|
-
doc.fontSize(10);
|
|
1875
|
-
doc.font("Helvetica-Bold");
|
|
1876
|
-
gen_text("From", 50, null, null, 3);
|
|
1877
|
-
doc.font("Helvetica");
|
|
1878
|
-
gen_text(this.server.company.legal_name, 50, null, { align: "left" }, 2);
|
|
1879
|
-
gen_text(`${this.server.company.street}, ${this.server.company.postal_code}`, 50, null, { align: "left" }, 2);
|
|
1880
|
-
gen_text(`${this.server.company.city}, ${this.server.company.province}, ${this.server.company.country}`, 50, null, { align: "left" }, 2);
|
|
1881
|
-
gen_text(`VAT ID: ${this.server.company.tax_id}`, 50, null, { align: "left" }, 2);
|
|
1882
|
-
const left_top_offset = top_offset;
|
|
1883
|
-
top_offset = start_top_offset;
|
|
1884
|
-
doc.fillColor("#444444");
|
|
1885
|
-
doc.fontSize(10);
|
|
1886
|
-
doc.font("Helvetica-Bold");
|
|
1887
|
-
gen_text("Invoice details", 550 - (150 + 10 + 80), null, null, 3);
|
|
1888
|
-
doc.font("Helvetica");
|
|
1889
|
-
for (const item of [
|
|
1890
|
-
["Invoice:", expanded_payment.id],
|
|
1891
|
-
["Date of issue:", format_date(/* @__PURE__ */ new Date())]
|
|
1892
|
-
]) {
|
|
1893
|
-
gen_col_text(item[0], 550 - (150 + 10 + 80), { width: 80 });
|
|
1894
|
-
gen_col_text(item[1], 550 - 150, { width: 150 }, true);
|
|
1895
|
-
}
|
|
1896
|
-
top_offset = Math.max(top_offset, left_top_offset) + 25;
|
|
1897
|
-
doc.fillColor("#444444");
|
|
1898
|
-
doc.fontSize(10);
|
|
1899
|
-
doc.font("Helvetica-Bold");
|
|
1900
|
-
gen_text("Billing Details", 50, null, null, 3);
|
|
1901
|
-
doc.font("Helvetica");
|
|
1902
|
-
if (expanded_payment.billing_details.business != null) {
|
|
1903
|
-
gen_text(`${expanded_payment.billing_details.business}`, 50, null, { align: "left" }, 2);
|
|
1904
|
-
} else {
|
|
1905
|
-
gen_text(`${expanded_payment.billing_details.name}`, 50, null, { align: "left" }, 2);
|
|
1906
|
-
}
|
|
1907
|
-
gen_text(expanded_payment.billing_details.email, 50, null, { align: "left" }, 2);
|
|
1908
|
-
gen_text(`${expanded_payment.billing_details.address}`, 50, null, { align: "left" }, 2);
|
|
1909
|
-
gen_text(`${expanded_payment.billing_details.city}, ${expanded_payment.billing_details.province}, ${expanded_payment.billing_details.country}`, 50, null, { align: "left" }, 2);
|
|
1910
|
-
if (expanded_payment.billing_details.vat_id != null) {
|
|
1911
|
-
gen_text(`${expanded_payment.billing_details.vat_id}`, 50, null, { align: "left" }, 2);
|
|
1912
|
-
}
|
|
1913
|
-
top_offset += 35;
|
|
1914
|
-
doc.font("Helvetica-Bold");
|
|
1915
|
-
gen_line_item({
|
|
1916
|
-
name: "Item",
|
|
1917
|
-
desc: "Description",
|
|
1918
|
-
unit_cost: "Unit Cost",
|
|
1919
|
-
quantity: "Quantity",
|
|
1920
|
-
total_cost: "Line Total"
|
|
1921
|
-
});
|
|
1922
|
-
top_offset -= spacing * 0.5;
|
|
1923
|
-
doc.font("Helvetica");
|
|
1924
|
-
gen_divider();
|
|
1925
|
-
for (const item of expanded_payment.line_items) {
|
|
1926
|
-
gen_line_item({
|
|
1927
|
-
name: item.product.name,
|
|
1928
|
-
desc: item.product.description,
|
|
1929
|
-
unit_cost: `${currency} ${(item.subtotal / item.quantity).toFixed(2)}`,
|
|
1930
|
-
quantity: item.quantity.toString(),
|
|
1931
|
-
total_cost: `${currency} ${item.total.toFixed(2)}`
|
|
1932
|
-
});
|
|
1933
|
-
top_offset += 10;
|
|
1934
|
-
gen_divider();
|
|
1935
|
-
}
|
|
1936
|
-
;
|
|
1937
|
-
gen_line_item({ unit_cost: "Subtotal:", total_cost: `${currency} ${subtotal.toFixed(2)}` });
|
|
1938
|
-
top_offset -= spacing - 3;
|
|
1939
|
-
gen_line_item({ unit_cost: "Taxes:", total_cost: `${currency} ${subtotal_tax.toFixed(2)}` });
|
|
1940
|
-
top_offset -= spacing - 3;
|
|
1941
|
-
gen_line_item({ unit_cost: "Total:", total_cost: `${currency} ${total.toFixed(2)}` });
|
|
1942
|
-
top_offset -= spacing - 3;
|
|
1943
|
-
doc.font("Helvetica-Bold");
|
|
1944
|
-
gen_line_item({ unit_cost: "Total Due:", total_cost: `${currency} ${total_due.toFixed(2)}` });
|
|
1945
|
-
top_offset -= spacing - 3;
|
|
1946
|
-
const chunks = [];
|
|
1947
|
-
return await new Promise((resolve, reject) => {
|
|
1948
|
-
doc.on("data", (chunk) => chunks.push(chunk));
|
|
1949
|
-
doc.on("end", () => resolve(Buffer.concat(chunks)));
|
|
1950
|
-
doc.on("error", (err) => reject(err));
|
|
1951
|
-
doc.end();
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
// ---------------------------------------------------------
|
|
1955
|
-
// Development.
|
|
1956
|
-
// Cancel all subscriptions to clear development environment.
|
|
1957
|
-
async dev_cancel_all_subscriptions() {
|
|
1958
|
-
if (!this.sandbox) {
|
|
1959
|
-
throw new Error("This function is only for a sandbox environment.");
|
|
1960
|
-
}
|
|
1961
|
-
let subs = [], after = null;
|
|
1962
|
-
while (true) {
|
|
1963
|
-
const response = await this._req("GET", "/subscriptions", after == null ? { per_page: 100 } : { per_page: 100, after });
|
|
1964
|
-
subs = subs.concat(response.data);
|
|
1965
|
-
if (!response.meta.has_more) {
|
|
1966
|
-
break;
|
|
1967
|
-
}
|
|
1968
|
-
after = subs.last().id;
|
|
1969
|
-
}
|
|
1970
|
-
for (const sub of subs) {
|
|
1971
|
-
if (sub.status === "active") {
|
|
1972
|
-
this.server.log("Cancelling subscription ", sub.id);
|
|
1973
|
-
await this._req("POST", `/subscriptions/${sub.id}/cancel`, {
|
|
1974
|
-
effective_from: "immediately"
|
|
1975
|
-
});
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
}
|
|
1980
|
-
(function(Paddle2) {
|
|
1981
|
-
class RequestError extends Error {
|
|
1982
|
-
status_code;
|
|
1983
|
-
constructor(err, status_code) {
|
|
1984
|
-
super(err);
|
|
1985
|
-
this.status_code = status_code;
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
Paddle2.RequestError = RequestError;
|
|
1989
|
-
})(Paddle || (Paddle = {}));
|
|
1990
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1991
|
-
0 && (module.exports = {
|
|
1992
|
-
LineItem,
|
|
1993
|
-
Paddle,
|
|
1994
|
-
Payment,
|
|
1995
|
-
PaymentStatusValues
|
|
1996
|
-
});
|