soundbip 2.0.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.
- package/index.js +513 -0
- package/package.json +30 -0
package/index.js
ADDED
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const readline = require('readline');
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const { exec } = require('child_process');
|
|
5
|
+
|
|
6
|
+
const API_URL = 'api.dltpays.com';
|
|
7
|
+
|
|
8
|
+
// Colors
|
|
9
|
+
const c = {
|
|
10
|
+
reset: '\x1b[0m',
|
|
11
|
+
bold: '\x1b[1m',
|
|
12
|
+
dim: '\x1b[2m',
|
|
13
|
+
green: '\x1b[32m',
|
|
14
|
+
cyan: '\x1b[36m',
|
|
15
|
+
yellow: '\x1b[33m',
|
|
16
|
+
red: '\x1b[31m',
|
|
17
|
+
magenta: '\x1b[35m',
|
|
18
|
+
blue: '\x1b[34m',
|
|
19
|
+
bgBlue: '\x1b[44m',
|
|
20
|
+
bgGreen: '\x1b[42m',
|
|
21
|
+
bgMagenta: '\x1b[45m',
|
|
22
|
+
white: '\x1b[37m',
|
|
23
|
+
gray: '\x1b[90m'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const rl = readline.createInterface({
|
|
27
|
+
input: process.stdin,
|
|
28
|
+
output: process.stdout
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function ask(question) {
|
|
32
|
+
return new Promise(resolve => rl.question(question, resolve));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isValidEmail(email) {
|
|
36
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
37
|
+
return emailRegex.test(email);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isValidUrl(url) {
|
|
41
|
+
try {
|
|
42
|
+
const parsed = new URL(url.startsWith('http') ? url : `https://${url}`);
|
|
43
|
+
return parsed.hostname.includes('.');
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function normalizeUrl(url) {
|
|
50
|
+
if (!url.startsWith('http')) {
|
|
51
|
+
return `https://${url}`;
|
|
52
|
+
}
|
|
53
|
+
return url;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function askWithValidation(question, validator, errorMessage, normalizer = null) {
|
|
57
|
+
while (true) {
|
|
58
|
+
const answer = await ask(question);
|
|
59
|
+
|
|
60
|
+
if (!answer.trim()) {
|
|
61
|
+
console.log(`${c.red} ✗ This field is required${c.reset}`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (validator && !validator(answer.trim())) {
|
|
66
|
+
console.log(`${c.red} ✗ ${errorMessage}${c.reset}`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return normalizer ? normalizer(answer.trim()) : answer.trim();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function apiCall(method, path, data = null) {
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
const options = {
|
|
77
|
+
hostname: API_URL,
|
|
78
|
+
port: 443,
|
|
79
|
+
path: `/api/v1${path}`,
|
|
80
|
+
method,
|
|
81
|
+
headers: { 'Content-Type': 'application/json' }
|
|
82
|
+
};
|
|
83
|
+
const req = https.request(options, res => {
|
|
84
|
+
let body = '';
|
|
85
|
+
res.on('data', chunk => body += chunk);
|
|
86
|
+
res.on('end', () => {
|
|
87
|
+
try {
|
|
88
|
+
resolve(JSON.parse(body));
|
|
89
|
+
} catch {
|
|
90
|
+
resolve(body);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
req.on('error', reject);
|
|
95
|
+
if (data) req.write(JSON.stringify(data));
|
|
96
|
+
req.end();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function openBrowser(url) {
|
|
101
|
+
const platform = process.platform;
|
|
102
|
+
let command;
|
|
103
|
+
|
|
104
|
+
if (platform === 'darwin') {
|
|
105
|
+
command = `open "${url}"`;
|
|
106
|
+
} else if (platform === 'win32') {
|
|
107
|
+
command = `start "" "${url}"`;
|
|
108
|
+
} else {
|
|
109
|
+
command = `xdg-open "${url}"`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
exec(command, (err) => {
|
|
113
|
+
if (err) {
|
|
114
|
+
console.log(`${c.dim} Could not open browser automatically.${c.reset}`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function banner() {
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log(`${c.cyan} ███████╗ ██████╗ ██╗ ██╗███╗ ██╗██████╗ ██████╗ ██╗██████╗${c.reset}`);
|
|
122
|
+
console.log(`${c.cyan} ██╔════╝██╔═══██╗██║ ██║████╗ ██║██╔══██╗██╔══██╗██║██╔══██╗${c.reset}`);
|
|
123
|
+
console.log(`${c.green} ███████╗██║ ██║██║ ██║██╔██╗ ██║██║ ██║██████╔╝██║██████╔╝${c.reset}`);
|
|
124
|
+
console.log(`${c.green} ╚════██║██║ ██║██║ ██║██║╚██╗██║██║ ██║██╔══██╗██║██╔═══╝${c.reset}`);
|
|
125
|
+
console.log(`${c.cyan} ███████║╚██████╔╝╚██████╔╝██║ ╚████║██████╔╝██████╔╝██║██║${c.reset}`);
|
|
126
|
+
console.log(`${c.cyan} ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═╝╚═╝${c.reset}`);
|
|
127
|
+
console.log('');
|
|
128
|
+
console.log(`${c.bold}${c.white} ⚡ POS & Affiliate Commissions on XRPL ⚡${c.reset}`);
|
|
129
|
+
console.log(`${c.dim} Pay affiliates in seconds, not months${c.reset}`);
|
|
130
|
+
console.log('');
|
|
131
|
+
console.log(`${c.gray} ════════════════════════════════════════════════════════════════════════════════════${c.reset}`);
|
|
132
|
+
console.log('');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function section(emoji, title) {
|
|
136
|
+
console.log('');
|
|
137
|
+
console.log(`${c.gray} ──────────────────────────────────────────────────────────────────────────────────${c.reset}`);
|
|
138
|
+
console.log(`${c.bold} ${emoji} ${title}${c.reset}`);
|
|
139
|
+
console.log(`${c.gray} ──────────────────────────────────────────────────────────────────────────────────${c.reset}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function box(lines, color = c.cyan) {
|
|
143
|
+
const maxLen = Math.max(...lines.map(l => l.replace(/\x1b\[[0-9;]*m/g, '').length));
|
|
144
|
+
const pad = (s) => {
|
|
145
|
+
const plainLen = s.replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
146
|
+
return s + ' '.repeat(maxLen - plainLen);
|
|
147
|
+
};
|
|
148
|
+
console.log(`${color} ╭${'─'.repeat(maxLen + 2)}╮${c.reset}`);
|
|
149
|
+
lines.forEach(line => {
|
|
150
|
+
console.log(`${color} │${c.reset} ${pad(line)} ${color}│${c.reset}`);
|
|
151
|
+
});
|
|
152
|
+
console.log(`${color} ╰${'─'.repeat(maxLen + 2)}╯${c.reset}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function success(msg) {
|
|
156
|
+
console.log(`${c.green} ✓ ${msg}${c.reset}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function info(label, value, indent = ' ') {
|
|
160
|
+
const labelPad = 15;
|
|
161
|
+
const paddedLabel = label.padEnd(labelPad);
|
|
162
|
+
console.log(`${indent}${c.dim}${paddedLabel}${c.reset}${c.bold}${value}${c.reset}`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function spinner(text) {
|
|
166
|
+
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
167
|
+
let i = 0;
|
|
168
|
+
process.stdout.write(`\n${c.yellow} ${frames[0]} ${text}${c.reset}`);
|
|
169
|
+
return setInterval(() => {
|
|
170
|
+
i = (i + 1) % frames.length;
|
|
171
|
+
process.stdout.clearLine(0);
|
|
172
|
+
process.stdout.cursorTo(0);
|
|
173
|
+
process.stdout.write(`${c.yellow} ${frames[i]} ${text}${c.reset}`);
|
|
174
|
+
}, 80);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function stopSpinner(interval) {
|
|
178
|
+
clearInterval(interval);
|
|
179
|
+
process.stdout.clearLine(0);
|
|
180
|
+
process.stdout.cursorTo(0);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const PLATFORMS = {
|
|
184
|
+
'1': { name: 'WooCommerce / WordPress', key: 'woocommerce' },
|
|
185
|
+
'2': { name: 'Shopify', key: 'shopify' },
|
|
186
|
+
'3': { name: 'Custom / API Integration', key: 'custom' },
|
|
187
|
+
'4': { name: 'Stripe Checkout', key: 'stripe' },
|
|
188
|
+
'5': { name: 'Gumroad', key: 'gumroad' },
|
|
189
|
+
'6': { name: 'LemonSqueezy', key: 'lemonsqueezy' },
|
|
190
|
+
'7': { name: 'Paddle', key: 'paddle' }
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
function showPlatformMenu() {
|
|
194
|
+
console.log('');
|
|
195
|
+
console.log(`${c.bold} What platform is your store on?${c.reset}`);
|
|
196
|
+
console.log('');
|
|
197
|
+
Object.entries(PLATFORMS).forEach(([num, platform]) => {
|
|
198
|
+
const icon = num === '1' ? '🟢' : num === '2' ? '🟣' : num === '3' ? '⚡' : '○';
|
|
199
|
+
console.log(`${c.dim} ${icon}${c.reset} ${c.cyan}[${num}]${c.reset} ${platform.name}`);
|
|
200
|
+
});
|
|
201
|
+
console.log('');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function getWooCommerceInstructions(storeId, apiSecret) {
|
|
205
|
+
return `
|
|
206
|
+
${c.bold}${c.green} WooCommerce Setup (Easiest - 2 minutes)${c.reset}
|
|
207
|
+
|
|
208
|
+
${c.bold}Step 1:${c.reset} Download the plugin
|
|
209
|
+
${c.cyan}https://github.com/TokenCanvasIO/YesAllofUs-wordpress/releases/download/v1.0.0/YesAllofUs.zip${c.reset}
|
|
210
|
+
|
|
211
|
+
${c.bold}Step 2:${c.reset} Install in WordPress
|
|
212
|
+
${c.dim}WordPress Admin → Plugins → Add New → Upload Plugin → Select the .zip${c.reset}
|
|
213
|
+
|
|
214
|
+
${c.bold}Step 3:${c.reset} Activate & Configure
|
|
215
|
+
${c.dim}Go to Settings → YesAllofUs and enter your API credentials${c.reset}
|
|
216
|
+
|
|
217
|
+
${c.bold}What you get:${c.reset}
|
|
218
|
+
${c.green}✓${c.reset} Affiliate signup page ${c.dim}[yesallofus_affiliate_signup]${c.reset}
|
|
219
|
+
${c.green}✓${c.reset} Affiliate dashboard ${c.dim}[yesallofus_affiliate_dashboard]${c.reset}
|
|
220
|
+
${c.green}✓${c.reset} Auto commission tracking ${c.dim}on every WooCommerce order${c.reset}
|
|
221
|
+
${c.green}✓${c.reset} Store admin dashboard ${c.dim}manage affiliates & payouts${c.reset}
|
|
222
|
+
${c.green}✓${c.reset} Instant RLUSD payouts ${c.dim}via Xaman or Crossmark auto-sign${c.reset}
|
|
223
|
+
`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function getShopifyInstructions(storeId, apiSecret) {
|
|
227
|
+
return `
|
|
228
|
+
${c.bold}${c.magenta} Shopify Setup${c.reset}
|
|
229
|
+
|
|
230
|
+
${c.bold}Step 1:${c.reset} Add tracking script to your theme
|
|
231
|
+
${c.dim}Online Store → Themes → Edit Code → theme.liquid (before </head>)${c.reset}
|
|
232
|
+
|
|
233
|
+
${c.blue} <script>
|
|
234
|
+
(function() {
|
|
235
|
+
const ref = new URLSearchParams(window.location.search).get('ref');
|
|
236
|
+
if (ref) {
|
|
237
|
+
document.cookie = 'yesallofus_ref=' + ref + ';path=/;max-age=2592000';
|
|
238
|
+
}
|
|
239
|
+
})();
|
|
240
|
+
</script>${c.reset}
|
|
241
|
+
|
|
242
|
+
${c.bold}Step 2:${c.reset} Create a Shopify Flow or use webhooks
|
|
243
|
+
${c.dim}Settings → Notifications → Webhooks → Create webhook${c.reset}
|
|
244
|
+
${c.dim}Event: Order payment → URL: Your server endpoint${c.reset}
|
|
245
|
+
|
|
246
|
+
${c.bold}Step 3:${c.reset} Call SoundBip API on order completion
|
|
247
|
+
${c.dim}(See API integration below)${c.reset}
|
|
248
|
+
|
|
249
|
+
${c.yellow}⚠ Shopify requires a small backend to call our API.${c.reset}
|
|
250
|
+
${c.dim}We're building a native Shopify app - join the waitlist: support@soundbip.com${c.reset}
|
|
251
|
+
`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function getCustomInstructions(storeId, apiSecret) {
|
|
255
|
+
return `
|
|
256
|
+
${c.bold}${c.cyan} Custom API Integration${c.reset}
|
|
257
|
+
|
|
258
|
+
${c.bold}Step 1:${c.reset} Track referral codes
|
|
259
|
+
${c.dim}Capture the ?ref= parameter and store it with the user/order${c.reset}
|
|
260
|
+
|
|
261
|
+
${c.bold}Step 2:${c.reset} Call payout endpoint on successful order
|
|
262
|
+
|
|
263
|
+
${c.blue} // When order completes successfully:
|
|
264
|
+
const response = await fetch('https://api.dltpays.com/api/v1/payout', {
|
|
265
|
+
method: 'POST',
|
|
266
|
+
headers: {
|
|
267
|
+
'Authorization': 'Bearer ${c.yellow}${apiSecret}${c.blue}',
|
|
268
|
+
'Content-Type': 'application/json'
|
|
269
|
+
},
|
|
270
|
+
body: JSON.stringify({
|
|
271
|
+
order_id: orderId, // Your unique order ID
|
|
272
|
+
order_total: 49.99, // Order amount in USD
|
|
273
|
+
referral_code: refCode // The ?ref= code from cookie
|
|
274
|
+
})
|
|
275
|
+
});${c.reset}
|
|
276
|
+
|
|
277
|
+
${c.bold}Step 3:${c.reset} Share your affiliate signup link
|
|
278
|
+
${c.cyan}https://soundbip.com/member-login?store=${storeId}${c.reset}
|
|
279
|
+
`;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function getStripeInstructions(storeId, apiSecret) {
|
|
283
|
+
return `
|
|
284
|
+
${c.bold}${c.blue} Stripe Checkout Integration${c.reset}
|
|
285
|
+
|
|
286
|
+
${c.bold}Step 1:${c.reset} Add metadata to checkout session
|
|
287
|
+
|
|
288
|
+
${c.blue} const session = await stripe.checkout.sessions.create({
|
|
289
|
+
// ... your config
|
|
290
|
+
metadata: {
|
|
291
|
+
referral_code: req.cookies.yesallofus_ref || ''
|
|
292
|
+
}
|
|
293
|
+
});${c.reset}
|
|
294
|
+
|
|
295
|
+
${c.bold}Step 2:${c.reset} Handle checkout.session.completed webhook
|
|
296
|
+
|
|
297
|
+
${c.blue} // In your Stripe webhook handler:
|
|
298
|
+
if (event.type === 'checkout.session.completed') {
|
|
299
|
+
const session = event.data.object;
|
|
300
|
+
|
|
301
|
+
await fetch('https://api.dltpays.com/api/v1/payout', {
|
|
302
|
+
method: 'POST',
|
|
303
|
+
headers: {
|
|
304
|
+
'Authorization': 'Bearer ${c.yellow}${apiSecret}${c.blue}',
|
|
305
|
+
'Content-Type': 'application/json'
|
|
306
|
+
},
|
|
307
|
+
body: JSON.stringify({
|
|
308
|
+
order_id: session.id,
|
|
309
|
+
order_total: session.amount_total / 100,
|
|
310
|
+
referral_code: session.metadata.referral_code
|
|
311
|
+
})
|
|
312
|
+
});
|
|
313
|
+
}${c.reset}
|
|
314
|
+
`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function getGenericInstructions(platform, storeId, apiSecret) {
|
|
318
|
+
return `
|
|
319
|
+
${c.bold}${c.yellow} ${PLATFORMS[platform].name} Integration${c.reset}
|
|
320
|
+
|
|
321
|
+
${c.dim}We're working on native integrations for ${PLATFORMS[platform].name}.${c.reset}
|
|
322
|
+
${c.dim}For now, use the webhook/API approach:${c.reset}
|
|
323
|
+
|
|
324
|
+
${c.bold}Core concept:${c.reset}
|
|
325
|
+
${c.cyan}1.${c.reset} Track ?ref= parameter in cookies
|
|
326
|
+
${c.cyan}2.${c.reset} On successful payment, POST to our API
|
|
327
|
+
${c.cyan}3.${c.reset} We handle commission calculation & instant payout
|
|
328
|
+
|
|
329
|
+
${c.bold}API Endpoint:${c.reset}
|
|
330
|
+
${c.cyan}POST https://api.dltpays.com/api/v1/payout${c.reset}
|
|
331
|
+
|
|
332
|
+
${c.bold}Request body:${c.reset}
|
|
333
|
+
${c.blue} {
|
|
334
|
+
"order_id": "unique_order_123",
|
|
335
|
+
"order_total": 99.99,
|
|
336
|
+
"referral_code": "ABC123"
|
|
337
|
+
}${c.reset}
|
|
338
|
+
|
|
339
|
+
${c.bold}Need help?${c.reset} ${c.cyan}support@soundbip.com${c.reset}
|
|
340
|
+
`;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async function main() {
|
|
344
|
+
banner();
|
|
345
|
+
|
|
346
|
+
console.log(`${c.bold} Let's get your store set up with SoundBip POS & affiliate payouts${c.reset}`);
|
|
347
|
+
console.log(`${c.dim} Takes about 2 minutes for WooCommerce, 5-10 for custom integrations${c.reset}`);
|
|
348
|
+
console.log('');
|
|
349
|
+
|
|
350
|
+
// Store details with validation
|
|
351
|
+
const storeName = await askWithValidation(
|
|
352
|
+
`${c.cyan} Store name: ${c.reset}`,
|
|
353
|
+
(name) => name.length >= 2,
|
|
354
|
+
'Store name must be at least 2 characters'
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
const storeUrl = await askWithValidation(
|
|
358
|
+
`${c.cyan} Website URL: ${c.reset}`,
|
|
359
|
+
isValidUrl,
|
|
360
|
+
'Please enter a valid URL (e.g. mystore.com or https://mystore.com)',
|
|
361
|
+
normalizeUrl
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
const email = await askWithValidation(
|
|
365
|
+
`${c.cyan} Email: ${c.reset}`,
|
|
366
|
+
isValidEmail,
|
|
367
|
+
'Please enter a valid email address'
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
// Referral code (optional)
|
|
371
|
+
const referralCode = await ask(`${c.cyan} Referral code (optional): ${c.reset}`);
|
|
372
|
+
|
|
373
|
+
let referred_by_store = null;
|
|
374
|
+
if (referralCode.trim()) {
|
|
375
|
+
const lookupResult = await apiCall('GET', `/store/lookup-referral/${referralCode.trim()}`);
|
|
376
|
+
if (lookupResult.success) {
|
|
377
|
+
referred_by_store = lookupResult.store_id;
|
|
378
|
+
console.log(`${c.green} ✓ Referred by: ${lookupResult.store_name} (50% off first month!)${c.reset}`);
|
|
379
|
+
} else {
|
|
380
|
+
console.log(`${c.yellow} ⚠ Referral code not found - continuing without referral${c.reset}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Platform selection
|
|
385
|
+
showPlatformMenu();
|
|
386
|
+
const platformChoice = await ask(`${c.cyan} Select platform [1-7]: ${c.reset}`);
|
|
387
|
+
const platform = PLATFORMS[platformChoice] || PLATFORMS['3'];
|
|
388
|
+
|
|
389
|
+
const spin = spinner('Registering your store...');
|
|
390
|
+
|
|
391
|
+
const result = await apiCall('POST', '/store/register', {
|
|
392
|
+
store_name: storeName,
|
|
393
|
+
store_url: storeUrl,
|
|
394
|
+
email: email,
|
|
395
|
+
platform: platform.key,
|
|
396
|
+
referred_by_store: referred_by_store
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
stopSpinner(spin);
|
|
400
|
+
|
|
401
|
+
if (result.error) {
|
|
402
|
+
console.log(`\n${c.red} ✗ Error: ${result.error}${c.reset}\n`);
|
|
403
|
+
rl.close();
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (result.reconnected) {
|
|
408
|
+
console.log('');
|
|
409
|
+
console.log(`${c.yellow} ⚠ Store already registered for ${storeUrl}${c.reset}`);
|
|
410
|
+
console.log('');
|
|
411
|
+
console.log(`${c.bold} Log in to your vendor dashboard:${c.reset}`);
|
|
412
|
+
console.log(`${c.cyan} https://soundbip.com/partner-login${c.reset}`);
|
|
413
|
+
console.log('');
|
|
414
|
+
console.log(`${c.dim} Need a new API secret? Regenerate it from the dashboard.${c.reset}`);
|
|
415
|
+
console.log('');
|
|
416
|
+
rl.close();
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
console.log('');
|
|
421
|
+
success('Store registered successfully!');
|
|
422
|
+
|
|
423
|
+
// Credentials
|
|
424
|
+
section('🔐', 'Your Credentials');
|
|
425
|
+
console.log('');
|
|
426
|
+
box([
|
|
427
|
+
`${c.dim}Store ID${c.reset} ${c.bold}${result.store_id}${c.reset}`,
|
|
428
|
+
`${c.dim}API Key${c.reset} ${c.bold}${result.api_key}${c.reset}`,
|
|
429
|
+
`${c.dim}API Secret${c.reset} ${c.bold}${c.yellow}${result.api_secret}${c.reset}`,
|
|
430
|
+
`${c.dim}Referral Code${c.reset} ${c.bold}${result.store_referral_code}${c.reset}`
|
|
431
|
+
]);
|
|
432
|
+
console.log(`\n${c.yellow} ⚠ Save your API Secret now - it cannot be retrieved later${c.reset}`);
|
|
433
|
+
|
|
434
|
+
// Platform-specific instructions
|
|
435
|
+
section('📦', `${platform.name} Setup`);
|
|
436
|
+
|
|
437
|
+
switch (platform.key) {
|
|
438
|
+
case 'woocommerce':
|
|
439
|
+
console.log(getWooCommerceInstructions(result.store_id, result.api_secret));
|
|
440
|
+
break;
|
|
441
|
+
case 'shopify':
|
|
442
|
+
console.log(getShopifyInstructions(result.store_id, result.api_secret));
|
|
443
|
+
console.log(getCustomInstructions(result.store_id, result.api_secret));
|
|
444
|
+
break;
|
|
445
|
+
case 'stripe':
|
|
446
|
+
console.log(getStripeInstructions(result.store_id, result.api_secret));
|
|
447
|
+
break;
|
|
448
|
+
case 'custom':
|
|
449
|
+
console.log(getCustomInstructions(result.store_id, result.api_secret));
|
|
450
|
+
break;
|
|
451
|
+
default:
|
|
452
|
+
console.log(getGenericInstructions(platformChoice, result.store_id, result.api_secret));
|
|
453
|
+
console.log(getCustomInstructions(result.store_id, result.api_secret));
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Affiliate signup
|
|
457
|
+
section('🎯', 'Affiliate Signup Page');
|
|
458
|
+
console.log('');
|
|
459
|
+
console.log(`${c.dim} Share this link for affiliates to register:${c.reset}`);
|
|
460
|
+
console.log('');
|
|
461
|
+
console.log(`${c.bold}${c.cyan} https://soundbip.com/member-login?store=${result.store_id}${c.reset}`);
|
|
462
|
+
|
|
463
|
+
if (platform.key === 'woocommerce') {
|
|
464
|
+
console.log('');
|
|
465
|
+
console.log(`${c.dim} Or use the shortcode on any WordPress page:${c.reset}`);
|
|
466
|
+
console.log(`${c.blue} [yesallofus_affiliate_signup]${c.reset}`);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Resources
|
|
470
|
+
section('📚', 'Resources');
|
|
471
|
+
console.log('');
|
|
472
|
+
info('Documentation', 'https://soundbip.com/docs');
|
|
473
|
+
info('Support', 'support@soundbip.com');
|
|
474
|
+
info('Twitter', '@PayByBip');
|
|
475
|
+
|
|
476
|
+
console.log('');
|
|
477
|
+
console.log(`${c.gray} ════════════════════════════════════════════════════════════════════════════════════${c.reset}`);
|
|
478
|
+
console.log('');
|
|
479
|
+
console.log(`${c.bold}${c.green} 🚀 You're ready to pay affiliates instantly!${c.reset}`);
|
|
480
|
+
console.log(`${c.dim} Lagos to London, same speed. That's the future.${c.reset}`);
|
|
481
|
+
console.log('');
|
|
482
|
+
|
|
483
|
+
// Wallet connection
|
|
484
|
+
section('👛', 'Connect Your Wallet');
|
|
485
|
+
console.log('');
|
|
486
|
+
console.log(`${c.dim} Payout options:${c.reset}`);
|
|
487
|
+
console.log(`${c.white} • Google${c.reset} ${c.dim}- Easiest setup, automatic 24/7 payouts${c.reset}`);
|
|
488
|
+
console.log(`${c.green} • Xaman${c.reset} ${c.dim}- Manual approval via push notification${c.reset}`);
|
|
489
|
+
console.log(`${c.blue} • Crossmark${c.reset} ${c.dim}- Automatic 24/7 payouts (browser extension)${c.reset}`);
|
|
490
|
+
console.log('');
|
|
491
|
+
|
|
492
|
+
const dashboardUrl = `https://soundbip.com/partner-login?claim=${result.claim_token}`;
|
|
493
|
+
|
|
494
|
+
console.log(`${c.bold} Open this URL to connect your wallet and access your vendor dashboard:${c.reset}`);
|
|
495
|
+
console.log('');
|
|
496
|
+
console.log(`${c.cyan} ${dashboardUrl}${c.reset}`);
|
|
497
|
+
console.log('');
|
|
498
|
+
console.log(`${c.yellow} 💡 Use Chrome or Brave for best experience (required for Crossmark)${c.reset}`)
|
|
499
|
+
|
|
500
|
+
console.log('');
|
|
501
|
+
console.log(`${c.gray} ════════════════════════════════════════════════════════════════════════════════════${c.reset}`);
|
|
502
|
+
console.log('');
|
|
503
|
+
console.log(`${c.bold}${c.white} Thanks for choosing SoundBip! 🤝${c.reset}`);
|
|
504
|
+
console.log(`${c.dim} Questions? support@soundbip.com${c.reset}`);
|
|
505
|
+
console.log('');
|
|
506
|
+
|
|
507
|
+
rl.close();
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
main().catch(err => {
|
|
511
|
+
console.error(`${c.red}Error: ${err.message}${c.reset}`);
|
|
512
|
+
rl.close();
|
|
513
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "soundbip",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "CLI for SoundBip POS - instant affiliate commissions on XRPL",
|
|
5
|
+
"bin": {
|
|
6
|
+
"soundbip": "./index.js"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"pos",
|
|
10
|
+
"point-of-sale",
|
|
11
|
+
"affiliate",
|
|
12
|
+
"xrpl",
|
|
13
|
+
"rlusd",
|
|
14
|
+
"commissions",
|
|
15
|
+
"payouts",
|
|
16
|
+
"crypto",
|
|
17
|
+
"instant-payments",
|
|
18
|
+
"woocommerce",
|
|
19
|
+
"shopify",
|
|
20
|
+
"ecommerce",
|
|
21
|
+
"soundbip"
|
|
22
|
+
],
|
|
23
|
+
"author": "SoundBip <support@soundbip.com>",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/TokenCanvasIO/yesallofus-cli.git"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://soundbip.com"
|
|
30
|
+
}
|