@galva-io/galva-admin-node 1.0.0-dev → 1.0.1-dev
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 +70 -159
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Galva Admin Node SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Node.js SDK for syncing billing events and managing end users with Galva.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,211 +8,122 @@ TypeScript SDK for integrating with Galva Admin API. This SDK provides a type-sa
|
|
|
8
8
|
npm install galva-admin-node
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
**Peer dependencies** (install as needed):
|
|
12
|
+
```bash
|
|
13
|
+
npm install @paddle/paddle-node-sdk # For Paddle
|
|
14
|
+
npm install googleapis # For Play Store
|
|
15
|
+
```
|
|
16
|
+
|
|
11
17
|
## Quick Start
|
|
12
18
|
|
|
13
19
|
```typescript
|
|
14
|
-
import
|
|
20
|
+
import { Galva } from 'galva-admin-node';
|
|
15
21
|
|
|
16
|
-
const galva =
|
|
17
|
-
|
|
18
|
-
baseUrl: 'https://api.galva.io', // optional
|
|
19
|
-
debug: true // optional, enables logging
|
|
20
|
-
});
|
|
22
|
+
const galva = new Galva({ apiKey: 'your-api-key' });
|
|
23
|
+
// Or set GALVA_API_KEY environment variable
|
|
21
24
|
```
|
|
22
25
|
|
|
23
|
-
##
|
|
26
|
+
## Billing Events
|
|
24
27
|
|
|
25
|
-
###
|
|
28
|
+
### With Pre-verified Payloads
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
await galva.trackPurchase({
|
|
29
|
-
id: 'evt_123',
|
|
30
|
-
endUserId: 'user_456',
|
|
31
|
-
appIdentifier: 'com.example.app',
|
|
32
|
-
productIdentifier: 'premium_monthly',
|
|
33
|
-
planIdentifier: 'monthly',
|
|
34
|
-
platform: 'ios',
|
|
35
|
-
eventTimestamp: new Date().toISOString(),
|
|
36
|
-
purchasedAt: new Date().toISOString(),
|
|
37
|
-
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
38
|
-
isTrial: false
|
|
39
|
-
});
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Track a Renewal
|
|
30
|
+
Use when you've already decoded/verified payloads yourself.
|
|
43
31
|
|
|
44
32
|
```typescript
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
planIdentifier: 'monthly',
|
|
51
|
-
platform: 'ios',
|
|
52
|
-
eventTimestamp: new Date().toISOString(),
|
|
53
|
-
purchasedAt: new Date().toISOString(),
|
|
54
|
-
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()
|
|
33
|
+
// App Store
|
|
34
|
+
await galva.billingEvent.appstore('user-123', {
|
|
35
|
+
signedPayload: '...',
|
|
36
|
+
bundleId: 'com.example.app',
|
|
37
|
+
appAppleId: 123456789,
|
|
55
38
|
});
|
|
56
|
-
```
|
|
57
39
|
|
|
58
|
-
|
|
40
|
+
// Play Store (decoded notification)
|
|
41
|
+
await galva.billingEvent.playstore('user-123', decodedNotification);
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
await galva.
|
|
62
|
-
id: 'evt_125',
|
|
63
|
-
endUserId: 'user_456',
|
|
64
|
-
appIdentifier: 'com.example.app',
|
|
65
|
-
productIdentifier: 'premium_monthly',
|
|
66
|
-
planIdentifier: 'monthly',
|
|
67
|
-
platform: 'ios',
|
|
68
|
-
eventTimestamp: new Date().toISOString(),
|
|
69
|
-
cancelReason: 'too_expensive',
|
|
70
|
-
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
|
|
71
|
-
});
|
|
43
|
+
// Paddle (verified event)
|
|
44
|
+
await galva.billingEvent.paddle('user-123', verifiedEvent);
|
|
72
45
|
```
|
|
73
46
|
|
|
74
|
-
###
|
|
47
|
+
### With Credentials (Auto-verification)
|
|
48
|
+
|
|
49
|
+
Use `withCredentials()` to let the SDK handle decoding and verification.
|
|
75
50
|
|
|
76
51
|
```typescript
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
52
|
+
const galvaWithCreds = galva.withCredentials({
|
|
53
|
+
appstore: {
|
|
54
|
+
bundleId: 'com.example.app',
|
|
55
|
+
appAppleId: 123456789,
|
|
56
|
+
},
|
|
57
|
+
playstore: {
|
|
58
|
+
email: 'service-account@project.iam.gserviceaccount.com',
|
|
59
|
+
key: '-----BEGIN PRIVATE KEY-----\n...',
|
|
60
|
+
},
|
|
61
|
+
paddle: {
|
|
62
|
+
apiKey: 'pdl_...',
|
|
63
|
+
secretKey: 'whsec_...',
|
|
64
|
+
},
|
|
86
65
|
});
|
|
87
|
-
```
|
|
88
66
|
|
|
89
|
-
|
|
67
|
+
// App Store (signed payload only)
|
|
68
|
+
await galvaWithCreds.billingEvent.appstore('user-123', signedPayload);
|
|
90
69
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
id: 'evt_126',
|
|
95
|
-
type: 'initial-purchase' as const,
|
|
96
|
-
endUserId: 'user_789',
|
|
97
|
-
appIdentifier: 'com.example.app',
|
|
98
|
-
productIdentifier: 'premium_yearly',
|
|
99
|
-
planIdentifier: 'yearly',
|
|
100
|
-
platform: 'android' as const,
|
|
101
|
-
eventTimestamp: new Date().toISOString(),
|
|
102
|
-
purchasedAt: new Date().toISOString(),
|
|
103
|
-
expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString()
|
|
104
|
-
},
|
|
105
|
-
// ... more events
|
|
106
|
-
];
|
|
70
|
+
// Play Store (base64 from Pub/Sub - auto-decodes and fetches subscription)
|
|
71
|
+
await galvaWithCreds.billingEvent.playstore('user-123', base64Payload);
|
|
107
72
|
|
|
108
|
-
|
|
73
|
+
// Paddle (raw body + signature - auto-verifies)
|
|
74
|
+
await galvaWithCreds.billingEvent.paddle('user-123', rawBody, signature);
|
|
109
75
|
```
|
|
110
76
|
|
|
111
|
-
|
|
77
|
+
## End User Management
|
|
112
78
|
|
|
113
79
|
```typescript
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
eventTimestamp: new Date().toISOString(),
|
|
124
|
-
purchasedAt: new Date().toISOString()
|
|
125
|
-
}, {
|
|
126
|
-
maxBatchSize: 50, // Flush after 50 events
|
|
127
|
-
flushInterval: 10000 // Flush every 10 seconds
|
|
80
|
+
import { EndUserDefaultTraitName } from 'galva-admin-node';
|
|
81
|
+
|
|
82
|
+
// Identify with traits
|
|
83
|
+
await galva.endUser.identify('user-123', {
|
|
84
|
+
traits: {
|
|
85
|
+
[EndUserDefaultTraitName.EMAIL]: 'user@example.com',
|
|
86
|
+
[EndUserDefaultTraitName.FULL_NAME]: 'John Doe',
|
|
87
|
+
customTrait: 'value',
|
|
88
|
+
},
|
|
128
89
|
});
|
|
129
90
|
|
|
130
|
-
//
|
|
131
|
-
await galva.
|
|
91
|
+
// Update default profile info
|
|
92
|
+
await galva.endUser.updateDefaultInfo('user-123', {
|
|
93
|
+
email: 'user@example.com',
|
|
94
|
+
fullName: 'John Doe',
|
|
95
|
+
country: 'US',
|
|
96
|
+
});
|
|
132
97
|
```
|
|
133
98
|
|
|
134
|
-
##
|
|
135
|
-
|
|
136
|
-
### Configuration
|
|
99
|
+
## Configuration
|
|
137
100
|
|
|
138
101
|
```typescript
|
|
139
|
-
interface
|
|
140
|
-
apiKey
|
|
141
|
-
|
|
142
|
-
timeout?: number;
|
|
143
|
-
debug?: boolean; // Optional: Enable debug logging (default: false)
|
|
102
|
+
interface GalvaOptions {
|
|
103
|
+
apiKey?: string; // Falls back to GALVA_API_KEY env
|
|
104
|
+
environment?: 'production' | 'development'; // Falls back to NODE_ENV
|
|
105
|
+
timeout?: number; // Request timeout in ms (default: 10000)
|
|
144
106
|
}
|
|
145
107
|
```
|
|
146
108
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
#### Event Tracking
|
|
150
|
-
|
|
151
|
-
- `trackPurchase(event)` - Track an initial purchase event
|
|
152
|
-
- `trackRenewal(event)` - Track a subscription renewal
|
|
153
|
-
- `trackCancellation(event)` - Track a subscription cancellation
|
|
154
|
-
- `trackBillingIssue(event)` - Track a billing issue
|
|
155
|
-
- `trackExpiration(event)` - Track a subscription expiration
|
|
156
|
-
- `trackUpgrade(event)` - Track a plan upgrade
|
|
157
|
-
- `trackRefund(event)` - Track a refund
|
|
158
|
-
|
|
159
|
-
#### Generic Event Methods
|
|
160
|
-
|
|
161
|
-
- `syncEvent(event)` - Sync a single billing event
|
|
162
|
-
- `syncEvents(events)` - Batch sync multiple events
|
|
163
|
-
- `queueEvent(event, options?)` - Queue an event for batch processing
|
|
164
|
-
- `flush()` - Manually flush the event queue
|
|
165
|
-
|
|
166
|
-
#### User Management
|
|
167
|
-
|
|
168
|
-
- `identify(userData)` - Identify a user and sync their attributes
|
|
169
|
-
- `getUserStatus(userId)` - Get a user's subscription status
|
|
170
|
-
|
|
171
|
-
#### Utility
|
|
172
|
-
|
|
173
|
-
- `healthCheck()` - Check API health status
|
|
174
|
-
|
|
175
|
-
### Event Types
|
|
176
|
-
|
|
177
|
-
The SDK supports the following billing event types:
|
|
178
|
-
|
|
179
|
-
- `initial-purchase` - New subscription or trial
|
|
180
|
-
- `renewal` - Subscription renewal
|
|
181
|
-
- `cancellation` - Subscription cancellation
|
|
182
|
-
- `billing-issue` - Payment failure or issue
|
|
183
|
-
- `expiration` - Subscription expiration
|
|
184
|
-
- `upgraded` - Plan upgrade
|
|
185
|
-
- `refund` - Refund processed
|
|
186
|
-
- `resubscribe` - User resubscribed
|
|
187
|
-
- `transfer` - Subscription transferred between users
|
|
188
|
-
- `grace_period_start` - Grace period started
|
|
189
|
-
|
|
190
|
-
### Error Handling
|
|
109
|
+
## Error Handling
|
|
191
110
|
|
|
192
111
|
```typescript
|
|
193
112
|
import { GalvaError } from 'galva-admin-node';
|
|
194
113
|
|
|
195
114
|
try {
|
|
196
|
-
await galva.
|
|
115
|
+
await galva.billingEvent.appstore('user-123', payload);
|
|
197
116
|
} catch (error) {
|
|
198
117
|
if (error instanceof GalvaError) {
|
|
199
|
-
console.error(
|
|
200
|
-
code: error.code,
|
|
201
|
-
message: error.message,
|
|
202
|
-
statusCode: error.statusCode,
|
|
203
|
-
details: error.details
|
|
204
|
-
});
|
|
205
|
-
} else {
|
|
206
|
-
console.error('Unexpected error:', error);
|
|
118
|
+
console.error(error.code, error.message);
|
|
207
119
|
}
|
|
208
120
|
}
|
|
209
121
|
```
|
|
210
122
|
|
|
211
123
|
## Requirements
|
|
212
124
|
|
|
213
|
-
- Node.js 18.0
|
|
214
|
-
- TypeScript 5.0 or higher (for development)
|
|
125
|
+
- Node.js >= 18.0
|
|
215
126
|
|
|
216
127
|
## License
|
|
217
128
|
|
|
218
|
-
MIT
|
|
129
|
+
MIT
|