← Back to list

Como integrar Stone no Flutter com o plugin stone_payment_tech

Este guia técnico foi criado para ajudar você, desenvolvedor Flutter, a integrar pagamentos com a Stone utilizando o plugin…

Jhonathan Queiroz · 2025-09-18 16:51 · 0 claps · 3.7 min read
#stone #pagamento #pagamentos-digitais #sdk #android-sdk
Open on Medium ↗
Wiki topics: FIN · Fintech & Banking 📱 · Mobile Development

Como integrar Stone no Flutter com o plugin stone_payment_tech

Este guia técnico foi criado para ajudar você, desenvolvedor Flutter, a integrar pagamentos com a Stone utilizando o plugin stone_payment_tech.

⚠️ Atenção: este plugin NÃO É OFICIAL da Stone. Trata-se de uma implementação independente criada para facilitar a integração com os POS homologados.

Como adquirir uma licença?

  1. Acesse o site do projeto.
  2. Faça seu registro.
  3. Cadastre o terminal.
  4. Adquira a licença correspondente ao produto que deseja integrar.

Configuração inicial:

No arquivo pubspec.yaml do seu projeto, adicione o plugin como dependência:

dependencies:  
  stone_payment_tech: any

No arquivo build.gradle (nível de app), configure o minSdkVersion para 23, exigência do SDK da Stone:

…
defaultConfig { 
  applicationId "com.example.stone_example" 
  minSdkVersion 23 
  targetSdkVersion flutter.targetSdkVersion 
  versionCode flutterVersionCode.toInteger() 
  versionName flutterVersionName 
} 
…

Configuração de Flavors (Stone SDK ≥ 4.11.5)

A partir da versão 4.11.5 do SDK da Stone, é necessário configurar productFlavors, pois o PartnerHub exige que seja enviada uma versão para cada modelo de equipamento homologado.

Exemplo de configuração:

android {
    ...
    signingConfigs {
        release {
            storeFile keyProperties.storeFile
            keyAlias keyProperties.keyAlias
            keyPassword keyProperties.keyPassword
            storePassword keyProperties.storePassword
        }
    }
    flavorDimensions "model"
    productFlavors {
        gertecGPOS700X {
            dimension "model"
            signingConfig signingConfigs.release
        }
        positivoSeriesL {
            dimension "model"
            signingConfig signingConfigs.release
        }
        sunmi {
            dimension "model"
            signingConfig signingConfigs.release
        }
        tectoySeriesT {
            dimension "model"
            signingConfig signingConfigs.release
        }
        ingenico {
            dimension "model"
            signingConfig signingConfigs.release
        }
    }
...
}

Implementação no Flutter

Para receber todas as mensagens e eventos do fluxo de transação, crie uma classe que estenda IStoneHandler.

Essa classe será responsável por tratar todos os retornos do SDK da Stone — fluxo de autenticação, mensagens ao usuário, erros e resultados finais.

Exemplo:

class StoneHandler extends IStoneHandler {
@override
void onAuthProgress(String message) {
//Todo flow de autenticação é retornado aqui
}
@override
void onError(String message) {
//Todas as mensagens de erro são retornadas aqui
}
@override
void onMessage(String message) {
//Todas as mensagens que devem ser exibidas ao usuário final, são exibidas aqui
}
@override
void onFinishedResponse(String message) {
//Todos os retornos são retornados em um objeto json
}
@override
void onTransactionSuccess() {
}
@override
void onLoading(bool show) {}
@override
void onChanged(String message) {
//Sempre que for necessário exibir algum popup ou chamar algum método //junto do flow de transação, essa chamada vai vir aqui. Exemplo: Em uma //transação PIX o QRCode deve ser retornado aqui.
}
}

Iniciando uma transação

Primeiro, inicialize o plugin informando a classe criada como IStoneHandler:

final handler = StoneHandler(); 
StoneTech.I.initPayment(handler);

Depois, ative o PinPad informando o seu StoneCode (disponível na sua conta Stone) e o nome da aplicação:

StoneTech.I.payment.activePinpad(
appName: 'Exemplo Stone',
stoneCode: '123456',
);

Após o retorno em onFinishedResponse com o método “active”, prossiga com a função de pagamento escolhida:

StoneTech.I.payment.debitPayment(1000, isPrinterEstablishment: true);

O parâmetro isPrinterEstablishment define se deve ser impressa a via do estabelecimento ao final da transação.

O retorno final (sucesso ou erro, com motivo) virá em onFinishedResponse.

Métodos de pagamento disponíveis

  • Débito:
StoneTech.I.payment.debitPayment
  • Crédito:
StoneTech.I.payment.creditPayment
  • Crédito parcelado:
StoneTech.I.payment.creditPaymentParc
  • PIX:
StoneTech.I.payment.pixPayment
  • Voucher (alimentação/refeição):
StoneTech.I.payment.voucherPayment

Boas práticas

  • Para transações PIX, utilize StoneTech.I.payment.activePinpadWithCredentials, passando as credenciais fornecidas pela Stone (necessárias para geração do QR Code).
  • Para abortar uma transação em andamento:
StoneTech.I.payment.abortTransaction;
  • Para abortar especificamente uma transação PIX em andamento:
StoneTech.I.payment.abortPixTransaction;
  • Para cancelar uma transação já finalizada:
StoneTech.I.payment.cancelTransaction;
  • Caso a função de pagamento retorne em onChanged o método “PaymentOptions”, exiba ao usuário as opções disponíveis. Após a escolha, envie a opção selecionada com:
StoneTech.I.payment.setPaymentOption;

Exemplo prático: ao chamar um pagamento via voucher, se o cartão do cliente for alimentação e refeição, ele precisará escolher qual modalidade usar.

Modelos de resposta do plugin

onAuthProgress, onChanged, onError:

{
  "method": "transaction",
  "message": "Transação aprovada",
  "errorMessage": "",
  "result": 0
}

onFinishedResponse:

{
  "method": "transaction",
  "idFromBase": 0,
  "amount": 1250,
  "cardHolderNumber": "",
  "cardBrand": "",
  "date": "",
  "time": "",
  "aid": "",
  "arcq": "",
  "transactionReference": "",
  "saleAffiliationKey": "",
  "entryMode": "",
  "typeOfTransactionEnum": "",
  "serialNumber": "",
  "manufacture": "",
  "actionCode": "",
  "transactionStatus": "",
  "messageFromAuthorize": "",
  "errorMessage": "",
  "result": 0
}

Dica 💡

A resposta mais completa do SDK Stone sempre virá no método onFinishedResponse. Use o campo “method” da resposta para identificar o evento:

void onFinishedResponseMonitor(StoneTransaction? stoneTransaction) {
  switch (stoneTransaction?.method) {
    case 'active':
      // Terminal ativado
      break;
    case 'transaction':
      // Transação finalizada
      break;
    case 'abort':
    case 'abortPix':
    case 'cancel':
    case 'printer':
    case 'QRCode':
      // Exibir QR Code
      break;
    case 'PaymentOptions':
      // Use _stoneTech.payment.setPaymentOption(option: ...)
      break;
    case 'reversal':
      break;
    default:
  }
}

Extra!!!

Abaixo vou deixar alguns exemplos de como você pode fazer uma navegação para uma tela pronta do plugin ou chamar um dialog. Essa tela e esse dialog vai processar TUDO para você, todo o fluxo de pagamento é feito por ela, e ao final ela te devolve o response.

Implementação de página

Abaixo segue um exemplo usando uma tela pré montada, onde você deve passar os parâmetros solicitados e a tela faz todo o fluxo de transação, e ao terminar lhe devolve um StoneTransactionModel.

final result = await Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => StoneStreamPage(
      stonePaymentParams: StonePaymentParams(
        amount: 15,
        type: StonePaymentType.debit,
        credentials: StoneCredentialsModel(
          stoneCode: 'StoneCode',
          appName: 'nome_do_seu_app',
        ),
      ),
    ),
  ),
);

Implementação usando Dialog

Abaixo segue um exemplo usando um dialog pré montado, onde você deve passar os parâmetros solicitados e o dialog faz todo o fluxo de transação, e ao terminar lhe devolve um StoneTransactionModel.

await showDialog(
  context: context,
  builder: (context) {
    return StoneStreamDialog(
      stonePaymentParams: StonePaymentParams(
        amount: 15,
        type: StonePaymentType.debit,
        credentials: StoneCredentialsModel(
          stoneCode: 'StoneCode',
          appName: 'nome_do_seu_app',
        ),
      ),
      onConfirmPayment: (transaction) {
        print('***Response dialog: $transaction');
      },
    );
  });

Implementação usando Tela para IMPRESSÃO

final result = await Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => StonePrinterPage(
      credentials: StoneCredentialsModel(
          stoneCode: 'StoneCode',
          appName: 'nome_do_seu_app',
        ),
        child: <Seu widget montando seu layout para impressão>
    ),
  ),
);

Documentação oficial

Para mais detalhes, consulte a documentação oficial da Stone.

Conclusão

Com essa configuração, seu app Flutter estará apto a processar pagamentos em terminais Stone.

Sempre que possível, pretendo compartilhar mais integrações que ajudem a comunidade Flutter a automatizar pagamentos em POS. 🚀

Espero ter ajudado vocês!


메타데이터
post_id
f49ec17d3348
slug
como-integrar-stone-no-flutter-com-o-plugin-stone-payment-tech-f49ec17d3348
url
https://medium.com/@jhonathanqz011/como-integrar-stone-no-flutter-com-o-plugin-stone-payment-tech-f49ec17d3348
canonical_url
https://medium.com/@jhonathanqz011/como-integrar-stone-no-flutter-com-o-plugin-stone-payment-tech-f49ec17d3348
author_url
https://medium.com/@jhonathanqz011
status
ok
fetched_at
2026-06-24 11:06:28