Implementação da tela PIN TEF
Ingenico
A Ingenico tem um mecanismo de skin para montar a tela de senha. A integradora terá que implementar conforme o exemplo abaixo:
private void configurePinpadSkin() {
// Configura layout customizado do PINPAD
Intent configureSkin = new Intent("com.landicorp.pinpad.pinentry.server.SET_SKIN");
configureSkin.putExtra("disorder", false);
// Força texto de entrada (os ‘*’) a ser apresentada
configureSkin.putExtra("show_input", true);
// Define o nome da Skin
configureSkin.putExtra("skin_name", "GETNET4");
// Totalmente transparente
configureSkin.putExtra("dim_amount", 0);
// Tamanho em altura do PinPad
configureSkin.putExtra("skb_height", 580);
// Comunica a configuração ao serviço pinentry
mContext.sendBroadcast(configureSkin);
}
private fun configurePinpadSkin() {
// Configura layout customizado do PINPAD
val configureSkin = Intent("com.landicorp.pinpad.pinentry.server.SET_SKIN").apply {
putExtra("disorder", false)
// Força texto de entrada (os ‘*’) a ser apresentada
putExtra("show_input", true)
// Define o nome da Skin
putExtra("skin_name", "GETNET4")
// Totalmente transparente
putExtra("dim_amount", 0)
// Tamanho em altura do PinPad
putExtra("skb_height", 580)
}
// Comunica a configuração ao serviço pinentry
mContext.sendBroadcast(configureSkin)
}
const configurePinpadSkin = () => {
const extras: { [key: string]: string|int|boolean } = {
'disorder': false,
// Força texto de entrada (os ‘*’) a ser apresentada
'show_input': true,
// Define o nome da Skin
'skin_name': 'GETNET4',
// Totalmente transparente
'dim_amount': 0,
// Tamanho em altura do PinPad
'skb_height': 580
};
const intentParams = {
extra: extras,
};
// Comunica a configuração ao serviço pinentry
IntentLauncher.startActivityAsync('com.landicorp.pinpad.pinentry.server.SET_SKIN', intentParams);
}
Será necessário fazer uso do código nativo:
package com.example.deeplink_test
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
class MainActivity: FlutterActivity(), MethodCallHandler {
private val CHANNEL = "sample.android/deeplink"
private lateinit var channel: MethodChannel
private var callback: Result? = null
private var requestCode: Int = -1
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).apply {
setMethodCallHandler(this@MainActivity)
}
}
override fun onMethodCall(call: MethodCall, result: Result) {
var action = ""
var bundle = Bundle()
when(call.method) {
"sendBroadcast" -> {
callback = result
val params = call.arguments as? Map<String, Any>
params?.run {
for ((key, value) in this) {
when(key.toString()) {
"action" -> action = value.toString()
"arguments" -> {
bundle.apply{
for((argKey, argValue) in (value as Map<String, Any>)) {
when(argValue) {
is String -> putString(argKey, argValue as String)
is Int -> putInt(argKey, argValue as Int)
is Boolean -> putBoolean(argKey, argValue as Boolean)
}
}
}
}
}
}
val intent = Intent(action).apply {
putExtras(bundle)
}
sendBroadcast(intent)
callback?.success(1)
}
}
else -> result.notImplemented()
}
}
}
E com o código nativo criado, podemos chamar ele através do sendBroadcast abaixo:
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key,});
@override
State<MyApp> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
static const platform = MethodChannel('sample.android/deeplink');
void sendBroadcast(String action, Map<String, dynamic> bundle) async {
try {
final intent = {
'action': action,
'arguments': bundle,
};
var result = await platform.invokeMethod('sendBroadcast', intent);
if (result == 1) {
log('sendBroadcast enviado com sucesso!');
} else {
log('Error launching intent: $action');
}
} catch (e) {
log('Error launching intent: $e');
}
}
void _sendBroadcast() {
Map<String, dynamic> intentParams = {
'disorder': false,
'show_input': true,
'skin_name': 'GETNET4',
'dim_amount': 0,
'skb_height': 580
};
sendBroadcast('com.landicorp.pinpad.pinentry.server.SET_SKIN', intentParams);
}
@override
void initState() {
super.initState();
_sendBroadcast();
}
@override
Widget build(BuildContext context) {
return ();
}
}
Este mecanismo enviará um broadcast para o service da Ingenico que quando for chamado um goOnChip ou getPin, a tela de senha será invocada pelo service e ficará em primeiro plano.
Atualmente, além da skin default do fabricante existem 3 opções de skin customizadas: GETNET4, SKIN_LIGHT, SKIN_DARK. Para ter acesso a essas skins baixe o aplicativo “Teclados de Senha para TEF” no Portal do Desenvolvedor.
Para usar a skin default do fabricante basta remover a linha:
“configureSkin.putExtra("skin_name", "GETNET4");”. Para as outras você deverá substituir o
GETNET4 pelas demais citadas anteriormente.