@raba7ni/raba7ni 1.0.2 → 1.0.4

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 CHANGED
@@ -1,6 +1,10 @@
1
1
  # @raba7ni/raba7ni
2
2
 
3
- Official TypeScript SDK for the Raba7ni Coffee Loyalty Platform Developer API.
3
+ Official TypeScript SDK for the Raba7ni Loyalty Platform Developer API.
4
+
5
+ [![npm version](https://badge.fury.io/js/%40raba7ni%2Fraba7ni.svg)](https://www.npmjs.com/package/@raba7ni/raba7ni)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
7
+ [![Node.js](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
4
8
 
5
9
  ## Installation
6
10
 
@@ -14,42 +18,412 @@ npm install @raba7ni/raba7ni
14
18
  import { Raba7niSDK } from '@raba7ni/raba7ni';
15
19
 
16
20
  const sdk = new Raba7niSDK({
17
- appId: 'app_abc123def456789...',
18
- apiKey: 'dev_xyz789uvw456...',
19
- baseUrl: 'https://your-domain.com' // optional, defaults to production
21
+ appId: 'app_your_app_id',
22
+ apiKey: 'dev_your_api_key'
23
+ // baseUrl defaults to 'https://api.raba7ni.com'
20
24
  });
21
25
 
26
+ // Test connection
27
+ const scopes = await sdk.testConnection();
28
+ console.log('Connected! Scopes:', scopes.scopes);
29
+
22
30
  // Validate a member
23
31
  const result = await sdk.validateMember(5, '+1234567890');
24
- console.log(result.is_member); // true/false
32
+ console.log('Is member:', result.is_member);
33
+ ```
34
+
35
+ ### Local Development
36
+
37
+ For local testing, specify your development server:
38
+
39
+ ```typescript
40
+ const sdk = new Raba7niSDK({
41
+ appId: 'app_your_app_id',
42
+ apiKey: 'dev_your_api_key',
43
+ baseUrl: 'http://localhost:8000' // Only for local testing
44
+ });
45
+ ```
46
+
47
+ ## Configuration
48
+
49
+ ```typescript
50
+ const sdk = new Raba7niSDK({
51
+ appId: 'app_...', // Required: Application ID
52
+ apiKey: 'dev_...', // Required: API Key
53
+ baseUrl: 'https://...', // Optional: defaults to 'https://api.raba7ni.com'
54
+ locale: 'en', // Optional: Locale (default: 'en')
55
+ timeout: 30000, // Optional: Request timeout ms (default: 30000)
56
+ maxRetries: 3, // Optional: Max retry attempts (default: 3)
57
+ retryDelay: 1000 // Optional: Initial retry delay ms (default: 1000)
58
+ });
59
+ ```
60
+
61
+ ---
62
+
63
+ ## API Reference
64
+
65
+ ### Connection & Scopes
66
+
67
+ #### `testConnection()`
68
+ Test API connection and get available scopes.
69
+
70
+ ```typescript
71
+ const result = await sdk.testConnection();
72
+ // { scopes: ['members:read', 'members:write', ...], application: { id, name } }
73
+ ```
74
+
75
+ #### `getWebhookEvents()`
76
+ Get list of available webhook events.
77
+
78
+ ```typescript
79
+ const events = await sdk.getWebhookEvents();
80
+ ```
81
+
82
+ ---
83
+
84
+ ### Member APIs
85
+
86
+ #### `validateMember(cardId, phoneNumber, options?)`
87
+ Check if a phone number is a registered member.
88
+
89
+ ```typescript
90
+ const result = await sdk.validateMember(5, '+1234567890', {
91
+ include_member_data: true
92
+ });
93
+
94
+ if (result.is_member) {
95
+ console.log('Member:', result.member);
96
+ }
97
+ ```
98
+
99
+ #### `getMemberDetails(cardId, phoneNumber)`
100
+ Get detailed member information.
101
+
102
+ ```typescript
103
+ const details = await sdk.getMemberDetails(5, '+1234567890');
104
+ console.log('Points:', details.card_relationship.points);
105
+ ```
106
+
107
+ #### `requestMemberOTP(email, cardId)`
108
+ Request OTP for new member registration.
109
+
110
+ ```typescript
111
+ const otp = await sdk.requestMemberOTP('john@example.com', 5);
112
+
113
+ if (otp.member_exists) {
114
+ console.log('Member already registered');
115
+ } else {
116
+ console.log('OTP sent, expires at:', otp.expires_at);
117
+ }
118
+ ```
119
+
120
+ #### `findOrCreateMember(request)`
121
+ Find existing member or create new one. Optionally create order and award points.
122
+
123
+ ```typescript
124
+ // Basic usage - find or create member
125
+ const result = await sdk.findOrCreateMember({
126
+ card_id: 5,
127
+ name: 'John Doe',
128
+ email: 'john@example.com',
129
+ phone_number: '+1234567890',
130
+ verification_code: '123456' // Required for NEW members only
131
+ });
25
132
 
26
- // Find or create a member with points
27
- const member = await sdk.findOrCreateMember({
133
+ // With order and points
134
+ const result = await sdk.findOrCreateMember({
28
135
  card_id: 5,
29
136
  name: 'John Doe',
30
137
  email: 'john@example.com',
31
138
  phone_number: '+1234567890',
139
+ create_order: true,
32
140
  order: {
33
141
  award_points: true,
34
- total_amount: 50.00
142
+ total_amount: 50.00,
143
+ items: [
144
+ { name: 'Coffee', amount: 15.00 },
145
+ { name: 'Sandwich', amount: 35.00 }
146
+ ]
35
147
  }
36
148
  });
149
+
150
+ console.log('Is new member:', result.is_new);
151
+ console.log('Points awarded:', result.transaction?.points);
152
+ ```
153
+
154
+ ---
155
+
156
+ ### Card APIs
157
+
158
+ #### `listCards()`
159
+ Get all loyalty cards accessible by your API key.
160
+
161
+ ```typescript
162
+ const { cards, total } = await sdk.listCards();
163
+ cards.forEach(card => console.log(card.name));
37
164
  ```
38
165
 
39
- ## Features
166
+ #### `getCardInfo(cardId)`
167
+ Get details about a specific card.
168
+
169
+ ```typescript
170
+ const card = await sdk.getCardInfo(5);
171
+ console.log('Points per currency:', card.points_per_currency);
172
+ ```
173
+
174
+ #### `listCardRewards(cardId)`
175
+ Get available rewards for a card.
176
+
177
+ ```typescript
178
+ const { rewards } = await sdk.listCardRewards(5);
179
+ rewards.forEach(reward => {
180
+ console.log(`${reward.name}: ${reward.points} points`);
181
+ });
182
+ ```
183
+
184
+ ---
185
+
186
+ ### Claim Request APIs
187
+
188
+ #### `listClaimRequests(cardId, status?)`
189
+ Get claim requests for a card.
190
+
191
+ ```typescript
192
+ // All claims
193
+ const { claim_requests } = await sdk.listClaimRequests(5);
194
+
195
+ // Filtered by status
196
+ const pending = await sdk.listClaimRequests(5, 'pending');
197
+ ```
198
+
199
+ #### `requestClaimOTP(memberEmail, cardId, rewardId?)`
200
+ Request OTP for claiming a reward.
201
+
202
+ ```typescript
203
+ const otp = await sdk.requestClaimOTP('john@example.com', 5, 10);
204
+ console.log('Claim OTP expires:', otp.expires_at);
205
+ ```
206
+
207
+ #### `createClaimRequest(request)`
208
+ Create a new reward claim request.
209
+
210
+ ```typescript
211
+ const { claim_request } = await sdk.createClaimRequest({
212
+ member_email: 'john@example.com',
213
+ card_id: 5,
214
+ reward_id: 10,
215
+ verification_code: '123456',
216
+ member_note: 'Please deliver to office'
217
+ });
218
+
219
+ console.log('Claim ID:', claim_request.id);
220
+ console.log('Status:', claim_request.status); // 'pending'
221
+ ```
222
+
223
+ #### `getClaimRequest(requestId)`
224
+ Get claim request details.
225
+
226
+ ```typescript
227
+ const { claim_request } = await sdk.getClaimRequest(123);
228
+ ```
229
+
230
+ #### `approveClaimRequest(requestId, staffNote?)`
231
+ Approve a pending claim request.
232
+
233
+ ```typescript
234
+ const { claim_request } = await sdk.approveClaimRequest(123, 'Approved!');
235
+ ```
236
+
237
+ #### `rejectClaimRequest(requestId, staffNote?)`
238
+ Reject a pending claim request.
239
+
240
+ ```typescript
241
+ const { claim_request } = await sdk.rejectClaimRequest(123, 'Out of stock');
242
+ ```
243
+
244
+ ---
245
+
246
+ ### Referral APIs
247
+
248
+ #### `getReferralStats(cardId)`
249
+ Get referral statistics for a card.
250
+
251
+ ```typescript
252
+ const stats = await sdk.getReferralStats(5);
253
+ console.log('Total referrals:', stats.total_referrals);
254
+ console.log('Successful:', stats.successful_referrals);
255
+ ```
256
+
257
+ #### `listReferrers(cardId)`
258
+ Get top referrers for a card.
259
+
260
+ ```typescript
261
+ const { referrers } = await sdk.listReferrers(5);
262
+ referrers.forEach(r => {
263
+ console.log(`${r.member_name}: ${r.referral_count} referrals`);
264
+ });
265
+ ```
266
+
267
+ #### `listReferrerReferrals(cardId, memberId)`
268
+ Get all referrals made by a specific member.
269
+
270
+ ```typescript
271
+ const { referrals } = await sdk.listReferrerReferrals(5, 100);
272
+ ```
273
+
274
+ #### `validateReferralCode(referralCode, cardId)`
275
+ Check if a referral code is valid.
276
+
277
+ ```typescript
278
+ const result = await sdk.validateReferralCode('REF123ABC', 5);
279
+ if (result.is_valid) {
280
+ console.log('Referred by:', result.referrer?.name);
281
+ }
282
+ ```
283
+
284
+ #### `applyReferral(referralCode, cardId, refereeEmail)`
285
+ Apply a referral code to a new member.
286
+
287
+ ```typescript
288
+ const { referral } = await sdk.applyReferral('REF123ABC', 5, 'newbie@example.com');
289
+ ```
290
+
291
+ ---
292
+
293
+ ## Webhook Handling
294
+
295
+ ### Verifying Webhooks
296
+
297
+ ```typescript
298
+ import { WebhookHandler } from '@raba7ni/raba7ni';
299
+
300
+ const handler = new WebhookHandler('your_webhook_secret');
301
+
302
+ // Express example
303
+ app.post('/webhooks', (req, res) => {
304
+ const signature = req.headers['x-webhook-signature'];
305
+ const payload = JSON.stringify(req.body);
306
+
307
+ handler.handleWebhook(payload, signature, {
308
+ onMemberJoined: async (data) => {
309
+ console.log('New member:', data.member.name);
310
+ },
311
+ onMemberLeft: async (data) => {
312
+ console.log('Member left:', data.member.name);
313
+ },
314
+ onClaimRequestCreated: async (data) => {
315
+ console.log('New claim:', data.claim_request.id);
316
+ },
317
+ onClaimRequestProcessed: async (data) => {
318
+ console.log('Claim processed:', data.status);
319
+ },
320
+ onUnknownEvent: async (event, data) => {
321
+ console.log('Unknown event:', event);
322
+ }
323
+ });
324
+
325
+ res.status(200).send('OK');
326
+ });
327
+ ```
328
+
329
+ ### Manual Verification
330
+
331
+ ```typescript
332
+ import { verifyWebhookSignature, parseWebhookPayload } from '@raba7ni/raba7ni';
333
+
334
+ const isValid = verifyWebhookSignature(payload, signature, secret);
335
+ if (isValid) {
336
+ const webhook = parseWebhookPayload(payload);
337
+ console.log('Event:', webhook.event);
338
+ }
339
+ ```
340
+
341
+ ---
342
+
343
+ ## Error Handling
344
+
345
+ ```typescript
346
+ import {
347
+ Raba7niError,
348
+ AuthenticationError,
349
+ RateLimitError,
350
+ ValidationError
351
+ } from '@raba7ni/raba7ni';
352
+
353
+ try {
354
+ await sdk.validateMember(5, '+123');
355
+ } catch (error) {
356
+ if (error instanceof AuthenticationError) {
357
+ console.error('Invalid credentials');
358
+ } else if (error instanceof RateLimitError) {
359
+ console.error('Rate limited, retry after:', error.retryAfter);
360
+ } else if (error instanceof ValidationError) {
361
+ console.error('Validation errors:', error.validationErrors);
362
+ } else if (error instanceof Raba7niError) {
363
+ console.error('API error:', error.message, error.code);
364
+ }
365
+ }
366
+ ```
367
+
368
+ ---
369
+
370
+ ## Rate Limiting
371
+
372
+ The SDK tracks rate limits automatically:
373
+
374
+ ```typescript
375
+ const info = sdk.getRateLimitInfo();
376
+ console.log('Hourly remaining:', info.hourlyRemaining);
377
+ console.log('Daily remaining:', info.dailyRemaining);
378
+ ```
379
+
380
+ ---
381
+
382
+ ## Utilities
383
+
384
+ ```typescript
385
+ import {
386
+ normalizePhoneNumber,
387
+ validateEmail,
388
+ validateCardId
389
+ } from '@raba7ni/raba7ni';
390
+
391
+ // Normalize phone numbers
392
+ normalizePhoneNumber('+1 (555) 123-4567'); // '+15551234567'
393
+
394
+ // Validate email format
395
+ validateEmail('test@example.com'); // true
396
+
397
+ // Validate card ID
398
+ validateCardId('5'); // 5 (number)
399
+ ```
400
+
401
+ ---
402
+
403
+ ## TypeScript Types
404
+
405
+ All types are exported for full TypeScript support:
406
+
407
+ ```typescript
408
+ import type {
409
+ Member,
410
+ Card,
411
+ Reward,
412
+ ClaimRequest,
413
+ Order,
414
+ Transaction,
415
+ WebhookPayload,
416
+ ClaimRequestCreatedWebhookData,
417
+ ClaimRequestProcessedWebhookData
418
+ } from '@raba7ni/raba7ni';
419
+ ```
40
420
 
41
- - ✅ Full TypeScript support with comprehensive types
42
- - ✅ Automatic authentication handling
43
- - ✅ Rate limiting with automatic retry logic
44
- - ✅ Comprehensive error handling
45
- - ✅ Input validation
46
- - ✅ Webhook signature verification utilities
47
- - ✅ Node.js 18+ support
48
- - ✅ ES modules and CommonJS compatibility
421
+ ---
49
422
 
50
- ## Documentation
423
+ ## Requirements
51
424
 
52
- For complete API documentation, see the [Developer API Documentation](https://docs.raba7ni.com/developer-api).
425
+ - Node.js 18+
426
+ - TypeScript 5.0+ (for TypeScript users)
53
427
 
54
428
  ## License
55
429