southgames_flutter 0.5.10
southgames_flutter: ^0.5.10 copied to clipboard
Flutter SDK for SouthGames — integrate gamification and loyalty features (spin wheel, scratch cards, trivia, slot machine, promo codes, in-app notifications) into your Flutter app with a single package.
SouthGames Flutter SDK #
Flutter SDK para integrar gamificacion y loyalty de SouthGames en tu app.
Funcionalidades #
- Registro de clientes — upsert por
externalIdcon custom params y device tokens. - Idioma automatico — detecta el locale del dispositivo (ej:
es-CL) y lo envia al registrar. - Identificacion automatica — envia y refresca el device token en cada inicio de app.
- Campanas activas — listado de campanas con configuracion de juego.
- 4 tipos de juego — spin wheel, scratch card, trivia y slot machine.
- Juegos del marketplace — carga juegos HTML5 en WebView con
SouthGamesGameView. - Codigos promocionales — generacion automatica al ganar + canje.
- Sistema de puntos — consultar saldo, historial, gastar y ganar puntos canjeables.
- Notificaciones in-app — filtradas por segment rules del cliente.
- Push notifications — registro de device tokens con cualquier proveedor (FCM, APNs, etc.).
Instalacion #
Agrega southgames_flutter a tu pubspec.yaml:
dependencies:
southgames_flutter: ^0.5.6
Luego ejecuta:
flutter pub get
Inicio rapido #
import 'package:southgames_flutter/southgames_flutter.dart';
// Si usas Firebase Cloud Messaging:
// import 'package:firebase_messaging/firebase_messaging.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
// 1. Inicializar el SDK
SouthGamesSDK.init(
apiKey: 'sg_live_xxxxxxxxxxxxxxxx',
orgId: 'tu-org-slug',
// Token automatico con FCM (opcional):
// tokenProvider: () => FirebaseMessaging.instance.getToken(),
// onTokenRefresh: FirebaseMessaging.instance.onTokenRefresh,
);
runApp(const MyApp());
}
// 2. Identificar al usuario (envia el token automaticamente)
final res = await SouthGamesSDK.identify(
externalId: 'user_123',
email: 'usuario@app.com',
customParams: {'plan': 'premium'},
);
print('Client ID: ${res.clientId}');
// 3. Obtener campanas activas
final campaigns = await SouthGamesSDK.getCampaigns();
// 4. Jugar
final play = await SouthGamesSDK.play(
campaignId: campaigns.first.id,
externalUserId: 'user_123',
);
if (play.won && play.prizeCode != null) {
print('Ganaste! Codigo: ${play.prizeCode}');
}
// 5. Canjear un codigo
final redeem = await SouthGamesSDK.redeem(code: play.prizeCode!);
print('Descuento: ${redeem.discountValue}%');
Uso #
Inicializacion #
Llama a SouthGamesSDK.init() antes de usar cualquier otro metodo. Generalmente en main().
SouthGamesSDK.init(
apiKey: 'sg_live_xxxxxxxxxxxxxxxx',
orgId: 'tu-org-slug',
);
Token automatico (recomendado)
Para enviar y refrescar el device token automaticamente en cada inicio de app, pasa tokenProvider y onTokenRefresh:
SouthGamesSDK.init(
apiKey: 'sg_live_xxxxxxxxxxxxxxxx',
orgId: 'tu-org-slug',
tokenProvider: () => FirebaseMessaging.instance.getToken(),
onTokenRefresh: FirebaseMessaging.instance.onTokenRefresh,
);
tokenProvider: callback async que retorna el token actual del dispositivo.onTokenRefresh: stream que emite tokens nuevos cuando se refrescan.
Cuando se usa junto con identify(), el SDK:
- Obtiene el token via
tokenProvidery lo envia al registrar al usuario. - Escucha
onTokenRefreshy re-registra automaticamente cuando el token cambia.
Nota: Si usas el SDK sin llamar a
init(), se lanzaSouthGamesNotInitializedException.
Identificacion de usuario #
identify() registra o actualiza al usuario y envia el device token automaticamente. El idioma del dispositivo (ej: es-CL) se detecta y envia automaticamente. Llamalo en cada inicio de app una vez que conozcas la identidad del usuario.
final res = await SouthGamesSDK.identify(
externalId: 'user_123', // ID del usuario en tu plataforma
email: 'user@example.com', // opcional
firstName: 'Juan', // opcional
lastName: 'Perez', // opcional
phone: '+56912345678', // opcional
latitude: -33.45, // opcional
longitude: -70.66, // opcional
customParams: {'tier': 'gold'}, // opcional
);
print(res.clientId); // ID unico del cliente en SouthGames
print(res.created); // true si es nuevo, false si se actualizo
print(res.deviceTokenSent); // true si el device token fue enviado
Debug: El SDK imprime logs con el prefijo
[SouthGames]en la consola de debug. Si el token no se esta enviando, busca mensajes como"No tokenProvider configured"o"tokenProvider returned null".
Registro manual de cliente #
Si necesitas mas control, puedes usar registerClient() directamente:
final res = await SouthGamesSDK.registerClient(
externalId: 'user_123',
email: 'user@example.com',
deviceToken: 'fcm_or_apns_token', // opcional
);
Heartbeat #
Actualiza lastSeenAt del cliente. Util para trackear actividad.
await SouthGamesSDK.heartbeat(clientId: 'client_id');
Campanas activas #
Retorna las campanas con status == "active" dentro de su rango de fechas.
final campaigns = await SouthGamesSDK.getCampaigns();
for (final c in campaigns) {
print('${c.name} (${c.gameType})');
}
Jugar un juego #
// Spin wheel / scratch card / slot machine
final play = await SouthGamesSDK.play(
campaignId: 'campaign_id',
externalUserId: 'user_123',
);
// Trivia (requiere respuestas)
final triviaPlay = await SouthGamesSDK.play(
campaignId: 'trivia_campaign_id',
externalUserId: 'user_123',
answers: [0, 2, 1, 3], // indice de la opcion elegida por pregunta
);
print(play.won); // true si gano
print(play.prizeCode); // codigo promo si gano, null si no
print(play.result); // descripcion del resultado
print(play.metadata); // metadata especifica del juego
Juegos del marketplace (WebView) #
Para campanas con juegos del marketplace, usa SouthGamesGameView:
if (campaign.isMarketplaceGame) {
Navigator.push(context, MaterialPageRoute(
builder: (_) => SouthGamesGameView(
campaign: campaign,
externalUserId: 'user_123',
onResult: (result) {
print(result.won ? 'Ganaste!' : 'No ganaste');
Navigator.pop(context);
},
onClose: () => Navigator.pop(context),
onError: (error) => print('Error: $error'),
),
));
}
Canjear codigo promocional #
final redeem = await SouthGamesSDK.redeem(
code: 'SG-AB2C-XY9Z',
externalUserId: 'user_123', // opcional
);
print(redeem.success); // true
print(redeem.discountType); // 'percentage' | 'fixed'
print(redeem.discountValue); // ej: 20
print(redeem.remainingUses); // usos restantes
Notificaciones in-app #
Retorna notificaciones activas que matchean las segment rules del cliente.
final notifications = await SouthGamesSDK.getInAppNotifications(
clientId: 'client_id',
);
for (final n in notifications) {
print('${n.title} — ${n.body}');
if (n.cta != null) {
print('CTA: ${n.cta!.label} -> ${n.cta!.action}');
}
}
Puntos #
Consulta el saldo, historial, gasta y gana puntos canjeables.
// Consultar saldo
final balance = await SouthGamesSDK.getPointsBalance(
externalUserId: 'user_123',
);
print('${balance.pointsName}: ${balance.pointsBalance}');
print('Ganados: ${balance.pointsEarned}');
print('Gastados: ${balance.pointsSpent}');
// Historial de puntos
final history = await SouthGamesSDK.getPointsHistory(
externalUserId: 'user_123',
limit: 10,
);
for (final entry in history) {
print('${entry.type}: ${entry.amount} — ${entry.reason}');
}
// Gastar puntos
try {
final spend = await SouthGamesSDK.spendPoints(
externalUserId: 'user_123',
amount: 100,
reason: 'Canje por descuento',
);
print('Gastaste ${spend.pointsSpent} puntos. Saldo: ${spend.newBalance}');
} on SouthGamesException catch (e) {
if (e.code == 'INSUFFICIENT_BALANCE') {
print('Saldo insuficiente');
}
}
// Ganar puntos manualmente
final earn = await SouthGamesSDK.earnPoints(
externalUserId: 'user_123',
action: 'custom',
eventName: 'purchase_completed',
);
print('Ganaste ${earn.pointsAwarded} puntos. Saldo: ${earn.newBalance}');
Nota: Los puntos tambien se ganan automaticamente al jugar, ganar juegos y canjear codigos, si hay reglas de ganancia configuradas en el dashboard.
Push notifications (manual) #
Si no usas tokenProvider/onTokenRefresh, puedes registrar tokens manualmente:
await SouthGamesSDK.push.registerDeviceToken(
externalId: 'user_123',
token: 'fcm_or_apns_token',
);
Limpieza #
Libera los recursos del HTTP client cuando ya no necesites el SDK.
SouthGamesSDK.dispose();
Manejo de errores #
Todas las llamadas pueden lanzar SouthGamesException:
try {
await SouthGamesSDK.redeem(code: 'INVALID');
} on SouthGamesException catch (e) {
print(e.message); // "Codigo no encontrado"
print(e.code); // "CODE_NOT_FOUND"
print(e.statusCode); // 404
}
Codigos de error comunes #
| Codigo | HTTP | Descripcion |
|---|---|---|
MISSING_API_KEY |
401 | Falta API key |
MISSING_ORG_ID |
401 | Falta org ID |
INVALID_API_KEY |
401 | API key invalida o inactiva |
API_KEY_EXPIRED |
401 | API key expirada |
VALIDATION_ERROR |
400 | Datos de entrada invalidos |
NOT_FOUND |
404 | Recurso no encontrado |
CAMPAIGN_INACTIVE |
400 | Campana no activa |
CODE_NOT_FOUND |
404 | Codigo promo no existe |
CODE_INACTIVE |
400 | Codigo desactivado |
CODE_EXPIRED |
400 | Codigo expirado |
CODE_MAX_USES_REACHED |
400 | Codigo sin usos restantes |
INSUFFICIENT_BALANCE |
400 | Saldo de puntos insuficiente |
POINTS_NOT_ENABLED |
400 | Sistema de puntos no habilitado |
Modelos #
| Clase | Descripcion |
|---|---|
RegisterResponse |
Resultado del registro (clientId, created, deviceTokenSent) |
Campaign |
Campana activa (id, name, gameType, config, fechas) |
PlayResponse |
Resultado de jugar (sessionId, won, prizeCode, metadata) |
RedeemResult |
Resultado de canje (discountType, discountValue, remainingUses) |
InAppNotification |
Notificacion in-app (title, body, type, position, cta, colores) |
CtaButton |
Boton CTA de notificacion (label, action) |
PointsBalance |
Saldo de puntos (pointsBalance, pointsEarned, pointsSpent, pointsName) |
PointsLedgerEntry |
Entrada del historial de puntos (type, amount, balance, reason) |
SpendPointsResponse |
Resultado de gastar puntos (pointsSpent, newBalance) |
EarnPointsResponse |
Resultado de ganar puntos (pointsAwarded, newBalance, totalEarned) |
Requisitos #
- Dart SDK
>=3.0.0 <4.0.0 - Flutter
>=3.10.0 - Una cuenta en SouthGames con API key activa
Licencia #
MIT — ver LICENSE.