Skip to main content

cielo_payment_tech 2.0.0 copy "cielo_payment_tech: ^2.0.0" to clipboard
cielo_payment_tech: ^2.0.0 copied to clipboard

PlatformAndroid

Plugin Flutter para facilitar a integração com o SDK de pagamentos da Cielo através do LIO.

cielo_payment_tech #

[Cielo Payment Tech]

🚨 Aviso #

Este plugin é não oficial e foi desenvolvido de forma independente para facilitar a integração de pagamentos via SDK da Cielo em dispositivos Android Smart POS.

Plugin Flutter para facilitar a integração com o SDK de pagamentos da Cielo através do LIO.

Package: br.com.jylabtech.cielo_payment_tech

Descrição #

Este plugin simplifica a integração com o SDK de pagamentos da Cielo, permitindo que desenvolvedores trabalhem apenas com código Flutter, enquanto o plugin gerencia toda a comunicação nativa com o LIO através de deep linking.

Características principais:

  • ✅ Integração simplificada com LIO via deep linking
  • ✅ Sistema de licenciamento integrado e seguro
  • ✅ Validação de licença automática no nativo
  • ✅ Callbacks assíncronos para sucesso e erro
  • ✅ Suporte a pagamentos de crédito e débito
  • ✅ Interface simples e intuitiva

Instalação #

Adicione a dependência no seu pubspec.yaml:

dependencies:
  cielo_payment_tech: ^2.0.0

Configuração Android #

1. Enviar as chaves de licença em tempo de execução #

As chaves não são mais configuradas no local.properties. Elas devem ser fornecidas pelo app ao chamar CieloPaymentTech.I.initPayment (por exemplo, lidas de um backend seguro). Veja a seção Licença do plugin para saber onde adquirir a chave e qual valor usar em licenceInternalKey.

2. Configurar Intent Filter #

Adicione os intent filters no AndroidManifest.xml do seu app (na MainActivity) para receber os callbacks do LIO. O host payment recebe o retorno dos pagamentos e o host response recebe o retorno de cancelamentos e impressões:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop"
    android:exported="true"
    ...>

    <!-- Intent filter para deep linking -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="payment"
            android:scheme="order" />
    </intent-filter>

    <!-- Retorno de cancelamento e impressão -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="response"
            android:scheme="order" />
    </intent-filter>
</activity>

Nota:

  • O launchMode="singleTop" é importante para garantir que o deep link seja processado corretamente
  • O android:exported="true" é necessário para que o deep link funcione
  • O plugin processa automaticamente os deep links no nativo, então não é necessário configurar nada adicional no código Dart

Uso #

1. Implementar o Handler #

Crie uma classe que implementa a interface ICieloHandler para receber os callbacks do plugin:

import 'package:cielo_payment_tech/cielo_payment_tech.dart';

class MyPaymentHandler implements ICieloHandler {
  @override
  Future<void> onTransactionSuccess(Map<String, dynamic> response) async {
    // response contém os dados completos do pagamento aprovado
    // Exemplo: id, status, payments, items, etc.
    print('Pagamento aprovado: $response');

    // Você pode acessar os campos específicos:
    // final orderId = response['id'];
    // final status = response['status'];
    // final payments = response['payments'];

    // Atualizar UI, salvar no banco de dados, etc.
  }

  @override
  Future<void> onCancelSuccess(Map<String, dynamic> response) async {
    // Retorno do LIO após um cancelamento concluído
    print('Cancelamento concluído: $response');
  }

  @override
  Future<void> onPrintSuccess(Map<String, dynamic> response) async {
    // Retorno do LIO após uma impressão concluída
    print('Impressão concluída: $response');
  }

  @override
  Future<void> onError(String message) async {
    // message contém a descrição do erro
    print('Erro no pagamento: $message');

    // Mostrar mensagem de erro ao usuário, fazer log, etc.
  }

  @override
  Future<void> onMessage(String message) async {
    // message contém mensagens informativas durante o processo
    // Exemplo: "Licença recebida. Validando...", "Licença ativada", "Pagamento iniciado...", etc.
    print('Mensagem: $message');

    // Atualizar status na UI, mostrar loading, etc.
  }
}

2. Inicializar o Plugin #

import 'package:cielo_payment_tech/cielo_payment_tech.dart';

// Criar o handler
final handler = MyPaymentHandler();

// Inicializar o plugin informando as chaves de licença
final payment = CieloPaymentTech.I.initPayment(
  handler: handler,
  licenceKey: 'SUA_LICENCE_KEY', // chave obtida em https://portal.jylabtech.com.br
  // licenceInternalKey é opcional (padrão: CieloPaymentTech.licenceCheck)
  urlCallback: "order://payment", // Opcional, padrão é "order://payment"
);

// Agora você pode usar o objeto payment para realizar pagamentos

Nota:

  • As chaves precisam ser fornecidas em tempo de execução ao chamar initPayment. Recomenda-se obtê-las de uma API segura.
  • A inicialização deve ser feita uma vez, geralmente no initState() ou main()
  • O plugin valida a licença automaticamente antes de cada pagamento, cancelamento e impressão. Sem licença válida a operação não é executada e o erro LICENCE_ERROR chega em onError

3. Realizar Pagamento #

Pagamento de Crédito à Vista

try {
  final success = await payment.creditPayment(
    amount: 10000, // Valor em centavos (R$ 100,00)
    accessToken: "seu_access_token",
    clientId: "seu_client_id",
    merchantCode: "seu_merchant_code", // Opcional
    email: "email@exemplo.com", // Opcional
    installments: 0, // Para crédito à vista, use 0
    items: [
      PaymentItem(
        name: "Produto",
        quantity: 1,
        sku: "SKU123",
        unitOfMeasure: "UN",
        unitPrice: 10000,
      ),
    ],
  );

  if (success) {
    // O pagamento foi iniciado
    // O resultado será retornado via onTransactionSuccess ou onError no handler
  }
} catch (e) {
  // Tratar erros de licença ou outros erros
  print('Erro: $e');
}

Pagamento de Débito à Vista

try {
  final success = await payment.debitPayment(
    amount: 10000, // Valor em centavos (R$ 100,00)
    accessToken: "seu_access_token",
    clientId: "seu_client_id",
    merchantCode: "seu_merchant_code", // Opcional
    email: "email@exemplo.com", // Opcional
    items: [
      PaymentItem(
        name: "Produto",
        quantity: 1,
        sku: "SKU123",
        unitOfMeasure: "UN",
        unitPrice: 10000,
      ),
    ],
  );

  if (success) {
    // O pagamento foi iniciado
    // O resultado será retornado via onTransactionSuccess ou onError no handler
  }
} catch (e) {
  // Tratar erros de licença ou outros erros
  print('Erro: $e');
}

Pagamento Customizado

Para ter mais controle sobre o pagamento, você pode criar um PaymentRequest customizado com qualquer tipo de pagamento suportado:

import 'package:cielo_payment_tech/cielo_payment_tech.dart';

// Exemplo: Pagamento PIX
final paymentRequestPix = PaymentRequest(
  accessToken: "seu_access_token",
  clientId: "seu_client_id",
  email: "email@exemplo.com",
  installments: 0,
  items: [
    PaymentItem(
      name: "Produto",
      quantity: 1,
      sku: "SKU123",
      unitOfMeasure: "UN",
      unitPrice: 10000,
    ),
  ],
  merchantCode: "seu_merchant_code",
  paymentCode: PaymentType.pix.code,
  value: 10000,
);

// Exemplo: Crédito Parcelado Loja (3x)
final paymentRequestParcelado = PaymentRequest(
  accessToken: "seu_access_token",
  clientId: "seu_client_id",
  email: "email@exemplo.com",
  installments: 3, // Número de parcelas
  items: [
    PaymentItem(
      name: "Produto",
      quantity: 1,
      sku: "SKU123",
      unitOfMeasure: "UN",
      unitPrice: 10000,
    ),
  ],
  merchantCode: "seu_merchant_code",
  paymentCode: PaymentType.creditoParceladoLoja.code,
  value: 10000,
);

// Exemplo: Voucher Alimentação
final paymentRequestVoucher = PaymentRequest(
  accessToken: "seu_access_token",
  clientId: "seu_client_id",
  email: "email@exemplo.com",
  installments: 0,
  items: [
    PaymentItem(
      name: "Produto",
      quantity: 1,
      sku: "SKU123",
      unitOfMeasure: "UN",
      unitPrice: 10000,
    ),
  ],
  merchantCode: "seu_merchant_code",
  paymentCode: PaymentType.voucherAlimentacao.code,
  value: 10000,
);

try {
  final success = await payment.checkout(paymentRequest: paymentRequestPix);
  if (success) {
    // Pagamento iniciado
  }
} catch (e) {
  print('Erro: $e');
}

Todos os tipos de pagamento disponíveis:

// Listar todos os códigos disponíveis
final allCodes = PaymentType.allCodes;
print(allCodes); // ['DEBITO_AVISTA', 'CREDITO_AVISTA', 'PIX', ...]

// Converter código string para PaymentType
final type = PaymentType.fromCode('PIX');
if (type != null) {
  print(type.code); // 'PIX'
}

Exemplos de uso por categoria:

  • Débito: PaymentType.debitoAvista.code
  • Crédito: PaymentType.creditoAvista.code, PaymentType.creditoParceladoLoja.code, etc.
  • Vouchers: PaymentType.voucherAlimentacao.code, PaymentType.voucherRefeicao.code, etc.
  • Cartão Loja: PaymentType.cartaoLojaAvista.code, PaymentType.cartaoLojaParceladoLoja.code, etc.
  • Outros: PaymentType.pix.code, PaymentType.preAutorizacao.code, etc.

Cancelamento e Impressão

// Cancelar um pagamento (retorno via onCancelSuccess ou onError)
await payment.cancelPayment(
  cancelRequest: CancelRequest(
    id: "order_id",
    clientId: "seu_client_id",
    accessToken: "seu_access_token",
    cieloCode: "cielo_code_do_pagamento",
    authCode: "auth_code_do_pagamento",
    value: 10000,
  ),
);

// Imprimir texto ou imagem (retorno via onPrintSuccess ou onError)
await payment.printText(text: "Comprovante de teste");
await payment.printImage(imagePath: "/caminho/da/imagem.png");

Cancelamento e impressão usam order://response como callback padrão. Todas as operações (pagamento, cancelamento e impressão) validam a licença antes de abrir o LIO.

4. Estrutura de Resposta #

Quando o pagamento é processado com sucesso, o método onTransactionSuccess recebe um Map<String, dynamic> com a seguinte estrutura:

{
  "id": "order_id",
  "status": "PAID",  // ou "PENDING", "CANCELLED", etc.
  "number": "order_number",
  "reference": "order_reference",
  "price": 10000,
  "paidAmount": 10000,
  "pendingAmount": 0,
  "createdAt": "2024-01-01T00:00:00",
  "updatedAt": "2024-01-01T00:00:00",
  "items": [
    {
      "id": "item_id",
      "name": "Produto",
      "quantity": 1,
      "unitPrice": 10000,
      ...
    }
  ],
  "payments": [
    {
      "id": "payment_id",
      "amount": 10000,
      "brand": "VISA",
      "mask": "1234",
      "authCode": "123456",
      "cieloCode": "00",
      "terminal": "terminal_info",
      "merchantCode": "merchant_code",
      ...
    }
  ]
}

Exemplo de uso da resposta:

@override
Future<void> onTransactionSuccess(Map<String, dynamic> response) async {
  final orderId = response['id'] as String?;
  final status = response['status'] as String?;
  final paidAmount = response['paidAmount'] as int?;

  if (status == 'PAID') {
    // Pagamento aprovado
    final payments = response['payments'] as List?;
    if (payments != null && payments.isNotEmpty) {
      final payment = payments[0] as Map<String, dynamic>;
      final authCode = payment['authCode'];
      final brand = payment['brand'];
      // Processar dados do pagamento
    }
  }
}

5. Tratamento de Erros #

O plugin pode retornar erros em diferentes situações:

  • Erro de Licença: Quando a licença não é válida ou não está configurada
  • Erro de LIO: Quando o app LIO não está instalado
  • Erro de Pagamento: Quando o pagamento é recusado ou cancelado
  • Erro de Rede: Quando há problemas de comunicação

Todos os erros são retornados via onError no handler, e o método chamado (checkout, creditPayment, cancelPayment, print...) retorna false. Quando a licença é recusada, a mensagem chega no formato Erro ao iniciar pagamento: PlatformException(LICENCE_ERROR, <mensagem>, ...) (ou Erro ao iniciar cancelamento/Erro ao iniciar impressão):

@override
Future<void> onError(String message) async {
  // message contém a descrição do erro
  // Exemplos:
  // - "Sua licença não foi ativada."
  // - "Erro: App LIO não instalado."
  // - "Erro desconhecido no pagamento"

  // Tratar o erro apropriadamente
}

Licença do plugin #

O plugin só executa pagamentos, cancelamentos e impressões com uma licença válida e ativa. A validação é sempre feita no servidor oficial da JY Labtech (https://portal-api.jylabtech.com.br/pos-payments/licence/check).

Onde adquirir #

  • Crie a conta ou entre em portal.jylabtech.com.br (mesmo e-mail e senha do portal antigo).
  • O produto é a Licença plugin de pagamento, que vale para qualquer plugin de pagamento da JY Labtech (Cielo, Stone, etc.).
  • Planos:
    • debug (cortesia): concedido automaticamente no cadastro, válido por 365 dias e para até 2 aparelhos. Ideal para desenvolvimento e homologação.
    • mensal: cobrado por dispositivo.
  • No portal você acompanha os aparelhos que usam a licença e pode desativá-los. Um aparelho desativado deixa de ser aceito.

As chaves de licença já existentes continuam valendo, com o mesmo valor. Chaves novas (formato JYL-...) também funcionam.

Como configurar #

Passe a chave ao chamar initPayment:

Parâmetro Valor
licenceKey Obrigatório. A chave da sua licença, copiada do portal.
licenceInternalKey Opcional. Padrão: CieloPaymentTech.licenceCheck (aHR0cHM6Ly9wb3J0YWwtYXBpLmp5bGFidGVjaC5jb20uYnIvcG9zLXBheW1lbnRzL2xpY2VuY2UvY2hlY2s=, base64 de https://portal-api.jylabtech.com.br/pos-payments/licence/check).

O plugin sempre valida no servidor oficial da JY Labtech. O licenceInternalKey (URL em texto ou em base64) só é aceito se apontar para https://portal-api.jylabtech.com.br/pos-payments/licence/check (ou as variantes /invoice e /subscription). Qualquer outro valor é ignorado e o servidor oficial é usado no lugar.

Migração: o valor antigo do licenceInternalKey (que começa com aHR0cHM6Ly9wb3MtcGF5bWVudHMtYXBp...) é ignorado: a validação vai para o servidor novo. A licença guardada no aparelho com o valor antigo é descartada e validada de novo online na primeira operação. Pode remover o parâmetro do seu código.

Como a validação funciona #

  • O aparelho é identificado principalmente pelo ANDROID_ID. Cada aparelho novo ocupa uma vaga da licença.
  • A validação acontece no nativo antes de cada pagamento, cancelamento ou impressão. Com licença inválida a operação não é executada. A resposta do LIO (deep link) de uma operação já iniciada é sempre repassada ao app.
  • A licença só libera o uso se estiver dentro da validade e não estiver vencida, inativa/suspensa ou cancelada. Uma resposta do servidor com licença nessas condições também bloqueia.
  • Depois de validada, a licença fica guardada no aparelho (criptografada com EncryptedSharedPreferences) e funciona offline até a data de vencimento, por no máximo 7 dias sem nova consulta ao servidor. Depois disso, o aparelho precisa de internet para validar de novo. Uma licença guardada com data no futuro (relógio do aparelho adulterado) é descartada.
  • Trocar a licenceKey força uma nova consulta ao servidor.
  • A consulta ao servidor roda fora da thread principal, com timeout de 15 segundos.

Erros de licença #

HTTP Situação O que fazer
404 Licença não encontrada Confira a licenceKey (sem espaços ou quebras de linha).
412 Limite de aparelhos atingido ou aparelho desativado Libere ou reative o aparelho no portal, ou contrate mais dispositivos.
428 Licença vencida, suspensa ou cancelada Renove ou regularize o pagamento no portal.
403 Requisição sem chave Verifique se licenceKey foi informada no initPayment.
400 Aparelho sem identificador estável Verifique se o aparelho expõe o ANDROID_ID.
429 Muitas tentativas em pouco tempo Aguarde alguns instantes e tente de novo.

A mensagem retornada pelo servidor (campo message) é repassada para o onError com o código LICENCE_ERROR. Se a resposta não tiver mensagem, ela vira Erro ao validar licença (HTTP <código>). Se o servidor não estiver acessível e não houver licença válida guardada, a mensagem será o erro de rede (por exemplo, Tempo esgotado ao validar a licença...). Uma licença recusada pelas regras do plugin gera Licença vencida., Licença inativa ou suspensa. ou Licença cancelada..

Recursos #

Tipos de Pagamento Suportados #

Débito:

  • ✅ Débito à vista

Crédito:

  • ✅ Crédito à vista
  • ✅ Crédito parcelado loja
  • ✅ Crédito parcelado administradora
  • ✅ Crédito parcelado banco
  • ✅ Crédito parcelado cliente
  • ✅ Crédito crediário

Vouchers:

  • ✅ Voucher alimentação
  • ✅ Voucher refeição
  • ✅ Voucher automotivo
  • ✅ Voucher cultura
  • ✅ Voucher benefícios
  • ✅ Voucher auto

Cartão Loja:

  • ✅ Cartão loja à vista
  • ✅ Cartão loja parcelado loja
  • ✅ Cartão loja parcelado
  • ✅ Cartão loja parcelado banco
  • ✅ Cartão loja pagamento fatura cheque
  • ✅ Cartão loja pagamento fatura dinheiro

Outros:

  • ✅ PIX
  • ✅ Pré-autorização
  • ✅ Crediário venda

Outros Recursos #

  • ✅ Deep linking automático com o LIO
  • ✅ Sistema de licenciamento integrado e seguro
  • ✅ Validação de licença automática no nativo
  • ✅ Callbacks assíncronos para sucesso e erro
  • ✅ Suporte a itens de pagamento
  • ✅ Armazenamento criptografado de licença
  • ✅ Interface simples e intuitiva
  • ✅ Processamento de deep links no nativo

Estrutura do Projeto #

O plugin segue a mesma estrutura do projeto Stone Payment Tech:

  • lib/src/interface/ - Interfaces e handlers
    • handler/ - Interface ICieloHandler
    • model/ - Modelos de dados (PaymentRequest, PaymentResponse, PaymentType, etc.)
  • lib/src/payments/ - Lógica de pagamento
    • payment.dart - Classe Payment com métodos de pagamento
  • lib/src/cielo_payment_tech.dart - Classe principal do plugin
  • android/native/src/main/java/br/com/jylabtech/cielo_payment_tech/ - Código nativo Android (compilado no AAR)
    • licence/ - Sistema de licenciamento
    • payments/ - Presenter de pagamentos
    • core/ - Classes core do plugin

Requisitos #

  • Flutter >= 3.3.0
  • Android SDK 24+ (minSdk 24)
  • LIO instalado no dispositivo
  • Chaves de licença válidas fornecidas em tempo de execução (ver initPayment)

Exemplo Completo #

Aqui está um exemplo completo de uso do plugin:

import 'package:flutter/material.dart';
import 'package:cielo_payment_tech/cielo_payment_tech.dart';

class PaymentScreen extends StatefulWidget {
  @override
  _PaymentScreenState createState() => _PaymentScreenState();
}

class _PaymentScreenState extends State<PaymentScreen> {
  Payment? _payment;

  @override
  void initState() {
    super.initState();
    _initializePayment();
  }

  void _initializePayment() {
    final handler = MyPaymentHandler();
    _payment = CieloPaymentTech.I.initPayment(
      handler: handler,
      licenceKey: 'SUA_LICENCE_KEY',
    );
  }

  Future<void> _processPayment() async {
    try {
      await _payment?.creditPayment(
        amount: 10000,
        accessToken: "seu_access_token",
        clientId: "seu_client_id",
      );
    } catch (e) {
      print('Erro: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Pagamento')),
      body: Center(
        child: ElevatedButton(
          onPressed: _processPayment,
          child: Text('Pagar'),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _payment?.dispose();
    super.dispose();
  }
}

class MyPaymentHandler implements ICieloHandler {
  @override
  Future<void> onTransactionSuccess(Map<String, dynamic> response) async {
    print('Pagamento aprovado: $response');
  }

  @override
  Future<void> onCancelSuccess(Map<String, dynamic> response) async {
    print('Cancelamento concluído: $response');
  }

  @override
  Future<void> onPrintSuccess(Map<String, dynamic> response) async {
    print('Impressão concluída: $response');
  }

  @override
  Future<void> onError(String message) async {
    print('Erro: $message');
  }

  @override
  Future<void> onMessage(String message) async {
    print('Mensagem: $message');
  }
}

Veja também o exemplo completo em example/lib/payment_page.dart para uma implementação funcional com interface de usuário completa.

Troubleshooting #

Erro: "LicenceKey não encontrado" #

  • Verifique se CieloPaymentTech.I.initPayment está sendo chamado com licenceKey preenchida
  • Confirme que as chaves estão chegando corretamente do seu backend/configuração segura
  • Certifique-se de remover espaços extras ou caracteres inválidos nas chaves

Erro: "App LIO não instalado" #

  • Instale o app LIO no dispositivo
  • Verifique se o app LIO está atualizado
  • Verifique se o intent filter está configurado no AndroidManifest.xml
  • Confirme que o launchMode="singleTop" está configurado na Activity
  • Verifique se o urlCallback está correto

Licença não é validada #

  • Garanta que o app chamou initPayment antes de qualquer operação de pagamento/cancelamento/impressão
  • Verifique no portal se a licença está ativa, dentro da validade e se o aparelho não foi desativado ou excedeu o limite
  • Confirme que há conexão com a internet para a primeira validação (e a cada 7 dias)
  • Consulte a tabela Erros de licença para a mensagem recebida em onError

Erro: "Licença não configurada" #

  • initPayment não foi chamado, ou foi chamado com licenceKey vazia

Testes #

Testes Dart (MethodChannel mockado):

flutter test

Testes JVM da validação de licença no nativo (android/native/src/test), usando o wrapper do example e a JDK 17:

FLUTTER_SDK=<caminho do Flutter SDK> example/android/gradlew -p android/native testDebugUnitTest

Depois de alterar o código em android/native, gere de novo o binário distribuído em android/libs com make build-native (ou sh scripts/build_android_aar.sh).

Contribuindo #

Contribuições são bem-vindas! Por favor, abra uma issue ou pull request.

Licença #

Este projeto é proprietário e está protegido por direitos autorais.

ATENÇÃO: Este software é propriedade de JYLabtech e está protegido por lei de direitos autorais. O uso deste software é restrito e está sujeito aos termos e condições da licença proprietária.

Você NÃO tem permissão para:

  • Copiar, reproduzir ou duplicar o software
  • Modificar, adaptar ou criar trabalhos derivados
  • Vender, alugar, sublicenciar ou distribuir o software
  • Fazer engenharia reversa ou descompilar o software
  • Usar o software para fins não autorizados

Para mais informações sobre licenciamento, consulte o arquivo LICENSE ou entre em contato com JYLabtech.

Copyright (c) 2024 JYLabtech. All Rights Reserved.

📞 Suporte #

Para questões relacionadas ao LIO e ao SDK da Cielo, consulte a documentação oficial da Cielo.

Para licenças, acesse portal.jylabtech.com.br.

Para questões específicas sobre este plugin, verifique os issues do repositório ou entre em contato com a equipe de desenvolvimento.



0
likes
130
points
95
downloads

Documentation

API reference

Publisher

verified publisherjylabtech.com.br

Weekly Downloads

Plugin Flutter para facilitar a integração com o SDK de pagamentos da Cielo através do LIO.

Homepage

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on cielo_payment_tech

Packages that implement cielo_payment_tech