@neocleus/razorpay-firebase-functions 1.0.0
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/README.md +165 -0
- package/lib/admin.d.ts +8 -0
- package/lib/admin.js +155 -0
- package/lib/admin.js.map +1 -0
- package/lib/api.d.ts +4 -0
- package/lib/api.js +203 -0
- package/lib/api.js.map +1 -0
- package/lib/callables/subscriptions.d.ts +9 -0
- package/lib/callables/subscriptions.js +138 -0
- package/lib/callables/subscriptions.js.map +1 -0
- package/lib/handlers/payments.d.ts +4 -0
- package/lib/handlers/payments.js +135 -0
- package/lib/handlers/payments.js.map +1 -0
- package/lib/handlers/subscriptions.d.ts +4 -0
- package/lib/handlers/subscriptions.js +87 -0
- package/lib/handlers/subscriptions.js.map +1 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.js +88 -0
- package/lib/index.js.map +1 -0
- package/lib/logs.d.ts +10 -0
- package/lib/logs.js +36 -0
- package/lib/logs.js.map +1 -0
- package/lib/security.d.ts +1 -0
- package/lib/security.js +14 -0
- package/lib/security.js.map +1 -0
- package/lib/triggers/createCustomer.d.ts +4 -0
- package/lib/triggers/createCustomer.js +79 -0
- package/lib/triggers/createCustomer.js.map +1 -0
- package/lib/triggers/createOrder.d.ts +6 -0
- package/lib/triggers/createOrder.js +173 -0
- package/lib/triggers/createOrder.js.map +1 -0
- package/lib/triggers/createSubscription.d.ts +6 -0
- package/lib/triggers/createSubscription.js +211 -0
- package/lib/triggers/createSubscription.js.map +1 -0
- package/lib/triggers/onUserDeleted.d.ts +5 -0
- package/lib/triggers/onUserDeleted.js +118 -0
- package/lib/triggers/onUserDeleted.js.map +1 -0
- package/lib/triggers/syncClaims.d.ts +5 -0
- package/lib/triggers/syncClaims.js +92 -0
- package/lib/triggers/syncClaims.js.map +1 -0
- package/lib/types.d.ts +43 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/lib/utils/customerMapping.d.ts +9 -0
- package/lib/utils/customerMapping.js +68 -0
- package/lib/utils/customerMapping.js.map +1 -0
- package/lib/utils/ensureCustomer.d.ts +10 -0
- package/lib/utils/ensureCustomer.js +78 -0
- package/lib/utils/ensureCustomer.js.map +1 -0
- package/lib/utils/index.d.ts +15 -0
- package/lib/utils/index.js +75 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/processingLock.d.ts +12 -0
- package/lib/utils/processingLock.js +78 -0
- package/lib/utils/processingLock.js.map +1 -0
- package/lib/utils/retry.d.ts +9 -0
- package/lib/utils/retry.js +53 -0
- package/lib/utils/retry.js.map +1 -0
- package/lib/utils/typedFirestore.d.ts +25 -0
- package/lib/utils/typedFirestore.js +77 -0
- package/lib/utils/typedFirestore.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.buildCreateCustomer = void 0;
|
|
37
|
+
const admin = __importStar(require("firebase-admin"));
|
|
38
|
+
const functions = __importStar(require("firebase-functions"));
|
|
39
|
+
const firestore_1 = require("firebase-admin/firestore");
|
|
40
|
+
const logs_1 = require("../logs");
|
|
41
|
+
const typedFirestore_1 = require("../utils/typedFirestore");
|
|
42
|
+
const buildCreateCustomer = (config, rzp) => {
|
|
43
|
+
return functions.auth.user().onCreate(async (user) => {
|
|
44
|
+
if (!config.syncCustomers) {
|
|
45
|
+
logs_1.logs.info(`Customer sync disabled. Skipping Razorpay customer creation for user: ${user.uid}`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
logs_1.logs.info(`Creating Razorpay customer for new user: ${user.uid}`);
|
|
50
|
+
const customerParams = {
|
|
51
|
+
email: user.email || undefined,
|
|
52
|
+
contact: user.phoneNumber || undefined,
|
|
53
|
+
name: user.displayName || undefined,
|
|
54
|
+
fail_existing: false,
|
|
55
|
+
notes: {
|
|
56
|
+
firebaseUID: user.uid,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
const customer = await rzp.customers.create(customerParams);
|
|
60
|
+
logs_1.logs.info(`Created Razorpay customer ${customer.id} for user ${user.uid}`);
|
|
61
|
+
const typedFs = new typedFirestore_1.TypedFirestore(admin.firestore(), config);
|
|
62
|
+
const customerData = {
|
|
63
|
+
razorpay_customer_id: customer.id,
|
|
64
|
+
email: user.email || null,
|
|
65
|
+
name: user.displayName || null,
|
|
66
|
+
phone: user.phoneNumber || null,
|
|
67
|
+
created_at: firestore_1.FieldValue.serverTimestamp(),
|
|
68
|
+
updated_at: firestore_1.FieldValue.serverTimestamp(),
|
|
69
|
+
};
|
|
70
|
+
await typedFs.getCustomerDoc(user.uid).set(customerData, { merge: true });
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const errMsg = error.message || (typeof error === 'object' ? JSON.stringify(error) : String(error));
|
|
74
|
+
logs_1.logs.error(new Error(`Failed to create Razorpay customer for user ${user.uid}: ${errMsg}`));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
exports.buildCreateCustomer = buildCreateCustomer;
|
|
79
|
+
//# sourceMappingURL=createCustomer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createCustomer.js","sourceRoot":"","sources":["../../src/triggers/createCustomer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAAwC;AACxC,8DAAgD;AAChD,wDAAsD;AAGtD,kCAA+B;AAE/B,4DAAyD;AAElD,MAAM,mBAAmB,GAAG,CAAC,MAA0B,EAAE,GAAa,EAAE,EAAE;IAC7E,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,QAAQ,CACjC,KAAK,EAAE,IAAI,EAAiB,EAAE;QAC1B,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YACxB,WAAI,CAAC,IAAI,CAAC,yEAAyE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/F,OAAO;QACX,CAAC;QAED,IAAI,CAAC;YACD,WAAI,CAAC,IAAI,CAAC,4CAA4C,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAElE,MAAM,cAAc,GAAgD;gBAChE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;gBAC9B,OAAO,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS;gBACtC,IAAI,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS;gBACnC,aAAa,EAAE,KAAK;gBACpB,KAAK,EAAE;oBACH,WAAW,EAAE,IAAI,CAAC,GAAG;iBACxB;aACJ,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAC5D,WAAI,CAAC,IAAI,CAAC,6BAA6B,QAAQ,CAAC,EAAE,aAAa,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAE3E,MAAM,OAAO,GAAG,IAAI,+BAAc,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAgB;gBAC9B,oBAAoB,EAAE,QAAQ,CAAC,EAAE;gBACjC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;gBACzB,IAAI,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;gBAC9B,KAAK,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;gBAC/B,UAAU,EAAE,sBAAU,CAAC,eAAe,EAAE;gBACxC,UAAU,EAAE,sBAAU,CAAC,eAAe,EAAE;aAC3C,CAAC;YAEF,MAAM,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9E,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACpG,WAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;QAChG,CAAC;IACL,CAAC,CACJ,CAAC;AACN,CAAC,CAAC;AA1CW,QAAA,mBAAmB,uBA0C9B"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import Razorpay from 'razorpay';
|
|
2
|
+
import { RazorpaySyncConfig } from '../types';
|
|
3
|
+
export declare const buildCreateOrder: (config: RazorpaySyncConfig, rzp: Razorpay) => import("firebase-functions/v2/core").CloudFunction<import("firebase-functions/v2/firestore").FirestoreEvent<import("firebase-functions/v2/firestore").QueryDocumentSnapshot | undefined, {
|
|
4
|
+
uid: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}>>;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.buildCreateOrder = void 0;
|
|
37
|
+
const firestore_1 = require("firebase-functions/v2/firestore");
|
|
38
|
+
const firestore_2 = require("firebase-admin/firestore");
|
|
39
|
+
const admin = __importStar(require("firebase-admin"));
|
|
40
|
+
const logs_1 = require("../logs");
|
|
41
|
+
const ensureCustomer_1 = require("../utils/ensureCustomer");
|
|
42
|
+
const processingLock_1 = require("../utils/processingLock");
|
|
43
|
+
const typedFirestore_1 = require("../utils/typedFirestore");
|
|
44
|
+
const buildCreateOrder = (config, rzp) => {
|
|
45
|
+
const createOrderHandler = async (event) => {
|
|
46
|
+
logs_1.logs.info('createOrderHandler');
|
|
47
|
+
const snap = event.data;
|
|
48
|
+
if (!snap) {
|
|
49
|
+
logs_1.logs.error(new Error('No data associated with the event'));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const currentData = snap.data();
|
|
53
|
+
if (!currentData)
|
|
54
|
+
return;
|
|
55
|
+
// Guard: This is already processed or paid
|
|
56
|
+
if (currentData.status === 'created' || currentData.status === 'paid') {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Validate productId
|
|
60
|
+
if (!currentData.productId || typeof currentData.productId !== 'string' || currentData.productId.length > 256) {
|
|
61
|
+
await snap.ref.update({
|
|
62
|
+
status: 'failed',
|
|
63
|
+
error: 'Missing or invalid productId. A valid productId string must be provided.',
|
|
64
|
+
});
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const typedFs = new typedFirestore_1.TypedFirestore(admin.firestore(), config);
|
|
68
|
+
const productSnap = await typedFs.getProductDoc(currentData.productId).get();
|
|
69
|
+
if (!productSnap.exists) {
|
|
70
|
+
logs_1.logs.error(new Error(`Product ${currentData.productId} not found.`));
|
|
71
|
+
await snap.ref.update({
|
|
72
|
+
status: 'failed',
|
|
73
|
+
error: 'The selected product is not available.',
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const productData = productSnap.data();
|
|
78
|
+
if (!productData || !productData.active) {
|
|
79
|
+
logs_1.logs.error(new Error(`Product ${currentData.productId} is inactive or invalid.`));
|
|
80
|
+
await snap.ref.update({
|
|
81
|
+
status: 'failed',
|
|
82
|
+
error: 'The selected product is not available.',
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Guard: Verify it's a one-time product
|
|
87
|
+
if (productData.type === 'subscription') {
|
|
88
|
+
logs_1.logs.error(new Error(`Product ${currentData.productId} is a subscription product, but used in checkout_sessions.`));
|
|
89
|
+
await snap.ref.update({
|
|
90
|
+
status: 'failed',
|
|
91
|
+
error: 'The selected product requires a subscription.',
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!productData.amount || productData.amount <= 0) {
|
|
96
|
+
logs_1.logs.error(new Error(`Product ${currentData.productId} has invalid amount: ${productData.amount}`));
|
|
97
|
+
await snap.ref.update({
|
|
98
|
+
status: 'failed',
|
|
99
|
+
error: 'The selected product has an invalid configuration.',
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const orderAmount = productData.amount;
|
|
104
|
+
const orderCurrency = productData.currency || 'INR';
|
|
105
|
+
// Acquire processing lock to prevent race conditions
|
|
106
|
+
const shouldProcess = await (0, processingLock_1.acquireProcessingLock)(snap.ref, (data) => !!(data.status === 'created' || data.status === 'paid'));
|
|
107
|
+
if (!shouldProcess) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// Lazy Customer Creation via shared utility
|
|
111
|
+
let customerId = null;
|
|
112
|
+
try {
|
|
113
|
+
customerId = await (0, ensureCustomer_1.ensureRazorpayCustomer)(event.params.uid, config, rzp);
|
|
114
|
+
}
|
|
115
|
+
catch (customerError) {
|
|
116
|
+
const errMsg = customerError instanceof Error ? customerError.message : (typeof customerError === 'object' ? JSON.stringify(customerError) : String(customerError));
|
|
117
|
+
logs_1.logs.error(new Error(`Failed to dynamically create Razorpay customer: ${errMsg}`));
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const receipt = event.params.id.substring(0, 40);
|
|
121
|
+
let order;
|
|
122
|
+
// Enforce only string key-value pairs for Razorpay notes metadata, filtering out reserved keys and capping to 12
|
|
123
|
+
const RESERVED_NOTE_KEYS = new Set(['uid', 'sessionId', 'productId']);
|
|
124
|
+
const notesMetadata = {};
|
|
125
|
+
let keyCount = 0;
|
|
126
|
+
if (currentData.metadata) {
|
|
127
|
+
for (const [key, value] of Object.entries(currentData.metadata)) {
|
|
128
|
+
if (!RESERVED_NOTE_KEYS.has(key)) {
|
|
129
|
+
if (keyCount >= 12) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
notesMetadata[key] = String(value).substring(0, 512);
|
|
133
|
+
keyCount++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const options = {
|
|
138
|
+
amount: orderAmount,
|
|
139
|
+
currency: orderCurrency,
|
|
140
|
+
receipt,
|
|
141
|
+
notes: {
|
|
142
|
+
...notesMetadata,
|
|
143
|
+
uid: event.params.uid,
|
|
144
|
+
sessionId: event.params.id,
|
|
145
|
+
productId: currentData.productId,
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
if (customerId) {
|
|
149
|
+
options.customer_id = customerId;
|
|
150
|
+
}
|
|
151
|
+
order = await rzp.orders.create(options);
|
|
152
|
+
logs_1.logs.orderCreated(order.id, snap.ref.path);
|
|
153
|
+
// Write the raw order response to a separate subcollection document
|
|
154
|
+
const orderDocRef = typedFs.getCheckoutSessionOrderDoc(event.params.uid, event.params.id);
|
|
155
|
+
await orderDocRef.set(order);
|
|
156
|
+
// Update main document status and timestamps only
|
|
157
|
+
await snap.ref.update({
|
|
158
|
+
status: 'created',
|
|
159
|
+
updated_at: firestore_2.FieldValue.serverTimestamp(),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
logs_1.logs.error(error);
|
|
164
|
+
await snap.ref.update({
|
|
165
|
+
status: 'failed',
|
|
166
|
+
error: 'Failed to create Razorpay Order due to an internal error or validation issue',
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
return (0, firestore_1.onDocumentCreated)(`${config.customersCollection}/{uid}/checkout_sessions/{id}`, createOrderHandler);
|
|
171
|
+
};
|
|
172
|
+
exports.buildCreateOrder = buildCreateOrder;
|
|
173
|
+
//# sourceMappingURL=createOrder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createOrder.js","sourceRoot":"","sources":["../../src/triggers/createOrder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import Razorpay from 'razorpay';
|
|
2
|
+
import { RazorpaySyncConfig } from '../types';
|
|
3
|
+
export declare const buildCreateSubscription: (config: RazorpaySyncConfig, rzp: Razorpay) => import("firebase-functions/v2/core").CloudFunction<import("firebase-functions/v2/firestore").FirestoreEvent<import("firebase-functions/v2/firestore").QueryDocumentSnapshot | undefined, {
|
|
4
|
+
uid: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}>>;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.buildCreateSubscription = void 0;
|
|
37
|
+
const firestore_1 = require("firebase-admin/firestore");
|
|
38
|
+
const firestore_2 = require("firebase-functions/v2/firestore");
|
|
39
|
+
const admin = __importStar(require("firebase-admin"));
|
|
40
|
+
const logs_1 = require("../logs");
|
|
41
|
+
const ensureCustomer_1 = require("../utils/ensureCustomer");
|
|
42
|
+
const processingLock_1 = require("../utils/processingLock");
|
|
43
|
+
const typedFirestore_1 = require("../utils/typedFirestore");
|
|
44
|
+
const buildCreateSubscription = (config, rzp) => {
|
|
45
|
+
const createSubscriptionHandler = async (event) => {
|
|
46
|
+
const snap = event.data;
|
|
47
|
+
if (!snap) {
|
|
48
|
+
logs_1.logs.error(new Error('No data associated with the event'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// If the document ID starts with 'sub_', it's a canonical subscription document
|
|
52
|
+
// created by this trigger, not a draft subscription request. Exit silently.
|
|
53
|
+
if (event.params.id.startsWith('sub_')) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const currentData = snap.data();
|
|
57
|
+
if (!currentData)
|
|
58
|
+
return;
|
|
59
|
+
if (currentData.status === 'created' || currentData.status === 'active') {
|
|
60
|
+
logs_1.logs.info(`Subscription ${event.params.id} for user ${event.params.uid} is already created/active. Skipping trigger.`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const db = admin.firestore();
|
|
64
|
+
const typedFs = new typedFirestore_1.TypedFirestore(db, config);
|
|
65
|
+
// Ensure Razorpay customer exists via shared utility
|
|
66
|
+
let razorpayCustomerId;
|
|
67
|
+
try {
|
|
68
|
+
razorpayCustomerId = await (0, ensureCustomer_1.ensureRazorpayCustomer)(event.params.uid, config, rzp);
|
|
69
|
+
}
|
|
70
|
+
catch (customerError) {
|
|
71
|
+
const errMsg = customerError instanceof Error ? customerError.message : (typeof customerError === 'object' ? JSON.stringify(customerError) : String(customerError));
|
|
72
|
+
logs_1.logs.error(new Error(`Failed to create Razorpay customer for UID ${event.params.uid}: ${errMsg}`));
|
|
73
|
+
await snap.ref.update({
|
|
74
|
+
status: 'failed',
|
|
75
|
+
error: 'Account setup incomplete. Please contact support.',
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!razorpayCustomerId) {
|
|
80
|
+
logs_1.logs.error(new Error(`No linked Razorpay customer ID for UID ${event.params.uid}.`));
|
|
81
|
+
await snap.ref.update({
|
|
82
|
+
status: 'failed',
|
|
83
|
+
error: 'Account setup incomplete. Please contact support.',
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Validate productId (consistent with createOrder.ts)
|
|
88
|
+
if (!currentData.productId || typeof currentData.productId !== 'string' || currentData.productId.length > 256) {
|
|
89
|
+
await snap.ref.update({
|
|
90
|
+
status: 'failed',
|
|
91
|
+
error: 'Missing or invalid productId. A valid productId string must be provided.',
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const productDoc = await typedFs.getProductDoc(currentData.productId).get();
|
|
96
|
+
if (!productDoc.exists) {
|
|
97
|
+
logs_1.logs.error(new Error(`Product ${currentData.productId} not found for UID ${event.params.uid}.`));
|
|
98
|
+
await snap.ref.update({
|
|
99
|
+
status: 'failed',
|
|
100
|
+
error: 'The selected product is not available.',
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const productData = productDoc.data();
|
|
105
|
+
if (!productData || !productData.active) {
|
|
106
|
+
logs_1.logs.error(new Error(`Product ${currentData.productId} is inactive or invalid.`));
|
|
107
|
+
await snap.ref.update({
|
|
108
|
+
status: 'failed',
|
|
109
|
+
error: 'The selected product is not available.',
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// Guard: Verify it's a subscription product
|
|
114
|
+
if (productData.type !== 'subscription') {
|
|
115
|
+
logs_1.logs.error(new Error(`Product ${currentData.productId} is a one-time product, but used in subscriptions.`));
|
|
116
|
+
await snap.ref.update({
|
|
117
|
+
status: 'failed',
|
|
118
|
+
error: 'The selected product is not a subscription.',
|
|
119
|
+
});
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
let planId;
|
|
123
|
+
const allowedPlans = productData.allowedPlans || {};
|
|
124
|
+
const interval = currentData.interval;
|
|
125
|
+
if (interval && allowedPlans[interval]) {
|
|
126
|
+
planId = allowedPlans[interval];
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const planKeys = Object.keys(allowedPlans);
|
|
130
|
+
if (planKeys.length === 1) {
|
|
131
|
+
planId = allowedPlans[planKeys[0]];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!planId) {
|
|
135
|
+
logs_1.logs.error(new Error(`No planId resolved for product '${currentData.productId}' (Interval: ${currentData.interval}).`));
|
|
136
|
+
await snap.ref.update({
|
|
137
|
+
status: 'failed',
|
|
138
|
+
error: 'The selected plan configuration is invalid or missing.',
|
|
139
|
+
});
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// Retrieve total_count config from resolved plan or product level
|
|
143
|
+
let resolvedTotalCount = 12;
|
|
144
|
+
if (productData.plans && interval && productData.plans[interval]) {
|
|
145
|
+
const planDetails = productData.plans[interval];
|
|
146
|
+
resolvedTotalCount = Number(planDetails.notes?.total_count) || Number(productData.plans[interval].notes?.total_count) || 12;
|
|
147
|
+
}
|
|
148
|
+
// Acquire processing lock on the draft to prevent race conditions
|
|
149
|
+
const shouldProcess = await (0, processingLock_1.acquireProcessingLock)(snap.ref, (data) => !!(data.status === 'created' || data.status === 'active'));
|
|
150
|
+
if (!shouldProcess) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
// Enforce only string key-value pairs for Razorpay notes metadata, filtering out reserved keys and capping to 12
|
|
155
|
+
const RESERVED_NOTE_KEYS = new Set(['uid', 'subscriptionId', 'productId']);
|
|
156
|
+
const notesMetadata = {};
|
|
157
|
+
let keyCount = 0;
|
|
158
|
+
if (currentData.metadata) {
|
|
159
|
+
for (const [key, value] of Object.entries(currentData.metadata)) {
|
|
160
|
+
if (!RESERVED_NOTE_KEYS.has(key)) {
|
|
161
|
+
if (keyCount >= 12) {
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
notesMetadata[key] = String(value).substring(0, 512);
|
|
165
|
+
keyCount++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const options = {
|
|
170
|
+
plan_id: planId,
|
|
171
|
+
total_count: Math.min(Math.max(resolvedTotalCount, 1), 2000),
|
|
172
|
+
quantity: 1,
|
|
173
|
+
customer_id: razorpayCustomerId,
|
|
174
|
+
notes: {
|
|
175
|
+
...notesMetadata,
|
|
176
|
+
uid: event.params.uid,
|
|
177
|
+
subscriptionId: event.params.id, // client-draft ID
|
|
178
|
+
productId: currentData.productId,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
const subscription = await rzp.subscriptions.create(options);
|
|
182
|
+
logs_1.logs.subscriptionCreated(subscription.id, snap.ref.path);
|
|
183
|
+
const subscriptionData = {
|
|
184
|
+
productId: currentData.productId,
|
|
185
|
+
interval: currentData.interval,
|
|
186
|
+
metadata: currentData.metadata,
|
|
187
|
+
status: subscription.status,
|
|
188
|
+
draftId: event.params.id,
|
|
189
|
+
created_at: firestore_1.FieldValue.serverTimestamp(),
|
|
190
|
+
};
|
|
191
|
+
// Write to the canonical subscription doc
|
|
192
|
+
const canonicalDocRef = typedFs.getSubscriptionDoc(event.params.uid, subscription.id);
|
|
193
|
+
await canonicalDocRef.set(subscriptionData, { merge: true });
|
|
194
|
+
// Store the raw subscription object in the canonical subcollection
|
|
195
|
+
const detailsDocRef = typedFs.getSubscriptionDetailsDoc(event.params.uid, subscription.id);
|
|
196
|
+
await detailsDocRef.set(subscription);
|
|
197
|
+
// Delete the draft document used to trigger this creation
|
|
198
|
+
await snap.ref.delete();
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
logs_1.logs.error(error);
|
|
202
|
+
await snap.ref.update({
|
|
203
|
+
status: 'failed',
|
|
204
|
+
error: 'Failed to create Razorpay Subscription due to an internal error or validation issue',
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
return (0, firestore_2.onDocumentCreated)(`${config.customersCollection}/{uid}/subscriptions/{id}`, createSubscriptionHandler);
|
|
209
|
+
};
|
|
210
|
+
exports.buildCreateSubscription = buildCreateSubscription;
|
|
211
|
+
//# sourceMappingURL=createSubscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createSubscription.js","sourceRoot":"","sources":["../../src/triggers/createSubscription.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as functions from 'firebase-functions';
|
|
2
|
+
import Razorpay from 'razorpay';
|
|
3
|
+
import { RazorpaySyncConfig } from '../types';
|
|
4
|
+
export declare const buildOnCustomerDataDeleted: (config: RazorpaySyncConfig, rzp: Razorpay) => functions.CloudFunction<functions.firestore.QueryDocumentSnapshot>;
|
|
5
|
+
export declare const buildOnUserDeleted: (config: RazorpaySyncConfig) => functions.CloudFunction<import("firebase-admin/auth").UserRecord>;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.buildOnUserDeleted = exports.buildOnCustomerDataDeleted = void 0;
|
|
37
|
+
const firestore_1 = require("firebase-admin/firestore");
|
|
38
|
+
const functions = __importStar(require("firebase-functions"));
|
|
39
|
+
const admin = __importStar(require("firebase-admin"));
|
|
40
|
+
const logs_1 = require("../logs");
|
|
41
|
+
const typedFirestore_1 = require("../utils/typedFirestore");
|
|
42
|
+
const buildOnCustomerDataDeleted = (config, rzp) => {
|
|
43
|
+
return functions.firestore
|
|
44
|
+
.document(`${config.customersCollection}/{uid}`)
|
|
45
|
+
.onDelete(async (snapshot, context) => {
|
|
46
|
+
const uid = context.params.uid;
|
|
47
|
+
const db = admin.firestore();
|
|
48
|
+
const typedFs = new typedFirestore_1.TypedFirestore(db, config);
|
|
49
|
+
logs_1.logs.info(`Customer document deleted for user ${uid}. Cleaning up...`);
|
|
50
|
+
try {
|
|
51
|
+
const subscriptionsSnap = await typedFs.getSubscriptionsCollection(uid)
|
|
52
|
+
.where('status', 'in', ['active', 'created', 'authenticated'])
|
|
53
|
+
.get();
|
|
54
|
+
const batch = db.batch();
|
|
55
|
+
for (const doc of subscriptionsSnap.docs) {
|
|
56
|
+
const subscriptionId = doc.id;
|
|
57
|
+
if (subscriptionId) {
|
|
58
|
+
try {
|
|
59
|
+
await rzp.subscriptions.cancel(subscriptionId);
|
|
60
|
+
logs_1.logs.info(`Cancelled Razorpay subscription ${subscriptionId} for deleted user ${uid}`);
|
|
61
|
+
batch.update(doc.ref, {
|
|
62
|
+
status: 'cancelled',
|
|
63
|
+
updated_at: firestore_1.FieldValue.serverTimestamp(),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (rpError) {
|
|
67
|
+
logs_1.logs.error(`Failed to cancel Razorpay subscription ${subscriptionId}: ${rpError.message || rpError}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
batch.update(doc.ref, {
|
|
72
|
+
status: 'cancelled',
|
|
73
|
+
updated_at: firestore_1.FieldValue.serverTimestamp(),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!subscriptionsSnap.empty) {
|
|
78
|
+
await batch.commit();
|
|
79
|
+
logs_1.logs.info(`Cancelled ${subscriptionsSnap.size} active subscription(s) for user ${uid}`);
|
|
80
|
+
}
|
|
81
|
+
logs_1.logs.info(`Firestore cleanup complete for user ${uid}`);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
logs_1.logs.error(new Error(`Error cleaning up customer data for user ${uid}: ${error}`));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
exports.buildOnCustomerDataDeleted = buildOnCustomerDataDeleted;
|
|
89
|
+
const buildOnUserDeleted = (config) => {
|
|
90
|
+
return functions.auth.user().onDelete(async (user) => {
|
|
91
|
+
if (!config.syncCustomers) {
|
|
92
|
+
logs_1.logs.info(`Customer sync disabled. Skipping automatic cleanup for user: ${user.uid}`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const db = admin.firestore();
|
|
97
|
+
const typedFs = new typedFirestore_1.TypedFirestore(db, config);
|
|
98
|
+
logs_1.logs.info(`User ${user.uid} deleted from Auth. Initiating Razorpay cleanup.`);
|
|
99
|
+
const customerDoc = await typedFs.getCustomerDoc(user.uid).get();
|
|
100
|
+
if (!customerDoc.exists) {
|
|
101
|
+
logs_1.logs.info(`No customer document found for ${user.uid}. Nothing to clean up.`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const data = customerDoc.data();
|
|
105
|
+
if (!data || !data.razorpay_customer_id) {
|
|
106
|
+
logs_1.logs.info(`No Razorpay Customer ID associated with ${user.uid}. Nothing to clean up.`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
await typedFs.getCustomerDoc(user.uid).delete();
|
|
110
|
+
logs_1.logs.info(`Deleted Firestore customer document for ${user.uid} (this will cascade subscription cancellation).`);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
logs_1.logs.error(new Error(`Failed to process Auth deletion for user ${user.uid}: ${error.message}`));
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
exports.buildOnUserDeleted = buildOnUserDeleted;
|
|
118
|
+
//# sourceMappingURL=onUserDeleted.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onUserDeleted.js","sourceRoot":"","sources":["../../src/triggers/onUserDeleted.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RazorpaySyncConfig } from '../types';
|
|
2
|
+
export declare const buildSyncClaimsOnSubscriptionChange: (config: RazorpaySyncConfig) => import("firebase-functions/v2/core").CloudFunction<import("firebase-functions/v2/firestore").FirestoreEvent<import("firebase-functions/v2/firestore").Change<import("firebase-functions/v2/firestore").DocumentSnapshot> | undefined, {
|
|
3
|
+
uid: string;
|
|
4
|
+
subscriptionId: string;
|
|
5
|
+
}>>;
|