@moneybar.online/moneybar 9.1.1 → 9.1.3
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 +178 -16
- package/example-template.html +13 -11
- 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)
|
|
@@ -248,18 +415,13 @@ window.moneyBar.attachToButton('#convert-btn', (ctx) => {
|
|
|
248
415
|
|
|
249
416
|
## Getting Your Security Key
|
|
250
417
|
|
|
251
|
-
|
|
418
|
+
**MoneyBar is currently in private beta.**
|
|
252
419
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
'yourdomain.com', -- Your domain
|
|
257
|
-
'your@email.com', -- Your email
|
|
258
|
-
3 -- Free attempt limit
|
|
259
|
-
);
|
|
260
|
-
```
|
|
420
|
+
To get a security key for beta testing, please contact the authors:
|
|
421
|
+
- **Email**: ravi@cloudworks.com
|
|
422
|
+
- **GitHub**: [Open an issue](https://github.com/ravi-cloudworks/moneybar/issues)
|
|
261
423
|
|
|
262
|
-
|
|
424
|
+
We'll provide you with a security key and help you get set up!
|
|
263
425
|
|
|
264
426
|
---
|
|
265
427
|
|
package/example-template.html
CHANGED
|
@@ -94,52 +94,54 @@
|
|
|
94
94
|
window.moneyBar.attachToButton('#my-custom-btn', async (userContext) => {
|
|
95
95
|
|
|
96
96
|
// ⚠️ TOGGLE THIS TO TEST ERROR SCENARIO
|
|
97
|
-
const TEST_ERROR =
|
|
97
|
+
const TEST_ERROR = false ; // Set to true to test error handling
|
|
98
98
|
|
|
99
99
|
console.log('📊 UserContext:', userContext);
|
|
100
100
|
|
|
101
101
|
if (userContext.isPremium) {
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
// Premium user - unlimited access
|
|
104
103
|
try {
|
|
105
104
|
// Call your custom function
|
|
106
105
|
const result = await customX(TEST_ERROR);
|
|
107
106
|
console.log('✅ Success:', result);
|
|
108
|
-
alert('Success
|
|
107
|
+
alert('✅ Success! (Premium - unlimited access)');
|
|
109
108
|
|
|
110
|
-
// ✅ If we reach here: count WILL be incremented
|
|
109
|
+
// ✅ If we reach here: count WILL be incremented (but premium has no limits)
|
|
111
110
|
|
|
112
111
|
} catch (error) {
|
|
113
112
|
// ❌ If error thrown: count will NOT be incremented
|
|
114
113
|
console.error('❌ Custom function error:', error.message);
|
|
115
|
-
alert('❌ Error: ' + error.message + '\n\
|
|
114
|
+
alert('❌ Error: ' + error.message + '\n\n(Premium - no attempt counted)');
|
|
116
115
|
|
|
117
116
|
// Re-throw to prevent count increment
|
|
118
117
|
throw error;
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
} else {
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
// Free user - limited attempts
|
|
124
122
|
try {
|
|
125
123
|
// Call your custom function
|
|
126
124
|
const result = await customX(TEST_ERROR);
|
|
127
125
|
console.log('✅ Success:', result);
|
|
128
|
-
|
|
126
|
+
|
|
127
|
+
// Success - show NEW remaining count (after this action)
|
|
128
|
+
const newRemaining = userContext.remaining - 1;
|
|
129
|
+
alert(`✅ Success!\n\nYou have ${newRemaining} attempts remaining.`);
|
|
129
130
|
|
|
130
131
|
// ✅ If we reach here: count WILL be incremented
|
|
131
132
|
|
|
132
133
|
} catch (error) {
|
|
133
134
|
// ❌ If error thrown: count will NOT be incremented
|
|
134
135
|
console.error('❌ Error:', error.message);
|
|
135
|
-
|
|
136
|
+
|
|
137
|
+
// Error - show UNCHANGED remaining count (action failed, no count used)
|
|
138
|
+
alert(`❌ Error: ${error.message}\n\nYou still have ${userContext.remaining} attempts remaining.`);
|
|
136
139
|
|
|
137
140
|
// Re-throw to prevent count increment
|
|
138
141
|
throw error;
|
|
139
142
|
}
|
|
140
143
|
}
|
|
141
144
|
});
|
|
142
|
-
|
|
143
145
|
// ========================================
|
|
144
146
|
// HOW TO TEST:
|
|
145
147
|
// ========================================
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
// Self-contained bundle (works without import map)
|
|
10
10
|
// Use specific version to avoid CDN cache issues
|
|
11
|
-
import { MoneyBar } from 'https://cdn.jsdelivr.net/npm/@moneybar.online/moneybar@9.1.
|
|
11
|
+
import { MoneyBar } from 'https://cdn.jsdelivr.net/npm/@moneybar.online/moneybar@9.1.2/dist/index.bundle.js';
|
|
12
12
|
|
|
13
13
|
// For NPM projects:
|
|
14
14
|
// import { MoneyBar } from '@moneybar.online/moneybar';
|
|
@@ -72,11 +72,11 @@ const CONFIG = {
|
|
|
72
72
|
},
|
|
73
73
|
|
|
74
74
|
// Success message after action (optional)
|
|
75
|
-
successMessage: {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
},
|
|
75
|
+
// successMessage: {
|
|
76
|
+
// enabled: true,
|
|
77
|
+
// title: 'Success!',
|
|
78
|
+
// message: 'Your action completed successfully.'
|
|
79
|
+
// },
|
|
80
80
|
|
|
81
81
|
// ========================================
|
|
82
82
|
// ⚠️ DO NOT MODIFY - REQUIRED CONFIGURATION
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moneybar.online/moneybar",
|
|
3
|
-
"version": "9.1.
|
|
3
|
+
"version": "9.1.3",
|
|
4
4
|
"description": "The navbar of monetization. Fix the 3 money-blocking stages: forced sign-ins, silent drop-offs, and broken payment flows. Turn browsers into buyers.",
|
|
5
5
|
"main": "dist/index.esm.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|