backend-manager 5.0.146 → 5.0.147
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/package.json
CHANGED
|
@@ -19,13 +19,13 @@ const fetch = require('wonderful-fetch');
|
|
|
19
19
|
* Track payment events across analytics platforms (non-blocking)
|
|
20
20
|
* Fires GA4, Meta, and TikTok independently with per-platform payloads
|
|
21
21
|
*/
|
|
22
|
-
function trackPayment({ category, transitionName, eventType, unified, uid, processor, assistant }) {
|
|
22
|
+
function trackPayment({ category, transitionName, eventType, unified, order, uid, processor, assistant }) {
|
|
23
23
|
const Manager = assistant.Manager;
|
|
24
24
|
const config = Manager.config;
|
|
25
25
|
|
|
26
26
|
try {
|
|
27
27
|
// Resolve what kind of payment event this is
|
|
28
|
-
const resolved = resolvePaymentEvent(category, transitionName, eventType, unified);
|
|
28
|
+
const resolved = resolvePaymentEvent(category, transitionName, eventType, unified, order);
|
|
29
29
|
|
|
30
30
|
if (!resolved) {
|
|
31
31
|
assistant.log(`trackPayment: skipped — no trackable event (category=${category}, transition=${transitionName || 'null'}, eventType=${eventType})`);
|
|
@@ -53,13 +53,16 @@ function trackPayment({ category, transitionName, eventType, unified, uid, proce
|
|
|
53
53
|
* Determine what kind of payment event occurred and extract common fields
|
|
54
54
|
* Returns null if nothing should be tracked
|
|
55
55
|
*/
|
|
56
|
-
function resolvePaymentEvent(category, transitionName, eventType, unified) {
|
|
56
|
+
function resolvePaymentEvent(category, transitionName, eventType, unified, order) {
|
|
57
57
|
const productId = unified.product?.id;
|
|
58
58
|
const productName = unified.product?.name;
|
|
59
59
|
const frequency = unified.payment?.frequency || null;
|
|
60
60
|
const isTrial = unified.trial?.claimed === true;
|
|
61
61
|
const resourceId = unified.payment?.resourceId;
|
|
62
|
-
const price = unified.payment?.price || 0;
|
|
62
|
+
const price = parseFloat(unified.payment?.price || 0);
|
|
63
|
+
|
|
64
|
+
// Compute actual amount paid (accounting for trial and discount)
|
|
65
|
+
const value = resolveActualValue(price, isTrial, order?.discount);
|
|
63
66
|
|
|
64
67
|
const base = { productId, productName, frequency, resourceId, isTrial };
|
|
65
68
|
|
|
@@ -70,7 +73,7 @@ function resolvePaymentEvent(category, transitionName, eventType, unified) {
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
if (transitionName === 'new-subscription') {
|
|
73
|
-
return { ...base, reason: 'first-purchase', value
|
|
76
|
+
return { ...base, reason: 'first-purchase', value, isRecurring: false };
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
if (transitionName === 'payment-recovered') {
|
|
@@ -78,6 +81,7 @@ function resolvePaymentEvent(category, transitionName, eventType, unified) {
|
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
// No transition but a payment event fired (renewal)
|
|
84
|
+
// Renewals always use full price (discount is one-time only)
|
|
81
85
|
if (!transitionName && isPaymentEvent(eventType) && price > 0) {
|
|
82
86
|
return { ...base, reason: 'renewal', value: price, isRecurring: true };
|
|
83
87
|
}
|
|
@@ -88,7 +92,7 @@ function resolvePaymentEvent(category, transitionName, eventType, unified) {
|
|
|
88
92
|
// --- One-time transitions ---
|
|
89
93
|
if (category === 'one-time') {
|
|
90
94
|
if (transitionName === 'purchase-completed') {
|
|
91
|
-
return { ...base, reason: 'one-time-purchase', value
|
|
95
|
+
return { ...base, reason: 'one-time-purchase', value, isRecurring: false, productId: productId || 'unknown', productName: productName || 'Unknown' };
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
return null;
|
|
@@ -97,6 +101,22 @@ function resolvePaymentEvent(category, transitionName, eventType, unified) {
|
|
|
97
101
|
return null;
|
|
98
102
|
}
|
|
99
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Compute the actual amount paid, accounting for trial and promo discount
|
|
106
|
+
* Trial = $0, discount = price - savings, otherwise full price
|
|
107
|
+
*/
|
|
108
|
+
function resolveActualValue(price, isTrial, discount) {
|
|
109
|
+
if (isTrial) {
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (discount?.valid === true && discount?.percent > 0) {
|
|
114
|
+
return parseFloat((price - (price * discount.percent / 100)).toFixed(2));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return price;
|
|
118
|
+
}
|
|
119
|
+
|
|
100
120
|
/**
|
|
101
121
|
* Check if a webhook event type represents a payment being made
|
|
102
122
|
*/
|
|
@@ -281,7 +281,7 @@ async function processPaymentEvent({ category, library, resource, resourceType,
|
|
|
281
281
|
// Track payment analytics (non-blocking)
|
|
282
282
|
// Fires independently of transitions — renewals have no transition but still need tracking
|
|
283
283
|
if (shouldRunHandlers) {
|
|
284
|
-
trackPayment({ category, transitionName, eventType, unified, uid, processor, assistant });
|
|
284
|
+
trackPayment({ category, transitionName, eventType, unified, order, uid, processor, assistant });
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
// Write unified subscription to user doc (subscriptions only)
|
package/src/manager/events/firestore/payments-webhooks/transitions/subscription/new-subscription.js
CHANGED
|
@@ -36,6 +36,10 @@ module.exports = async function ({ before, after, order, uid, userDoc, assistant
|
|
|
36
36
|
promoPercent: discount.percent,
|
|
37
37
|
promoSavings: (price * discount.percent / 100).toFixed(2),
|
|
38
38
|
}),
|
|
39
|
+
// Amount charged on the first real payment (after trial if applicable)
|
|
40
|
+
firstChargeAmount: hasPromoDiscount
|
|
41
|
+
? (price - (price * discount.percent / 100)).toFixed(2)
|
|
42
|
+
: price.toFixed(2),
|
|
39
43
|
totalToday: isTrial
|
|
40
44
|
? '0.00'
|
|
41
45
|
: hasPromoDiscount
|