backend-manager 3.2.171 → 3.2.173

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.
Files changed (87) hide show
  1. package/package.json +5 -5
  2. package/src/cli/cli.js +27 -11
  3. package/dist/cli/cli.js +0 -1534
  4. package/dist/manager/functions/core/actions/api/admin/backup.js +0 -338
  5. package/dist/manager/functions/core/actions/api/admin/create-post.js +0 -388
  6. package/dist/manager/functions/core/actions/api/admin/cron.js +0 -37
  7. package/dist/manager/functions/core/actions/api/admin/database-read.js +0 -35
  8. package/dist/manager/functions/core/actions/api/admin/database-write.js +0 -39
  9. package/dist/manager/functions/core/actions/api/admin/edit-post.js +0 -158
  10. package/dist/manager/functions/core/actions/api/admin/firestore-query.js +0 -165
  11. package/dist/manager/functions/core/actions/api/admin/firestore-read.js +0 -38
  12. package/dist/manager/functions/core/actions/api/admin/firestore-write.js +0 -54
  13. package/dist/manager/functions/core/actions/api/admin/get-stats.js +0 -269
  14. package/dist/manager/functions/core/actions/api/admin/payment-processor.js +0 -57
  15. package/dist/manager/functions/core/actions/api/admin/run-hook.js +0 -95
  16. package/dist/manager/functions/core/actions/api/admin/send-notification.js +0 -197
  17. package/dist/manager/functions/core/actions/api/admin/sync-users.js +0 -125
  18. package/dist/manager/functions/core/actions/api/admin/templates/post.html +0 -16
  19. package/dist/manager/functions/core/actions/api/firebase/get-providers.js +0 -102
  20. package/dist/manager/functions/core/actions/api/general/emails/general:download-app-link.js +0 -21
  21. package/dist/manager/functions/core/actions/api/general/fetch-post.js +0 -99
  22. package/dist/manager/functions/core/actions/api/general/generate-uuid.js +0 -41
  23. package/dist/manager/functions/core/actions/api/general/send-email.js +0 -112
  24. package/dist/manager/functions/core/actions/api/handler/create-post.js +0 -146
  25. package/dist/manager/functions/core/actions/api/special/setup-electron-manager-client.js +0 -103
  26. package/dist/manager/functions/core/actions/api/template.js +0 -33
  27. package/dist/manager/functions/core/actions/api/test/authenticate.js +0 -22
  28. package/dist/manager/functions/core/actions/api/test/create-test-accounts.js +0 -27
  29. package/dist/manager/functions/core/actions/api/test/lab.js +0 -55
  30. package/dist/manager/functions/core/actions/api/test/redirect.js +0 -26
  31. package/dist/manager/functions/core/actions/api/test/webhook.js +0 -30
  32. package/dist/manager/functions/core/actions/api/user/create-custom-token.js +0 -32
  33. package/dist/manager/functions/core/actions/api/user/delete.js +0 -68
  34. package/dist/manager/functions/core/actions/api/user/get-active-sessions.js +0 -45
  35. package/dist/manager/functions/core/actions/api/user/get-subscription-info.js +0 -49
  36. package/dist/manager/functions/core/actions/api/user/oauth2/discord.js +0 -114
  37. package/dist/manager/functions/core/actions/api/user/oauth2/google.js +0 -99
  38. package/dist/manager/functions/core/actions/api/user/oauth2.js +0 -476
  39. package/dist/manager/functions/core/actions/api/user/regenerate-api-keys.js +0 -54
  40. package/dist/manager/functions/core/actions/api/user/resolve.js +0 -32
  41. package/dist/manager/functions/core/actions/api/user/sign-out-all-sessions.js +0 -118
  42. package/dist/manager/functions/core/actions/api/user/sign-up copy.js +0 -544
  43. package/dist/manager/functions/core/actions/api/user/sign-up.js +0 -99
  44. package/dist/manager/functions/core/actions/api/user/submit-feedback.js +0 -96
  45. package/dist/manager/functions/core/actions/api/user/validate-settings.js +0 -86
  46. package/dist/manager/functions/core/actions/api.js +0 -354
  47. package/dist/manager/functions/core/actions/create-post-handler.js +0 -184
  48. package/dist/manager/functions/core/actions/generate-uuid.js +0 -62
  49. package/dist/manager/functions/core/actions/sign-up-handler.js +0 -205
  50. package/dist/manager/functions/core/admin/create-post.js +0 -206
  51. package/dist/manager/functions/core/admin/firestore-write.js +0 -72
  52. package/dist/manager/functions/core/admin/get-stats.js +0 -218
  53. package/dist/manager/functions/core/admin/query.js +0 -198
  54. package/dist/manager/functions/core/admin/send-notification.js +0 -206
  55. package/dist/manager/functions/core/cron/daily/ghostii-auto-publisher.js +0 -377
  56. package/dist/manager/functions/core/cron/daily/reset-usage.js +0 -197
  57. package/dist/manager/functions/core/cron/daily.js +0 -114
  58. package/dist/manager/functions/core/events/auth/before-create.js +0 -124
  59. package/dist/manager/functions/core/events/auth/before-signin.js +0 -62
  60. package/dist/manager/functions/core/events/auth/on-create copy.js +0 -121
  61. package/dist/manager/functions/core/events/auth/on-create.js +0 -564
  62. package/dist/manager/functions/core/events/auth/on-delete.js +0 -72
  63. package/dist/manager/functions/core/events/firestore/on-subscription.js +0 -107
  64. package/dist/manager/functions/test/authenticate.js +0 -38
  65. package/dist/manager/functions/test/create-test-accounts.js +0 -144
  66. package/dist/manager/functions/test/webhook.js +0 -37
  67. package/dist/manager/functions/wrappers/mailchimp/addToList.js +0 -25
  68. package/dist/manager/helpers/analytics copy.js +0 -217
  69. package/dist/manager/helpers/analytics.js +0 -467
  70. package/dist/manager/helpers/api-manager.js +0 -324
  71. package/dist/manager/helpers/assistant.js +0 -1043
  72. package/dist/manager/helpers/metadata.js +0 -32
  73. package/dist/manager/helpers/middleware.js +0 -154
  74. package/dist/manager/helpers/roles.js +0 -69
  75. package/dist/manager/helpers/settings.js +0 -158
  76. package/dist/manager/helpers/subscription-resolver-new.js +0 -828
  77. package/dist/manager/helpers/subscription-resolver.js +0 -842
  78. package/dist/manager/helpers/usage.js +0 -381
  79. package/dist/manager/helpers/user.js +0 -198
  80. package/dist/manager/helpers/utilities.js +0 -292
  81. package/dist/manager/index.js +0 -1076
  82. package/dist/manager/libraries/openai.js +0 -460
  83. package/dist/manager/routes/restart/index.js +0 -52
  84. package/dist/manager/routes/test/index.js +0 -43
  85. package/dist/manager/schemas/restart.js +0 -13
  86. package/dist/manager/schemas/test.js +0 -13
  87. package/dist/require.js +0 -3
@@ -1,842 +0,0 @@
1
- const moment = require('moment');
2
- const { get } = require('lodash');
3
- const { arrayify } = require('node-powertools');
4
-
5
- function SubscriptionResolver(Manager, profile, resource) {
6
- const self = this;
7
-
8
- self.Manager = Manager;
9
- self.profile = profile || {};
10
- self.resource = resource || {};
11
-
12
- return self;
13
- }
14
-
15
- SubscriptionResolver.prototype.resolve = function (options) {
16
- const self = this;
17
-
18
- const datePast = moment(0);
19
-
20
- const resolved = {
21
- status: '',
22
- frequency: '',
23
- resource: {
24
- id: '',
25
- },
26
- payment: {
27
- completed: false,
28
- refunded: false,
29
- },
30
- start: {
31
- timestamp: datePast,
32
- timestampUNIX: datePast,
33
- },
34
- expires: {
35
- timestamp: datePast,
36
- timestampUNIX: datePast,
37
- },
38
- cancelled: {
39
- timestamp: datePast,
40
- timestampUNIX: datePast,
41
- },
42
- lastPayment: {
43
- amount: 0,
44
- date: {
45
- timestamp: datePast,
46
- timestampUNIX: datePast,
47
- }
48
- },
49
- trial: {
50
- claimed: false,
51
- active: false,
52
- daysLeft: 0,
53
- expires: {
54
- timestamp: datePast,
55
- timestampUNIX: datePast,
56
- },
57
- },
58
- details: {
59
- message: '',
60
- }
61
- }
62
-
63
- // Set
64
- const profile = self.profile;
65
- const resource = self.resource;
66
-
67
- // Set defaults
68
- profile.type = profile.type || null;
69
- profile.details = profile.details || {};
70
- profile.details.planFrequency = profile.details.planFrequency || null;
71
- profile.authorization = profile.authorization || {};
72
- profile.authorization.status = profile.authorization.status || 'pending';
73
-
74
- // Set
75
- options = options || {};
76
- options.log = typeof options.log === 'undefined' ? false : options.log;
77
- options.resolveProcessor = typeof options.resolveProcessor === 'undefined' ? false : options.resolveProcessor;
78
- options.resolveType = typeof options.resolveType === 'undefined' ? false : options.resolveType;
79
- options.today = typeof options.today === 'undefined' ? moment() : moment(options.today);
80
- options.message = typeof options.message === 'undefined' ? true : options.message;
81
-
82
- // Set provider if not set
83
- if (!profile.processor) {
84
- /*** PayPal ***/
85
- // Order
86
- if (
87
- resource.purchase_units
88
- ) {
89
- profile.processor = 'paypal';
90
- profile.type = profile.type || 'order';
91
- // Subscription
92
- } else if (
93
- // resource.billing_info
94
- resource.create_time
95
- ) {
96
- profile.processor = 'paypal';
97
- profile.type = profile.type || 'subscription';
98
-
99
- /*** Chargebee ***/
100
- // Order
101
- } else if (
102
- resource.line_items
103
- ) {
104
- profile.processor = 'chargebee';
105
- profile.type = profile.type || 'order';
106
- // Subscription
107
- } else if (
108
- resource.billing_period_unit
109
- ) {
110
- profile.processor = 'chargebee';
111
- profile.type = profile.type || 'subscription';
112
-
113
- /*** Stripe ***/
114
- // Order
115
- } else if (
116
- resource.object === 'charge'
117
- ) {
118
- profile.processor = 'stripe';
119
- profile.type = profile.type || 'order';
120
- // Subscription
121
- } else if (
122
- resource.object === 'subscription'
123
- ) {
124
- profile.processor = 'stripe';
125
- profile.type = profile.type || 'subscription';
126
-
127
- /*** Coinbase ***/
128
- // Order AND Subscription
129
- } else if (
130
- resource.addresses
131
- ) {
132
- profile.processor = 'coinbase';
133
- // profile.type = profile.type || 'subscription';
134
-
135
- /*** Error ***/
136
- } else {
137
- throw new Error('Unable to determine subscription provider');
138
- }
139
- }
140
-
141
- // Set profile.type
142
- if (!profile.type) {
143
- profile.type = profile.type || 'subscription';
144
- }
145
-
146
- // Set processor if needed
147
- if (options.resolveProcessor) {
148
- resolved.processor = profile.processor;
149
- }
150
-
151
- // Set type if needed
152
- if (options.resolveType) {
153
- resolved.type = profile.type;
154
- }
155
-
156
- // Set frequency if order
157
- if (profile.type === 'order') {
158
- resolved.frequency = 'single';
159
- }
160
-
161
- // Log if requested
162
- if (options.log) {
163
- console.log('profile', profile);
164
- console.log('resource', resource);
165
- }
166
-
167
- // Resolve
168
- const processor = self[`resolve_${profile.processor}`];
169
- if (processor) {
170
- processor(profile, resource, resolved, options);
171
- } else {
172
- throw new Error('Unknown processor');
173
- }
174
-
175
- // console.log('---resolved', resolved);
176
-
177
- // Check for frequency
178
- if (!resolved.frequency) {
179
- throw new Error('Unknown frequency');
180
- }
181
-
182
- // Fix expiry by adding time to the date of last payment
183
- // console.log('----expires 2', resolved.resource.id, resolved.status, resolved.frequency, resolved.trial.active, resolved.expires.timestamp.toISOString ? resolved.expires.timestamp.toISOString() : resolved.expires.timestamp);
184
- if (resolved.status === 'active') {
185
- // Set days left
186
- if (resolved.trial.active) {
187
- resolved.trial.daysLeft = Math.abs(resolved.expires.timestamp.diff(options.today, 'days'));
188
- resolved.trial.expires.timestamp = moment(resolved.start.timestamp).add(14, 'days');
189
- }
190
-
191
- // Set expiration
192
- // resolved.expires.timestamp.add(1, 'year').add(30, 'days');
193
- resolved.expires.timestamp.add(1, 'year').add(2, 'months');
194
- } else {
195
- // If trial, it's already set to the trial end above
196
- if (!resolved.trial.active) {
197
- if (resolved.frequency === 'annually') {
198
- resolved.expires.timestamp.add(1, 'year');
199
- } else if (resolved.frequency === 'monthly') {
200
- resolved.expires.timestamp.add(1, 'month');
201
- } else if (resolved.frequency === 'weekly') {
202
- resolved.expires.timestamp.add(1, 'week');
203
- } else if (resolved.frequency === 'daily') {
204
- resolved.expires.timestamp.add(1, 'day');
205
- }
206
- }
207
- }
208
- // console.log('----expires 3', resolved.resource.id, resolved.status, resolved.frequency, resolved.trial.active, resolved.expires.timestamp.toISOString ? resolved.expires.timestamp.toISOString() : resolved.expires.timestamp);
209
-
210
- // If they are not trialing AND there was NEVER any payment sent OR the last payment failed, then set the expiration to 0
211
- if (
212
- !resolved.trial.active
213
- && (!resolved.payment.completed || resolved.lastPayment.amount === 0)
214
- ) {
215
- resolved.expires.timestamp = moment(0);
216
- // resolved.cancelled.timestamp = moment(0);
217
- resolved.details.message = 'Most recent payment failed because there is no working payment method on file.'
218
- }
219
-
220
- // If they are trialing and the authorization charge is failed, set to suspended
221
- if (
222
- resolved.trial.active
223
- && profile.authorization.status === 'failed'
224
- ) {
225
- resolved.status = 'suspended';
226
- resolved.details.message = 'Pre-payment authorization failed because there is no working payment method on file.'
227
- }
228
-
229
- // If they got a refund (AND cancelled), set the expiration to 0
230
- // This allows for partial refunds without disabling the subscription
231
- if (resolved.payment.refunded && resolved.status === 'cancelled') {
232
- resolved.expires.timestamp = moment(0);
233
- resolved.details.message = 'Refund was issued so subscription is inactive.'
234
- }
235
-
236
- // If they are suspended, set the expiration to 0
237
- if (resolved.status === 'suspended') {
238
- resolved.expires.timestamp = moment(0);
239
- }
240
-
241
- // console.log('----expires 4', resolved.resource.id, resolved.status, resolved.frequency, resolved.trial.active, resolved.expires.timestamp.toISOString ? resolved.expires.timestamp.toISOString() : resolved.expires.timestamp);
242
-
243
- // Fix timestamps
244
- resolved.start.timestampUNIX = resolved.start.timestamp.unix();
245
- resolved.start.timestamp = resolved.start.timestamp.toISOString();
246
-
247
- resolved.expires.timestampUNIX = resolved.expires.timestamp.unix();
248
- resolved.expires.timestamp = resolved.expires.timestamp.toISOString ? resolved.expires.timestamp.toISOString() : resolved.expires.timestamp;
249
-
250
- resolved.cancelled.timestampUNIX = resolved.cancelled.timestamp.unix();
251
- resolved.cancelled.timestamp = resolved.cancelled.timestamp.toISOString();
252
-
253
- resolved.trial.expires.timestampUNIX = resolved.trial.expires.timestamp.unix();
254
- resolved.trial.expires.timestamp = resolved.trial.expires.timestamp.toISOString();
255
-
256
- // Fix trial days
257
- resolved.trial.daysLeft = resolved.trial.daysLeft < 0 ? 0 : resolved.trial.daysLeft;
258
-
259
- // Set last payment
260
- resolved.lastPayment.date.timestampUNIX = moment(resolved.lastPayment.date.timestamp).unix();
261
- resolved.lastPayment.date.timestamp = resolved.lastPayment.date.timestamp.toISOString();
262
-
263
- // Log if needed
264
- if (options.log) {
265
- console.log('resolved', resolved);
266
- }
267
-
268
- if (!options.message) {
269
- resolved.details.message = '[REDACTED]';
270
- }
271
-
272
- self.resolved = resolved;
273
- // console.log('----expires 6', resolved.resource.id, resolved.status, resolved.frequency, resolved.trial.active, resolved.expires.timestamp.toISOString ? resolved.expires.timestamp.toISOString() : resolved.expires.timestamp);
274
-
275
- return resolved;
276
- };
277
-
278
- SubscriptionResolver.prototype.resolve_paypal = function (profile, resource, resolved, options) {
279
- const self = this;
280
-
281
- // Set status
282
- /*
283
- subscription: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_get
284
- APPROVAL_PENDING. The subscription is created but not yet approved by the buyer.
285
- APPROVED. The buyer has approved the subscription.
286
- ACTIVE. The subscription is active.
287
- SUSPENDED. The subscription is suspended.
288
- CANCELLED. The subscription is cancelled.
289
- EXPIRED. The subscription is expired.
290
-
291
- order: https://developer.paypal.com/docs/api/orders/v2/#orders_get
292
- CREATED The order was created with the specified context.
293
- SAVED The order was saved and persisted. The order status continues to be in progress until a capture is made with final_capture = true for all purchase units within the order.
294
- APPROVED The customer approved the payment through the PayPal wallet or another form of guest or unbranded payment. For example, a card, bank account, or so on.
295
- VOIDED All purchase units in the order are voided.
296
- COMPLETED The payment was authorized or the authorized payment was captured for the order.
297
- PAYER_ACTION_REQUIRED The order requires an action from the payer (e.g. 3DS authentication). Redirect the payer to the "rel":"payer-action" HATEOAS link returned as part of the response prior to authorizing or capturing the order.
298
- */
299
- if (['ACTIVE'].includes(resource.status)) {
300
- resolved.status = 'active';
301
-
302
- // Check for failed payments
303
- /*
304
- Special condition for PayPal
305
- Because I set the payment_failure_threshold to 0, it will not automatically set the status to suspended.
306
- We must check for failed payments and set the status to suspended if there are any.
307
- */
308
- if (get(resource, 'billing_info.failed_payments_count', 0) > 0) {
309
- resolved.status = 'suspended';
310
- }
311
- } else if (['SUSPENDED'].includes(resource.status)) {
312
- resolved.status = 'suspended';
313
- } else {
314
- resolved.status = 'cancelled';
315
- }
316
-
317
- // Setup preliminary variables
318
- const order = get(resource, 'purchase_units[0].payments.captures[0]');
319
- const subscription = get(resource, 'billing_info.last_payment');
320
- const isOrder = !!order;
321
-
322
- // Set resource ID
323
- resolved.resource.id = resource.id;
324
-
325
- // Set start
326
- resolved.start.timestamp = moment(
327
- (
328
- isOrder
329
- // Order
330
- ? get(resource, 'create_time', 0)
331
-
332
- // Subscription
333
- : get(resource, 'start_time', 0)
334
- )
335
- )
336
-
337
- // Set expiration
338
- resolved.expires.timestamp = moment(
339
- (
340
- isOrder
341
- // Order
342
- ? get(resource, 'create_time', 0)
343
-
344
- // Subscription
345
- : get(resource, 'billing_info.last_payment.time', 0)
346
- )
347
- )
348
-
349
- // Set cancelled
350
- if (resolved.status === 'cancelled') {
351
- resolved.cancelled.timestamp = moment(
352
- (
353
- isOrder
354
- // Order
355
- ? get(resource, 'create_time', 0)
356
-
357
- // Subscription
358
- : get(resource, 'status_update_time', 0)
359
- )
360
- )
361
- }
362
-
363
- // Set last payment
364
- if (order) {
365
- resolved.lastPayment.amount = parseFloat(
366
- get(order, 'amount.value', '0.00')
367
- );
368
- resolved.lastPayment.date.timestamp = moment(
369
- order.create_time || 0
370
- );
371
- } else if (subscription) {
372
- resolved.lastPayment.amount = parseFloat(subscription.amount.value);
373
- resolved.lastPayment.date.timestamp = moment(subscription.time);
374
- }
375
-
376
- // Get trial
377
- const trialTenure = get(resource, 'plan.billing_cycles', []).find((cycle) => cycle.tenure_type === 'TRIAL');
378
- const regularTenure = get(resource, 'plan.billing_cycles', []).find((cycle) => cycle.tenure_type === 'REGULAR');
379
- const trialClaimed = !!trialTenure && parseFloat(get(trialTenure, 'pricing_scheme.fixed_price.value', '0.00')) === 0;
380
-
381
- // Resolve trial
382
- /*
383
- Special condition for PayPal
384
- Because you cannot remove trial on a sub-level, you have to charge a prorated amount for the "trial".
385
- Even if charged, it is still considered a trial period by paypal.
386
- Thus, we must remove the trial indicator if the user has been charged.
387
- */
388
- if (
389
- resolved.status === 'active'
390
- && (trialTenure && regularTenure && regularTenure.total_cycles === 0)
391
- && resolved.lastPayment.amount === 0
392
- ) {
393
- resolved.trial.active = true;
394
-
395
- // Set expiration
396
- resolved.expires.timestamp = moment(
397
- get(resource, 'billing_info.next_billing_time', 0)
398
- )
399
-
400
- /*
401
- Special condition for PayPal #2
402
- I want to put the subscription in a suspended state if it's even one day past due
403
- */
404
- const trialLength = get(trialTenure, 'frequency.interval_count', 0);
405
- const daysSinceStart = Math.abs(moment(options.today).diff(moment(resolved.start.timestamp), 'days'));
406
- if (daysSinceStart > trialLength) {
407
- resolved.status = 'suspended';
408
- resolved.trial.active = false;
409
- }
410
- // console.log('----resolved.resource.id', resolved.resource.id);
411
- // console.log('----resolved.start.timestamp', resolved.start.timestamp);
412
- // console.log('----options.today', options.today);
413
- // console.log('======daysSinceStart', daysSinceStart);
414
- // console.log('======trialLength', trialLength);
415
- }
416
- resolved.trial.claimed = trialClaimed;
417
-
418
- // Resolve frequency
419
- const unit = get(regularTenure, 'frequency.interval_unit');
420
- if (unit === 'YEAR') {
421
- resolved.frequency = 'annually';
422
- } else if (unit === 'MONTH') {
423
- resolved.frequency = 'monthly';
424
- } else if (unit === 'WEEK') {
425
- resolved.frequency = 'weekly';
426
- } else if (unit === 'DAY') {
427
- resolved.frequency = 'daily';
428
- }
429
-
430
- // Set completed
431
- if (resource.plan) {
432
- resolved.payment.completed = !['APPROVAL_PENDING', 'APPROVED'].includes(resource.status);
433
- } else {
434
- resolved.payment.completed = !['CREATED', 'SAVED', 'APPROVED', 'VOIDED', 'PAYER_ACTION_REQUIRED'].includes(resource.status);
435
- }
436
-
437
- // Check if refunded
438
- if (resource.plan) {
439
- const transactions = arrayify(get(resource, 'transactions', []));
440
-
441
- resolved.payment.refunded = transactions.some(t => t.status === 'REFUNDED');
442
- // ALSO PARTIALLY_REFUNDED?
443
- } else {
444
- // resolved.payment.refunded = false; // @@@ TODO: check if this is correct
445
- }
446
-
447
- return resolved;
448
- }
449
-
450
- SubscriptionResolver.prototype.resolve_chargebee = function (profile, resource, resolved, options) {
451
- const self = this;
452
-
453
- // Set status
454
- // subscription: https://apidocs.chargebee.com/docs/api/subscriptions?prod_cat_ver=2#subscription_status
455
- // future The subscription is scheduled to start at a future date.
456
- // in_trial The subscription is in trial.
457
- // active The subscription is active and will be charged for automatically based on the items in it.
458
- // non_renewing The subscription will be canceled at the end of the current term.
459
- // paused The subscription is paused. The subscription will not renew while in this state.
460
- // cancelled The subscription has been canceled and is no longer in service.
461
-
462
- // order: https://apidocs.chargebee.com/docs/api/invoices?prod_cat_ver=2#invoice_status
463
- // paid: Indicates a paid invoice.
464
- // posted: Indicates the payment is not yet collected and will be in this state till the due date to indicate the due period.
465
- // payment_due: Indicates the payment is not yet collected and is being retried as per retry settings.
466
- // not_paid: Indicates the payment is not made and all attempts to collect is failed.
467
- // voided: Indicates a voided invoice.
468
- // pending: The invoice is yet to be closed (sent for payment collection). An invoice is generated with this status when it has line items that belong to items that are metered or when the subscription.create_pending_invoicesattribute is set to true.
469
-
470
- if (['in_trial', 'active'].includes(resource.status)) {
471
- resolved.status = 'active';
472
-
473
- // If there's a due invoice, it's suspended
474
- if (resource.total_dues > 0) {
475
- resolved.status = 'suspended';
476
- }
477
- } else if (['paused'].includes(resource.status)) {
478
- resolved.status = 'suspended';
479
- } else {
480
- resolved.status = 'cancelled';
481
- }
482
-
483
- // Setup preliminary variables
484
- const isOrder = profile.type === 'order';
485
-
486
- // Set resource ID
487
- resolved.resource.id = resource.id;
488
-
489
- // Set start
490
- resolved.start.timestamp = moment(
491
- (
492
- isOrder
493
- // Order
494
- ? get(resource, 'date', 0)
495
-
496
- // Subscription
497
- : get(resource, 'created_at', 0)
498
- ) * 1000
499
- )
500
-
501
- // Set expiration
502
- resolved.expires.timestamp = moment(
503
- (
504
- isOrder
505
- // Order
506
- ? get(resource, 'date', 0)
507
-
508
- // Subscription
509
- : get(resource, 'current_term_start', 0)
510
- ) * 1000
511
- )
512
- // console.log('---resolved.expires 1', resolved.expires);
513
- // if (resource.total_dues > 0) {
514
- // resolved.expires.timestamp = moment(0);
515
- // } else {
516
- // resolved.expires.timestamp = moment(
517
- // (
518
- // get(resource, 'current_term_start', 0)
519
- // ) * 1000
520
- // )
521
- // }
522
-
523
- // Set cancelled
524
- if (resolved.status === 'cancelled') {
525
- resolved.cancelled.timestamp = moment(
526
- (
527
- isOrder
528
- // Order
529
- ? get(resource, 'date', 0)
530
-
531
- // Subscription
532
- : get(resource, 'cancelled_at', 0)
533
- ) * 1000
534
- )
535
- }
536
-
537
- // Set last payment
538
- if (
539
- // Order
540
- resource.amount_due > 0
541
-
542
- // Subscription
543
- || resource.total_dues > 0
544
- ) {
545
- resolved.lastPayment.amount = 0;
546
- resolved.lastPayment.date.timestamp = moment(
547
- (
548
- isOrder
549
- // Order
550
- ? (resource.date || 0)
551
-
552
- // Subscription
553
- : (resource.due_since || 0)
554
- ) * 1000
555
- );
556
- } else {
557
- resolved.lastPayment.amount = (
558
- (
559
- isOrder
560
- // Order
561
- ? (resource.amount_paid)
562
-
563
- // Subscription
564
- : (resource.plan_amount)
565
- ) / 100
566
- )
567
- resolved.lastPayment.date.timestamp = moment(
568
- (
569
- isOrder
570
- // Order
571
- ? (resource.date || 0)
572
-
573
- // Subscription
574
- : (resource.current_term_start || 0)
575
- ) * 1000
576
- );
577
- }
578
-
579
- // Get trial
580
- if (resource.status === 'in_trial') {
581
- resolved.trial.active = true;
582
-
583
- // Set expiration
584
- resolved.expires.timestamp = moment(
585
- (
586
- get(resource, 'trial_end', 0)
587
- ) * 1000
588
- )
589
- }
590
-
591
- // Resolve frequency
592
- const unit = get(resource, 'billing_period_unit');
593
- if (unit === 'year') {
594
- resolved.frequency = 'annually';
595
- } else if (unit === 'month') {
596
- resolved.frequency = 'monthly';
597
- } else if (unit === 'week') {
598
- resolved.frequency = 'weekly';
599
- } else if (unit === 'day') {
600
- resolved.frequency = 'daily';
601
- }
602
-
603
- // Set completed
604
- if (isOrder) {
605
- resolved.payment.completed = !['posted', 'payment_due', 'not_paid', 'voided', 'pending'].includes(resource.status);
606
- } else {
607
- resolved.payment.completed = !['future'].includes(resource.status);
608
- }
609
-
610
- // Check if refunded
611
- if (isOrder) {
612
- resolved.payment.refunded = false; // @@@ TODO: check if this is correct
613
- } else {
614
- const invoices = get(resource, 'invoices', []);
615
-
616
- resolved.payment.refunded = invoices.some(invoice => {
617
- const creditNotes = get(invoice, 'invoice.issued_credit_notes', []);
618
- return creditNotes.some(creditNote => {
619
- return creditNote.cn_status === 'refunded'
620
- })
621
- })
622
- }
623
-
624
- // Special chargebee reset lastPayment
625
- // If trial is active OR if it was cancelled after the trial has ended
626
- const trialStart = get(resource, 'trial_start', 0) * 1000;
627
- const trialEnd = get(resource, 'trial_end', 0) * 1000;
628
- const cancelledAt = get(resource, 'cancelled_at', 0) * 1000;
629
- const trialDaysDifference = Math.abs(moment(trialEnd).diff(moment(trialStart), 'days'));
630
- const trialClaimed = !!trialStart && !!trialEnd && trialDaysDifference > 1;
631
- if (
632
- resolved.trial.active
633
- || (trialEnd > 0 && cancelledAt > 0 && cancelledAt === trialEnd)
634
- ) {
635
- resolved.lastPayment.amount = 0;
636
- resolved.lastPayment.date.timestamp = moment(0);
637
- }
638
- resolved.trial.claimed = trialClaimed;
639
-
640
- return resolved;
641
- }
642
-
643
- SubscriptionResolver.prototype.resolve_stripe = function (profile, resource, resolved, options) {
644
- const self = this;
645
-
646
- // Subscription: https://stripe.com/docs/api/subscriptions/object#subscription_object-status
647
- // incomplete
648
- // incomplete_expired
649
- // trialing
650
- // active
651
- // past_due
652
- // canceled
653
- // unpaid
654
-
655
- // Charge: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-status
656
- // requires_payment_method
657
- // requires_confirmation
658
- // requires_action
659
- // processing
660
- // requires_capture
661
- // canceled
662
- // succeeded
663
- // Set status
664
- if (['trialing', 'active'].includes(resource.status)) {
665
- resolved.status = 'active';
666
- } else if (['past_due', 'unpaid'].includes(resource.status)) {
667
- resolved.status = 'suspended';
668
- } else {
669
- resolved.status = 'cancelled';
670
- }
671
-
672
- // Setup preliminary variables
673
- const order = resource.object === 'charge' ? resource : null;
674
- const subscription = get(resource, 'latest_invoice');
675
- const isOrder = !!order;
676
-
677
- // Set resource ID
678
- resolved.resource.id = resource.id;
679
-
680
- // Set start
681
- resolved.start.timestamp = moment(
682
- (
683
- isOrder
684
- // Order
685
- ? get(resource, 'created', 0)
686
-
687
- // Subscription
688
- : get(resource, 'start_date', 0)
689
- ) * 1000
690
- );
691
-
692
- // Set expiration
693
- resolved.expires.timestamp = moment(
694
- (
695
- isOrder
696
- // Order
697
- ? get(resource, 'created', 0)
698
-
699
- // Subscription
700
- : get(resource, 'current_period_start', 0)
701
- ) * 1000
702
- );
703
-
704
- // Set cancelled
705
- if (resolved.status === 'cancelled') {
706
- resolved.cancelled.timestamp = moment(
707
- (
708
- isOrder
709
- // Order
710
- ? get(resource, 'created', 0)
711
-
712
- // Subscription
713
- : get(resource, 'canceled_at', 0)
714
- ) * 1000
715
- )
716
- }
717
-
718
- // Set last payment
719
- // TODO: check if suspended payments are handled correctly when using resource.latest_invoice.amount_paid
720
- if (order) {
721
- resolved.lastPayment.amount = order.amount_captured / 100;
722
- resolved.lastPayment.date.timestamp = moment(
723
- (order.created || 0) * 1000
724
- );
725
- } else if (subscription) {
726
- resolved.lastPayment.amount = subscription.amount_paid / 100;
727
- resolved.lastPayment.date.timestamp = moment(
728
- (subscription.created || 0) * 1000
729
- );
730
- }
731
-
732
- // Get trial
733
- const trialStart = get(resource, 'trial_start', 0) * 1000;
734
- const trialEnd = get(resource, 'trial_end', 0) * 1000;
735
- const trialDaysDifference = Math.abs(moment(trialEnd).diff(moment(trialStart), 'days'));
736
- const trialClaimed = !!trialStart && !!trialEnd && trialDaysDifference > 1;
737
- if (resource.status === 'trialing') {
738
- resolved.trial.active = true;
739
-
740
- // Set expiration
741
- resolved.expires.timestamp = moment(
742
- (
743
- trialEnd
744
- )
745
- )
746
- }
747
- resolved.trial.claimed = trialClaimed;
748
-
749
- // Resolve frequency
750
- const unit = get(resource, 'plan.interval');
751
- if (unit === 'year') {
752
- resolved.frequency = 'annually';
753
- } else if (unit === 'month') {
754
- resolved.frequency = 'monthly';
755
- } else if (unit === 'week') {
756
- resolved.frequency = 'weekly';
757
- } else if (unit === 'day') {
758
- resolved.frequency = 'daily';
759
- }
760
-
761
- // Set completed
762
- if (resource.object === 'charge') {
763
- resolved.payment.completed = !['requires_payment_method', 'requires_confirmation', 'requires_action', 'processing', 'requires_capture', 'canceled'].includes(resource.status);
764
- } else {
765
- resolved.payment.completed = !['incomplete', 'incomplete_expired'].includes(resource.status);
766
- }
767
-
768
- // Check if refunded
769
- if (resource.object === 'charge') {
770
- resolved.payment.refunded = resource.refunded;
771
- } else {
772
- resolved.payment.refunded = get(resource, 'latest_invoice.charge.refunded', false);
773
- }
774
-
775
- return resolved;
776
- }
777
-
778
- SubscriptionResolver.prototype.resolve_coinbase = function (profile, resource, resolved, options) {
779
- const self = this;
780
-
781
- // Setup preliminary variables
782
- const isOrder = profile.type === 'order';
783
-
784
- // Set status
785
- resolved.status = 'cancelled';
786
-
787
- // Set resource ID
788
- resolved.resource.id = resource.id;
789
-
790
- // Set start
791
- resolved.start.timestamp = moment(
792
- get(resource, 'created_at', 0)
793
- );
794
-
795
- // Set expiration
796
- resolved.expires.timestamp = moment(
797
- get(resource, 'created_at', 0)
798
- );
799
-
800
- // Set cancelled
801
- resolved.cancelled.timestamp = moment(
802
- get(resource, 'created_at', 0)
803
- )
804
-
805
- // Retrieve last payment
806
- // Coinbase at some point changed status from being UPPER to lower case!!! FUCK YOU!
807
- const lastPayment = resource.payments.find(p => p.status.toLowerCase() === 'confirmed');
808
-
809
- // Set last payment
810
- if (lastPayment) {
811
- resolved.lastPayment.amount = parseFloat(lastPayment.value.local.amount);
812
- resolved.lastPayment.date.timestamp = moment(lastPayment.detected_at);
813
- }
814
-
815
- // Get trial
816
- if (true) {
817
- resolved.trial.active = false;
818
- }
819
- resolved.trial.claimed = false;
820
-
821
- // Resolve frequency
822
- const unit = profile.details.planFrequency;
823
- if (unit) {
824
- resolved.frequency = unit;
825
- } else {
826
- resolved.frequency = 'single';
827
- }
828
-
829
- // Set completed
830
- if (true) {
831
- resolved.payment.completed = !!lastPayment;
832
- }
833
-
834
- // Check if refunded
835
- if (true) {
836
- resolved.payment.refunded = false;
837
- }
838
-
839
- return resolved;
840
- }
841
-
842
- module.exports = SubscriptionResolver;