chub-dev 0.1.0 → 0.1.2-beta.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.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1219 @@
1
+ ---
2
+ name: payments
3
+ description: "Razorpay Node.js SDK coding guidelines for building payment systems with orders, payments, refunds, and subscriptions"
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "2.9.6"
7
+ updated-on: "2026-03-02"
8
+ source: maintainer
9
+ tags: "razorpay,payments,india,checkout,upi"
10
+ ---
11
+
12
+ # Razorpay Node.js Coding Guidelines
13
+
14
+ You are a Razorpay payment gateway coding expert. Help me with writing code using the Razorpay Node.js SDK for building payment systems with orders, payments, refunds, subscriptions, customers, and invoices.
15
+
16
+ Please follow the following guidelines when generating code.
17
+
18
+ You can find the official SDK documentation and code samples here:
19
+ https://razorpay.com/docs/payments/server-integration/nodejs/
20
+
21
+ ## Golden Rule: Use the Correct and Current SDK
22
+
23
+ Always use the official Razorpay Node.js SDK, which is the standard library for all Razorpay API interactions.
24
+
25
+ **Library Name:** Razorpay Node.js SDK
26
+ **NPM Package:** `razorpay`
27
+ **Current Version:** 2.9.6
28
+ **Supported Node.js Versions:** Node.js 10+
29
+
30
+ **Installation:**
31
+ - **Correct:** `npm install razorpay` or `yarn add razorpay`
32
+
33
+ **APIs and Usage:**
34
+ - **Correct:** `const Razorpay = require('razorpay')`
35
+ - **Correct:** `const instance = new Razorpay({ key_id: 'YOUR_KEY_ID', key_secret: 'YOUR_KEY_SECRET' })`
36
+ - **Correct:** `instance.orders.create({...})` for creating orders
37
+ - **Correct:** `instance.payments.fetch(paymentId)` for fetching payments
38
+ - **Incorrect:** Using unofficial Razorpay libraries or wrappers
39
+ - **Incorrect:** Exposing credentials in front-end applications
40
+
41
+ ## Authentication and Initialization
42
+
43
+ The Razorpay Node.js library requires your Key ID and Key Secret for authentication. You can obtain these from the Razorpay Dashboard at Settings > API Keys.
44
+
45
+ ### Environment Variables (Recommended)
46
+
47
+ Set up environment variables for secure credential management:
48
+
49
+ ```javascript
50
+ // Load environment variables
51
+ require('dotenv').config();
52
+
53
+ // Initialize Razorpay instance
54
+ const Razorpay = require('razorpay');
55
+
56
+ const instance = new Razorpay({
57
+ key_id: process.env.RAZORPAY_KEY_ID,
58
+ key_secret: process.env.RAZORPAY_KEY_SECRET
59
+ });
60
+ ```
61
+
62
+ ### Direct Initialization
63
+
64
+ ```javascript
65
+ const Razorpay = require('razorpay');
66
+
67
+ const instance = new Razorpay({
68
+ key_id: 'rzp_test_xxxxxxxxxx',
69
+ key_secret: 'your_key_secret_here'
70
+ });
71
+ ```
72
+
73
+ ### Client Configuration Options
74
+
75
+ ```javascript
76
+ const instance = new Razorpay({
77
+ key_id: process.env.RAZORPAY_KEY_ID,
78
+ key_secret: process.env.RAZORPAY_KEY_SECRET,
79
+ headers: {
80
+ 'X-Razorpay-Account': 'acc_xxxxxxxxxxxxx' // Optional: For partner integrations
81
+ }
82
+ });
83
+ ```
84
+
85
+ ## Orders API
86
+
87
+ ### Create Order
88
+
89
+ Create an order before accepting payments from customers:
90
+
91
+ ```javascript
92
+ const Razorpay = require('razorpay');
93
+ const instance = new Razorpay({
94
+ key_id: process.env.RAZORPAY_KEY_ID,
95
+ key_secret: process.env.RAZORPAY_KEY_SECRET
96
+ });
97
+
98
+ async function createOrder() {
99
+ try {
100
+ const options = {
101
+ amount: 50000, // Amount in paise (50000 paise = ₹500)
102
+ currency: "INR",
103
+ receipt: "receipt_order_12345",
104
+ notes: {
105
+ key1: "value1",
106
+ key2: "value2"
107
+ }
108
+ };
109
+
110
+ const order = await instance.orders.create(options);
111
+ console.log('Order ID:', order.id);
112
+ console.log('Order:', order);
113
+ return order;
114
+ } catch (error) {
115
+ console.error('Error creating order:', error);
116
+ throw error;
117
+ }
118
+ }
119
+ ```
120
+
121
+ ### Fetch Order Details
122
+
123
+ ```javascript
124
+ async function fetchOrder(orderId) {
125
+ try {
126
+ const order = await instance.orders.fetch(orderId);
127
+ console.log('Order details:', order);
128
+ return order;
129
+ } catch (error) {
130
+ console.error('Error fetching order:', error);
131
+ throw error;
132
+ }
133
+ }
134
+ ```
135
+
136
+ ### Fetch All Orders
137
+
138
+ ```javascript
139
+ async function fetchAllOrders() {
140
+ try {
141
+ const options = {
142
+ count: 10, // Number of orders to fetch (default: 10, max: 100)
143
+ skip: 0, // Number of orders to skip (for pagination)
144
+ from: 1640995200, // Unix timestamp (fetch orders from this time)
145
+ to: 1672531199 // Unix timestamp (fetch orders till this time)
146
+ };
147
+
148
+ const orders = await instance.orders.all(options);
149
+ console.log('Orders:', orders);
150
+ return orders;
151
+ } catch (error) {
152
+ console.error('Error fetching orders:', error);
153
+ throw error;
154
+ }
155
+ }
156
+ ```
157
+
158
+ ### Fetch Payments for an Order
159
+
160
+ ```javascript
161
+ async function fetchOrderPayments(orderId) {
162
+ try {
163
+ const payments = await instance.orders.fetchPayments(orderId);
164
+ console.log('Payments for order:', payments);
165
+ return payments;
166
+ } catch (error) {
167
+ console.error('Error fetching order payments:', error);
168
+ throw error;
169
+ }
170
+ }
171
+ ```
172
+
173
+ ## Payments API
174
+
175
+ ### Fetch Payment Details
176
+
177
+ ```javascript
178
+ async function fetchPayment(paymentId) {
179
+ try {
180
+ const payment = await instance.payments.fetch(paymentId);
181
+ console.log('Payment details:', payment);
182
+ return payment;
183
+ } catch (error) {
184
+ console.error('Error fetching payment:', error);
185
+ throw error;
186
+ }
187
+ }
188
+ ```
189
+
190
+ ### Fetch All Payments
191
+
192
+ ```javascript
193
+ async function fetchAllPayments() {
194
+ try {
195
+ const options = {
196
+ count: 10,
197
+ skip: 0,
198
+ from: 1640995200,
199
+ to: 1672531199
200
+ };
201
+
202
+ const payments = await instance.payments.all(options);
203
+ console.log('Payments:', payments);
204
+ return payments;
205
+ } catch (error) {
206
+ console.error('Error fetching payments:', error);
207
+ throw error;
208
+ }
209
+ }
210
+ ```
211
+
212
+ ### Capture Payment
213
+
214
+ Capture an authorized payment:
215
+
216
+ ```javascript
217
+ async function capturePayment(paymentId, amount) {
218
+ try {
219
+ const payment = await instance.payments.capture(paymentId, amount, "INR");
220
+ console.log('Payment captured:', payment);
221
+ return payment;
222
+ } catch (error) {
223
+ console.error('Error capturing payment:', error);
224
+ throw error;
225
+ }
226
+ }
227
+ ```
228
+
229
+ ### Update Payment
230
+
231
+ ```javascript
232
+ async function updatePayment(paymentId) {
233
+ try {
234
+ const notes = {
235
+ notes: {
236
+ note_key_1: "updated value 1",
237
+ note_key_2: "updated value 2"
238
+ }
239
+ };
240
+
241
+ const payment = await instance.payments.edit(paymentId, notes);
242
+ console.log('Payment updated:', payment);
243
+ return payment;
244
+ } catch (error) {
245
+ console.error('Error updating payment:', error);
246
+ throw error;
247
+ }
248
+ }
249
+ ```
250
+
251
+ ## Refunds API
252
+
253
+ ### Create Refund
254
+
255
+ ```javascript
256
+ async function createRefund(paymentId) {
257
+ try {
258
+ const options = {
259
+ amount: 10000, // Amount in paise to refund
260
+ speed: "normal", // "normal" or "optimum"
261
+ notes: {
262
+ notes_key_1: "Refund reason"
263
+ },
264
+ receipt: "Receipt No. 31"
265
+ };
266
+
267
+ const refund = await instance.payments.refund(paymentId, options);
268
+ console.log('Refund created:', refund);
269
+ return refund;
270
+ } catch (error) {
271
+ console.error('Error creating refund:', error);
272
+ throw error;
273
+ }
274
+ }
275
+ ```
276
+
277
+ ### Fetch Refund Details
278
+
279
+ ```javascript
280
+ async function fetchRefund(paymentId, refundId) {
281
+ try {
282
+ const refund = await instance.payments.fetchRefund(paymentId, refundId);
283
+ console.log('Refund details:', refund);
284
+ return refund;
285
+ } catch (error) {
286
+ console.error('Error fetching refund:', error);
287
+ throw error;
288
+ }
289
+ }
290
+ ```
291
+
292
+ ### Fetch All Refunds for a Payment
293
+
294
+ ```javascript
295
+ async function fetchPaymentRefunds(paymentId) {
296
+ try {
297
+ const refunds = await instance.payments.fetchMultipleRefund(paymentId);
298
+ console.log('Refunds:', refunds);
299
+ return refunds;
300
+ } catch (error) {
301
+ console.error('Error fetching refunds:', error);
302
+ throw error;
303
+ }
304
+ }
305
+ ```
306
+
307
+ ### Fetch All Refunds
308
+
309
+ ```javascript
310
+ async function fetchAllRefunds() {
311
+ try {
312
+ const options = {
313
+ count: 10,
314
+ skip: 0,
315
+ from: 1640995200,
316
+ to: 1672531199
317
+ };
318
+
319
+ const refunds = await instance.refunds.all(options);
320
+ console.log('All refunds:', refunds);
321
+ return refunds;
322
+ } catch (error) {
323
+ console.error('Error fetching all refunds:', error);
324
+ throw error;
325
+ }
326
+ }
327
+ ```
328
+
329
+ ## Customers API
330
+
331
+ ### Create Customer
332
+
333
+ ```javascript
334
+ async function createCustomer() {
335
+ try {
336
+ const customerData = {
337
+ name: "John Doe",
338
+ email: "john.doe@example.com",
339
+ contact: "+919876543210",
340
+ fail_existing: 0, // 0 to return existing customer if exists, 1 to fail
341
+ notes: {
342
+ customer_type: "premium"
343
+ }
344
+ };
345
+
346
+ const customer = await instance.customers.create(customerData);
347
+ console.log('Customer created:', customer);
348
+ return customer;
349
+ } catch (error) {
350
+ console.error('Error creating customer:', error);
351
+ throw error;
352
+ }
353
+ }
354
+ ```
355
+
356
+ ### Fetch Customer Details
357
+
358
+ ```javascript
359
+ async function fetchCustomer(customerId) {
360
+ try {
361
+ const customer = await instance.customers.fetch(customerId);
362
+ console.log('Customer details:', customer);
363
+ return customer;
364
+ } catch (error) {
365
+ console.error('Error fetching customer:', error);
366
+ throw error;
367
+ }
368
+ }
369
+ ```
370
+
371
+ ### Update Customer
372
+
373
+ ```javascript
374
+ async function updateCustomer(customerId) {
375
+ try {
376
+ const updates = {
377
+ name: "Jane Doe",
378
+ email: "jane.doe@example.com",
379
+ contact: "+919876543211"
380
+ };
381
+
382
+ const customer = await instance.customers.edit(customerId, updates);
383
+ console.log('Customer updated:', customer);
384
+ return customer;
385
+ } catch (error) {
386
+ console.error('Error updating customer:', error);
387
+ throw error;
388
+ }
389
+ }
390
+ ```
391
+
392
+ ### Fetch All Customers
393
+
394
+ ```javascript
395
+ async function fetchAllCustomers() {
396
+ try {
397
+ const options = {
398
+ count: 10,
399
+ skip: 0
400
+ };
401
+
402
+ const customers = await instance.customers.all(options);
403
+ console.log('Customers:', customers);
404
+ return customers;
405
+ } catch (error) {
406
+ console.error('Error fetching customers:', error);
407
+ throw error;
408
+ }
409
+ }
410
+ ```
411
+
412
+ ## Subscriptions API
413
+
414
+ ### Create Subscription
415
+
416
+ ```javascript
417
+ async function createSubscription() {
418
+ try {
419
+ const subscriptionData = {
420
+ plan_id: "plan_xxxxxxxxxxxxx",
421
+ customer_notify: 1,
422
+ quantity: 1,
423
+ total_count: 12,
424
+ start_at: Math.floor(Date.now() / 1000) + 86400, // Start after 1 day
425
+ addons: [
426
+ {
427
+ item: {
428
+ name: "Extra Storage",
429
+ amount: 5000,
430
+ currency: "INR"
431
+ }
432
+ }
433
+ ],
434
+ notes: {
435
+ subscription_type: "premium"
436
+ }
437
+ };
438
+
439
+ const subscription = await instance.subscriptions.create(subscriptionData);
440
+ console.log('Subscription created:', subscription);
441
+ return subscription;
442
+ } catch (error) {
443
+ console.error('Error creating subscription:', error);
444
+ throw error;
445
+ }
446
+ }
447
+ ```
448
+
449
+ ### Fetch Subscription Details
450
+
451
+ ```javascript
452
+ async function fetchSubscription(subscriptionId) {
453
+ try {
454
+ const subscription = await instance.subscriptions.fetch(subscriptionId);
455
+ console.log('Subscription details:', subscription);
456
+ return subscription;
457
+ } catch (error) {
458
+ console.error('Error fetching subscription:', error);
459
+ throw error;
460
+ }
461
+ }
462
+ ```
463
+
464
+ ### Cancel Subscription
465
+
466
+ ```javascript
467
+ async function cancelSubscription(subscriptionId) {
468
+ try {
469
+ const options = {
470
+ cancel_at_cycle_end: 0 // 0 to cancel immediately, 1 to cancel at end of cycle
471
+ };
472
+
473
+ const subscription = await instance.subscriptions.cancel(subscriptionId, options);
474
+ console.log('Subscription cancelled:', subscription);
475
+ return subscription;
476
+ } catch (error) {
477
+ console.error('Error cancelling subscription:', error);
478
+ throw error;
479
+ }
480
+ }
481
+ ```
482
+
483
+ ### Fetch All Subscriptions
484
+
485
+ ```javascript
486
+ async function fetchAllSubscriptions() {
487
+ try {
488
+ const options = {
489
+ count: 10,
490
+ skip: 0
491
+ };
492
+
493
+ const subscriptions = await instance.subscriptions.all(options);
494
+ console.log('Subscriptions:', subscriptions);
495
+ return subscriptions;
496
+ } catch (error) {
497
+ console.error('Error fetching subscriptions:', error);
498
+ throw error;
499
+ }
500
+ }
501
+ ```
502
+
503
+ ## Plans API
504
+
505
+ ### Create Plan
506
+
507
+ ```javascript
508
+ async function createPlan() {
509
+ try {
510
+ const planData = {
511
+ period: "monthly",
512
+ interval: 1,
513
+ item: {
514
+ name: "Premium Plan",
515
+ amount: 99900, // Amount in paise
516
+ currency: "INR",
517
+ description: "Premium monthly subscription"
518
+ },
519
+ notes: {
520
+ plan_type: "premium"
521
+ }
522
+ };
523
+
524
+ const plan = await instance.plans.create(planData);
525
+ console.log('Plan created:', plan);
526
+ return plan;
527
+ } catch (error) {
528
+ console.error('Error creating plan:', error);
529
+ throw error;
530
+ }
531
+ }
532
+ ```
533
+
534
+ ### Fetch Plan Details
535
+
536
+ ```javascript
537
+ async function fetchPlan(planId) {
538
+ try {
539
+ const plan = await instance.plans.fetch(planId);
540
+ console.log('Plan details:', plan);
541
+ return plan;
542
+ } catch (error) {
543
+ console.error('Error fetching plan:', error);
544
+ throw error;
545
+ }
546
+ }
547
+ ```
548
+
549
+ ### Fetch All Plans
550
+
551
+ ```javascript
552
+ async function fetchAllPlans() {
553
+ try {
554
+ const options = {
555
+ count: 10,
556
+ skip: 0
557
+ };
558
+
559
+ const plans = await instance.plans.all(options);
560
+ console.log('Plans:', plans);
561
+ return plans;
562
+ } catch (error) {
563
+ console.error('Error fetching plans:', error);
564
+ throw error;
565
+ }
566
+ }
567
+ ```
568
+
569
+ ## Invoices API
570
+
571
+ ### Create Invoice
572
+
573
+ ```javascript
574
+ async function createInvoice() {
575
+ try {
576
+ const invoiceData = {
577
+ type: "invoice",
578
+ description: "Invoice for the month of January 2025",
579
+ customer: {
580
+ name: "John Doe",
581
+ email: "john.doe@example.com",
582
+ contact: "+919876543210"
583
+ },
584
+ line_items: [
585
+ {
586
+ name: "Premium Subscription",
587
+ description: "Monthly subscription",
588
+ amount: 99900,
589
+ currency: "INR",
590
+ quantity: 1
591
+ }
592
+ ],
593
+ currency: "INR",
594
+ email_notify: 1,
595
+ sms_notify: 1,
596
+ date: Math.floor(Date.now() / 1000)
597
+ };
598
+
599
+ const invoice = await instance.invoices.create(invoiceData);
600
+ console.log('Invoice created:', invoice);
601
+ return invoice;
602
+ } catch (error) {
603
+ console.error('Error creating invoice:', error);
604
+ throw error;
605
+ }
606
+ }
607
+ ```
608
+
609
+ ### Fetch Invoice Details
610
+
611
+ ```javascript
612
+ async function fetchInvoice(invoiceId) {
613
+ try {
614
+ const invoice = await instance.invoices.fetch(invoiceId);
615
+ console.log('Invoice details:', invoice);
616
+ return invoice;
617
+ } catch (error) {
618
+ console.error('Error fetching invoice:', error);
619
+ throw error;
620
+ }
621
+ }
622
+ ```
623
+
624
+ ### Fetch All Invoices
625
+
626
+ ```javascript
627
+ async function fetchAllInvoices() {
628
+ try {
629
+ const options = {
630
+ count: 10,
631
+ skip: 0
632
+ };
633
+
634
+ const invoices = await instance.invoices.all(options);
635
+ console.log('Invoices:', invoices);
636
+ return invoices;
637
+ } catch (error) {
638
+ console.error('Error fetching invoices:', error);
639
+ throw error;
640
+ }
641
+ }
642
+ ```
643
+
644
+ ### Cancel Invoice
645
+
646
+ ```javascript
647
+ async function cancelInvoice(invoiceId) {
648
+ try {
649
+ const invoice = await instance.invoices.cancel(invoiceId);
650
+ console.log('Invoice cancelled:', invoice);
651
+ return invoice;
652
+ } catch (error) {
653
+ console.error('Error cancelling invoice:', error);
654
+ throw error;
655
+ }
656
+ }
657
+ ```
658
+
659
+ ## Payment Verification
660
+
661
+ ### Verify Payment Signature
662
+
663
+ Verify payment signatures to ensure payment authenticity:
664
+
665
+ ```javascript
666
+ const crypto = require('crypto');
667
+ const { validatePaymentVerification } = require('razorpay/dist/utils/razorpay-utils');
668
+
669
+ // Method 1: Using Razorpay's built-in utility
670
+ function verifyPaymentSignature(orderId, paymentId, signature) {
671
+ try {
672
+ const isValid = validatePaymentVerification(
673
+ { order_id: orderId, payment_id: paymentId },
674
+ signature,
675
+ process.env.RAZORPAY_KEY_SECRET
676
+ );
677
+
678
+ if (isValid) {
679
+ console.log('Payment signature verified successfully');
680
+ return true;
681
+ } else {
682
+ console.log('Invalid payment signature');
683
+ return false;
684
+ }
685
+ } catch (error) {
686
+ console.error('Error verifying payment signature:', error);
687
+ return false;
688
+ }
689
+ }
690
+
691
+ // Method 2: Manual verification
692
+ function verifyPaymentSignatureManual(orderId, paymentId, signature) {
693
+ try {
694
+ const generatedSignature = crypto
695
+ .createHmac('sha256', process.env.RAZORPAY_KEY_SECRET)
696
+ .update(`${orderId}|${paymentId}`)
697
+ .digest('hex');
698
+
699
+ const isValid = generatedSignature === signature;
700
+
701
+ if (isValid) {
702
+ console.log('Payment signature verified successfully');
703
+ return true;
704
+ } else {
705
+ console.log('Invalid payment signature');
706
+ return false;
707
+ }
708
+ } catch (error) {
709
+ console.error('Error verifying payment signature:', error);
710
+ return false;
711
+ }
712
+ }
713
+ ```
714
+
715
+ ## Webhook Handling and Validation
716
+
717
+ ### Express.js Webhook Integration
718
+
719
+ Handle and validate incoming Razorpay webhooks:
720
+
721
+ ```javascript
722
+ const express = require('express');
723
+ const crypto = require('crypto');
724
+ const { validateWebhookSignature } = require('razorpay/dist/utils/razorpay-utils');
725
+
726
+ const app = express();
727
+
728
+ // IMPORTANT: Use express.text() to get raw body for webhook signature validation
729
+ app.use(express.json({
730
+ verify: (req, res, buf) => {
731
+ req.rawBody = buf.toString();
732
+ }
733
+ }));
734
+
735
+ // Webhook validation middleware
736
+ function validateWebhook(req, res, next) {
737
+ const signature = req.headers['x-razorpay-signature'];
738
+ const webhookSecret = process.env.RAZORPAY_WEBHOOK_SECRET;
739
+
740
+ try {
741
+ const isValid = validateWebhookSignature(
742
+ req.rawBody,
743
+ signature,
744
+ webhookSecret
745
+ );
746
+
747
+ if (!isValid) {
748
+ return res.status(400).json({ error: 'Invalid signature' });
749
+ }
750
+
751
+ next();
752
+ } catch (error) {
753
+ console.error('Webhook validation error:', error);
754
+ return res.status(400).json({ error: 'Webhook validation failed' });
755
+ }
756
+ }
757
+
758
+ // Webhook endpoint
759
+ app.post('/webhook', validateWebhook, (req, res) => {
760
+ const event = req.body;
761
+
762
+ console.log('Webhook event:', event.event);
763
+
764
+ switch (event.event) {
765
+ case 'payment.authorized':
766
+ handlePaymentAuthorized(event.payload.payment.entity);
767
+ break;
768
+
769
+ case 'payment.captured':
770
+ handlePaymentCaptured(event.payload.payment.entity);
771
+ break;
772
+
773
+ case 'payment.failed':
774
+ handlePaymentFailed(event.payload.payment.entity);
775
+ break;
776
+
777
+ case 'order.paid':
778
+ handleOrderPaid(event.payload.order.entity);
779
+ break;
780
+
781
+ case 'refund.created':
782
+ handleRefundCreated(event.payload.refund.entity);
783
+ break;
784
+
785
+ case 'subscription.activated':
786
+ handleSubscriptionActivated(event.payload.subscription.entity);
787
+ break;
788
+
789
+ case 'subscription.cancelled':
790
+ handleSubscriptionCancelled(event.payload.subscription.entity);
791
+ break;
792
+
793
+ case 'invoice.paid':
794
+ handleInvoicePaid(event.payload.invoice.entity);
795
+ break;
796
+
797
+ default:
798
+ console.log('Unhandled event:', event.event);
799
+ }
800
+
801
+ res.json({ status: 'ok' });
802
+ });
803
+
804
+ function handlePaymentAuthorized(payment) {
805
+ console.log('Payment authorized:', payment.id);
806
+ // Capture the payment or perform other actions
807
+ }
808
+
809
+ function handlePaymentCaptured(payment) {
810
+ console.log('Payment captured:', payment.id);
811
+ // Update order status, send confirmation email, etc.
812
+ }
813
+
814
+ function handlePaymentFailed(payment) {
815
+ console.log('Payment failed:', payment.id);
816
+ // Notify customer, update order status, etc.
817
+ }
818
+
819
+ function handleOrderPaid(order) {
820
+ console.log('Order paid:', order.id);
821
+ // Process order fulfillment
822
+ }
823
+
824
+ function handleRefundCreated(refund) {
825
+ console.log('Refund created:', refund.id);
826
+ // Update records, notify customer
827
+ }
828
+
829
+ function handleSubscriptionActivated(subscription) {
830
+ console.log('Subscription activated:', subscription.id);
831
+ // Grant access to subscription features
832
+ }
833
+
834
+ function handleSubscriptionCancelled(subscription) {
835
+ console.log('Subscription cancelled:', subscription.id);
836
+ // Revoke access, send cancellation email
837
+ }
838
+
839
+ function handleInvoicePaid(invoice) {
840
+ console.log('Invoice paid:', invoice.id);
841
+ // Update invoice status, send receipt
842
+ }
843
+
844
+ app.listen(3000, () => {
845
+ console.log('Webhook server listening on port 3000');
846
+ });
847
+ ```
848
+
849
+ ### Manual Webhook Signature Validation
850
+
851
+ ```javascript
852
+ const crypto = require('crypto');
853
+
854
+ function validateWebhookManual(webhookBody, signature, secret) {
855
+ try {
856
+ const generatedSignature = crypto
857
+ .createHmac('sha256', secret)
858
+ .update(webhookBody)
859
+ .digest('hex');
860
+
861
+ return generatedSignature === signature;
862
+ } catch (error) {
863
+ console.error('Error validating webhook:', error);
864
+ return false;
865
+ }
866
+ }
867
+
868
+ // Usage
869
+ app.post('/webhook', (req, res) => {
870
+ const signature = req.headers['x-razorpay-signature'];
871
+ const isValid = validateWebhookManual(
872
+ req.rawBody,
873
+ signature,
874
+ process.env.RAZORPAY_WEBHOOK_SECRET
875
+ );
876
+
877
+ if (!isValid) {
878
+ return res.status(400).json({ error: 'Invalid signature' });
879
+ }
880
+
881
+ // Process webhook event
882
+ res.json({ status: 'ok' });
883
+ });
884
+ ```
885
+
886
+ ## Transfers API (Route)
887
+
888
+ ### Create Transfer
889
+
890
+ Transfer funds to linked accounts:
891
+
892
+ ```javascript
893
+ async function createTransfer(paymentId) {
894
+ try {
895
+ const transferData = {
896
+ transfers: [
897
+ {
898
+ account: "acc_xxxxxxxxxxxxx",
899
+ amount: 10000, // Amount in paise
900
+ currency: "INR",
901
+ notes: {
902
+ name: "Transfer to vendor",
903
+ roll_no: "IEC2011025"
904
+ },
905
+ linked_account_notes: ["branch"],
906
+ on_hold: 0, // 0 to transfer immediately, 1 to hold
907
+ on_hold_until: null
908
+ }
909
+ ]
910
+ };
911
+
912
+ const transfer = await instance.payments.transfer(paymentId, transferData);
913
+ console.log('Transfer created:', transfer);
914
+ return transfer;
915
+ } catch (error) {
916
+ console.error('Error creating transfer:', error);
917
+ throw error;
918
+ }
919
+ }
920
+ ```
921
+
922
+ ### Fetch Transfer Details
923
+
924
+ ```javascript
925
+ async function fetchTransfer(transferId) {
926
+ try {
927
+ const transfer = await instance.transfers.fetch(transferId);
928
+ console.log('Transfer details:', transfer);
929
+ return transfer;
930
+ } catch (error) {
931
+ console.error('Error fetching transfer:', error);
932
+ throw error;
933
+ }
934
+ }
935
+ ```
936
+
937
+ ## Virtual Accounts API
938
+
939
+ ### Create Virtual Account
940
+
941
+ ```javascript
942
+ async function createVirtualAccount() {
943
+ try {
944
+ const vaData = {
945
+ receivers: {
946
+ types: ["bank_account"]
947
+ },
948
+ description: "Virtual Account for customer XYZ",
949
+ customer_id: "cust_xxxxxxxxxxxxx",
950
+ close_by: Math.floor(Date.now() / 1000) + 86400 * 30, // Close after 30 days
951
+ notes: {
952
+ purpose: "Rent collection"
953
+ }
954
+ };
955
+
956
+ const virtualAccount = await instance.virtualAccounts.create(vaData);
957
+ console.log('Virtual Account created:', virtualAccount);
958
+ return virtualAccount;
959
+ } catch (error) {
960
+ console.error('Error creating virtual account:', error);
961
+ throw error;
962
+ }
963
+ }
964
+ ```
965
+
966
+ ### Fetch Virtual Account Details
967
+
968
+ ```javascript
969
+ async function fetchVirtualAccount(vaId) {
970
+ try {
971
+ const virtualAccount = await instance.virtualAccounts.fetch(vaId);
972
+ console.log('Virtual Account details:', virtualAccount);
973
+ return virtualAccount;
974
+ } catch (error) {
975
+ console.error('Error fetching virtual account:', error);
976
+ throw error;
977
+ }
978
+ }
979
+ ```
980
+
981
+ ## Error Handling
982
+
983
+ ### Comprehensive Error Handling
984
+
985
+ ```javascript
986
+ async function safeApiCall() {
987
+ try {
988
+ const order = await instance.orders.create({
989
+ amount: 50000,
990
+ currency: "INR",
991
+ receipt: "receipt_12345"
992
+ });
993
+
994
+ return {
995
+ success: true,
996
+ data: order
997
+ };
998
+ } catch (error) {
999
+ console.error('Razorpay API Error:', {
1000
+ statusCode: error.statusCode,
1001
+ error: error.error,
1002
+ description: error.error?.description,
1003
+ field: error.error?.field,
1004
+ reason: error.error?.reason
1005
+ });
1006
+
1007
+ return {
1008
+ success: false,
1009
+ error: {
1010
+ code: error.statusCode,
1011
+ message: error.error?.description || 'An error occurred',
1012
+ field: error.error?.field
1013
+ }
1014
+ };
1015
+ }
1016
+ }
1017
+ ```
1018
+
1019
+ ### Common Error Codes
1020
+
1021
+ Handle specific error scenarios:
1022
+
1023
+ ```javascript
1024
+ async function handleErrors() {
1025
+ try {
1026
+ const payment = await instance.payments.fetch('pay_xxxxxxxxxxxxx');
1027
+ return payment;
1028
+ } catch (error) {
1029
+ switch (error.statusCode) {
1030
+ case 400:
1031
+ console.error('Bad Request - Invalid parameters');
1032
+ break;
1033
+ case 401:
1034
+ console.error('Unauthorized - Invalid API credentials');
1035
+ break;
1036
+ case 404:
1037
+ console.error('Not Found - Resource does not exist');
1038
+ break;
1039
+ case 500:
1040
+ console.error('Internal Server Error - Razorpay issue');
1041
+ break;
1042
+ default:
1043
+ console.error('Unknown error:', error);
1044
+ }
1045
+ throw error;
1046
+ }
1047
+ }
1048
+ ```
1049
+
1050
+ ## Complete Payment Flow Example
1051
+
1052
+ ### Server-Side Integration
1053
+
1054
+ ```javascript
1055
+ const express = require('express');
1056
+ const Razorpay = require('razorpay');
1057
+ const crypto = require('crypto');
1058
+ const { validatePaymentVerification } = require('razorpay/dist/utils/razorpay-utils');
1059
+
1060
+ const app = express();
1061
+ app.use(express.json());
1062
+
1063
+ const instance = new Razorpay({
1064
+ key_id: process.env.RAZORPAY_KEY_ID,
1065
+ key_secret: process.env.RAZORPAY_KEY_SECRET
1066
+ });
1067
+
1068
+ // Step 1: Create order
1069
+ app.post('/create-order', async (req, res) => {
1070
+ try {
1071
+ const { amount, currency, receipt } = req.body;
1072
+
1073
+ const options = {
1074
+ amount: amount * 100, // Convert to paise
1075
+ currency: currency || 'INR',
1076
+ receipt: receipt || `receipt_${Date.now()}`,
1077
+ notes: {
1078
+ description: 'Order payment'
1079
+ }
1080
+ };
1081
+
1082
+ const order = await instance.orders.create(options);
1083
+
1084
+ res.json({
1085
+ success: true,
1086
+ order: {
1087
+ id: order.id,
1088
+ amount: order.amount,
1089
+ currency: order.currency
1090
+ },
1091
+ key_id: process.env.RAZORPAY_KEY_ID
1092
+ });
1093
+ } catch (error) {
1094
+ console.error('Error creating order:', error);
1095
+ res.status(500).json({
1096
+ success: false,
1097
+ message: 'Failed to create order'
1098
+ });
1099
+ }
1100
+ });
1101
+
1102
+ // Step 2: Verify payment
1103
+ app.post('/verify-payment', async (req, res) => {
1104
+ try {
1105
+ const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = req.body;
1106
+
1107
+ const isValid = validatePaymentVerification(
1108
+ { order_id: razorpay_order_id, payment_id: razorpay_payment_id },
1109
+ razorpay_signature,
1110
+ process.env.RAZORPAY_KEY_SECRET
1111
+ );
1112
+
1113
+ if (isValid) {
1114
+ // Payment is successful, update database
1115
+ const payment = await instance.payments.fetch(razorpay_payment_id);
1116
+
1117
+ res.json({
1118
+ success: true,
1119
+ message: 'Payment verified successfully',
1120
+ payment: {
1121
+ id: payment.id,
1122
+ amount: payment.amount,
1123
+ status: payment.status
1124
+ }
1125
+ });
1126
+ } else {
1127
+ res.status(400).json({
1128
+ success: false,
1129
+ message: 'Payment verification failed'
1130
+ });
1131
+ }
1132
+ } catch (error) {
1133
+ console.error('Error verifying payment:', error);
1134
+ res.status(500).json({
1135
+ success: false,
1136
+ message: 'Payment verification error'
1137
+ });
1138
+ }
1139
+ });
1140
+
1141
+ // Step 3: Fetch payment details
1142
+ app.get('/payment/:id', async (req, res) => {
1143
+ try {
1144
+ const payment = await instance.payments.fetch(req.params.id);
1145
+ res.json({
1146
+ success: true,
1147
+ payment
1148
+ });
1149
+ } catch (error) {
1150
+ console.error('Error fetching payment:', error);
1151
+ res.status(500).json({
1152
+ success: false,
1153
+ message: 'Failed to fetch payment'
1154
+ });
1155
+ }
1156
+ });
1157
+
1158
+ app.listen(3000, () => {
1159
+ console.log('Server running on port 3000');
1160
+ });
1161
+ ```
1162
+
1163
+ ## Security Best Practices
1164
+
1165
+ ### Never Expose Credentials
1166
+
1167
+ ```javascript
1168
+ // Good - Use environment variables
1169
+ const instance = new Razorpay({
1170
+ key_id: process.env.RAZORPAY_KEY_ID,
1171
+ key_secret: process.env.RAZORPAY_KEY_SECRET
1172
+ });
1173
+
1174
+ // Bad - Hardcoded credentials
1175
+ const instance = new Razorpay({
1176
+ key_id: 'rzp_test_xxxxxxxxxxxx',
1177
+ key_secret: 'your_secret_here'
1178
+ });
1179
+ ```
1180
+
1181
+ ### Always Validate Webhooks
1182
+
1183
+ ```javascript
1184
+ // Always verify webhook signatures before processing
1185
+ const isValid = validateWebhookSignature(
1186
+ req.rawBody,
1187
+ req.headers['x-razorpay-signature'],
1188
+ process.env.RAZORPAY_WEBHOOK_SECRET
1189
+ );
1190
+
1191
+ if (!isValid) {
1192
+ return res.status(400).json({ error: 'Invalid signature' });
1193
+ }
1194
+ ```
1195
+
1196
+ ### Verify Payment Signatures
1197
+
1198
+ ```javascript
1199
+ // Always verify payment signatures on the server
1200
+ const isValid = validatePaymentVerification(
1201
+ { order_id: orderId, payment_id: paymentId },
1202
+ signature,
1203
+ process.env.RAZORPAY_KEY_SECRET
1204
+ );
1205
+ ```
1206
+
1207
+ ## Useful Links
1208
+
1209
+ - **Documentation:** https://razorpay.com/docs/
1210
+ - **API Reference:** https://razorpay.com/docs/api/
1211
+ - **Node.js SDK Docs:** https://razorpay.com/docs/payments/server-integration/nodejs/
1212
+ - **NPM Package:** https://www.npmjs.com/package/razorpay
1213
+ - **GitHub Repository:** https://github.com/razorpay/razorpay-node
1214
+ - **Dashboard:** https://dashboard.razorpay.com/
1215
+ - **Support:** https://razorpay.com/support/
1216
+
1217
+ ## Notes
1218
+
1219
+ This guide covers the core functionality of the Razorpay Node.js SDK. The SDK provides a promise-based API for all Razorpay services including payments, orders, refunds, subscriptions, customers, invoices, transfers, and virtual accounts. Always use environment variables for credentials and validate all payment signatures and webhook signatures to ensure security.