Primeros pasos
Inicio rápido con npx
Un comando configura Perly Pay en tu proyecto: la ruta de pago, la ruta del webhook con verificación de firma, un botón Pay y tu clave de prueba.
npx perly-pay init lee tu proyecto, escribe código para su framework y te deja a un clic de un pago de prueba. Solo configura el modo de prueba; el modo real se activa en el panel.
Ejecútalo
Detecta el framework y el gestor de paquetes, abre Dashboard → Developers y pide una clave de prueba (sk_test_…). Rechaza una clave real.
Qué escribe
| Framework | Cómo lo detecta | Archivos |
|---|---|---|
| Next.js (App Router) | next | lib/perly-pay.ts, app/api/perly-pay/checkout/route.ts, app/api/perly-pay/webhook/route.ts, components/PayButton.tsx, app/perly-pay/page.tsx |
| Express | express | lib/perly-pay.js, routes/perly-pay.js |
| Hono | hono | lib/perly-pay.ts, routes/perly-pay.ts |
| Laravel | artisan, laravel/framework | app/Http/Controllers/PerlyPayController.php, routes/perly-pay.php, config/perly-pay.php, resources/views/perly-pay/button.blade.php |
| Node.js | cualquier otro package.json | lib/perly-pay.js, perly-pay.js (node:http) |
TypeScript o JavaScript, módulos ES o CommonJS, como tu proyecto, y en src/ si tu código está ahí. npm, pnpm, yarn, bun y Composer.
- Pago. El botón envía un formulario a
/perly-pay/checkout(/api/perly-pay/checkouten Next.js). Abre una factura y lleva al comprador a pagarla. - Webhook.
/perly-pay/webhookverificaPerly-Signaturesobre el cuerpo en bruto. Coninvoice.fulfilledllama agrantAccess(), el único TODO que escribes tú. - Planes. Ventas únicas y paquetes de créditos, en
PLANSal principio del módulo principal. El plan, sus créditos y tu id de usuario viajan en los metadatos de la factura y vuelven en el webhook. - Claves.
PERLY_PAY_SECRET_KEYyPERLY_PAY_WEBHOOK_SECRETen.env.local(Next.js) o.env, y el archivo en.gitignore. Si git ya sigue ese archivo, init no escribe la clave en él y te dice cómo dejar de seguirlo.
--force sí.Conecta el webhook
Perly Pay tiene que llegar a la dirección del webhook. Añádela en Dashboard → Developers → Webhooks para invoice.fulfilled y pega su secreto whsec_… en PERLY_PAY_WEBHOOK_SECRET. O deja que init haga las dos cosas:
npx perly-pay init --webhook-url https://your-app.example/perly-pay/webhookEn un portátil, un túnel te da una dirección pública: cloudflared tunnel --url http://localhost:3000. Más en Webhooks.
Un pago en modo de prueba
- 1
Arranca tu app
Express y Node leen
.envconnode --env-file=.envo dotenv. - 2
Abre /perly-pay
Pulsa Pay with crypto. Estás en la página de pago.
- 3
Simulate payment
La factura pasa a pagada y luego a entregada. Ver Modo de prueba.
- 4
Mira cómo actúa grantAccess
Tu webhook recibe
invoice.fulfilled. Ahora escribe qué da.
Con un asistente de IA
--yes no pregunta nada, así que Claude Code, Cursor o Codex pueden ejecutarlo por ti. Dale la clave y lo que vendes:
npx perly-pay init --yes --key sk_test_… --product "Logo review" --amount 4900--json imprime un resultado que el asistente puede leer.
Opciones
| Flag | Qué hace |
|---|---|
--yes, -y | Sin preguntas. Para asistentes de IA y scripts. |
--framework <name> | next, express, hono, laravel o node, si no acertó. |
--key <sk_test_…> | Tu clave de prueba. Por defecto: PERLY_PAY_SECRET_KEY, o la pregunta. |
--webhook-url <url> | Registra la dirección para invoice.fulfilled y guarda su secreto. |
--product <name>, --amount <cents>, --currency <code> | Qué vendes, en USD o EUR. --amount 4900 es $49.00. |
--install | Además instala el SDK. Si no, imprime el comando. |
--force | Reemplaza los archivos y valores que ya existen. |
--plugin, --mcp | Imprime cómo añadir el plugin de Claude Code y el servidor perly-pay-mcp. |
--dry-run | Dice qué haría, sin escribir nada. |
--json | Imprime el resultado como JSON. |
--api <origin>, --dir <path> | Otro Perly Pay (local), otra carpeta. |
Modo real
- Conecta las claves reales de tu billetera en Dashboard → Wallets.
- Crea una clave real (
sk_live_…) y un webhook real. - Configúralos donde se ejecuta tu app. El código se queda igual. El resto de la API está en los SDK.