{"_id":"@carts1024/velo-sdk","_rev":"2-cea8c61ad588928f67ac545993be2ffd","name":"@carts1024/velo-sdk","dist-tags":{"latest":"0.1.0-alpha.2"},"versions":{"0.1.0-alpha.1":{"name":"@carts1024/velo-sdk","version":"0.1.0-alpha.1","_id":"@carts1024/velo-sdk@0.1.0-alpha.1","maintainers":[{"name":"carts1024","email":"carlbergado67.3@gmail.com"}],"dist":{"shasum":"a606ba2a99e0188fac4196b382a173422770cae4","tarball":"https://registry.npmjs.org/@carts1024/velo-sdk/-/velo-sdk-0.1.0-alpha.1.tgz","fileCount":13,"integrity":"sha512-TWGp9aoyGsHnI0+dpP3N+D11CagHcQHZDM3Ta2Q7hiXtv1XAdI3DKFcJzbbr0jp9fKPsR4j8abYILER4i5rAFg==","signatures":[{"sig":"MEUCIQDaVt7tQu1ZxofjCG5a59Dq+n/4W2/T3+PNCHh7NWgZrgIgGeD3loiQdXH9RmTsp/tYm0W8s9LUEcHmhCPSaEVTqrI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48235},"type":"module","exports":{".":"./src/index.ts"},"gitHead":"21be3fd39716aadf6d87cd573392fa1c32301732","private":false,"scripts":{"test":"node --experimental-strip-types --test src/*.test.ts","lint:fix":"oxlint --fix . && oxfmt --write . && tsc --noEmit"},"_npmUser":{"name":"carts1024","email":"carlbergado67.3@gmail.com"},"_npmVersion":"10.9.4","description":"The official Velo SDK for Node.js and modern JavaScript environments.","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"5.9.2","@types/node":"^22.15.3","@repo/typescript-config":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/velo-sdk_0.1.0-alpha.1_1782955612935_0.34488417394628956","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-alpha.2":{"name":"@carts1024/velo-sdk","version":"0.1.0-alpha.2","private":false,"type":"module","exports":{".":"./src/index.ts"},"scripts":{"lint:fix":"oxlint --fix . && oxfmt --write . && tsc --noEmit","test":"node --experimental-strip-types --test src/*.test.ts"},"devDependencies":{"@repo/typescript-config":"workspace:*","@types/node":"^22.15.3","typescript":"5.9.2"},"_id":"@carts1024/velo-sdk@0.1.0-alpha.2","gitHead":"a1b73b0edf9bd9625dd1b9d9405cd1be1bfc7d21","description":"The official Velo SDK for Node.js and modern JavaScript environments.","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-pFGjupOdy5j8Qs5JxLkluSpSb98514HvfY2k+yFNl+TGWHIcwaokCJBIya7KSgXag2zYZHTELqE8R0ntlnCRQQ==","shasum":"73c46c1a7dfacedd1a6dae2966d28446cd18f82a","tarball":"https://registry.npmjs.org/@carts1024/velo-sdk/-/velo-sdk-0.1.0-alpha.2.tgz","fileCount":13,"unpackedSize":48493,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICJXAXknqPkuonky6ez+suybVDc5BofwTGdFVMPVqUUtAiEAgSgg5wBkT2u9CYw8P0/Zu8lu+k3twjiYcaVzpWDlb4g="}]},"_npmUser":{"name":"carts1024","email":"carlbergado67.3@gmail.com"},"directories":{},"maintainers":[{"name":"carts1024","email":"carlbergado67.3@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/velo-sdk_0.1.0-alpha.2_1782959623522_0.817149997449272"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-02T01:26:52.690Z","modified":"2026-07-02T02:33:43.823Z","0.1.0-alpha.1":"2026-07-02T01:26:53.090Z","0.1.0-alpha.2":"2026-07-02T02:33:43.683Z"},"description":"The official Velo SDK for Node.js and modern JavaScript environments.","maintainers":[{"name":"carts1024","email":"carlbergado67.3@gmail.com"}],"readme":"# Velo SDK for Node.js (Alpha)\n\nThe official Velo SDK for Node.js and modern JavaScript environments.\n\n> [!NOTE]\n> This package is currently in **Alpha** (`0.1.0-alpha.2`) and is meant for server-side environments only.\n\n## Installation\n\n```bash\nnpm install @carts1024/velo-sdk\n# or\npnpm add @carts1024/velo-sdk\n# or\nyarn add @carts1024/velo-sdk\n```\n\n## Getting Started\n\nInitialize the client with your Velo API key:\n\n```ts\nimport { Velo } from \"@carts1024/velo-sdk\";\n\nconst velo = new Velo({\n  apiKey: process.env.VELO_API_KEY!,\n  environment: \"testnet\", // 'production', 'testnet', or 'development'\n});\n```\n\n### Creating a Checkout Session\n\n```ts\nconst { checkoutUrl, paymentIntentId } = await velo.checkout.sessions.create({\n  amount: \"10.00\",\n  asset: \"USDC\",\n  description: \"Order #1001\",\n  successUrl: \"https://yourdomain.com/success\",\n  cancelUrl: \"https://yourdomain.com/cancel\",\n});\n\n// Redirect customer to the checkout URL\n```\n\n### Retrieving a Payment Intent\n\n```ts\nconst paymentIntent = await velo.paymentIntents.retrieve(\"pi_12345\");\nconsole.log(`Payment status: ${paymentIntent.status}`);\n```\n\n---\n\n## Webhook Verification\n\nVelo signs webhook events sent to your endpoints using HMAC-SHA256. Webhook verification is required to verify that incoming payloads are authentic and untampered.\n\n> [!IMPORTANT]\n> Webhook signature verification requires the **raw, unparsed request body**. Do not parse the request body as JSON prior to calling verify.\n>\n> Your webhook signing secret (`VELO_WEBHOOK_SECRET`) must remain **server-side only**. Never expose it to the browser.\n\n### Verification API\n\nYou can verify signatures using the static `Velo.webhooks.verify` method or an instance-level `velo.webhooks.verify` method:\n\n```ts\nconst event = await Velo.webhooks.verify({\n  payload: rawBody, // Raw string payload\n  signature: signatureHeader, // 'x-velo-signature' header value\n  secret: process.env.VELO_WEBHOOK_SECRET!, // Webhook signing secret\n  toleranceSeconds: 300, // Optional clock drift tolerance (default 5 minutes)\n});\n```\n\n`verify` will throw a `VeloWebhookSignatureVerificationError` (which extends `VeloValidationError`) if:\n\n- The signature is missing or malformed.\n- The timestamp is expired (older than `toleranceSeconds` or from the future).\n- The computed signature does not match the header.\n\n### Next.js App Router Example\n\n```ts\nimport { NextResponse } from \"next/server\";\nimport { Velo } from \"@carts1024/velo-sdk\";\n\nexport async function POST(request: Request) {\n  // 1. Get the raw text payload (DO NOT call request.json())\n  const payload = await request.text();\n\n  // 2. Get the signature header\n  const signature = request.headers.get(\"x-velo-signature\");\n  const secret = process.env.VELO_WEBHOOK_SECRET!;\n\n  try {\n    // 3. Verify the signature\n    const event = await Velo.webhooks.verify({\n      payload,\n      signature,\n      secret,\n    });\n\n    // 4. Handle typed events\n    switch (event.type) {\n      case \"payment.succeeded\": {\n        const paymentIntent = event.paymentIntent;\n        console.log(`Payment succeeded for amount: ${paymentIntent.amount}`);\n        break;\n      }\n      case \"payment.failed\": {\n        console.log(`Payment failed: ${event.paymentIntent.id}`);\n        break;\n      }\n      case \"payment_access.activated\": {\n        console.log(`Project payment access activated!`);\n        break;\n      }\n      default:\n        console.log(`Unhandled event type: ${event.type}`);\n    }\n\n    return NextResponse.json({ received: true });\n  } catch (error) {\n    console.error(\"Signature verification failed:\", error);\n    return new NextResponse(\"Webhook signature verification failed\", { status: 400 });\n  }\n}\n```\n\n### Express.js Example\n\nEnsure you capture the raw body as a string. You can use `express.raw` middleware for this specific route.\n\n```ts\nimport express from \"express\";\nimport { Velo } from \"@carts1024/velo-sdk\";\n\nconst app = express();\n\napp.post(\"/webhooks\", express.raw({ type: \"application/json\" }), async (req, res) => {\n  // 1. Get raw string payload\n  const payload = req.body.toString(\"utf8\");\n\n  // 2. Get the signature header\n  const signature = req.headers[\"x-velo-signature\"];\n  const secret = process.env.VELO_WEBHOOK_SECRET!;\n\n  try {\n    // 3. Verify signature\n    const event = await Velo.webhooks.verify({\n      payload,\n      signature: Array.isArray(signature) ? signature[0] : signature || null,\n      secret,\n    });\n\n    // 4. Handle events\n    if (event.type === \"payment.succeeded\") {\n      console.log(`Payment succeeded: ${event.paymentIntent.id}`);\n    }\n\n    res.status(200).send(\"OK\");\n  } catch (error) {\n    console.error(\"Signature verification failed:\", error);\n    res.status(400).send(\"Webhook signature verification failed\");\n  }\n});\n```\n\n---\n\n## Environment Variables\n\nConfigure the following environment variables in your server environments:\n\n| Variable              | Required          | Description                                                                                     |\n| --------------------- | ----------------- | ----------------------------------------------------------------------------------------------- |\n| `VELO_API_KEY`        | **Yes**           | Your Velo project API key (e.g. `tk_live_...` or `tk_test_...`).                                |\n| `VELO_WEBHOOK_SECRET` | Only for Webhooks | Used to verify signature of incoming webhook events.                                            |\n| `VELO_BASE_URL`       | No                | Overrides the default Velo API endpoint (defaults to `https://api.velo.xyz` or local dev base). |\n\n---\n\n## Idempotency\n\nTo prevent double-charging or duplicate session creation due to network retries, pass an `idempotencyKey` in the `RequestOptions` object as the second parameter:\n\n```ts\nconst session = await velo.checkout.sessions.create(\n  {\n    amount: \"10.00\",\n    asset: \"USDC\",\n    description: \"Order #1001\",\n  },\n  {\n    idempotencyKey: \"unique-order-id-1001\", // Prevents duplicates\n  },\n);\n```\n\nIdempotency keys are scoped to your project. Repeating a request with the same payload and same key will return the cached original response. Repeating with a different payload will throw a `VeloAPIError` with status code `409` (conflict).\n\n---\n\n## Testnet vs Mainnet & Alpha Limitations\n\n> [!WARNING]\n> This SDK is currently in **Alpha** (`0.1.0-alpha.2`) and subject to changes.\n>\n> - **Stellar Testnet Only**: During the alpha phase, all transactions and checkout sessions are routed through the Stellar Testnet. Mainnet is currently unsupported.\n> - **ESM-Only**: The package uses ESM exports and requires `\"type\": \"module\"` or an ESM-compatible bundler/environment. CommonJS `require()` is not supported directly.\n> - **Server-Side Only**: The SDK initializes and communicates using highly sensitive API keys and secrets. Do **NOT** use this SDK in browser environments or client-side code as it will leak your API credentials.\n> - **Browser Limitations**: Direct wallet connection, browser-based payment tracking, and front-end React components are excluded from the current alpha release.\n","readmeFilename":"README.md"}