BMT Recargas API — Integración (Proyecto Adjuntado)
Esta guía describe el flujo init → widget 3DS → confirm y los archivos reales incluidos en los ejemplos de Next.js y PHP. Todo corresponde al proyecto finalizado que montaste.
Ambientes & URLs
Producción (activo)
- Base:
https://api.bmticket.com - Init:
POST /api/v1/checkout/init - Confirm:
POST /api/v1/checkout/confirm - Orders:
GET /api/v1/orders/:order_id - Widget:
/bmt-checkout.js
El ambiente de desarrollo (sandbox) se habilita bajo solicitud y registra los Origins de dev.
Cabeceras y seguridad
Enviar SIEMPRE
Content-Type: application/jsonAccept: application/jsonX-API-Key: <clave>X-App-Key: <clave>(si aplica)OriginyRefererque coincidan exacto con la allowlist
Claves
.env / servidor
BMT_BASE_URL=https://api.bmticket.com
BMT_API_KEY=<TU_API_KEY>
BMT_APP_KEY=<OPCIONAL_OTRA_KEY>
BMT_ORIGIN=https://<tu-dominio-exacto>/Nunca expongas claves de servidor en el navegador.
Crear orden (init)
Request
{
"amount": 25,
"currency": "HNL",
"description": "Recarga Hondubet",
"customer": { "name": "Nombre", "email": "correo@ejemplo.com" },
"billing": { "address": "Barrio", "country": "HN", "state": "CM", "city": "Siguatepeque", "phone": "+504..." }
}Response
{
"success": true,
"order_id": "ORD-...",
"checkout_url": "https://api.bmticket.com/checkout/ORD-...?mode=sale"
}Widget & 3DS
Carga /bmt-checkout.js y abre el modal con el checkout_url que te devolvió init.
Abrir modal (client)
if (!window.BMTCheckout) throw new Error("Widget no disponible");
window.BMTCheckout.open({
checkoutUrl: initResp.checkout_url,
onResult: async (result: any) => {
// Llama confirm con order_id + datos opcionales del widget
},
});Confirmar resultado
Request mínimo
{
"order_id": "ORD-...",
"status": "APPROVED",
"payment_uuid": "P-...",
"payment_hash": "...",
"message": "opcional",
"pixel_codes": { "code": "01", "uuid": "P-...", "hash": "..." }
}Response
{ "success": true, "status": "PAID|DECLINED|ERROR", "message": "Texto", "data": { "http": 200|401|412|... } }Integración Next.js (ejemplo adjunto)
- Handlers:
app/api/bmt/init/route.tsyapp/api/bmt/confirm/route.tscon headers correctos. - UI:
src/components/DepositDialog.tsx(init → widget → confirm). - Mensajes:
src/lib/pixel/codes.tsysrc/lib/pixel/buildMessage.ts.
Lado servidor (init)
// Headers claves:
"X-API-Key": key,
"X-App-Key": appKey,
"Origin": process.env.BMT_ORIGIN!,
"Referer": process.env.BMT_ORIGIN!,
"Accept": "application/json",Integración PHP (ejemplo adjunto)
config.php: endpoints, claves y helpers cURL con headers.crear-orden.php→/checkout/initconfirmar-orden.php→/checkout/confirmcodes.js: mapa de errores / sandbox
Test rápido (cURL)
curl -X POST https://api.bmticket.com/api/v1/checkout/init -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-API-Key: <TU_API_KEY>' -H 'X-App-Key: <TU_APP_KEY>' -H 'Origin: https://<tu-dominio-exacto>/' -H 'Referer: https://<tu-dominio-exacto>/' -d '{ "amount":1,"currency":"HNL","description":"Recarga Hondubet","customer":{"name":"Nombre","email":"correo@ejemplo.com"},"billing":{"address":"...","country":"HN","state":"CM","city":"Siguatepeque","phone":"+504..."}}'Errores & mensajes
HTTP del API
- 401/403 No autorizado (keys/origin)
- 402 Pago declinado
- 412 Intentos excedidos / precondición
- 422 Input inválido
- 408 Timeout
- 5xx Falla del servicio
Códigos del proveedor
Ver src/lib/pixel/codes.ts (Next) y codes.js (PHP).
La UI prioriza: estado del API > código proveedor > sandbox.
Sandbox & QA
Casos por monto (1..14) disponibles. En Next: NEXT_PUBLIC_BMT_ENV=sandbox.
Checklist
- Claves en servidor (no en cliente).
- Headers completos:
X-API-Key,X-App-Key,Origin,Referer,Accept. - Origin/Referer coinciden exacto con allowlist.
- Mensajería de errores integrada.
- Sandbox activado bajo solicitud.