@puertochenta/pay-sdk
v1.3.0
Published
SDK oficial de PuertoChenta Pay — pagos USDC sobre Stellar (sin custodia).
Maintainers
Readme
@puertochenta/pay-sdk
SDK TypeScript para integrar PuertoChenta Pay (pagos USDC sobre Stellar). Publicado como paquete independiente, con builds ESM + CJS y tipos incluidos.
Instalación
npm install @puertochenta/pay-sdkFunciona en Node ≥ 18, Edge Runtime, Cloudflare Workers y navegador (la verificación de firmas usa cripto en JS puro).
⚠️ La API key (
pk_live_…/pk_test_…) es un secreto de servidor. Nunca la incluyas en código de frontend ni en bundles del navegador. Para mostrar el pago al cliente final usapaymentUri/checkoutUrl/qrCode(no requieren key). Por seguridad, el cliente exigebaseUrlcon HTTPS (salvolocalhost).
Uso
import { PuertoChentaPay } from "@puertochenta/pay-sdk"; // en este repo: "@/sdk"
// Solo tu API key: por defecto apunta a https://pay.puertochenta.com/api
const client = new PuertoChentaPay({ apiKey: "pk_live_xxx" });
// (Self-host / tests) puedes sobreescribir el endpoint:
// const client = new PuertoChentaPay({ apiKey: "pk_test_xxx", baseUrl: "https://otra/api" });
// Overrides por llamada (reintentos / timeout / cancelación):
await client.payments.create(params, { maxRetries: 0, timeoutMs: 5000 });
// Crear un pago (idempotente opcional)
const payment = await client.payments.create({
amount: "25.00",
externalOrderId: "ORDER-1001",
description: "Compra de producto",
metadata: { customerEmail: "[email protected]" },
idempotencyKey: "ORDER-1001",
});
// Consultar / cancelar / listar
const fresh = await client.payments.retrieve(payment.id);
await client.payments.cancel(payment.id);
const { data } = await client.payments.list({ status: "confirmed" });Verificar webhooks
La verificación está implementada en JS puro (sin node:crypto), por lo que
funciona en Node, Edge Runtime, Cloudflare Workers y navegador.
import { PuertoChentaPay } from "@puertochenta/pay-sdk";
const ok = PuertoChentaPay.webhooks.verifySignature({
payload: rawBody, // cuerpo CRUDO del request
signature: req.headers["x-puertochenta-signature"],
timestamp: req.headers["x-puertochenta-timestamp"],
secret: process.env.WEBHOOK_SECRET, // whsec_…
});
if (!ok) return res.status(400).end();O en un solo paso con constructEvent (verifica + parsea + tipa; lanza si la firma
es inválida):
const event = PuertoChentaPay.webhooks.constructEvent({
payload: rawBody,
signature: req.headers["x-puertochenta-signature"],
timestamp: req.headers["x-puertochenta-timestamp"],
eventType: req.headers["x-puertochenta-event"],
secret: process.env.WEBHOOK_SECRET,
});
// event.type === "payment.confirmed" · event.data es el pagoListar todo y cancelar peticiones
// Auto-paginación (recorre todas las páginas):
for await (const payment of client.payments.listAll({ status: "confirmed" })) {
console.log(payment.id);
}
// AbortSignal por petición:
const ac = new AbortController();
const p = client.payments.retrieve("pay_1", { signal: ac.signal });
ac.abort();Códigos QR
Genera un QR para que el cliente pague escaneándolo con su wallet Stellar. El QR
codifica un URI SEP-0007 (web+stellar:pay?...) que precarga destino, monto,
asset y memo en wallets compatibles (Lobstr, Freighter, etc.).
Las funciones de URI no tienen dependencias. La imagen del QR usa el paquete
opcional qrcode (peer dependency): instálalo solo si lo necesitas.
npm install qrcodeconst payment = await client.payments.create({ amount: "25.00", externalOrderId: "ORDER-1001" });
// Solo strings (sin dependencias):
const uri = client.payments.paymentUri(payment); // web+stellar:pay?destination=...&amount=...&memo=...
const url = client.payments.checkoutUrl(payment); // https://pay.midominio.com/pay/<id>
// Imagen del QR (requiere 'qrcode'):
const pngDataUrl = await client.payments.qrCode(payment); // data:image/png;base64,...
const svg = await client.payments.qrCode(payment, { type: "svg" });
const qrCheckout = await client.payments.qrCode(payment, { encode: "checkout" }); // QR de la URL hospedada// En un frontend basta con incrustar el data URL:
<img src={pngDataUrl} alt="Escanea para pagar" />También se exportan como funciones puras: buildStellarUri, buildCheckoutUrl,
qrToDataUrl, qrToSvg. Si qrcode no está instalado, las funciones de imagen lanzan
PuertoChentaPayError (código qrcode_missing); los builders de URI siguen funcionando.
Manejo de errores
Las respuestas no exitosas lanzan PuertoChentaPayError con status, code y message.
El cliente reintenta automáticamente ante errores de red, 5xx y 429.
Publicación (mantenedores)
El código fuente vive en src/sdk/ del repo principal. Para publicar a npm:
# desde la raíz del repo
npm run sdk:build # compila a src/sdk/dist (ESM + CJS + .d.ts) con tsup
npm run sdk:pack # opcional: genera el .tgz para inspeccionar el contenido
cd src/sdk
npm version patch # sube la versión (patch/minor/major)
npm publish # 'prepublishOnly' reconstruye el dist automáticamenteEl paquete solo incluye dist/ y README.md (campo files). Scope @puertochenta
publicado como público (publishConfig.access = public); requiere estar logueado
(npm login) con acceso a la organización.
