Crea una aplicación, conecta el consentimiento OAuth del merchant y llama a los endpoints de productos, pedidos y clientes con un token de acceso. Todo lo que necesitas para lanzar tu integración en producción.

Esta es la guía de APPS.
Si lo que construyes son TEMAS (plantillas de tienda con Liquid), esa es una documentación distinta. Las apps y los temas no comparten estructura, tokens ni flujos — no mezcles ambos contenidos. Ve a la guía de temas. A continuación solo hablamos de apps e integraciones.
Una app en VELSEFY es una integración OAuth 2.0: tú creas una aplicación, el merchant la autoriza desde su tienda y tu app recibe un token para llamar a la API. Es la forma estándar de conectar tu producto con tiendas VELSEFY.
Lo que puedes construir y modificar:
Consentimiento explícito del merchant. Tu app pide permisos (scopes) y solo accede a lo que el merchant aprueba.
Endpoints para productos, pedidos y clientes, con respuestas JSON y autenticación por token Bearer.
El cliente @velsefy/api-client envuelve la API en TypeScript, sin dependencias externas.
Pide solo lo que necesitas. Cada permiso es un capability declarado en la app y aprobado por el merchant.
El flujo típico es crear la app → autorizar → obtener token → llamar la API. Empezá por el Quickstart para tener un flujo completo funcionando en minutos.
El único requisito es una cuenta de partner. Crear una app en el panel te da un client_id y un client_secret; el resto es seguir el flujo de autorización.
Entra a partners.velsefy.com/apps, pulsa Crear App y configúrala: nombre, URL de redirección (redirect URI) y los scopes que necesite. Al terminar tienes tu client_id y client_secret.
Guarda tu client_secret
Redirige al merchant a la pantalla de consentimiento con tu client_id, la redirect_uri y los scope. Cuando aprueba, vuelve a tu URL con un code de autorización. Ver Autenticación OAuth 2.0.
En tu servidor, envía el code al token endpoint junto con tus credenciales. Recibirás un access_token (y un refresh_token para renovarlo).
Envía el token como Authorization: Bearer <access_token> en cada petición a https://api.velsefy.com/v1. Ya puedes leer y escribir productos, pedidos y clientes.
client_secret siempre en el servidor, nunca en el frontend. El canje de tokens ocurre backend-to-backend.access_token de forma segura y renóvalo con el refresh_token antes de que expire.OAuth 2.0 delega el acceso: el merchant nunca comparte su contraseña, sino que aprueba que tu app acceda a los recursos que indiquen los scope. El flujo completo es authorize → token → API.
| Paso | Qué ocurre | Quién participa |
|---|---|---|
| authorize | El merchant ve el consentimiento con los scopes solicitados y lo aprueba. Vuelves con un code. | Navegador ↗ tu app |
| token | Tu servidor canjea el code por un access_token (y un refresh_token). | Tu servidor ↔ VELSEFY |
| API | Llamas a los endpoints enviando el access_token como Bearer. | Tu app ↔ API |
Construye la URL de consentimiento. Los parámetros clave son response_type=code (flujo Authorization Code), client_id, redirect_uri, scope y un state opaco contra CSRF.
GET <AUTHORIZE_URL>?response_type=code
&client_id=<TU_CLIENT_ID>
&redirect_uri=https://miapp.com/oauth/callback
&scope=read_products write_products read_orders
&state=<OPAQUE_STATE>
# El merchant aprueba → al redirect_uri llega:
# https://miapp.com/oauth/callback?code=<AUTH_CODE>&state=<OPAQUE_STATE>En tu servidor, intercambia el code por un token enviando tus credenciales. Esto nunca debe correr en el navegador.
curl -X POST <TOKEN_URL> \
-u "<TU_CLIENT_ID>:<TU_CLIENT_SECRET>" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=<AUTH_CODE>" \
-d "redirect_uri=https://miapp.com/oauth/callback"{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "d1f8c2a0e91b4d3fbf7e8a6c2d19e034",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read_products write_products read_orders"
}El access_token es temporal (expires_in segundos). Cuando expira, usa el refresh_token para pedir uno nuevo sin volver a pedir consentimiento al merchant: grant_type=refresh_token. Esto mantiene la sesión activa sin incomodar al usuario.
curl -X POST <TOKEN_URL> \
-u "<TU_CLIENT_ID>:<TU_CLIENT_SECRET>" \
-d "grant_type=refresh_token" \
-d "refresh_token=<REFRESH_TOKEN>"Con el token listo, cada petición usa el header de autorización:
curl https://api.velsefy.com/v1/products \
-H "Authorization: Bearer <ACCESS_TOKEN>"Nunca metas tus credenciales en el frontend
El client_secret y el canje del code se hacen solo en tu servidor. Exponerlos en el navegador permitiría a cualquiera obtener tokens en nombre de tus merchants.
Todos los endpoints comparten la base https://api.velsefy.com/v1 y requieren el header Authorization: Bearer <access_token>. Las respuestas devuelven JSON.
| Recurso | Método | Qué hace |
|---|---|---|
| /products | GET | Lista productos (con paginación por limit/offset). |
| /products | POST | Crea un producto. |
| /products?id= | PUT | Actualiza un producto. |
| /products?id= | DELETE | Desactiva (borrado lógico) un producto. |
| /orders | GET | Lista pedidos. |
| /orders | POST | Crea un pedido. |
| /customers | GET | Lista clientes. |
| /customers | POST | Crea un cliente. |
curl "https://api.velsefy.com/v1/products?limit=20&offset=0&fields=id,name,price" \
-H "Authorization: Bearer <ACCESS_TOKEN>"{
"products": [
{ "id": "8f4b3c2a", "name": "Café de origen", "price": 12990 },
{ "id": "2d7e9f10", "name": "Taza premium", "price": 8990 }
]
}curl -X POST "https://api.velsefy.com/v1/products" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "name": "Producto nuevo", "price": 14990, "sku": "PN-001" }'curl -X PUT "https://api.velsefy.com/v1/products?id=<PRODUCT_ID>" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "price": 16990 }'
curl -X DELETE "https://api.velsefy.com/v1/products?id=<PRODUCT_ID>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"curl "https://api.velsefy.com/v1/orders?limit=10" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
curl -X POST "https://api.velsefy.com/v1/orders" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "Cliente Demo",
"items": [
{ "price": 12990, "qty": 2 },
{ "price": 8990, "qty": 1 }
]
}'{
"success": true,
"order": {
"id": "abc123",
"ticket_number": 1042,
"status": "open",
"total": 34970,
"customer_name": "Cliente Demo"
}
}curl "https://api.velsefy.com/v1/customers?limit=5" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
curl -X POST "https://api.velsefy.com/v1/customers" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "name": "Nuevo Cliente", "email": "cliente@correo.com" }'limit y offset para paginar listados grandes y no descargar todo de una vez.fields que necesitas con ?fields=id,name,price para aligerar las respuestas.Los scopes son el contrato de capacidades de tu app. Declarás cuáles necesitas al crear la app y cada uno se traduce en un permiso concreto sobre la API. El merchant los ve en pantalla antes de aprobar.
| Scope | Capacidad que otorga |
|---|---|
| read_products | Leer el catálogo de productos de la tienda. |
| write_products | Crear, actualizar y desactivar productos. |
| read_orders | Leer los pedidos de la tienda. |
| write_orders | Crear pedidos en nombre de la tienda. |
| read_customers | Leer la información de los clientes. |
| write_customers | Crear y actualizar clientes. |
Otorgan acceso de lectura a un recurso: puedes listar y consultar su información.
Otorgan acceso de escritura: puedes crear, actualizar y (según el recurso) eliminar.
Pide solo lo que necesitas
Cada scope extra es una garantía adicional que pides al merchant. Solicitar permisos que no vas a usar reduce la conversión de instalación y complica la revisión. Empieza con el mínimo y amplía solo cuando sea necesario.
El SDK oficial en TypeScript envuelve la API y te ahorra construir los fetch a mano. Cero dependencias externas y compatible con Node.js, Deno y navegadores. Solo necesita tu accessToken.
npm install @velsefy/api-clientLuego crea el cliente y usa la sección que corresponda:
import { VelsefyClient } from "@velsefy/api-client";
const client = new VelsefyClient({
accessToken: "<ACCESS_TOKEN>",
baseUrl: "https://api.velsefy.com/v1", // opcional (default este)
});
// Listar productos
const { products } = await client.products.list({
limit: 20,
offset: 0,
fields: ["id", "name", "price"],
});
// Crear un pedido
const { order } = await client.orders.create({
customer_name: "Cliente Demo",
items: [{ price: 12990, qty: 2 }],
});
// Listar clientes
const { customers } = await client.customers.list({ limit: 5 });| Sección | Métodos |
|---|---|
| products | list · create · update · delete |
| orders | list · create |
| customers | list · create |
Respuesta y errores
Todos los métodos devuelven el JSON del servidor. En caso de error lanzan un Error con el formato VELSEFY SDK [status]: mensaje, para que manejes los fallos de forma consistente.
Los webhooks permiten que la plataforma notifique a tu app cuando ocurre un evento en una tienda (por ejemplo, un pedido nuevo). Aún están en desarrollo.
Próximamente
Este apartado se completará cuando el sistema de eventos esté disponible. Mientras tanto, puedes integrarte con la API de forma activa (leer/escribir) y mantener tu flujo en la pantalla de consentimiento y el token de acceso.
Vamos a crear una app, autorizar una tienda y crear un producto con el SDK. El código corre en tu servidor.
En partners.velsefy.com/apps crea una app con la redirect URI https://miapp.com/oauth/callback y el scope read_products write_products. Guarda el client_id y client_secret en variables de entorno de tu servidor.
const authUrl = `${AUTHORIZE_URL}?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${CALLBACK_URL}&scope=read_products+write_products&state=${state}`;
// 1. Redirige al merchant → aprueba → vuelve con ?code=...
// 2. En tu servidor, canjea el code por un token:
const res = await fetch(TOKEN_URL, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic " + Buffer.from(CLIENT_ID + ":" + CLIENT_SECRET).toString("base64"),
},
body: new URLSearchParams({
grant_type: "authorization_code",
code: authCode,
redirect_uri: CALLBACK_URL,
}),
});
const { access_token } = await res.json();import { VelsefyClient } from "@velsefy/api-client";
const client = new VelsefyClient({
accessToken: access_token,
baseUrl: "https://api.velsefy.com/v1",
});const { success, product } = await client.products.create({
name: "Café de origen", // obligatorio
price: 12990, // obligatorio
sku: "CO-001", // opcional
});
if (success) {
console.log("Producto creado:", product.id, product.name);
} else {
console.warn("El servidor respondió:", product);
}const res = await fetch(TOKEN_URL, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic " + Buffer.from(CLIENT_ID + ":" + CLIENT_SECRET).toString("base64"),
},
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: refresh_token,
}),
});
const { access_token, refresh_token } = await res.json();Si algo falla
Un code inválido o un token vencido devuelve errores HTTP que el SDK transforma en VELSEFY SDK [status]: mensaje. 401 indica token faltante/expirado; 403 que falta un scope. Verifica que la app tenga el scope que usas y que el token no haya expirado.
Materiales de apoyo para profundizar: el SDK, la guía de temas y el panel donde creas y administras apps.
El código fuente y la referencia del cliente @velsefy/api-client con todos los tipos y ejemplos.
Si construyes plantillas de tienda con Liquid, esa es una documentación distinta: docs de temas.
Crea y administra tus aplicaciones, obtén tus credenciales y revisa la configuración de scopes y redirect URIs: partners.velsefy.com/apps.
Esta misma guía es el punto de partida: la sección de Endpoints de la API describe cada recurso y su operación.
¿Dónde encuentro el SDK?
Se instala desde npm con npm install @velsefy/api-client. El repositorio es público y el paquete no incluye secretos: el token lo provees siempre en runtime.