For developers

Add Veyro to your app.

You already built something. This is how it takes money: one product ID, one button, and nothing about payment infrastructure that you have to learn first.

@veyro/sdk is not on npm yet
Everything on this page is built and the endpoints are live, but the package has not been published, so npm install @veyro/sdk will answer 404 today. Until it does, the same thing works with no package at all — see Without the SDK below. This notice comes down when the install works.

1. What you need

A product with a price

Made on your Veyro dashboard. Its ID is what the button needs.

A guardian, if you are under 18

They complete the payment provider’s identity form once. The steps, in order.

That is it

No API keys, no webhook to set up, no server code. Veyro holds none of your customer’s card details and neither does your app.

2. Install it

Terminal
npm install @veyro/sdk

3. Add the button

React, with the component:

React
import { VeyroCheckout } from "@veyro/sdk/react";

export function BuyButton() {
  return (
    <VeyroCheckout
      productId="your-product-id"
      onSuccess={(transactionId) => {
        // The money has landed. Unlock the thing, send the file, show a receipt.
        console.log("paid", transactionId);
      }}
      onError={(error) => {
        console.error(error.message, error.fixPrompt);
      }}
    >
      Buy now — $25
    </VeyroCheckout>
  );
}

Anything else — Vue, Svelte, plain HTML — with the same function underneath:

Any framework
import { openCheckout } from "@veyro/sdk";

document.querySelector("#buy").addEventListener("click", () => {
  openCheckout("your-product-id", {
    onSuccess: (transactionId) => { /* … */ },
    onError: (error) => console.error(error.message, error.fixPrompt),
  });
});

Call it inside the click, with no await before it. Checkout opens in a window, and a browser blocks a window opened after an await — which looks like the button doing nothing at all.

Without the SDK

The package is a convenience, not a requirement — it calls two public endpoints. This does the same job with no dependency, and works today whether or not the package is published.

Plain fetch
async function buy(productId) {
  const res = await fetch("https://withveyro.com/api/checkout/create", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ productId }),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data.error);

  window.open(data.checkoutUrl, "_blank");

  // Ask every couple of seconds whether the payment has landed.
  for (;;) {
    await new Promise((r) => setTimeout(r, 2000));
    const s = await fetch(
      "https://withveyro.com/api/checkout/status?intent=" + data.intentId,
    ).then((r) => r.json());
    if (s.status === "completed") return s.transactionId;
  }
}

4. Check it before you ship

Paste this into your browser console, anywhere. It answers from Veyro, so it tells you about your product rather than about your code.

Browser console
await fetch("https://withveyro.com/api/integration-test", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ productId: "your-product-id" }),
}).then((r) => r.json()).then(console.log);

Every field is something the server can actually see. It cannot tell whether the package is installed in your project — nothing on our side can — so it does not pretend to.
readyToLaunch: true means a customer opening your link right now would get a payment form.

5. Go live

There is no switch. Once that check comes back ready, the button takes real money. Your first payment appears in your wallet, and the wallet shows what has settled and what is still on its way.


If an AI tool is writing this for you

Copy one of these, fill in the brackets, and paste it in. They are written so the assistant changes the payment button and nothing else.

Claude Code, or Cursor
Add Veyro payments to my [framework] project.

- Install the SDK: npm install @veyro/sdk
- Product ID: [paste it from your Veyro dashboard]
- Add a "Buy now" button on [which page]
- Import { VeyroCheckout } from "@veyro/sdk/react" and use it for the button
- On successful payment, [what should happen]
- Keep the existing design and do not change anything else
- Follow the official docs at https://withveyro.com/docs/sdk
Lovable, or another in-browser builder
Add Veyro payments to this project using the npm package @veyro/sdk.

- Add a button that opens Veyro checkout for product ID [paste it here]
- Handle both the success and the error callback
- Show the customer something after a successful payment
- Do not change the rest of the design
When something is not working
Veyro checkout is not working in my app. The error is:

[paste the whole error, including the fixPrompt if there is one]

Read https://withveyro.com/docs/sdk and fix only what that error points at.

When something goes wrong

Every refusal comes back with a code, a sentence in plain words, and a fixPrompt you can act on or paste back into whatever wrote the integration. This table is generated from the same source the API answers from, so it cannot fall out of date.

CodeWhat it meansWhat to do
product_not_foundNo product with that ID.The product ID does not match anything on Veyro. Open your Veyro dashboard, copy the ID from the product row, and replace the one in the code.
product_not_liveThat product is a draft, so it cannot take a payment yet.The product exists but is not published. Open your Veyro dashboard, edit the product and set its status to Live. The checkout link does not change when you do.
price_not_setThat product has no price.Open your Veyro dashboard, edit the product and give it a price. Nothing can be charged until there is an amount to charge.
price_below_minimumThat price is below what a card network will process.Card payments have a minimum of roughly $0.50. Edit the product on your Veyro dashboard and raise the price above it.
payments_not_set_upThis account cannot take payments yet.Payment setup is not finished. If you are under 18 this is your guardian's step: invite them from your Veyro dashboard, and they complete Stripe's identity form as themselves. Nothing can be charged until Stripe has accepted them.
no_product_idNo product ID was sent.The call reached Veyro without a productId. Check that the productId prop is set and is not undefined when the button is clicked.
rate_limitedToo many attempts from here. Wait a moment.Checkout is being started more often than a person could click. Make sure the checkout call runs inside the click handler and not on every render.
not_configuredPayments are not configured on this server.This one is ours, not yours. Email hello@withveyro.com and we will look.
stripe_unavailableWe could not reach the payment provider. Nothing has been charged.A temporary problem between Veyro and Stripe. Try again in a moment; if it keeps happening, email hello@withveyro.com.

Where the card details go

Not to your app, and not to your server. The button opens Veyro’s own checkout page, and the card form on it belongs to Stripe. Your site never receives a card number, which is why this package needs no keys and asks for no configuration.

The payment goes straight to your Stripe account. Veyro is never in the path of the money. How that works