@moneybar.online/moneybar 9.1.0 → 9.1.2
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 +173 -6
- package/dist/index.bundle.js +1 -1
- package/dist/index.bundle.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/example-template.html +18 -57
- package/moneybar-config-template.js +6 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -144,17 +144,49 @@ window.moneyBar.attachToButton('#my-btn', (userContext) => {
|
|
|
144
144
|
// User info
|
|
145
145
|
userContext.email // String - User's email (if signed in)
|
|
146
146
|
userContext.name // String - User's name (if available)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
userContext.
|
|
151
|
-
userContext.
|
|
152
|
-
userContext.
|
|
147
|
+
userContext.user // Object - Full Supabase user object
|
|
148
|
+
|
|
149
|
+
// Subscription details (only for subscription users)
|
|
150
|
+
userContext.subscriptionType // 'monthly', 'quarterly', 'yearly'
|
|
151
|
+
userContext.subscriptionId // String - Subscription ID
|
|
152
|
+
userContext.subscriptionExpiresAt // ISO date string - When subscription expires
|
|
153
|
+
userContext.subscriptionDaysRemaining // Number - Days until expiry
|
|
154
|
+
userContext.isSubscriptionActive // true/false - Active or cancelled
|
|
155
|
+
userContext.nextBillingDate // ISO date string - Next billing date
|
|
156
|
+
userContext.billingFrequency // String - 'monthly', 'quarterly', etc.
|
|
153
157
|
userContext.customerId // String - Customer ID for portal access
|
|
154
158
|
|
|
155
159
|
});
|
|
156
160
|
```
|
|
157
161
|
|
|
162
|
+
### UserContext for Different Payment Types
|
|
163
|
+
|
|
164
|
+
**One-Time Payment:**
|
|
165
|
+
```javascript
|
|
166
|
+
{
|
|
167
|
+
isPremium: true,
|
|
168
|
+
subscriptionType: 'one-time', // Indicates one-time payment
|
|
169
|
+
// No subscription fields (expiresAt, nextBillingDate, etc.)
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Subscription Payment:**
|
|
174
|
+
```javascript
|
|
175
|
+
{
|
|
176
|
+
isPremium: true,
|
|
177
|
+
subscriptionType: 'monthly', // or 'quarterly', 'yearly'
|
|
178
|
+
subscriptionId: 'sub_xxx',
|
|
179
|
+
subscriptionExpiresAt: '2026-02-06',
|
|
180
|
+
subscriptionDaysRemaining: 31,
|
|
181
|
+
isSubscriptionActive: true, // false if cancelled
|
|
182
|
+
nextBillingDate: '2026-02-06',
|
|
183
|
+
billingFrequency: 'monthly',
|
|
184
|
+
customerId: 'cus_xxx' // For customer portal
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Note:** Payment amounts, transaction IDs, and billing details are available in your Dodo Payments dashboard.
|
|
189
|
+
|
|
158
190
|
---
|
|
159
191
|
|
|
160
192
|
## Common Patterns
|
|
@@ -219,6 +251,141 @@ window.moneyBar.attachToButton('#convert-btn', (ctx) => {
|
|
|
219
251
|
|
|
220
252
|
---
|
|
221
253
|
|
|
254
|
+
## Integrating Your Existing Functions
|
|
255
|
+
|
|
256
|
+
MoneyBar works with your existing functions. Here's how to integrate them properly:
|
|
257
|
+
|
|
258
|
+
### Basic Integration
|
|
259
|
+
|
|
260
|
+
```javascript
|
|
261
|
+
// Your existing function
|
|
262
|
+
async function generatePDF(userId, template) {
|
|
263
|
+
const response = await fetch('/api/generate-pdf', {
|
|
264
|
+
method: 'POST',
|
|
265
|
+
body: JSON.stringify({ userId, template })
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (!response.ok) {
|
|
269
|
+
throw new Error('PDF generation failed');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return await response.json();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Integrate with MoneyBar
|
|
276
|
+
window.moneyBar.attachToButton('#generate-pdf-btn', async (userContext) => {
|
|
277
|
+
|
|
278
|
+
if (userContext.isPremium) {
|
|
279
|
+
// Premium: Unlimited access
|
|
280
|
+
try {
|
|
281
|
+
const result = await generatePDF(userContext.email, 'premium-template');
|
|
282
|
+
alert('✅ PDF generated successfully!');
|
|
283
|
+
} catch (error) {
|
|
284
|
+
alert('❌ Error: ' + error.message);
|
|
285
|
+
throw error; // Re-throw to prevent count increment
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
} else {
|
|
289
|
+
// Free: Limited attempts
|
|
290
|
+
try {
|
|
291
|
+
const result = await generatePDF(userContext.email, 'basic-template');
|
|
292
|
+
const remaining = userContext.remaining - 1;
|
|
293
|
+
alert(`✅ PDF generated! ${remaining} attempts remaining.`);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
alert(`❌ Error: ${error.message}\n\nYou still have ${userContext.remaining} attempts.`);
|
|
296
|
+
throw error; // Re-throw to prevent count increment
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### How Success/Error Handling Works
|
|
303
|
+
|
|
304
|
+
**Critical: Count increments ONLY if your function succeeds**
|
|
305
|
+
|
|
306
|
+
```javascript
|
|
307
|
+
window.moneyBar.attachToButton('#my-btn', async (userContext) => {
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
// Your async function runs FIRST
|
|
311
|
+
await yourCustomFunction();
|
|
312
|
+
|
|
313
|
+
// ✅ SUCCESS PATH:
|
|
314
|
+
// - Function completed without error
|
|
315
|
+
// - MoneyBar increments count AFTER this
|
|
316
|
+
// - User consumed 1 attempt
|
|
317
|
+
|
|
318
|
+
} catch (error) {
|
|
319
|
+
// ❌ ERROR PATH:
|
|
320
|
+
// - Function threw an error
|
|
321
|
+
// - Re-throw the error to prevent count increment
|
|
322
|
+
// - User does NOT consume an attempt
|
|
323
|
+
|
|
324
|
+
console.error('Function failed:', error);
|
|
325
|
+
throw error; // IMPORTANT: Re-throw to prevent count increment
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Real-World Example: API Call with Error Handling
|
|
331
|
+
|
|
332
|
+
```javascript
|
|
333
|
+
// Your existing API function
|
|
334
|
+
async function processImage(imageUrl, format) {
|
|
335
|
+
const response = await fetch('https://api.yourapp.com/process', {
|
|
336
|
+
method: 'POST',
|
|
337
|
+
headers: { 'Content-Type': 'application/json' },
|
|
338
|
+
body: JSON.stringify({ imageUrl, format })
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
if (!response.ok) {
|
|
342
|
+
const error = await response.json();
|
|
343
|
+
throw new Error(error.message || 'Processing failed');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return await response.json();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Integrate with MoneyBar
|
|
350
|
+
window.moneyBar.attachToButton('#process-image-btn', async (userContext) => {
|
|
351
|
+
|
|
352
|
+
const imageUrl = document.getElementById('image-url').value;
|
|
353
|
+
const format = userContext.isPremium ? 'high-quality' : 'standard';
|
|
354
|
+
|
|
355
|
+
try {
|
|
356
|
+
const result = await processImage(imageUrl, format);
|
|
357
|
+
|
|
358
|
+
// Success
|
|
359
|
+
if (userContext.isPremium) {
|
|
360
|
+
alert('✅ Image processed in high quality!');
|
|
361
|
+
} else {
|
|
362
|
+
const remaining = userContext.remaining - 1;
|
|
363
|
+
alert(`✅ Image processed! ${remaining} attempts remaining.`);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
} catch (error) {
|
|
367
|
+
// Error - API failed, network issue, etc.
|
|
368
|
+
if (userContext.isPremium) {
|
|
369
|
+
alert('❌ Processing failed: ' + error.message);
|
|
370
|
+
} else {
|
|
371
|
+
alert(`❌ Processing failed: ${error.message}\n\nNo attempt used. You still have ${userContext.remaining} attempts.`);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
throw error; // Re-throw to prevent count increment
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Key Points
|
|
380
|
+
|
|
381
|
+
1. **Async Functions**: MoneyBar automatically waits for async functions to complete
|
|
382
|
+
2. **Error Handling**: If your function throws an error, count does NOT increment
|
|
383
|
+
3. **Re-throw Errors**: Always `throw error;` in catch blocks to prevent count increment
|
|
384
|
+
4. **Success/Error Feedback**: Show different messages based on outcome and user type
|
|
385
|
+
5. **userContext.isPremium**: Use this to provide different features/quality for premium users
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
222
389
|
## What MoneyBar Handles Automatically
|
|
223
390
|
|
|
224
391
|
✅ **Authentication** - Google sign-in (more providers coming)
|