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.
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
npm install @veyro/sdk
3. Add the button
React, with the component:
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:
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.
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.
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.
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/sdkAdd 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
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.
| Code | What it means | What to do |
|---|---|---|
| product_not_found | No 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_live | That 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_set | That 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_minimum | That 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_up | This 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_id | No 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_limited | Too 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_configured | Payments are not configured on this server. | This one is ours, not yours. Email hello@withveyro.com and we will look. |
| stripe_unavailable | We 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