vibecash 0.2.1 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +86 -45
  2. package/package.json +23 -7
package/dist/index.js CHANGED
@@ -165,7 +165,11 @@ function registerWalletCommands(program2) {
165
165
  try {
166
166
  const data = await apiRequest("POST", "/wallets/current/claim_link");
167
167
  output(data, (d) => {
168
- return `Claim Link: ${d.url || d.claimLink || d.link || JSON.stringify(d)}`;
168
+ return [
169
+ `Claim URL: ${d.claimUrl || "N/A"}`,
170
+ `Claim Token: ${d.claimToken || "N/A"}`,
171
+ `Expires At: ${d.expiresAt ? fmtDate(d.expiresAt) : "N/A"}`
172
+ ].join("\n");
169
173
  });
170
174
  } catch (err) {
171
175
  console.error(`Error: ${err.message}`);
@@ -296,22 +300,31 @@ function registerPriceCommands(program2) {
296
300
  // src/commands/checkout.ts
297
301
  function registerCheckoutCommands(program2) {
298
302
  const checkout = program2.command("checkout").description("Manage checkout sessions");
299
- checkout.command("create").description("Create a new checkout session").requiredOption("-p, --price-id <priceId>", "Price ID to checkout").requiredOption("--success-url <url>", "URL to redirect on success").requiredOption("--cancel-url <url>", "URL to redirect on cancel").option("-m, --mode <mode>", "payment or subscription", "payment").option("-q, --quantity <quantity>", "Quantity", "1").option("--methods <methods>", "Payment methods (comma-separated: card,alipay,paynow,wechat)", "card,alipay,paynow,wechat").action(async (opts) => {
303
+ checkout.command("create").description("Create a new checkout session").requiredOption("-p, --price-id <priceId>", "Price ID to checkout").requiredOption("--success-url <url>", "URL to redirect on success").requiredOption("--cancel-url <url>", "URL to redirect on cancel").option("-m, --mode <mode>", "payment or subscription", "payment").option("-q, --quantity <quantity>", "Quantity", "1").option("--methods <methods>", "Payment methods (comma-separated: card,alipay,paynow,wechat)", "card,alipay,paynow,wechat").option("--customer-id <id>", "Customer ID (optional, auto-created from email at payment time)").option("--trial-days <days>", "Trial period in days (subscription mode)").action(async (opts) => {
300
304
  try {
301
305
  const body = {
302
306
  mode: opts.mode,
303
307
  lineItems: [{ priceId: opts.priceId, quantity: parseInt(opts.quantity, 10) }],
304
308
  successUrl: opts.successUrl,
305
- cancelUrl: opts.cancelUrl,
306
- paymentMethodTypes: opts.methods.split(",").map((m) => m.trim())
309
+ cancelUrl: opts.cancelUrl
307
310
  };
311
+ if (opts.mode === "subscription") {
312
+ body.paymentMethodTypes = ["card"];
313
+ } else {
314
+ body.paymentMethodTypes = opts.methods.split(",").map((m) => m.trim());
315
+ }
316
+ if (opts.customerId) body.customerId = opts.customerId;
317
+ if (opts.trialDays) body.trialPeriodDays = parseInt(opts.trialDays, 10);
308
318
  const data = await apiRequest("POST", "/checkout/sessions", body);
309
319
  success("Checkout session created");
310
320
  output(data, (d) => {
311
- return [
321
+ const lines = [
312
322
  `Session ID: ${d.id}`,
323
+ `Mode: ${d.mode}`,
313
324
  `Checkout URL: ${d.url || d.checkoutUrl || "N/A"}`
314
- ].join("\n");
325
+ ];
326
+ if (d.mode === "subscription") lines.push(`(Subscription \u2014 customer will be created from email at checkout)`);
327
+ return lines.join("\n");
315
328
  });
316
329
  } catch (err) {
317
330
  console.error(`Error: ${err.message}`);
@@ -394,18 +407,27 @@ function registerSubscriptionCommands(program2) {
394
407
  process.exit(1);
395
408
  }
396
409
  });
397
- subscription.command("cancel <id>").description("Cancel a subscription").action(async (id) => {
410
+ subscription.command("cancel <id>").description("Cancel a subscription immediately").action(async (id) => {
398
411
  try {
399
- await apiRequest("POST", `/subscriptions/${id}/cancel`);
412
+ await apiRequest("DELETE", `/subscriptions/${id}`);
400
413
  success(`Subscription ${id} cancelled`);
401
414
  } catch (err) {
402
415
  console.error(`Error: ${err.message}`);
403
416
  process.exit(1);
404
417
  }
405
418
  });
406
- subscription.command("resume <id>").description("Resume a cancelled subscription").action(async (id) => {
419
+ subscription.command("pause <id>").description("Set subscription to cancel at end of current period").action(async (id) => {
407
420
  try {
408
- await apiRequest("POST", `/subscriptions/${id}/resume`);
421
+ await apiRequest("PATCH", `/subscriptions/${id}`, { cancelAtPeriodEnd: true });
422
+ success(`Subscription ${id} will cancel at period end`);
423
+ } catch (err) {
424
+ console.error(`Error: ${err.message}`);
425
+ process.exit(1);
426
+ }
427
+ });
428
+ subscription.command("resume <id>").description("Resume a subscription set to cancel at period end").action(async (id) => {
429
+ try {
430
+ await apiRequest("PATCH", `/subscriptions/${id}`, { cancelAtPeriodEnd: false });
409
431
  success(`Subscription ${id} resumed`);
410
432
  } catch (err) {
411
433
  console.error(`Error: ${err.message}`);
@@ -464,11 +486,31 @@ function registerCustomerCommands(program2) {
464
486
  process.exit(1);
465
487
  }
466
488
  });
467
- customer.command("portal <id>").description("Create a customer portal session").action(async (id) => {
489
+ customer.command("delete <id>").description("Delete a customer").action(async (id) => {
468
490
  try {
469
- const data = await apiRequest("POST", `/customers/${id}/portal-session`);
470
- success("Portal session created");
471
- output(data, (d) => `Portal URL: ${d.url || d.portalUrl || JSON.stringify(d)}`);
491
+ await apiRequest("DELETE", `/customers/${id}`);
492
+ success(`Customer ${id} deleted`);
493
+ } catch (err) {
494
+ console.error(`Error: ${err.message}`);
495
+ process.exit(1);
496
+ }
497
+ });
498
+ customer.command("update <id>").description("Update a customer").option("-e, --email <email>", "New email").option("-n, --name <name>", "New name").action(async (id, opts) => {
499
+ try {
500
+ const body = {};
501
+ if (opts.email) body.email = opts.email;
502
+ if (opts.name) body.name = opts.name;
503
+ if (Object.keys(body).length === 0) {
504
+ console.error("Provide at least --email or --name to update.");
505
+ process.exit(1);
506
+ }
507
+ const data = await apiRequest("PATCH", `/customers/${id}`, body);
508
+ success("Customer updated");
509
+ output(data, (d) => [
510
+ `Customer ID: ${d.id}`,
511
+ `Email: ${d.email}`,
512
+ `Name: ${d.name || "N/A"}`
513
+ ].join("\n"));
472
514
  } catch (err) {
473
515
  console.error(`Error: ${err.message}`);
474
516
  process.exit(1);
@@ -586,8 +628,8 @@ function registerCreateCommand(program2) {
586
628
  process.exit(1);
587
629
  }
588
630
  const amountStr = await prompt("Amount (in smallest currency unit, e.g. 1000 for $10.00): ");
589
- const amount = parseInt(amountStr, 10);
590
- if (isNaN(amount) || amount <= 0) {
631
+ const unitAmount = parseInt(amountStr, 10);
632
+ if (isNaN(unitAmount) || unitAmount <= 0) {
591
633
  console.error("Invalid amount.");
592
634
  process.exit(1);
593
635
  }
@@ -613,7 +655,7 @@ function registerCreateCommand(program2) {
613
655
  console.log("Creating price...");
614
656
  const priceBody = {
615
657
  productId: product.id,
616
- amount,
658
+ unitAmount,
617
659
  type,
618
660
  currency
619
661
  };
@@ -621,8 +663,10 @@ function registerCreateCommand(program2) {
621
663
  const price = await apiRequest("POST", "/prices", priceBody);
622
664
  success(`Price created: ${price.id}`);
623
665
  console.log("Creating checkout session...");
666
+ const mode = type === "recurring" ? "subscription" : "payment";
624
667
  const session = await apiRequest("POST", "/checkout/sessions", {
625
- priceId: price.id,
668
+ mode,
669
+ lineItems: [{ priceId: price.id, quantity: 1 }],
626
670
  successUrl,
627
671
  cancelUrl
628
672
  });
@@ -634,7 +678,7 @@ Checkout URL: ${checkoutUrl}`);
634
678
  }
635
679
  output({
636
680
  product: { id: product.id, name: productName },
637
- price: { id: price.id, amount, currency, type, interval },
681
+ price: { id: price.id, unitAmount, currency, type, interval },
638
682
  checkout: { id: session.id, url: checkoutUrl }
639
683
  });
640
684
  } catch (err) {
@@ -721,7 +765,7 @@ function registerBankCommands(program2) {
721
765
  const bank = program2.command("bank").description("Manage bank accounts");
722
766
  bank.command("list").description("List all bank accounts").action(async () => {
723
767
  try {
724
- const data = await apiRequest("GET", "/bank-accounts");
768
+ const data = await apiRequest("GET", "/bank_accounts");
725
769
  output(data, (d) => {
726
770
  const items = d.data || d.bankAccounts || d;
727
771
  if (!Array.isArray(items) || items.length === 0) return "No bank accounts found.";
@@ -744,19 +788,19 @@ function registerBankCommands(program2) {
744
788
  });
745
789
  bank.command("add").description("Add a new bank account").action(async () => {
746
790
  try {
747
- const accountHolderName = await prompt2("Account holder name: ");
791
+ const accountName = await prompt2("Account holder name: ");
748
792
  const bankName = await prompt2("Bank name: ");
749
- const routingNumber = await prompt2("Routing number: ");
793
+ const bankCode = await prompt2("Bank code / routing number (press Enter to skip): ");
750
794
  const accountNumber = await prompt2("Account number: ");
751
- const accountType = await prompt2("Account type (checking/savings, default: checking): ") || "checking";
795
+ const currency = await prompt2("Currency (default: SGD): ") || "SGD";
752
796
  const body = {
753
- accountHolderName,
797
+ accountName,
754
798
  bankName,
755
- routingNumber,
756
799
  accountNumber,
757
- accountType
800
+ currency
758
801
  };
759
- const data = await apiRequest("POST", "/bank-accounts", body);
802
+ if (bankCode) body.bankCode = bankCode;
803
+ const data = await apiRequest("POST", "/bank_accounts", body);
760
804
  success("Bank account added");
761
805
  output(data, (d) => [
762
806
  `Bank Account ID: ${d.id}`,
@@ -770,7 +814,7 @@ function registerBankCommands(program2) {
770
814
  });
771
815
  bank.command("remove <id>").description("Remove a bank account").action(async (id) => {
772
816
  try {
773
- await apiRequest("DELETE", `/bank-accounts/${id}`);
817
+ await apiRequest("DELETE", `/bank_accounts/${id}`);
774
818
  success(`Bank account ${id} removed`);
775
819
  } catch (err) {
776
820
  console.error(`Error: ${err.message}`);
@@ -779,7 +823,7 @@ function registerBankCommands(program2) {
779
823
  });
780
824
  bank.command("set-default <id>").description("Set a bank account as default").action(async (id) => {
781
825
  try {
782
- await apiRequest("PATCH", `/bank-accounts/${id}`, { isDefault: true });
826
+ await apiRequest("PATCH", `/bank_accounts/${id}`, { isDefault: true });
783
827
  success(`Bank account ${id} set as default`);
784
828
  } catch (err) {
785
829
  console.error(`Error: ${err.message}`);
@@ -805,22 +849,20 @@ function registerKycCommands(program2) {
805
849
  try {
806
850
  const fullName = await prompt3("Full name: ");
807
851
  const dateOfBirth = await prompt3("Date of birth (YYYY-MM-DD): ");
808
- const address = await prompt3("Street address: ");
809
- const city = await prompt3("City: ");
810
- const state = await prompt3("State/Province: ");
811
- const postalCode = await prompt3("Postal code: ");
812
- const country = await prompt3("Country (2-letter code, e.g. SG): ");
852
+ const nationality = await prompt3("Nationality (2-letter code, e.g. SG): ");
853
+ const documentType = await prompt3("Document type (passport / national_id / drivers_license): ");
854
+ const documentNumber = await prompt3("Document number: ");
855
+ const documentFrontUrl = await prompt3("Document front image URL: ");
856
+ const documentBackUrl = await prompt3("Document back image URL (press Enter to skip): ");
813
857
  const body = {
814
858
  fullName,
815
859
  dateOfBirth,
816
- address: {
817
- line1: address,
818
- city,
819
- state,
820
- postalCode,
821
- country
822
- }
860
+ nationality,
861
+ documentType,
862
+ documentNumber,
863
+ documentFrontUrl
823
864
  };
865
+ if (documentBackUrl) body.documentBackUrl = documentBackUrl;
824
866
  const data = await apiRequest("POST", "/kyc", body);
825
867
  success("KYC submission received");
826
868
  output(data, (d) => {
@@ -839,9 +881,8 @@ function registerKycCommands(program2) {
839
881
  const data = await apiRequest("GET", "/kyc/status");
840
882
  output(data, (d) => {
841
883
  return [
842
- `Status: ${d.status || "N/A"}`,
843
- `Verified: ${d.verified ?? "N/A"}`,
844
- `Requirements: ${d.requirements ? JSON.stringify(d.requirements) : "None"}`
884
+ `Account ID: ${d.accountId || "N/A"}`,
885
+ `KYC Status: ${d.kycStatus || "N/A"}`
845
886
  ].join("\n");
846
887
  });
847
888
  } catch (err) {
@@ -949,7 +990,7 @@ function registerWebhookCommands(program2) {
949
990
 
950
991
  // src/index.ts
951
992
  var program = new Command();
952
- program.name("vibecash").description("VibeCash CLI - manage payments from the command line").version("0.2.1").option("--json", "Output in JSON format").hook("preAction", (thisCommand) => {
993
+ program.name("vibecash").description("VibeCash CLI - manage payments from the command line").version("0.2.2").option("--json", "Output in JSON format").hook("preAction", (thisCommand) => {
953
994
  const opts = thisCommand.opts();
954
995
  if (opts.json) setOutputFormat("json");
955
996
  });
package/package.json CHANGED
@@ -1,15 +1,31 @@
1
1
  {
2
2
  "name": "vibecash",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "VibeCash CLI - Payment infrastructure for the AI era. Accept cards, e-wallets, and QR payments in Southeast Asia.",
5
5
  "type": "module",
6
- "bin": { "vibecash": "./dist/index.js" },
7
- "files": ["dist"],
8
- "scripts": { "build": "tsup", "dev": "tsx src/index.ts" },
6
+ "bin": {
7
+ "vibecash": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsup",
14
+ "dev": "tsx src/index.ts"
15
+ },
9
16
  "keywords": [
10
- "payment", "cli", "checkout", "subscription", "billing",
11
- "vibecash", "ai-native", "southeast-asia", "singapore",
12
- "wechat-pay", "alipay", "paynow"
17
+ "payment",
18
+ "cli",
19
+ "checkout",
20
+ "subscription",
21
+ "billing",
22
+ "vibecash",
23
+ "ai-native",
24
+ "southeast-asia",
25
+ "singapore",
26
+ "wechat-pay",
27
+ "alipay",
28
+ "paynow"
13
29
  ],
14
30
  "author": "VibeCash",
15
31
  "license": "MIT",