@hanix.io/business
v0.4.0
Published
SDK oficial de Node.js para la Hanix Business API (pagos, checkout, pedidos, envíos, catálogo y webhooks con autenticación HMAC)
Downloads
255
Maintainers
Readme
@hanix.io/business
SDK oficial de Node.js para la Hanix Business API: órdenes de pago, checkout, pedidos de venta, envíos, catálogo (merchant y storefront), webhooks y métodos PSP con autenticación HMAC-SHA256.
Instalación
npm install @hanix.io/businesspnpm add @hanix.io/businessRequisitos
- Node.js 22.12 o superior
- merchantId: UUID del comercio (cabecera
business-merchant-id) - apiKey: secreto HMAC del comercio (no se envía en la red; solo firma las solicitudes). Obtén ambos en el panel Hanix o en
GET /merchants/mecon tu sesión merchant.
El SDK apunta por defecto a https://api.hanix.io/api/v1.
Inicio rápido
import { HanixBusinessClient } from '@hanix.io/business';
const client = new HanixBusinessClient({
merchantId: process.env.HANIX_MERCHANT_ID!,
apiKey: process.env.HANIX_API_KEY!,
});
const order = await client.createPaymentOrder({
merchant_reference: 'pedido-1001',
amount_in_cents: 15000,
currency_id: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
country_id: 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy',
description: 'Suscripción mensual',
customer_email: '[email protected]',
});
console.log(order.payment_url);API del cliente
new HanixBusinessClient(options)
| Opción | Obligatorio | Descripción |
|--------|-------------|-------------|
| merchantId | Sí | UUID del comercio |
| apiKey | Sí | Clave API (secreto HMAC) |
| timeoutMs | No | Tiempo máximo por solicitud (default: 30000) |
| fetch | No | Implementación de fetch (tests o entornos custom) |
| userAgent | No | Cabecera User-Agent (default: @hanix.io/business) |
createPaymentOrder(input)
Crea una orden de pago (POST /business/payment-orders).
Campos obligatorios: merchant_reference, amount_in_cents, currency_id, country_id.
Opcionales: description, customer_email, success_url, cancel_url, expires_at, metadata.
Devuelve una PaymentOrder con payment_url, public_token, status, etc.
listPaymentOrders(params?)
Lista órdenes del comercio (GET /business/payment-orders).
Filtros opcionales: status, merchant_reference, currency_id, country_id, created_from, created_to, expires_from, expires_to, page, limit, sort (created_at_asc | created_at_desc).
getPaymentOrder(paymentOrderId)
Obtiene una orden por id (GET /business/payment-orders/:id).
listPaymentOrderAttempts(paymentOrderId, params?)
Lista intentos de pago de una orden (GET /business/payment-orders/:id/attempts).
Filtros opcionales: status (initiated, processing, succeeded, failed, expired, abandoned), page, limit, sort.
listMerchantPspMethods()
Lista métodos PSP del comercio agrupados por PSP (GET /business/merchant-payment-settings/psp-methods).
Devuelve un array de MerchantPspGroup con pspId, pspName, methods (cada uno con pspMethodId, countryId, currencyId, códigos ISO, isActive) y credentials descifradas por PSP, o null.
cancelBusinessPaymentOrder(paymentOrderId, input?)
Cancela una orden de pago (POST /business/payment-orders/:id/cancel).
getBusinessPaymentOrderCheckout(paymentOrderId)
Vista enriquecida para UI de checkout (GET /business/payment-orders/:id/checkout).
getBusinessPaymentOrderCheckoutByPublicToken(publicToken)
Vista de checkout por public_token (GET /business/payment-orders/by-public-token/:token/checkout).
listBusinessCheckoutPspMethods(params)
Métodos PSP para formulario de checkout, sin credenciales (GET /business/checkout/psp-methods). Requiere country_id y currency_id.
Checkout y pedidos (/business/cart, /business/sales-orders)
| Método del SDK | HTTP |
|----------------|------|
| quoteBusinessCart(input) | POST /business/cart/quote |
| createBusinessSalesOrder(input) | POST /business/sales-orders |
| listBusinessSalesOrders(params?) | GET /business/sales-orders |
| getBusinessSalesOrder(salesOrderId) | GET /business/sales-orders/:id |
| payBusinessSalesOrder(salesOrderId, input?) | POST /business/sales-orders/:id/pay |
| getBusinessSalesOrderTracking(salesOrderId) | GET /business/sales-orders/:id/tracking |
| getBusinessSalesOrderInvoice(salesOrderId) | GET /business/sales-orders/:id/invoice |
| cancelBusinessSalesOrder(salesOrderId) | POST /business/sales-orders/:id/cancel |
| changeBusinessSalesOrderFulfillment(salesOrderId, input) | PATCH /business/sales-orders/:id/fulfillment |
| refundBusinessSalesOrder(salesOrderId) | POST /business/sales-orders/:id/refund |
Referencia, tienda y webhooks
| Método del SDK | HTTP |
|----------------|------|
| listBusinessCountries() | GET /business/countries |
| listBusinessCurrencies() | GET /business/currencies |
| getBusinessStoreSettings() | GET /business/store/settings |
| getBusinessWebhookSettings() | GET /business/webhooks/settings |
| updateBusinessWebhookSettings(input) | PUT /business/webhooks/settings |
Envíos (/business/shipping)
| Método del SDK | HTTP |
|----------------|------|
| getBusinessShippingSettings() | GET /settings |
| updateBusinessShippingSettings(input) | PUT /settings |
| listBusinessShippingZones() | GET /zones |
| createBusinessShippingZone(input) | POST /zones |
| updateBusinessShippingZone(zoneId, input) | PUT /zones/:id |
| deleteBusinessShippingZone(zoneId) | DELETE /zones/:id |
| createBusinessShippingRate(zoneId, input) | POST /zones/:id/rates |
| updateBusinessShippingRate(zoneId, rateId, input) | PUT /zones/:id/rates/:rateId |
| deleteBusinessShippingRate(zoneId, rateId) | DELETE /zones/:id/rates/:rateId |
| listBusinessShippingPackageProfiles() | GET /package-profiles |
| createBusinessShippingPackageProfile(input) | POST /package-profiles |
| updateBusinessShippingPackageProfile(profileId, input) | PUT /package-profiles/:id |
| deleteBusinessShippingPackageProfile(profileId) | DELETE /package-profiles/:id |
Catálogo storefront (/business/catalog)
| Método del SDK | HTTP |
|----------------|------|
| searchBusinessCatalogProducts(params?) | GET /products/search |
| getBusinessCatalogProductSearchFacets(params?) | GET /products/search/facets |
| getBusinessCatalogProductBySlug(slug) | GET /products/by-slug/:slug |
| listBusinessCatalogCategories(params?) | GET /categories |
Catálogo merchant (/business/merchant-catalog)
Todos los métodos usan la misma autenticación HMAC. Los cuerpos de solicitud usan camelCase; las respuestas usan snake_case (como la API admin).
Categorías
| Método del SDK | HTTP |
|----------------|------|
| listCatalogCategories() | GET /categories |
| upsertCatalogCategories(categories) | PUT /categories/bulk |
| deleteCatalogCategories(ids) | DELETE /categories/bulk |
| requestCatalogCategoryImageDirectUploads(uploads) | POST /categories/images/direct-uploads |
| registerCatalogCategoryImages(images) | PUT /categories/images/bulk |
| deleteCatalogCategoryImages(ids) | DELETE /categories/images/bulk |
Productos
| Método del SDK | HTTP |
|----------------|------|
| listCatalogCurrencies() | GET /currencies |
| createCatalogProduct(input) | POST /products |
| listCatalogProducts(params?) | GET /products |
| getCatalogProduct(productId) | GET /products/:id |
| updateCatalogProduct(productId, input) | PATCH /products/:id |
| deleteCatalogProducts(ids) | DELETE /products/bulk |
| updateCatalogProductVariant(productId, variantId, input) | PATCH /products/:id/variants/:variantId |
| setCatalogVariantWarehouseStock(productId, variantId, qty) | PATCH .../warehouse-stock |
| upsertCatalogVariants(variants) | PUT /variants/bulk |
| deleteCatalogVariants(ids) | DELETE /variants/bulk |
| requestCatalogImageDirectUploads(uploads) | POST /images/direct-uploads |
| registerCatalogImages(images) | PUT /images/bulk |
| deleteCatalogImages(ids) | DELETE /images/bulk |
| adjustCatalogInventory(adjustments) | POST /inventory/adjustments/bulk |
Ejemplo: crear producto e imagen
const product = await client.createCatalogProduct({
id: crypto.randomUUID(),
name: 'Camiseta básica',
currencyId: process.env.HANIX_CURRENCY_ID!,
variants: [
{
id: crypto.randomUUID(),
sku: 'CAM-001',
priceInCents: 29900,
stockQuantity: 10,
},
],
});
const { uploads } = await client.requestCatalogImageDirectUploads([
{ clientReference: 'hero', productId: product.id },
]);
// Subir el archivo a uploads[0].upload_url (POST multipart a Cloudflare)
await fetch(uploads[0]!.upload_url, {
method: 'POST',
body: (() => {
const form = new FormData();
form.append('file', file);
return form;
})(),
});
await client.registerCatalogImages([
{
id: crypto.randomUUID(),
productId: product.id,
cloudflareImageId: uploads[0]!.cloudflare_image_id,
isPrimary: true,
},
]);Autenticación
Cada solicitud lleva estas cabeceras (generadas por el SDK):
| Cabecera | Descripción |
|----------|-------------|
| business-merchant-id | UUID del comercio |
| business-timestamp | Unix en segundos |
| business-signature | HMAC-SHA256(apiKey, timestamp + rawBody) en hexadecimal |
En GET, el cuerpo firmado es la cadena vacía. En solicitudes con cuerpo (POST, PUT, PATCH, DELETE), el JSON se serializa con claves ordenadas para que la firma coincida con los bytes enviados.
Errores
import {
HanixBusinessError,
HanixBusinessNetworkError,
HanixBusinessConfigError,
} from '@hanix.io/business';
try {
await client.getPaymentOrder('...');
} catch (error) {
if (error instanceof HanixBusinessError) {
// 4xx / 5xx de la API (error.status, error.message, error.body)
} else if (error instanceof HanixBusinessNetworkError) {
// Timeout o fallo de red (error.cause)
} else if (error instanceof HanixBusinessConfigError) {
// merchantId o apiKey inválidos al crear el cliente
}
}| Clase | Cuándo |
|-------|--------|
| HanixBusinessError | Respuesta HTTP no exitosa de Hanix |
| HanixBusinessNetworkError | Timeout, red o fetch no disponible |
| HanixBusinessConfigError | Opciones inválidas del cliente |
Buenas prácticas
- Guarda
apiKeyen variables de entorno o un gestor de secretos; no la subas al repositorio. - La
apiKeynunca viaja en cabeceras ni en el cuerpo; solo se usa para firmar. - Usa
merchant_referenceúnico por orden para evitar conflictos (409).
Utilidades exportadas
Para integraciones avanzadas o pruebas manuales:
HANIX_BUSINESS_API_BASE_URL— URL base de la APIstableStringify,signBusinessPayload,buildBusinessAuthHeaders,verifyBusinessPayload- Constantes de cabeceras:
BUSINESS_MERCHANT_ID_HEADER,BUSINESS_TIMESTAMP_HEADER,BUSINESS_SIGNATURE_HEADER
