GUÍA PARA DESARROLLADORES

Cómo Enviar SMS desde Laravel con la API de Grupo Tecnophone

Integre el envío de SMS en su aplicación Laravel con el cliente HTTP del framework, configuración centralizada y colas para procesar los envíos en segundo plano.

Antes de empezar

  • Una conexión API creada en el panel web (app.grupotecnophone.com), con su Bearer Token de sandbox o de producción.
  • La IP pública de su servidor registrada como autorizada para ese token.
  • Un User-Agent que identifique a su aplicación, por ejemplo MiEmpresa/1.0.
  • Laravel 9 o superior (el cliente Http viene incluido) y un sistema de colas configurado si enviará en segundo plano.

Guarde el token en una variable de entorno (en estos ejemplos, GTP_SMS_TOKEN) y nunca lo incluya en el código de una app móvil o de un sitio web: las llamadas a la API deben salir siempre de su backend, desde una IP autorizada.

Enviar un SMS con Laravel

1. Configuración. Agregue las credenciales a config/services.php y defina GTP_SMS_TOKEN en su archivo .env:

// config/services.php
'gtp_sms' => [
    'token'    => env('GTP_SMS_TOKEN'),
    'endpoint' => env('GTP_SMS_ENDPOINT', 'https://api.grupotecnophone.com/prod/v1/sms/send'),
],

2. Servicio. Centralice el envío en una clase reutilizable:

<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use RuntimeException;

class SmsService
{
    public function send(string $to, string $body): array
    {
        $response = Http::withToken(config('services.gtp_sms.token'))
            ->withHeaders(['User-Agent' => 'MiEmpresa/1.0'])
            ->acceptJson()
            ->timeout(30)
            ->post(config('services.gtp_sms.endpoint'), [
                'to'   => $to,
                'body' => $body,
            ]);

        $data = $response->json() ?? [];

        if ($response->successful() && ($data['status'] ?? null) === 'success') {
            return $data; // sid, encoding, num_chars, num_segments
        }

        $code = $data['error']['code'] ?? 'HTTP_' . $response->status();

        throw new RuntimeException($code . ': ' . ($data['error']['message'] ?? $response->body()));
    }
}

3. Envío en cola. Para no bloquear la petición web —y para absorber picos de envío— despache un job:

<?php

namespace App\Jobs;

use App\Services\SmsService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class SendSms implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 1; // evita reenvios duplicados ante errores de red

    public function __construct(public string $to, public string $body)
    {
    }

    public function handle(SmsService $sms): void
    {
        $result = $sms->send($this->to, $this->body);

        Log::info('SMS aceptado', ['sid' => $result['sid'], 'segmentos' => $result['num_segments']]);
    }
}

// Desde un controlador o un listener:
// SendSms::dispatch('+525512345678', 'Su codigo de verificacion es 482913. Vence en 5 minutos.');

Respuesta de la API

Si el mensaje fue aceptado, la API responde con HTTP 200 y un JSON como este:

{
  "sid": "sms_20261012143201_39bdafbd",
  "status": "success",
  "to": "+525512345678",
  "body": "Su codigo de verificacion es 482913. Vence en 5 minutos.",
  "encoding": "GSM7",
  "num_chars": 56,
  "num_segments": 1,
  "error": null
}

Guarde el sid: es el identificador con el que podrá conciliar el reporte de entrega del mensaje. El campo num_segments indica cuántos segmentos se cobrarán; vea cómo se calculan los segmentos.

Errores frecuentes

HTTPCódigoQué significa
400ENCRYPTION_REQUIREDLa conexión exige que to y body viajen cifrados con RSA-OAEP
400ENCRYPTION_NOT_ALLOWEDLa conexión opera en texto plano y se recibió contenido cifrado
400INPUT_PHONE_BLACKLISTEDEl número de destino está en lista negra
400INSUFFICIENT_BALANCESaldo insuficiente para el envío
401—Token ausente o inválido
403—La IP de origen no está autorizada para el token
500—Error interno no esperado

En los errores 400 la respuesta incluye un objeto error con code, code_num y message.

Probar en sandbox

Cambie el endpoint por https://api.grupotecnophone.com/test/v1/sms/send y use el token de sandbox. Ese entorno valida token, IP, payload y cifrado con la misma lógica que producción, pero no envía SMS reales.

Buenas prácticas

  • Defina un timeout y registre cada respuesta con su sid.
  • Ante un error de red sin respuesta, no reenvíe a ciegas: verifique primero para no duplicar el mensaje al usuario.
  • Reintente solo errores 500, con espera progresiva y un número máximo de intentos.
  • Encole los envíos masivos en lugar de enviarlos en el ciclo de una petición web.
  • Si el contenido es sensible, active el cifrado de la conexión; la documentación de la API incluye un ejemplo de cifrado RSA en PHP sin librerías externas.

Vea también la API SMS México, la conexión SMPP y las guías para PHP, Python, Node.js y Java. Si necesita credenciales de prueba, contáctenos.

Preguntas frecuentes: Enviar SMS con Laravel

Scroll al inicio