Pular para conteúdo

Pré-autorização | Deeplink

Este deeplink pode ser utilizado para realizar uma pré-autorização. Ao ser utilizado irá iniciar o app Pagamento na tela de Pré-autorização.

Exemplo de implementação (utilizando Pré-autorização V2)

public class MainActivity extends AppCompatActivity {
    private final int REQUEST_CODE = 1001;
    private final String ARG_RESULT = "result";
    private final String ARG_RESULT_DETAILS = "resultDetails";
    private final String ARG_AMOUNT = "amount";
    private final String ARG_TYPE = "type";
    private final String ARG_INPUT_TYPE = "inputType";
    private final String ARG_INSTALLMENTS = "installments";
    private final String ARG_NSU = "nsu";
    private final String ARG_BRAND = "brand";
    private final String ARG_CALLER_ID = "callerId";

    private final String PARAM_AMOUNT = "amount";
    private final String PARAM_CUR_POS = "currencyPosition";
    private final String PARAM_CUR_CODE = "currencyCode";
    private final String PARAM_CALLER_ID = "callerId";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        String callerId = UUID.randomUUID().toString();
        Bundle bundle = new Bundle();
        bundle.putString(PARAM_AMOUNT, "000000001000");
        bundle.putString(PARAM_CUR_POS, "CURRENCY_AFTER_AMOUNT");
        bundle.putString(PARAM_CUR_CODE, "986");
        bundle.putString(PARAM_CALLER_ID, callerId);
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("getnet://pagamento/v2/pre-authorization"));
        intent.putExtras(bundle);
        startActivityForResult(intent, REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        if(REQUEST_CODE == requestCode && RESULT_OK == resultCode){
            String result = data.getStringExtra(ARG_RESULT);
            String resultDetails = data.getStringExtra(ARG_RESULT_DETAILS);
            String amount = data.getStringExtra(ARG_AMOUNT);
            String callerId = data.getStringExtra(ARG_CALLER_ID);
            String type = data.getStringExtra(ARG_TYPE);
            String inputType = data.getStringExtra(ARG_INPUT_TYPE);
            String installments = data.getStringExtra(ARG_INSTALLMENTS);
            String nsu = data.getStringExtra(ARG_NSU);
            String brand = data.getStringExtra(ARG_BRAND);
        }
    }
}
class MainActivity : AppCompatActivity() {
    private val REQUEST_CODE = 1001
    private val ARG_RESULT = "result"
    private val ARG_RESULT_DETAILS = "resultDetails"
    private val ARG_AMOUNT = "amount"
    private val ARG_TYPE = "type"
    private val ARG_INPUT_TYPE = "inputType"
    private val ARG_INSTALLMENTS = "installments"
    private val ARG_NSU = "nsu"
    private val ARG_BRAND = "brand"
    private val ARG_CALLER_ID = "callerId"

    private val PARAM_AMOUNT = "amount";
    private val PARAM_CUR_POS = "currencyPosition";
    private val PARAM_CUR_CODE = "currencyCode";
    private val PARAM_CALLER_ID = "callerId";

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val callerId = UUID.randomUUID().toString()
        val bundle = Bundle().apply {
            putString(PARAM_AMOUNT, "000000001000")
            putString(PARAM_CUR_POS, "CURRENCY_AFTER_AMOUNT")
            putString(PARAM_CUR_CODE, "986")
            putString(PARAM_CALLER_ID, callerId)
        }
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse("getnet://pagamento/v2/pre-authorization"))
        intent.putExtras(bundle)
        startActivityForResult(intent, REQUEST_CODE)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (REQUEST_CODE == requestCode && resultCode == RESULT_OK) {
            val result = data?.getStringExtra(ARG_RESULT)
            val resultDetails = data?.getStringExtra(ARG_RESULT_DETAILS)
            val amount = data?.getStringExtra(ARG_AMOUNT)
            val callerId = data?.getStringExtra(ARG_CALLER_ID)
            val type = data?.getStringExtra(ARG_TYPE)
            val inputType = data?.getStringExtra(ARG_INPUT_TYPE)
            val installments = data?.getStringExtra(ARG_INSTALLMENTS)
            val nsu = data?.getStringExtra(ARG_NSU)
            val brand = data?.getStringExtra(ARG_BRAND)
        }
    }
}
import React, { useState, useLayoutEffect } from 'react';
import { View, Text } from 'react-native';
import * as IntentLauncher from 'expo-intent-launcher';
import { randomUUID } from 'expo-crypto';

const RESULT_OK = -1;
const RESULT_CANCELED = 0;

const ACTION_VIEW = 'android.intent.action.VIEW';

export default function MainComponent() {

  const ARG_RESULT = "result";
  const ARG_RESULT_DETAILS = "resultDetails";
  const ARG_AMOUNT = "amount";
  const ARG_TYPE = "type";
  const ARG_INPUT_TYPE = "inputType";
  const ARG_INSTALLMENTS = "installments";
  const ARG_NSU = "nsu";
  const ARG_BRAND = "brand";
  const ARG_CALLERID = "callerId";

  const PARAM_AMOUNT = 'amount';
  const PARAM_CUR_POS = 'currencyPosition';
  const PARAM_CUR_CODE = 'currencyCode';
  const PARAM_CALLER_ID = 'callerId';

  const [resultCode, setResultCode] = useState<number>();
  const [resultData, setResultData] = useState({});

  const launchIntent = async(deeplink: string, bundle: {}) =>  {

    const intentParams = { ...bundle, data: deeplink }; //Unindo URI Deeplink com o bundle no intentParams

    try {
      const activityResult = await IntentLauncher.startActivityAsync(ACTION_VIEW, intentParams);
      if (activityResult.data && activityResult.resultCode == RESULT_OK) {

        if(activityResult.extra) {
          const JSON_obj = JSON.parse(JSON.stringify(activityResult.extra))

          const result = JSON_obj[ARG_RESULT];
          const resultDetails = JSON_obj[ARG_RESULT_DETAILS];
          const amount =JSON_obj[ARG_AMOUNT];
          const callerId = JSON_obj[ARG_CALLERID];
          const type = JSON_obj[ARG_TYPE];
          const inputType = JSON_obj[ARG_INPUT_TYPE];
          const installments = JSON_obj[ARG_INSTALLMENTS];
          const nsu = JSON_obj[ARG_NSU];
          const brand = JSON_obj[ARG_BRAND];

          setResultData(JSON_obj);
          setResultCode(activityResult.resultCode);
        }
      }
    } catch (error) {
      console.error(error);
    }
  };

  useLayoutEffect(() => {
    const callerId = randomUUID();
    const extras: { [key: string]: string } = {
      [PARAM_AMOUNT]: '000000001000',
      [PARAM_CUR_POS]: 'CURRENCY_AFTER_AMOUNT',
      [PARAM_CUR_CODE]: '986',
      [PARAM_CALLER_ID]: callerId,
    };

    const intentParams = {
      extra: extras,
    };

    //Dispara o Deeplink assim que a tela termina de ser carregada
    launchIntent('getnet://pagamento/v2/pre-authorization', intentParams);
  }, []);

  return (
    <View>
      <Text>Result Code: {resultCode}</Text>
      <Text>Result Data: {JSON.stringify(resultData)}</Text>
    </View>
  );
}

Para utilizar o deeplink, 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 deeplink = ""
        var bundle = Bundle()

        when(call.method) {
            "startActivityForResult" -> {
                callback = result
                val params = call.arguments as? Map<String, Any>
                params?.run {
                    for ((key, value) in params) {
                        when(key.toString()) {
                            "action" -> action = value.toString()
                            "data" -> deeplink = value.toString()
                            "requestCode" -> requestCode = value.toString().toInt()
                            "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, Uri.parse(deeplink)).apply {
                        putExtras(bundle)
                    }
                    startActivityForResult(intent, requestCode)
                }
            }
            else -> result.notImplemented()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode) {
            this.requestCode -> {
                when(resultCode) {
                    Activity.RESULT_OK -> {
                        data?.getExtras()?.let { extras ->
                            val resultMap = hashMapOf<String, Any?>()
                            for(key in extras.keySet()) {
                                resultMap[key] = extras.get(key)
                            }
                            callback?.success(resultMap)
                        }
                    } else -> callback?.error("ERROR", "No valid return from DeepLink", null)
                }
            } else -> callback?.error("ERROR", "Activity result was not OK", null)
        }
    }
}

E com o código nativo criado, podemos chamar ele através do startIntent abaixo:

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:uuid/uuid.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 int REQUEST_CODE = 1001;
  static const String ARG_RESULT = 'result';
  static const String ARG_RESULT_DETAILS = 'resultDetails';
  static const String ARG_AMOUNT = 'amount';
  static const String ARG_TYPE = 'type';
  static const String ARG_INPUT_TYPE = 'inputType';
  static const String ARG_INSTALLMENTS = 'installments';
  static const String ARG_NSU = 'nsu';
  static const String ARG_BRAND = 'brand';
  static const String ARG_CALLER_ID = 'callerId';

  static const String PARAM_AMOUNT = 'amount';
  static const String PARAM_CUR_POS = 'currencyPosition';
  static const String PARAM_CUR_CODE = 'currencyCode';
  static const String PARAM_CALLER_ID = 'callerId';

  int? resultCode;
  var deeplinkResult = '';

  static const platform = MethodChannel('sample.android/deeplink');

  void startIntent(String deeplink, Map<String, String> bundle) async {
      try {
        final intent = {
          'requestCode': REQUEST_CODE,
          'action': 'android.intent.action.VIEW',
          'data': deeplink,
          'arguments': bundle,
        };
        var result = await platform.invokeMethod('startActivityForResult', intent);
        if (result != null) {
          var resultMap = Map<String, dynamic>.from(result);

          String resultValue = resultMap[ARG_RESULT];
          String resultDetails = resultMap[ARG_RESULT_DETAILS];
          String amount = resultMap[ARG_AMOUNT];
          String callerId = resultMap[ARG_CALLER_ID];
          String type = resultMap[ARG_TYPE];
          String inputType = resultMap[ARG_INPUT_TYPE];
          String installments = resultMap[ARG_INSTALLMENTS];
          String nsu = resultMap[ARG_NSU];
          String brand = resultMap[ARG_BRAND];

          setState(() {
            resultCode = 1;
          });
        }
      } catch (e) {
        log('Error launching intent: $e');
      }
    }

  void _sendDeeplink() {
    var uuid = Uuid();
    String callerId = uuid.v4();
    Map<String, String> intentParams = {
        PARAM_AMOUNT: '000000001000',
        PARAM_CUR_POS: 'CURRENCY_AFTER_AMOUNT',
        PARAM_CUR_CODE: '986',
        PARAM_CALLER_ID: callerId
    };
    startIntent('getnet://pagamento/v2/pre-authorization', intentParams);
  }

  @override
  void initState() {
    super.initState();
    _sendDeeplink();
  }
  @override
  Widget build(BuildContext context) {

    return ();
  }
}

Pré-autorização V1

O deeplink getnet://pagamento/v1/pre-authorization irá iniciar o app de Pagamento na tela de Pré-autorização.

Abaixo seguem as tabelas de requisição e resposta e seus respectivos parâmetros:

Request

Obrigatoriedade Parâmetro Formato Descrição
OBRIGATÓRIO amount String 12 dígitos representando o valor, considerando os últimos 2 dígitos como casas decimais. Exemplo: "000000001234" é equivalente R$ 12,34.
OBRIGATÓRIO currencyPosition String "CURRENCY_AFTER_AMOUNT" ou "CURRENCY_BEFORE_AMOUNT"
OBRIGATÓRIO currencyCode String Código da moeda, de acordo com a ISO-4217
Exemplo: "986" este é código do Real (R$)
Para a lista completa das moedas acesse: https://pt.wikipedia.org/wiki/ISO_4217
OPCIONAL orderId String Neste parâmetro deve ser enviado um valor único para cada pedido. Este identificador é de responsabilidade da automação e será repassado para o Conciliador.

String de até 50 caracteres.

Response

Quando retorna? Parâmetro Formato Descrição
SEMPRE result String Resultado da transação, conforme a Tabela de Resultados das Funcionalidades.
OPCIONAL resultDetails String Texto com detalhes do retorno, conforme a Tabela de Resultados das Funcionalidades.
SEMPRE amount String 12 dígitos representando o valor, considerando os últimos 2 dígitos como casas decimais.
Exemplo: 000000001234 = R$ 12,34
OPCIONAL nsu String Código de autorização da transação da Getnet – ele é único por terminal (CV impresso no comprovante, não pode se repetir no mesmo dia)
SEMPRE type String 11 - Crédito a vista
12 - Crédito parcelado Lojista
OPCIONAL brand String Bandeira do cartão utilizado
SEMPRE inputType String 021 - tarja magnética
051 - chip
071 - chip sem contato
801 - tarja magnética - fallback
OPCIONAL installments String Quantidade de parcelas selecionada
OPCIONAL cardholderName String Retorna o nome do portador gravado no cartão, se disponível.
OPCIONAL automationSlip String Neste parâmetro enviamos as informações que devem ser incluídas nos Comprovantes Impressos do estabelecimento e do cliente. Seu aplicativo só é obrigado a imprimir esses campos caso você opte por usar a funcionalidade Responsabilidade de Impressão, pois nesse caso o aplicativo Pagamento não irá imprimir os comprovantes.

Mais detalhes na seção Dados do Comprovante.
OPCIONAL orderId String Retorna caso um orderId tenha sido enviado na requisição.
Este identificador é de responsabilidade da automação e é repassado para o Conciliador.


Pré-autorização V2

Essa versão da aplicação de Pagamento tem suporte a Responsabilidade de Impressão, uma funcionalidade que permite que seu aplicativo imprima os comprovantes.

O deeplink getnet://pagamento/v2/pre-authorization irá iniciar o app de Pagamento na tela de Pré-autorização.

Foi adicionado o campo allowPrintCurrentTransaction, ao utilizar este parâmetro o aplicativo Pagamento não irá imprimir os comprovantes e seu aplicativo ficará responsável pela impressão. Para mais detalhes veja a seção Responsabilidade de Impressão.

Foi adicionado o campo callerId. Neste campo seu aplicativo deve enviar um valor único para cada requisição realizada (deeplink). Atenção: Este identificador é de responsabilidade da automação e deve ser gerenciado corretamente para que se possa consultar o status de transações a partir do deeplink Consulta Status.

Abaixo seguem as tabelas de requisição e resposta e seus respectivos parâmetros:

Request

Obrigatoriedade Parâmetro Formato Descrição
OBRIGATÓRIO amount String 12 dígitos representando o valor, considerando os últimos 2 dígitos como casas decimais. Exemplo: "000000001234" é equivalente R$ 12,34.
OBRIGATÓRIO currencyPosition String "CURRENCY_AFTER_AMOUNT" ou "CURRENCY_BEFORE_AMOUNT"
OBRIGATÓRIO currencyCode String Código da moeda, de acordo com a ISO-4217
Exemplo: "986" este é código do Real (R$)
Para a lista completa das moedas acesse: https://pt.wikipedia.org/wiki/ISO_4217
OBRIGATÓRIO callerId String Neste parâmetro deve ser enviado um valor único para cada requisição realizada (deeplink). Este identificador é de responsabilidade da automação e pode ser utilizado para consultar o status de transações a partir do deeplink Consulta Status.

String de até 50 caracteres.
OPCIONAL allowPrintCurrentTransaction boolean Ao habilitar este parâmetro, o aplicativo Pagamento não vai imprimir os comprovantes do estabelecimento e do cliente. Seu aplicativo ficará responsável pela impressão dos comprovantes. Mais detalhes na seção Responsabilidade de Impressão.

Para desabilitar: “false”
Para habilitar: “true”

Default: “false”
OPCIONAL orderId String Neste parâmetro deve ser enviado um valor único para cada pedido. Este identificador é de responsabilidade da automação e será repassado para o Conciliador.

String de até 50 caracteres.

Response

Quando retorna? Parâmetro Formato Descrição
SEMPRE result String Resultado da transação, conforme a Tabela de Resultados das Funcionalidades.
OPCIONAL resultDetails String Texto com detalhes do retorno, conforme a Tabela de Resultados das Funcionalidades.
SEMPRE amount String 12 dígitos representando o valor, considerando os últimos 2 dígitos como casas decimais.
Exemplo: 000000001234 = R$ 12,34
SEMPRE callerId String Retorna o callerId que foi enviado na requisição. Este identificador é de responsabilidade da automação.
OPCIONAL nsu String Código de autorização da transação da Getnet – ele é único por terminal (CV impresso no comprovante, não pode se repetir no mesmo dia)
SEMPRE type String 11 - Crédito a vista
12 - Crédito parcelado Lojista
OPCIONAL brand String Bandeira do cartão utilizado
SEMPRE inputType String 021 - tarja magnética
051 - chip
071 - chip sem contato
801 - tarja magnética - fallback
OPCIONAL installments String Quantidade de parcelas selecionada
OPCIONAL cardholderName String Retorna o nome do portador gravado no cartão, se disponível.
OPCIONAL automationSlip String Neste parâmetro enviamos as informações que devem ser incluídas nos Comprovantes Impressos do estabelecimento e do cliente. Seu aplicativo só é obrigado a imprimir esses campos caso você opte por usar a funcionalidade Responsabilidade de Impressão, pois nesse caso o aplicativo Pagamento não irá imprimir os comprovantes.

Mais detalhes na seção Dados do Comprovante.
OPCIONAL orderId String Retorna caso um orderId tenha sido enviado na requisição.
Este identificador é de responsabilidade da automação e é repassado para o Conciliador.