Skip to main content

Descripción

Las Guías de Remisión de Transportista (GRE tipo 31) son emitidas por empresas de transporte cuando prestan servicios de traslado de mercadería de terceros. Se diferencian de las guías de remitente (tipo 09) en que:
  • El emisor (empresa de transporte) NO es dueño de la mercadería
  • Se debe identificar al remitente (quien envía) y destinatario (quien recibe)
  • El transportista siempre usa transporte privado (modalidad 02)
  • Conductor y vehículo son siempre obligatorios
El sistema genera automáticamente la serie V001 para guías de transportista.

Flujo de Trabajo (Asíncrono GRE API)

Las guías de transportista usan el mismo flujo asíncrono que las guías de remitente.
  1. Crear guía: POST /api/guias-remision-transportista - Genera el registro y XML firmado
  2. Enviar a SUNAT GRE: POST /api/guias-remision-transportista/{id}/enviar - Envío asíncrono, devuelve ticket
  3. Consultar ticket: POST /api/guias-remision-transportista/{id}/ticket - Verifica estado y descarga CDR
  4. Obtener CDR: GET /api/guias-remision-transportista/{id}/cdr - Descarga la constancia

Diferencias con Guía de Remitente

AspectoRemitente (tipo 09)Transportista (tipo 31)
SerieT001V001
Tipo documento0931
EmisorDueño de mercaderíaEmpresa de transporte
Remitente(es el emisor)Tercero (campo requerido)
Modalidad transporte01 o 02Siempre 02 (privado)
ConductorOpcional si M1/LSiempre requerido
VehículoOpcional si M1/LSiempre requerido

POST /api/guias-remision-transportista

Crea una nueva guía de remisión de transportista.

Request Body

Remitente (quien envía la mercadería)

remitente_tipo_doc
string
required
Tipo de documento del remitente: 1 (DNI), 6 (RUC)
remitente_documento
string
required
Número de documento del remitente (máx 15 caracteres)
remitente_nombre
string
required
Razón social o nombre completo del remitente (máx 255 caracteres)
remitente_direccion
string
required
Dirección del remitente (máx 500 caracteres)
remitente_ubigeo
string
Código ubigeo INEI del remitente (6 dígitos)

Destinatario (quien recibe la mercadería)

destinatario_tipo_doc
string
required
Tipo de documento del destinatario: 1 (DNI), 4 (Carnet Extranjería), 6 (RUC)
destinatario_documento
string
required
Número de documento del destinatario (máx 15 caracteres)
destinatario_nombre
string
required
Razón social o nombre completo del destinatario (máx 255 caracteres)

Traslado

motivo_traslado
string
required
Código de motivo de traslado (2 dígitos). Ver tabla en página de Guía Remitente
descripcion_motivo
string
Descripción adicional del motivo (máx 255 caracteres)
fecha_traslado
date
required
Fecha en que se realizará el traslado (formato: YYYY-MM-DD)
peso_total
decimal
required
Peso total de la mercadería (mínimo 0.001)
und_peso_total
string
default:"KGM"
Unidad de medida del peso: KGM (kilogramos), TNE (toneladas)
ubigeo_partida
string
Ubigeo del punto de partida (usa dirección de empresa transportista si se omite)
dir_partida
string
required
Dirección de partida (máx 500 caracteres)
ubigeo_llegada
string
Ubigeo del punto de llegada
dir_llegada
string
required
Dirección de llegada (máx 500 caracteres)

Conductor (siempre requerido)

conductor_tipo_doc
string
required
Tipo de documento del conductor: 1 (DNI), 4 (Carnet Extranjería)
conductor_documento
string
required
Número de documento del conductor (máx 15 caracteres)
conductor_nombres
string
required
Nombres del conductor (máx 255 caracteres)
conductor_apellidos
string
required
Apellidos del conductor (máx 255 caracteres)
conductor_licencia
string
required
Número de licencia de conducir (máx 20 caracteres)

Vehículo (siempre requerido)

vehiculo_placa
string
required
Placa del vehículo principal (máx 10 caracteres)
vehiculo_placa_secundaria
string
Placa del vehículo secundario/remolque (máx 20 caracteres)

Mercadería

detalles
array
required
Lista de ítems a trasladar (mínimo 1)
detalles[].descripcion
string
required
Descripción del ítem
detalles[].cantidad
decimal
required
Cantidad del ítem (mínimo 0.001)
detalles[].unidad
string
default:"NIU"
Unidad de medida: NIU (unidades), KGM (kilogramos), etc.
detalles[].codigo
string
Código del producto (máx 30 caracteres)

Otros

observaciones
string
Observaciones adicionales

Lógica del Servidor

  1. Valida que todos los campos de remitente, conductor y vehículo estén presentes (son obligatorios)
  2. Asigna serie fija V001 y genera número correlativo
  3. Sincroniza con documentos_empresas para numeración base
  4. Fija mod_transporte = '02' (transporte privado, no puede ser público)
  5. Fija vehiculo_m1l = false (no aplica para guías de transportista)
  6. Usa ubigeo de empresa como fallback para partida
  7. Crea registros en guia_remision y guia_remision_detalle
  8. Genera XML UBL 2.1 versión 2022 con tipo documento 31
  9. En el XML, el remitente se mapea al campo <cac:Tercero> (tercero involucrado)
  10. Firma digitalmente el XML con certificado PEM
  11. Calcula hash CPE
  12. Almacena XML en storage/app/sunat/xml/{ruc}/
Ver SunatService::generarGuiaRemisionTransportistaXml() (línea 668).

Response

success
boolean
Indica si la operación fue exitosa
data
object
Objeto de la guía de transportista creada
xml
object
Información sobre el XML generado

Ejemplo de Request

{
  "remitente_tipo_doc": "6",
  "remitente_documento": "20456789012",
  "remitente_nombre": "FABRICA DE MUEBLES LIMA SAC",
  "remitente_direccion": "AV. INDUSTRIAL 890, LIMA",
  "remitente_ubigeo": "150101",
  "destinatario_tipo_doc": "6",
  "destinatario_documento": "20567890123",
  "destinatario_nombre": "COMERCIAL AREQUIPA EIRL",
  "motivo_traslado": "01",
  "descripcion_motivo": "Traslado por venta",
  "fecha_traslado": "2026-03-08",
  "peso_total": 1.8,
  "und_peso_total": "TNE",
  "dir_partida": "AV. INDUSTRIAL 890, LIMA",
  "ubigeo_partida": "150101",
  "dir_llegada": "CALLE MERCADERES 456, AREQUIPA",
  "ubigeo_llegada": "040101",
  "conductor_tipo_doc": "1",
  "conductor_documento": "43217654",
  "conductor_nombres": "PEDRO ALBERTO",
  "conductor_apellidos": "RAMIREZ CASTRO",
  "conductor_licencia": "Q87654321",
  "vehiculo_placa": "XYZ987",
  "vehiculo_placa_secundaria": "REM456",
  "detalles": [
    {
      "descripcion": "MUEBLES DE OFICINA DESARMADOS",
      "cantidad": 15,
      "unidad": "NIU",
      "codigo": "MUE-OFC"
    },
    {
      "descripcion": "SILLAS ERGONOMICAS",
      "cantidad": 30,
      "unidad": "NIU",
      "codigo": "SIL-ERG"
    }
  ],
  "observaciones": "Mercadería frágil, manipular con cuidado"
}

Ejemplo de Response (201 Created)

{
  "success": true,
  "data": {
    "id": 34,
    "serie": "V001",
    "numero": 128,
    "fecha_emision": "2026-03-06",
    "fecha_traslado": "2026-03-08",
    "remitente_tipo_doc": "6",
    "remitente_documento": "20456789012",
    "remitente_nombre": "FABRICA DE MUEBLES LIMA SAC",
    "remitente_direccion": "AV. INDUSTRIAL 890, LIMA",
    "remitente_ubigeo": "150101",
    "destinatario_tipo_doc": "6",
    "destinatario_documento": "20567890123",
    "destinatario_nombre": "COMERCIAL AREQUIPA EIRL",
    "motivo_traslado": "01",
    "descripcion_motivo": "Traslado por venta",
    "mod_transporte": "02",
    "peso_total": "1.800",
    "und_peso_total": "TNE",
    "ubigeo_partida": "150101",
    "dir_partida": "AV. INDUSTRIAL 890, LIMA",
    "ubigeo_llegada": "040101",
    "dir_llegada": "CALLE MERCADERES 456, AREQUIPA",
    "conductor_tipo_doc": "1",
    "conductor_documento": "43217654",
    "conductor_nombres": "PEDRO ALBERTO",
    "conductor_apellidos": "RAMIREZ CASTRO",
    "conductor_licencia": "Q87654321",
    "vehiculo_placa": "XYZ987",
    "vehiculo_placa_secundaria": "REM456",
    "vehiculo_m1l": false,
    "estado": "pendiente",
    "nombre_xml": "20612706702-31-V001-00000128",
    "hash_cpe": "pL9nK2mW7qT...",
    "xml_url": "sunat/xml/20612706702/20612706702-31-V001-00000128.xml",
    "detalles": [
      {
        "descripcion": "MUEBLES DE OFICINA DESARMADOS",
        "cantidad": "15.000",
        "unidad": "NIU",
        "codigo": "MUE-OFC"
      },
      {
        "descripcion": "SILLAS ERGONOMICAS",
        "cantidad": "30.000",
        "unidad": "NIU",
        "codigo": "SIL-ERG"
      }
    ]
  },
  "xml": {
    "success": true,
    "nombre_archivo": "20612706702-31-V001-00000128",
    "hash": "pL9nK2mW7qT..."
  }
}

POST /api/guias-remision-transportista//enviar

Envía la guía de transportista a SUNAT GRE. Devuelve un ticket para consulta posterior.

Path Parameters

id
integer
required
ID de la guía de transportista a enviar

Flujo

Idéntico al de guías de remitente (ver página de Guía Remitente). Usa los mismos endpoints GRE y el mismo flujo OAuth.

Response (Éxito)

{
  "success": true,
  "ticket": "16827899",
  "message": "Guía enviada. Use el ticket para consultar el estado."
}

POST /api/guias-remision-transportista//ticket

Consulta el estado de procesamiento en SUNAT usando el ticket.

Path Parameters

id
integer
required
ID de la guía de transportista

Flujo

Idéntico al de guías de remitente. Usa el mismo endpoint de consulta de GRE.

Respuestas Posibles

  • Código “0”: Aceptado (descarga CDR automáticamente)
  • Código “98”: En proceso (seguir consultando)
  • Otro código: Rechazado

Ejemplo de Response (En Proceso)

{
  "success": true,
  "codigo": "98",
  "mensaje": "En proceso. Intente nuevamente en unos segundos.",
  "en_proceso": true
}

Ejemplo de Response (Aceptado)

{
  "success": true,
  "codigo": "0",
  "mensaje": "Guía aceptada por SUNAT."
}

GET /api/guias-remision-transportista

Obtiene lista paginada de guías de transportista (solo serie V001).

Query Parameters

page
integer
default:"1"
Número de página

Response

Objeto de paginación Laravel con 15 items por página.

GET /api/guias-remision-transportista/

Obtiene detalle completo de una guía de transportista específica.

GET /api/guias-remision-transportista//cdr

Descarga el archivo CDR (Constancia de Recepción) en formato ZIP.

GET /api/guias-remision-transportista/xml/

Descarga el archivo XML de la guía.

GET /api/guias-remision-transportista/proximo-numero

Obtiene el próximo número correlativo para serie V001.

Response

{
  "success": true,
  "numero": 129,
  "numero_completo": "V001-00000129"
}

GET /api/guias-remision-transportista/motivos

Obtiene la lista de motivos de traslado disponibles (misma lista que guías de remitente).

Notas Técnicas

Mapeo UBL del Remitente

En el XML UBL 2.1, el remitente se mapea al campo <cac:Tercero> (tercero involucrado en la operación):
if ($guia->remitente_documento) {
    $remitente = (new Client())
        ->setTipoDoc($guia->remitente_tipo_doc)
        ->setNumDoc($guia->remitente_documento)
        ->setRznSocial($guia->remitente_nombre);
    $despatch->setTercero($remitente);
}
Ver línea 680 en SunatService.

Modelo de Datos

Ambas guías (remitente y transportista) usan la misma tabla guia_remision. Se distinguen por:
  • Serie: T001 (remitente) vs V001 (transportista)
  • Campos: Las guías transportista tienen remitente_* poblados, las de remitente no

Restricciones

  • El campo mod_transporte se fuerza a '02' (transporte privado) en línea 127
  • El campo vehiculo_m1l se fuerza a false en línea 144
  • Conductor y vehículo son siempre obligatorios, no hay excepciones

Placa Secundaria

Para vehículos con remolque/carreta, usar vehiculo_placa_secundaria. SUNAT lo registra pero no es obligatorio.

Mismo Flujo GRE

Las guías de transportista usan exactamente los mismos endpoints GRE que las guías de remitente:
  • Mismo OAuth
  • Mismo endpoint de envío
  • Mismo endpoint de consulta de ticket
  • Misma estructura de CDR
La única diferencia es el tipo de documento en el XML (31 vs 09).

Validación del Remitente

SUNAT valida que:
  • El RUC/DNI del remitente exista y esté activo
  • El RUC del destinatario exista y esté activo
  • El RUC del emisor (empresa de transporte) esté habilitado para GRE

Errores Comunes

CódigoDescripciónSolución
2800RUC emisor no autorizado para GREActivar GRE en SUNAT
2810RUC remitente inválidoVerificar que el RUC del remitente sea correcto
2324Datos de conductor incompletosTodos los campos del conductor son obligatorios
2325Placa de vehículo inválidaVerificar formato de placa
422Campos requeridos faltantesRemitente, conductor y vehículo son obligatorios

Ejemplo de Integración

// 1. Crear guía de transportista
const response = await fetch('/api/guias-remision-transportista', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify({
    remitente_tipo_doc: '6',
    remitente_documento: '20456789012',
    remitente_nombre: 'FABRICA MUEBLES SAC',
    remitente_direccion: 'AV. INDUSTRIAL 890',
    destinatario_tipo_doc: '6',
    destinatario_documento: '20567890123',
    destinatario_nombre: 'COMERCIAL AREQUIPA',
    motivo_traslado: '01',
    fecha_traslado: '2026-03-08',
    peso_total: 1.8,
    dir_partida: 'AV. INDUSTRIAL 890, LIMA',
    dir_llegada: 'CALLE MERCADERES 456, AREQUIPA',
    conductor_tipo_doc: '1',
    conductor_documento: '43217654',
    conductor_nombres: 'PEDRO',
    conductor_apellidos: 'RAMIREZ',
    conductor_licencia: 'Q87654321',
    vehiculo_placa: 'XYZ987',
    detalles: [
      { descripcion: 'MUEBLES', cantidad: 15, unidad: 'NIU' }
    ]
  })
});

const { data } = await response.json();
const guiaId = data.id;

// 2. Enviar a SUNAT
const envioResp = await fetch(`/api/guias-remision-transportista/${guiaId}/enviar`, {
  method: 'POST'
});
const { ticket } = await envioResp.json();

// 3. Consultar ticket cada 3 segundos
const checkStatus = async () => {
  const statusResp = await fetch(
    `/api/guias-remision-transportista/${guiaId}/ticket`,
    { method: 'POST' }
  );
  const status = await statusResp.json();
  
  if (status.en_proceso) {
    setTimeout(checkStatus, 3000);
  } else if (status.success) {
    alert('Guía aceptada por SUNAT');
  } else {
    alert('Guía rechazada: ' + status.message);
  }
};

setTimeout(checkStatus, 5000);

Build docs developers (and LLMs) love