Ir al contenido

Guías

Receta: créditos de API

Vende créditos prepagados para una API o una función de IA y descuenta uno por llamada. Si no alcanza el saldo, responde 402 con un enlace de recarga.

Ver como Markdown

Los compradores pagan por adelantado un paquete de créditos; cada llamada gasta algunos. Perly Pay lleva la cuenta: el gasto es una sola llamada atómica que no baja de cero, y cada comprador tiene su propia página de recarga. Nada se cobra solo: cuando se acaban los créditos, el comprador recarga. Todo sobre los créditos está en Sell credits; aquí, la receta alrededor.

Con un asistente: la skill sell-credits del plugin de Perly Pay hace esta receta en tu proyecto. El ejemplo ejecutable es examples/api-credits (MIT) en el repositorio del plugin.

Cómo funciona

  1. 1

    Un paquete de créditos

    Un producto y un precio con model: "credit_pack", unit_amount en centavos y credits. Una vez por modo.

  2. 2

    Tus usuarios son clientes

    Se crean una vez con external_id (tu id de usuario); después, credits.* aceptan ese id.

  3. 3

    Recargas

    credits.topUpUrl(userId) es la página propia del comprador: elige un paquete y paga. Cada paquete pagado suma créditos.

  4. 4

    Gasto por llamada

    Primero credits.consume(userId, cost, { idempotencyKey }), luego el trabajo. Un reintento con la misma clave devuelve el primer gasto, así que la clave de cada llamada la genera tu servidor y nunca la toma de quien llama.

  5. 5

    ¿No alcanza?

    insufficient_credits (409) no gasta nada: responde 402 con la página de recarga, no un 500.

Spend one request's credits
try {
  await pay.credits.consume(userId, cost, { product: PRODUCT, action: "api", idempotencyKey: `req-${userId}-${requestId}` });
} catch (e) {
  if (e.code !== "insufficient_credits") throw e;
  return reply(402, { top_up: await pay.credits.topUpUrl(userId, { product: PRODUCT }) });
}
// now do the work

Ejecuta el ejemplo

  1. 1

    Instala

    npm install en examples/api-credits (Node 20.12+).

  2. 2

    Clave

    Copia .env.example a .env y pon una clave de prueba (sk_test_…) en PERLY_PAY_SECRET_KEY.

  3. 3

    Prepara

    npm run setup crea el producto y el precio con tu clave e imprime sus ids para .env.

  4. 4

    Ejecuta

    npm start (o npm run dev), según diga su README.

  5. 5

    Paga sin billetera

    Llama a POST /v1/shout (402), abre la página que da POST /top-up, elige un paquete, pulsa Simulate payment en la factura y llama otra vez: 200 y X-Credits-Remaining: 499.

Errores comunes

  • Gastar sin clave de idempotencia: una llamada repetida descuenta dos veces.
  • Tomar la clave del gasto de lo que envía el cliente (una cabecera Idempotency-Key): la misma clave devuelve el primer gasto como éxito y el cliente vuelve a recibir el trabajo sin pagar.
  • Consultar el saldo y luego gastar en dos pasos. consume ya impide bajar de cero; el saldo es para mostrarlo.
  • Primero el trabajo, luego el gasto. Al revés: primero el gasto.
  • Ids de prueba con una clave real. Productos, precios y webhooks pertenecen a un modo: antes de lanzar, repite la configuración con sk_live_….