Only For Gamer Documentación API B2B
Acceso B2B
API disponible

API B2B de Only For Gamer

Integrá tu plataforma con nuestro catálogo digital, consultá precios, creá pedidos, controlá tu saldo y recibí actualizaciones automáticas mediante webhooks.

URL base
https://b2b.onlyforgamer.com/api/v1
No se encontraron secciones que coincidan con la búsqueda.
Primeros pasos

Inicio rápido

Todas las solicitudes utilizan JSON y deben enviarse por HTTPS. Para comenzar, realizá una consulta a tu perfil usando un token API generado desde el Centro de desarrolladores del Portal B2B.

cURL
curl --request GET \
  --url https://b2b.onlyforgamer.com/api/v1/me \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <TU_TOKEN_API>'
Credenciales
El token completo se muestra una sola vez cuando lo creás. Guardalo en un gestor de secretos y nunca lo publiques dentro del código fuente de tu aplicación.
Herramientas de integración

Colección oficial de Postman

Descargá la colección completa y el entorno de producción para probar todos los endpoints actuales de la API B2B.

P
Colección API B2B v1
7 solicitudes · Postman v2.1

Incluye perfil, productos, validación de cuenta cuando corresponde, creación y consulta de pedidos, además del historial de movimientos.

Descargar colección
E
Entorno de producción
Variables preparadas

Contiene la URL base y variables de ejemplo. No incluye tokens, secretos ni credenciales reales.

Descargar entorno

Cómo importarlo

  1. Descargá e importá los dos archivos en Postman.
  2. Seleccioná el entorno Only For Gamer - Producción.
  3. Pegá tu credencial en la variable api_token.
  4. Configurá sku y los datos indicados por required_fields, como player_id, server_id o player_ip.
  5. Dejá idempotency_key vacía para que la colección genere una automáticamente.
  6. Ejecutá primero Listar productos. La colección guarda el precio, moneda y disponibilidad de validación del SKU.
  7. Si account_validation_available es true, ejecutá Validar cuenta antes de Crear pedido.
Creación de pedidos reales
La solicitud POST /orders utiliza el saldo real del revendedor. Antes de crear otro pedido, vaciá idempotency_key para generar una clave nueva.
Número de pedido automático
Cuando se crea correctamente un pedido, la colección guarda su número en la variable order_number. Luego podés ejecutar directamente Consultar pedido por número.
Seguridad

Autenticación

La API utiliza un token Bearer. Incluí el encabezado Authorization en todas las solicitudes.

Encabezados
Authorization: Bearer <TU_TOKEN_API>
Accept: application/json
Content-Type: application/json
Respuestas JSON
Todas las rutas de la API responden en formato JSON, incluso cuando el cliente no envía el encabezado Accept.
X-Request-ID
Las respuestas procesadas normalmente por la API incluyen un identificador único en el encabezado X-Request-ID. Si está presente, guardalo para facilitar el diagnóstico.
Control de acceso

Permisos del token

Cada token puede limitarse a las funciones necesarias para una integración específica.

Permiso Descripción
profile:read Consultar perfil, moneda, saldo, límite de crédito y fondos disponibles.
balance:read Consultar saldo y mantener compatibilidad con tokens anteriores para movimientos.
wallet:read Consultar el historial de movimientos de saldo.
products:read Consultar catálogo, disponibilidad y precio B2B.
orders:read Listar y consultar pedidos.
orders:create Crear pedidos nuevos y reservar saldo.
Principio de menor privilegio
Creá tokens separados para sistemas diferentes y asignales solamente los permisos que realmente necesitan.
Disponibilidad

Límites de uso

Consultas generales
Hasta 300 solicitudes por minuto por revendedor.
Creación de pedidos
Hasta 60 pedidos por minuto y 2.000 pedidos por hora por revendedor.

El límite se comparte entre todos los tokens pertenecientes al mismo revendedor. Al superarlo, la API responde con HTTP 429.

Cuenta
GET /me
profile:read

Consultar perfil y saldo

Devuelve los datos públicos del revendedor, el saldo contable, el límite de crédito y los fondos totales disponibles.

cURL
curl --request GET \
  --url https://b2b.onlyforgamer.com/api/v1/me \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <TU_TOKEN_API>'

Respuesta exitosa

JSON · HTTP 200
{
  "success": true,
  "data": {
    "code": "RESELLER-CODE",
    "company_name": "Empresa revendedora",
    "currency": "USD",
    "balance": "105.080000",
    "credit_limit": "0.000000",
    "available_funds": "105.080000"
  }
}
Fondos disponibles
available_funds es la suma del saldo y el límite de crédito autorizado.
Catálogo
GET /products
products:read

Consultar productos

Devuelve únicamente los productos que están disponibles y son vendibles para el revendedor, junto con su precio B2B, moneda, campos requeridos y disponibilidad de verificación de cuenta.

Parámetro Tipo Descripción
search string Busca por nombre, SKU, marca o categoría. Máximo 100 caracteres.
brand string Filtra por marca exacta.
category string Filtra por categoría exacta.
region string Filtra por región.
product_type string Filtra por tipo de producto, por ejemplo topup.
per_page integer Entre 1 y 50. Valor predeterminado: 20.
page integer Número de página. Mínimo 1.
cURL
curl --request GET \
  --url 'https://b2b.onlyforgamer.com/api/v1/products?region=LATAM&product_type=topup&per_page=20' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <TU_TOKEN_API>'

Respuesta

JSON · HTTP 200
{
  "success": true,
  "data": [
    {
      "sku": "PRODUCT-SKU",
      "name": "Nombre del producto",
      "brand": "Marca",
      "category": "Recargas",
      "region": "LATAM",
      "product_type": "topup",
      "face_value": "86.000000",
      "face_currency": null,
      "required_fields": [
        "player_id",
        "server_id"
      ],
      "account_validation_available": true,
      "available": true,
      "price": "1.250000",
      "currency": "USD"
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 20,
    "last_page": 1,
    "total": 1
  }
}
Catálogo vendible
La API filtra automáticamente los productos que no pueden venderse al revendedor en ese momento. Los elementos devueltos por este endpoint incluyen available: true.
Campos requeridos
required_fields es la fuente de verdad para saber qué datos enviar en target_data. Puede incluir player_id, server_id, player_ip, email o phone.
Protección del precio
Antes de crear el pedido, utilizá el price y la currency recibidos aquí como expected_price y expected_currency. El servidor vuelve a calcular el precio inmediatamente antes de reservar saldo.
Datos de la cuenta
POST /products/{sku}/validate-account
orders:create

Validar una cuenta antes de comprar

Ejecutá este endpoint solamente cuando GET /products devuelva account_validation_available: true para el SKU elegido.

Flujo dinámico
Si account_validation_available es false, no necesitás llamar este endpoint y no debés inventar un token. En ambos casos respetá siempre required_fields.

Solicitud

cURL
curl --request POST   --url https://b2b.onlyforgamer.com/api/v1/products/PRODUCT-SKU/validate-account   --header 'Accept: application/json'   --header 'Content-Type: application/json'   --header 'Authorization: Bearer <TU_TOKEN_API>'   --data '{
    "target_data": {
      "player_id": "123456789",
      "server_id": "1234",
      "player_ip": "203.0.113.10"
    }
  }'

Enviá únicamente los valores correspondientes al producto. Por ejemplo, si required_fields contiene solamente player_id, no necesitás enviar servidor ni IP.

Cuenta verificada

JSON · HTTP 200
{
  "success": true,
  "data": {
    "verified": true,
    "message": "Cuenta verificada correctamente.",
    "player_name": "Cuenta confirmada",
    "account_validation_token": "TOKEN_OPACO",
    "expires_in": 600
  }
}
Token de corta duración
El account_validation_token está ligado al revendedor, al token API, al producto y a los datos validados. Utilizalo en POST /orders sin modificar player_id, server_id ni player_ip. Vence en aproximadamente 10 minutos.
Pedidos
POST /orders
orders:create

Crear un pedido

Crea un pedido B2B, vuelve a comprobar el precio y disponibilidad actuales y reserva los fondos únicamente cuando todas las validaciones requeridas son correctas.

Idempotency-Key obligatorio
Cada pedido debe incluir una clave única de entre 8 y 100 caracteres en el encabezado Idempotency-Key.
Campo Tipo Uso
sku
Obligatorio
string SKU público obtenido desde GET /products. Máximo 100 caracteres.
quantity
Opcional
integer Actualmente solo se admite el valor 1.
external_reference
Opcional
string Identificador del pedido en el sistema del revendedor. Máximo 150 caracteres.
target_data.player_id string Enviá este valor cuando required_fields incluya player_id.
target_data.server_id string Enviá este valor cuando required_fields incluya server_id.
target_data.email email Correo del destinatario cuando el producto lo requiera.
target_data.phone string Número telefónico cuando el producto lo requiera.
target_data.player_ip IP Enviá este valor cuando required_fields incluya player_ip.
expected_price decimal Precio aceptado por tu sistema. Utilizá el valor price obtenido en GET /products.
expected_currency string Moneda correspondiente al expected_price. Enviá ambos campos juntos.
account_validation_token string Obligatorio únicamente cuando el producto tiene account_validation_available: true. Se obtiene mediante POST /products/{sku}/validate-account.
cURL
curl --request POST \
  --url https://b2b.onlyforgamer.com/api/v1/orders \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <TU_TOKEN_API>' \
  --header 'Idempotency-Key: order-20260803-0001' \
  --data '{
    "sku": "PRODUCT-SKU",
    "quantity": 1,
    "external_reference": "MI-PEDIDO-0001",
    "expected_price": "1.250000",
    "expected_currency": "USD",
    "account_validation_token": "TOKEN_SI_CORRESPONDE",
    "target_data": {
      "player_id": "123456789",
      "server_id": "1234",
      "player_ip": "203.0.113.10"
    }
  }'
Confirmá el precio aceptado
Enviá expected_price y expected_currency con los valores obtenidos del catálogo. Si el precio cambió antes de reservar saldo, la API rechaza la solicitud para evitar cobrar silenciosamente un importe distinto. Actualizá el catálogo y decidí nuevamente.

Pedido creado

JSON · HTTP 201
{
  "success": true,
  "idempotent": false,
  "data": {
    "order_number": "B2B-01EXAMPLEORDER",
    "external_reference": "MI-PEDIDO-0001",
    "status": "pending",
    "sku": "PRODUCT-SKU",
    "product_name": "Nombre del producto",
    "quantity": 1,
    "currency": "USD",
    "unit_price": "1.250000",
    "total": "1.250000",
    "created_at": "2026-08-03T06:45:00+00:00"
  }
}
Prevención de duplicados

Idempotencia

La idempotencia permite repetir una solicitud cuando hubo un timeout o una interrupción de red sin crear dos pedidos.

  1. Generá una clave única para cada pedido.
  2. Conservá la misma clave al reintentar exactamente la misma solicitud.
  3. No reutilices la clave para otro SKU, jugador o servidor.
Mismo pedido
La API responde HTTP 200 con idempotent: true y devuelve el pedido existente.
Datos diferentes
La API responde HTTP 409 cuando la misma clave ya se utilizó para otro pedido.
JSON · Reintento seguro
{
  "success": true,
  "idempotent": true,
  "data": {
    "order_number": "B2B-01EXAMPLEORDER",
    "status": "pending"
  }
}
Pedidos
GET /orders
orders:read

Listar pedidos

Devuelve los pedidos pertenecientes al revendedor autenticado, ordenados desde el más reciente.

Parámetro Descripción
search Busca por número de pedido, referencia externa, SKU o nombre del producto.
per_page Entre 1 y 50. Valor predeterminado: 20.
cURL
curl --request GET \
  --url 'https://b2b.onlyforgamer.com/api/v1/orders?search=MI-PEDIDO&per_page=20' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <TU_TOKEN_API>'
Pedidos
GET /orders/{orderNumber}
orders:read

Consultar un pedido

Devuelve el detalle completo de un pedido, incluyendo los datos públicos del destinatario enviados en target_data.

cURL
curl --request GET \
  --url https://b2b.onlyforgamer.com/api/v1/orders/B2B-01EXAMPLEORDER \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <TU_TOKEN_API>'
JSON · HTTP 200
{
  "success": true,
  "data": {
    "order_number": "B2B-01EXAMPLEORDER",
    "external_reference": "MI-PEDIDO-0001",
    "status": "processing",
    "sku": "PRODUCT-SKU",
    "product_name": "Nombre del producto",
    "product_type": "topup",
    "quantity": 1,
    "currency": "USD",
    "unit_price": "1.250000",
    "total": "1.250000",
    "created_at": "2026-08-03T06:45:00+00:00",
    "updated_at": "2026-08-03T06:45:03+00:00",
    "completed_at": null,
    "failed_at": null,
    "target_data": {
      "player_id": "123456789",
      "server_id": "1234",
      "player_ip": "203.0.113.10"
    }
  }
}
Entrega digital

Recuperar Gift Cards

Cuando un pedido de tipo gift_card está completado y existe una entrega digital disponible, el endpoint GET /orders/{orderNumber} incluye el objeto delivery.

Información sensible
Los códigos y PIN deben tratarse como credenciales sensibles. No los almacenes en logs, herramientas de analítica ni sistemas de monitoreo.

Ejemplo de respuesta

JSON · Ejemplo ficticio
{
  "success": true,
  "data": {
    "order_number": "B2B-01EXAMPLEORDER",
    "status": "completed",
    "product_type": "gift_card",
    "delivery": {
      "status": "delivered",
      "card_count": 1,
      "delivered_at": "2026-08-28T03:00:00+00:00",
      "cards": [
        {
          "code": "EXAMPLE-CODE-NOT-VALID",
          "pin": "0000",
          "expires_at": "2027-12-31",
          "type": "Gift Card"
        }
      ]
    }
  }
}
Campos disponibles
Cada tarjeta puede incluir code, pin, expires_at y type cuando esos datos existen. No se exponen referencias internas ni payloads operativos.

Las respuestas que contienen una entrega digital utilizan encabezados de caché restrictivos: Cache-Control: no-store, private y Pragma: no-cache . No deben almacenarse en proxies, navegadores ni cachés intermedias.

Finanzas
GET /wallet-transactions
wallet:read o balance:read

Movimientos de saldo

Devuelve el historial financiero del revendedor. Los importes se entregan como strings para conservar la precisión decimal.

Parámetro Descripción
type Filtra por tipo de movimiento.
direction Admite debit o credit.
order_number Filtra por número exacto de pedido B2B.
date_from Fecha inicial en formato YYYY-MM-DD.
date_to Fecha final en formato YYYY-MM-DD.
per_page Entre 1 y 100. Valor predeterminado: 25.
page Número de página, mínimo 1.
cURL
curl --request GET \
  --url 'https://b2b.onlyforgamer.com/api/v1/wallet-transactions?direction=debit&date_from=2026-08-01&date_to=2026-08-31&per_page=25' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <TU_TOKEN_API>'
JSON · HTTP 200
{
  "success": true,
  "data": [
    {
      "id": 12,
      "type": "order_debit",
      "direction": "debit",
      "currency": "USD",
      "amount": "1.250000",
      "balance_before": "105.080000",
      "balance_after": "103.830000",
      "order_number": "B2B-01EXAMPLEORDER",
      "reference": "B2B-01EXAMPLEORDER",
      "description": "Débito automático por pedido B2B.",
      "created_at": "2026-08-03T06:45:00+00:00"
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 25,
    "last_page": 1,
    "total": 1,
    "from": 1,
    "to": 1
  }
}

Tipos de movimiento

order_debit

Débito generado por un pedido.

manual_credit

Crédito agregado manualmente.

refund_credit

Reembolso acreditado al saldo.

manual_adjustment

Ajuste administrativo de saldo.

Ciclo del pedido

Estados públicos

Los estados internos son normalizados antes de exponerse a los revendedores.

pending

Pedido creado y fondos reservados.

processing

El pedido está siendo procesado.

completed

Pedido entregado correctamente.

failed

El pedido no pudo completarse.

cancelled

El pedido fue cancelado.

refunded

El importe fue reembolsado.

unknown

Estado no reconocido temporalmente.

Consulta periódica
Utilizá webhooks como mecanismo principal y GET /orders/{orderNumber} como respaldo para verificar el estado.
Notificaciones

Webhooks

Only For Gamer envía solicitudes POST al endpoint HTTPS configurado para el revendedor cuando cambia el estado público de un pedido.

Configuración
El endpoint HTTPS, el secreto de firma y las pruebas de integración pueden administrarse desde Portal B2B → Desarrolladores . El secreto completo se muestra únicamente cuando se genera o regenera.

Eventos disponibles

order.processing

Pedido en procesamiento.

order.completed

Pedido completado.

order.failed

Pedido fallido.

order.refunded

Pedido reembolsado.

order.cancelled

Pedido cancelado.

integration.test

Evento manual de prueba enviado desde el Centro de desarrolladores.

Payload de un pedido

Los eventos de pedidos contienen solamente información pública. El webhook nunca incluye códigos, PIN, target_data ni payloads operativos.

JSON · order.completed
{
  "id": "00000000-0000-4000-8000-000000000000",
  "event": "order.completed",
  "created_at": "2026-08-28T03:00:00+00:00",
  "data": {
    "order_number": "B2B-01EXAMPLEORDER",
    "external_reference": "MI-PEDIDO-0001",
    "status": "completed",
    "sku": "PRODUCT-SKU",
    "product_name": "Nombre del producto",
    "product_type": "gift_card",
    "quantity": 1,
    "currency": "USD",
    "unit_price": "10.000000",
    "total": "10.000000",
    "delivery_available": true,
    "created_at": "2026-08-28T02:59:55+00:00",
    "updated_at": "2026-08-28T03:00:00+00:00",
    "completed_at": "2026-08-28T03:00:00+00:00",
    "failed_at": null
  }
}
Gift Cards
Cuando delivery_available es true, recuperá la entrega mediante GET /api/v1/orders/{order_number} . Los códigos y PIN nunca se envían dentro del webhook.

Encabezados enviados

Encabezado Contenido
X-OFG-Event Nombre del evento.
X-OFG-Delivery UUID único de la entrega.
X-OFG-Timestamp Timestamp Unix utilizado para firmar la solicitud.
X-OFG-Signature Firma con formato sha256=....
User-Agent OnlyForGamer-Webhook/1.0

Validación de la firma

Calculá un HMAC-SHA256 usando el timestamp, un punto y el cuerpo JSON original sin modificar.

Fórmula
HMAC_SHA256(
  X-OFG-Timestamp + "." + RAW_JSON_BODY,
  WEBHOOK_SECRET
)
PHP
<?php

$rawBody = file_get_contents('php://input');

$timestamp =
    $_SERVER['HTTP_X_OFG_TIMESTAMP']
    ?? '';

$receivedSignature =
    $_SERVER['HTTP_X_OFG_SIGNATURE']
    ?? '';

$secret = getenv('OFG_WEBHOOK_SECRET');

$expectedSignature =
    'sha256='
    . hash_hmac(
        'sha256',
        $timestamp . '.' . $rawBody,
        $secret
    );

if (
    ! hash_equals(
        $expectedSignature,
        $receivedSignature
    )
) {
    http_response_code(401);
    exit('Firma inválida');
}

http_response_code(200);
Node.js
import crypto from 'node:crypto';

function verifyWebhook({
  rawBody,
  timestamp,
  receivedSignature,
  secret,
}) {
  const expected =
    'sha256=' +
    crypto
      .createHmac('sha256', secret)
      .update(`${timestamp}.${rawBody}`)
      .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(receivedSignature)
  );
}
Usá el cuerpo original
No vuelvas a serializar el JSON antes de validar la firma. Debés utilizar exactamente los bytes recibidos.

Reintentos

El sistema realiza hasta cinco intentos. Los reintentos automáticos utilizan esperas aproximadas de 1, 5, 15 y 60 minutos.

  • Una respuesta HTTP 2xx se considera entregada correctamente.
  • HTTP 408, 425, 429 y respuestas 5xx pueden volver a intentarse.
  • El endpoint debe responder rápidamente y no depender de redirecciones.
Referencia

Códigos HTTP

Código Significado
200 Consulta correcta o reintento idempotente de un pedido.
201 Pedido creado correctamente.
401 Token ausente o inválido.
403 Permiso insuficiente, cuenta inactiva o API deshabilitada.
404 Pedido no encontrado.
409 Conflicto de idempotencia.
422 Error de validación, saldo insuficiente o producto no disponible.
429 Límite de solicitudes superado.
500 Error interno inesperado.

Ejemplo de validación

JSON · HTTP 422
{
  "message": "El encabezado Idempotency-Key es obligatorio.",
  "errors": {
    "idempotency_key": [
      "El encabezado Idempotency-Key es obligatorio."
    ]
  }
}

Verificación de cuenta requerida

JSON · HTTP 422
{
  "success": false,
  "code": "ACCOUNT_VALIDATION_REQUIRED",
  "message": "Primero debés verificar la cuenta del jugador."
}

Ejemplo de límite superado

JSON · HTTP 429
{
  "success": false,
  "message": "Se alcanzó temporalmente el límite de consultas de la API.",
  "error_code": "API_READ_RATE_LIMIT_EXCEEDED"
}
Producción

Buenas prácticas

No registres secretos
Ocultá tokens API, secretos webhook y datos sensibles en logs y reportes.
Definí timeouts
Utilizá timeouts de conexión y lectura razonables en todas las solicitudes.
Reintentos seguros
Reintentá pedidos únicamente usando la misma clave de idempotencia.
Verificá webhooks
Validá siempre la firma antes de procesar el evento recibido.
Guardá identificadores
Conservá el número de pedido y el encabezado X-Request-ID.
Tokens separados
Utilizá credenciales independientes para producción, pruebas y sistemas internos.