Tutorial: Gift Card, recarga de celular e tv em PHP

Caro desenvolvedor, nesse tutorial você aprenderá como usar as principais funções da API 2.0 para integrar recargas de celular, fixo, tv e gift cards em um aplicativo.

Para nosso aplicativo de exemplo usaremos o XAMPP como base para desenvolvermos os principais recursos de recargas. Assim o tutorial usará PHP, MySQL e o Apache.

Depois de ter configurado o XAMPP inicie os serviços do MySQL e do Apache em sua máquina.

Acessando http://localhost/phpmyadmin/ crie um banco de dados com o nome de recarga_gift_card. Iremos usar como codificação o utf8mb4.

Acessando o novo banco de dados crie as seguintes tabelas:

-- --------------------------------------------------------

--
-- Estrutura da tabela `product`
--

CREATE TABLE `product` (
  `sku` varchar(40) NOT NULL,
  `provider` varchar(30) DEFAULT NULL,
  `title` varchar(100) DEFAULT NULL,
  `amount` double DEFAULT NULL,
  `price` double DEFAULT NULL,
  `min_amount` double DEFAULT NULL,
  `max_amount` double DEFAULT NULL,
  `step` double DEFAULT NULL,
  `expiration` int(11) DEFAULT NULL,
  `info` varchar(300) DEFAULT NULL,
  `subcategory` varchar(30) DEFAULT NULL,
  `section` varchar(30) DEFAULT NULL,
  `type` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- --------------------------------------------------------

--
-- Estrutura da tabela `product_area_code`
--

CREATE TABLE `product_area_code` (
  `id` int(11) NOT NULL,
  `product_sku` varchar(30) DEFAULT NULL,
  `code` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- --------------------------------------------------------

--
-- Estrutura da tabela `provider`
--

CREATE TABLE `provider` (
  `provider` varchar(30) NOT NULL,
  `provider_name` varchar(100) DEFAULT NULL,
  `logo` text DEFAULT NULL,
  `info` varchar(300) DEFAULT NULL,
  `category` varchar(30) DEFAULT NULL,
  `country_code` char(2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

--
-- Índices para tabelas despejadas
--

--
-- Índices para tabela `product`
--
ALTER TABLE `product`
  ADD PRIMARY KEY (`sku`),
  ADD KEY `section` (`section`),
  ADD KEY `subcategory` (`subcategory`),
  ADD KEY `type` (`type`),
  ADD KEY `step` (`step`);

--
-- Índices para tabela `product_area_code`
--
ALTER TABLE `product_area_code`
  ADD PRIMARY KEY (`id`),
  ADD KEY `product_sku` (`product_sku`) USING BTREE,
  ADD KEY `code` (`code`) USING BTREE;

--
-- Índices para tabela `provider`
--
ALTER TABLE `provider`
  ADD PRIMARY KEY (`provider`),
  ADD KEY `provider` (`provider`),
  ADD KEY `category` (`category`);

--
-- AUTO_INCREMENT de tabelas despejadas
--

--
-- AUTO_INCREMENT de tabela `product_area_code`
--
ALTER TABLE `product_area_code`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;

Localize em seu computador a pasta xampp e acesse a subpasta htdocs. Nela você deverá criar um pasta chamada api.

Acessando esse novo diretório crie um arquivo chamado index.php. Iremos construir todo nosso aplicativo de exemplo nesse arquivo.

Edite o arquivo com seu editor de texto e crie a nossa principal função de interação com o webservice metallisson. A função callAPI.

function callAPI($method, $url, $producao, $data = false) {
    
    //abre uma conexão
    $curl = curl_init();

    //verifica qual ambiente será feito a interação
    if ($producao == 'PRODUCTION') {
        
        $token = '';//variável token de produção - gere no painel ou via api
        $endponit = 'https://api.metallisson.com';
        
    } else {

        $token = '';//variável token de integração  - gere no painel sandbox ou via api sandbox
        $endponit = 'https://api.sandbox.metallisson.com';
        
    }

    //monta o link do recurso
    $url = $endponit . $url;

    //prepara o cabeçário necessário para o consumo do webservice
    $header = array(
        'Accept: com.metallisson.api-v2+json',
        'Authorization: Bearer ' . $token
    );

    //testa qual o verbo utilizado e configura os parâmetros
    switch ($method) {
        case 'POST':
            array_push($header, 'Content-Type: application/json');
            curl_setopt($curl, CURLOPT_POST, 1);
            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            break;
        case 'PATCH':
            array_push($header, 'Content-Type: application/json');
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }
    
    //configura o envio dos dados
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
    //executa a chamada
    $result = curl_exec($curl);
    
    //verifica se houve resposta
    if (!$result) {
        die('Conexão falhou');
    }
    
    //finaliza a chamada
    curl_close($curl);
    
    return $result;
}

Acesse o sandbox e no gerenciador da api crie um token persistente. De posse dessa informação, cole a string na variável token de integração.

Logo após o fim da função insira as seguintes linhas para criarmos uma conexão com nosso mais novo banco de dados:

//será nossa variável para imprimirmos o resultado da operação
$resultado = '';

try {

    //abro uma conexão com o banco de dados
    $pdo = new PDO('mysql:host=localhost;dbname=recarga_gift_card;port=3306;charset=utf8', 'root', '');
    
} catch (PDOException $e) {

    $resultado = 'Erro de conexão com o banco de dados: ' . $e;
}

Agora que temos uma conexão com nosso banco de dados, iremos montar as interações com o webservice.

Com essa configuração básica já podemos fazer nossa primeira chamada, a leitura de saldo em carteira.

Lendo o saldo da carteira virtual

//faço uma leitura de saldo na api
$metallisson = json_decode(callAPI('GET', '/credits/balance', 'SANDBOX'));

//se houve resposta do webservice
if (isset($metallisson->return)) {

//se tudo ocorrer bem, mostro o saldo 
    if ($metallisson->return == 1) {

        $resultado = 'Saldo de R$' . $metallisson->amount;
    } else {

        $resultado = 'Erro ao ler o saldo com código ' . $metallisson->return;
    }
}

Observe que se tudo ocorreu bem com a interação, o saldo será exibido. Caso haja algum erro, será impresso o código do retorno.

Atualizando as tabelas de produtos

Conforme a documentação de integração de gift card e recarga, diariamente você deverá fazer uma única chamada de leitura do catálogo de produtos. Com essa ação você terá acesso a algum novo produto ou removerá qualquer produto que não exista mais.

No exemplo abaixo iremos atualizar as tabelas de produtos que criamos momentos atrás.

//faço uma leitura do catálogo
$metallisson = json_decode(callAPI('GET', '/catalogs', 'SANDBOX'));

//verifico se a api respondeu
if (isset($metallisson->return)) {

    //verifico se houve sucesso na leitura no catálogo
    if ($metallisson->return == 1) {

        //limpo as tabelas do banco de dados
        $pdo->prepare('TRUNCATE TABLE provider;')->execute();
        $pdo->prepare('TRUNCATE TABLE product;')->execute();
        $pdo->prepare('TRUNCATE TABLE product_area_code;')->execute();

        //leio todos os fornecedores
        foreach ($metallisson->content as $fornecedor) {

            //url da logo 
            //caso queira poderá está fazendo o download da logo e/ou a conversão para base64
            $logo = $fornecedor->logo;

            //faço o download da logo
            //$img = file_get_contents($logo);
            //converto a imagem em base64 
            //$logo = base64_encode($img);
            //insiro o fornecedor e seus dados
            $pdo->prepare('INSERT INTO provider (provider, provider_name, logo, info, category, country_code) VALUES ( ?,?,?,?,?,?);')
                    ->execute(array($fornecedor->provider, $fornecedor->provider_name, $logo,
                        $fornecedor->info, $fornecedor->category, $fornecedor->country_code));

            //leio todos os produtos do fornecedor
            foreach ($fornecedor->products as $produto) {

                //insiro os produtos do fornecedor
                $pdo->prepare('INSERT INTO product(sku, provider, title, amount, price, min_amount, max_amount, step, 
                            expiration, info, subcategory, section, type) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?);')
                        ->execute(
                                array($produto->sku, $fornecedor->provider, $produto->title,
                                    $produto->amount, $produto->price, $produto->min_amount,
                                    $produto->max_amount, $produto->step, $produto->expiration,
                                    $produto->info, $produto->subcategory, $produto->section,
                                    $produto->type));

                //leio os códigos de área do produto
                foreach ($produto->area_code as $codigo) {

                    //insiro os códigos de área
                    $pdo->prepare('INSERT INTO product_area_code (product_sku, code) VALUES (?,?);')
                            ->execute(
                                    array($produto->sku, $codigo));
                }
            }
        }

        $resultado = 'Tabelas atualizadas com sucesso!';
    } else {

        $resultado = 'Erro ao atualizar tabelas com código ' . $metallisson->return;
    }
}

Antes de montarmos nosso aplicativo, vamos ver como realizar algumas chamadas à API.

Abaixo será mostrado exemplos de como interagir com a API usando nossa função callAPI.

Gerando um Gift Card em PHP

No exemplo a seguir será gerado um Gift Card PS XBOX de R$10. Observe que nesse exemplo a compra já é confirma automaticamente e já retornará o PIN pronto para resgate.

//executo o pedido de autorização e confirmação para o webservice
$metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
    'sku' => 'XBOX_10',
    'status' => 'OK'
)));

//verifico se a api respondeu
if (isset($metallisson->return)) {

    //se o fornecedor respondeu e o pedido está confirmado
    if (isset($metallisson->status) && $metallisson->status == 'OK') {

        //Imprimo o pin. 
        echo 'PIN: ' . $metallisson->pin;
    } else {

        //imprimo o retorno do que houve de errado
        echo $metallisson->return;
    }
}

Agora vamos gerar um Gift Card com um SMS que enviará o PIN para o cliente final de número celular 83999999999.

Não entregue um PIN apenas por SMS. Some-o com outros meios. Um SMS pode não chegar ao destino por diversos fatores.

//executo o pedido de autorização e confirmação para o webservice
$metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
    'sku' => 'XBOX_10',
    'status' => 'OK',
    'receipt' => array(
        'sms' => array(
            'number' => '83999999999',
            'message' => 'Obrigado pelo pedido. Segue seu Gift Card [PROVIDER] [AMOUNT] PIN:[PIN] Serial:[SERIAL].'
        )
    )
)));

//verifico se a api respondeu
if (isset($metallisson->return)) {

    //se o fornecedor respondeu e o pedido está confirmado
    if (isset($metallisson->status) && $metallisson->status == 'OK') {

        //Imprimo o pin. 
        echo 'PIN: ' . $metallisson->pin;
    } else {

        //imprimo o retorno do que houve de errado
        echo $metallisson->return;
    }
}

Os dois exemplos acima mostram como realizar a compra de um gift card com apenas o envio de um único POST.

Mas poderíamos realizar a compra do gift card com duas interações com o webserve, sendo elas através de um POST e logo em seguida um PATCH.

//executo o pedido de autorização para o webservice
$metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
    'sku' => 'XBOX_10',
    //caso envie um SMS opcional
    //'receipt' => array(
    //    'sms' => array(
    //        'number' => '83999999999',
    //        'message' => 'Obrigado pelo pedido. Segue seu Gift Card [PROVIDER] [AMOUNT] PIN:[PIN] Serial:[SERIAL].'
    //    )
    //)
)));

//verifico se a api respondeu
if (isset($metallisson->return)) {

    //se o fornecedor respondeu e o pedido está aguardando a confirmação (AC)
    if (isset($metallisson->status) && $metallisson->status == 'AC') {

        //posso confirmar enviando um OK ou cancelar enviando um CA
        $status = 'OK';

        //id da autorização
        $id = $metallisson->id;

        //confirmo o pedido
        $metallisson = json_decode(callAPI('PATCH', '/orders/' . $id, 'SANDBOX', array(
            'status' => $status
        )));

        //verifico se a api respondeu
        if (isset($metallisson->return)) {

            //verifico se a confirmação/cancelamento foi processada(o) com sucesso
            if (isset($metallisson->status) && $metallisson->status == $status) {

                //Imprimo o pin. 
                //Se a operaçao foi confirmada será exibido o código digital do gift card,
                //caso tenha sido cancelada será exibido vazio
                echo 'PIN: ' . $metallisson->pin;
            } else {

                //imprimo o retorno do que houve de errado
                echo $metallisson->return;
            }
        }
    } else {

        //imprimo o retorno do que houve de errado
        echo $metallisson->return;
    }
}

Como fazer uma recarga via API

Fazendo um pedido com confirmação automática

Recarga de celular

Fazendo uma recarga TIM de R$10 para o número 83999999991.

//executo o pedido de autorização para o webservice
$metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
    'sku' => 'TIM_10',
    'identifier' => '83999999991',
    'status' => 'OK'
)));

Recarga de TV

Fazendo uma recarga SKY de R$120,90 para o CPF 09876543210.

//executo o pedido de autorização para o webservice
$metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
    'sku' => 'SKY_120.9',
    'identifier' => '09876543210',
    'status' => 'OK'
)));

Imprimindo o comprovante

//verifico se a api respondeu
if (isset($metallisson->return)) {

    //se o fornecedor respondeu e o pedido está confirmado
    if (isset($metallisson->status) && $metallisson->status == 'OK') {

        //Imprimo o nsu. 
        echo 'NSU: ' . $metallisson->nsu;
    } else {

        //imprimo o retorno do que houve de errado
        echo $metallisson->return;
    }
}

Fazendo um pedido com confirmação posterior

Confirmação posterior nada mais é do que ao receber um id de pedido via POST, com a autorização de compra do fornecedor, uma chamada PATCH deverá ser executada sobre o id retornado da chamada POST, para que o produto não deixe de ser entregue.

Recarga de celular

Fazendo uma recarga TIM de R$10 para o número 83999999991.

//executo o pedido de autorização para o webservice
$metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
    'sku' => 'TIM_10',
    'identifier' => '83999999991'
)));

Recarga de TV

Fazendo uma recarga SKY de R$120,90 para o CPF 09876543210.

//executo o pedido de autorização para o webservice
$metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
    'sku' => 'SKY_120.9',
    'identifier' => '09876543210'
)));

Confirmando ou cancelando a recarga realizada

//verifico se a api respondeu
if (isset($metallisson->return)) {

    //se o fornecedor respondeu e o pedido está aguardando a confirmação (AC)
    if (isset($metallisson->status) && $metallisson->status == 'AC') {

        //posso confirmar enviando um OK ou cancelar enviando um CA
        $status = 'OK';

        //id da autorização
        $id = $metallisson->id;

        //confirmo o pedido
        $metallisson = json_decode(callAPI('PATCH', '/orders/' . $id, 'SANDBOX', array(
            'status' => $status
        )));

        //verifico se a api respondeu
        if (isset($metallisson->return)) {

            //verifico se a confirmação/cancelamento foi processada(o) com sucesso
            if (isset($metallisson->status) && $metallisson->status == $status) {

                //Imprimo o NSU. 
                //Se a operaçao foi realizada com sucesso será exibido o código nsu
                echo 'NSU: ' . $metallisson->nsu;
            } else {

                //imprimo o retorno do que houve de errado
                echo $metallisson->return;
            }
        }
    } else {

        //imprimo o retorno do que houve de errado
        echo $metallisson->return;
    }
}

Demo da API de gift card e recarga

Juntamos as funções acima e adicionamos um menu em nosso script.

Abaixo está um simples aplicativo que demostra as principais funcionalidades para realizar recarga e gerar gift cards em um sistema.

Copie e cole os códigos do programa abaixo no index.php que criamos anteriormente e salve.

//funcção de interação com a API 
function callAPI($method, $url, $producao, $data = false) {

    //abre uma conexão
    $curl = curl_init();

    //verifica qual ambiente será feito a interação
    if ($producao == 'PRODUCTION') {

        $token = ''; //gere no painel ou via api
        $endponit = 'https://api.metallisson.com';
    } else {

        $token = ''; //gere no painel sandbox ou via api sendbox
        $endponit = 'https://api.sandbox.metallisson.com';
    }

    //monta o link do recurso
    $url = $endponit . $url;

    //prepara o cabeçário necessário para o consumo do webservice
    $header = array(
        'Accept: com.metallisson.api-v2+json',
        'Authorization: Bearer ' . $token
    );

    //testa qual o verbo utilizado e configura os parâmetros
    switch ($method) {
        case 'POST':
            array_push($header, 'Content-Type: application/json');
            curl_setopt($curl, CURLOPT_POST, 1);
            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            break;
        case 'PATCH':
            array_push($header, 'Content-Type: application/json');
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    //configura o envio dos dados
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    //executa a chamada
    $result = curl_exec($curl);

    //verifica se houve resposta
    if (!$result) {
        die('Conexão falhou');
    }

    //finaliza a chamada
    curl_close($curl);

    return $result;
}

$pdo = null;
$resultado = '';

try {

    //abro uma conexão com o banco de dados
    $pdo = new PDO('mysql:host=localhost;dbname=recarga;port=3306;charset=utf8', 'root', '');
} catch (PDOException $e) {

    $resultado = 'Erro de conexão com o banco de dados: ' . $e;
}

//menu de atualização de tabelas
if (isset($_GET['atualiza_tabelas'])) {

    //faço uma leitura do catálogo
    $metallisson = json_decode(callAPI('GET', '/catalogs', 'SANDBOX'));

    //verifico se a api respondeu
    if (isset($metallisson->return)) {

        //verifico se houve sucesso na leitura no catálogo
        if ($metallisson->return == 1) {

            //limpo as tabelas do banco de dados
            $pdo->prepare('TRUNCATE TABLE provider;')->execute();
            $pdo->prepare('TRUNCATE TABLE product;')->execute();
            $pdo->prepare('TRUNCATE TABLE product_area_code;')->execute();

            //leio todos os fornecedores
            foreach ($metallisson->content as $fornecedor) {

                //url da logo 
                //caso queira poderá está fazendo o download da logo e/ou a conversão para base64
                $logo = $fornecedor->logo;

                //faço o download da logo
                //$img = file_get_contents($logo);
                //converto a imagem em base64 
                //$logo = base64_encode($img);
                //insiro o fornecedor e seus dados
                $pdo->prepare('INSERT INTO provider (provider, provider_name, logo, info, category, country_code) VALUES ( ?,?,?,?,?,?);')
                        ->execute(array($fornecedor->provider, $fornecedor->provider_name, $logo,
                            $fornecedor->info, $fornecedor->category, $fornecedor->country_code));

                //leio todos os produtos do fornecedor
                foreach ($fornecedor->products as $produto) {

                    //insiro os produtos do fornecedor
                    $pdo->prepare('INSERT INTO product(sku, provider, title, amount, price, min_amount, max_amount, step, 
                            expiration, info, subcategory, section, type) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?);')
                            ->execute(
                                    array($produto->sku, $fornecedor->provider, $produto->title,
                                        $produto->amount, $produto->price, $produto->min_amount,
                                        $produto->max_amount, $produto->step, $produto->expiration,
                                        $produto->info, $produto->subcategory, $produto->section,
                                        $produto->type));

                    //leio os códigos de área do produto
                    foreach ($produto->area_code as $codigo) {

                        //insiro os códigos de área
                        $pdo->prepare('INSERT INTO product_area_code (product_sku, code) VALUES (?,?);')
                                ->execute(
                                        array($produto->sku, $codigo));
                    }
                }
            }

            $resultado = 'Tabelas atualizadas com sucesso!';
        } else {

            $resultado = 'Erro ao atualizar tabelas com código ' . $metallisson->return;
        }
    }

//menu de leitura de saldo    
} else if (isset($_GET['saldo'])) {

    //faço uma leitura de saldo na api
    $metallisson = json_decode(callAPI('GET', '/credits/balance', 'SANDBOX'));

    //verifico se a api respondeu
    if (isset($metallisson->return)) {
        //se tudo ocorrer bom, mostro o saldo 
        if ($metallisson->return == 1) {

            $resultado = 'Saldo de R$' . $metallisson->amount;
        } else {

            $resultado = 'Erro ao ler o saldo com código ' . $metallisson->return;
        }
        
    }
//menu de geração de gift cards
} else if (isset($_GET['gerar_gift_card'])) {

    $menu = '';


    try {

        //faço uma leitura dos fornecedores
        $rpdo = $pdo->query('SELECT provider, provider_name, logo, info, category, country_code FROM provider WHERE category LIKE \'GIFT_CARD\'');
        while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

            //substituo o underline do provider por um espaço em branco
            $nome_fornecedor = str_replace('_', ' ', $r->provider);

            $menu .= '<a href="/api/?gerar_gift_card=true&fornecedor=' . $r->provider . '"><img src="' . $r->logo . '" alt="' . $nome_fornecedor . '" title="' . $nome_fornecedor . '"/></a> ';
        }

        //se for clicado em um fornecedor, exibo os produtos
        if (isset($_GET['fornecedor'])) {

            $produtos = '';

            //faço uma leitura dos produtos do fornecedor 
            $rpdo = $pdo->prepare('SELECT sku, provider, title, amount, price, min_amount, 
                                    max_amount, step, expiration, info, subcategory, section, type 
                                    FROM product 
                                    WHERE provider = ?');

            $rpdo->execute(array($_GET['fornecedor']));

            while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

                $produtos .= '<a href="/api/?gerar_gift_card=true&fornecedor=' . $r->provider . '&sku=' . $r->sku . '">' . $r->title . '</a></br>';
            }

            $menu = $menu . '<br/><br/>Selecione um produto: <br/><br/>' . $produtos;
        }
    } catch (Exception $exc) {
        
    }

    //se há algo para imprimir
    if ($menu != '') {
        $resultado = 'Escolha um forcedor: <br/><br/>' . $menu . '';
    }


    //se for clicado em um fornecedor, exibo os produtos
    if (isset($_GET['sku'])) {

        $resultado = $resultado . '<br/><br/> <a href="/api/?gerar_gift_card=true&fornecedor=' . $_GET['fornecedor'] . '&sku=' . $_GET['sku'] . '&gerar=true">Clique para gerar um gift card ' . str_replace('_', ' ', $_GET['sku']) . '</a>';
    }

    if (isset($_GET['gerar'])) {

        $metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
            'sku' => $_GET['sku'],
            'status' => 'OK'
        )));

        //se houve resposta
        if (isset($metallisson->return)) {


            if (isset($metallisson->status) && $metallisson->status == 'OK') {


                $resultado = $resultado . '<br/><br/>Gift Card ' . str_replace('_', ' ', $_GET['sku']) . ' gerado com sucesso. PIN:' . $metallisson->pin . ' SERIAL:' . $metallisson->serial;
            } else {

                $resultado = $resultado . '<br/><br/>Erro ao gerar um gift card com código ' . $metallisson->return;
            }
        }
    }

//menu de geração de recarga
} else if (isset($_GET['fazer_recarga'])) {

    $menu = '';

    try {

        //faço uma leitura das categorias dos fornecedores
        $rpdo = $pdo->query('SELECT DISTINCT category FROM provider WHERE category <> \'GIFT_CARD\'');
        while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

            $menu .= '<a href="/api/?fazer_recarga=true&categoria=' . $r->category . '">' . $r->category . '</a> ';
        }

        //se for clicado em uma categoria
        if (isset($_GET['categoria'])) {

            $fornecedores = '';

            //faço uma leitura dos fornecedores
            $rpdo = $pdo->prepare('SELECT provider, provider_name, logo, info, category, country_code FROM provider WHERE category = ?');
            $rpdo->execute(array($_GET['categoria']));
            while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

                //substituo o underline do provider por um espaço em branco
                $nome_fornecedor = str_replace('_', ' ', $r->provider);

                $fornecedores .= '<a href="/api/?fazer_recarga=true&categoria=' . $_GET['categoria'] . '&fornecedor=' . $r->provider . '"><img src="' . $r->logo . '" alt="' . $nome_fornecedor . '" title="' . $nome_fornecedor . '"/></a> ';
            }

            $menu = $menu . '<br/><br/>Selecione um fornecedor: <br/><br/>' . $fornecedores;
        }

        if (isset($_GET['fornecedor'])) {
            //se for clicado em um fornecedor, exibo os ddds disponíveis 
            if ($_GET['categoria'] == 'TELEPHONY') {


                $menu = $menu . '<br/><br/>Digite seu número com DDD: <br/><br/>
                                <form action="/api/" method="get">
                                    <label for="lname">Seu número com DDD:</label>
                                    <input type="number" name="identificador" value="' . (isset($_GET['identificador']) ? $_GET['identificador'] : '') . '"><br><br>
                                    <input type="hidden" name="fazer_recarga" value="true">
                                    <input type="hidden" name="categoria" value="' . $_GET['categoria'] . '">
                                    <input type="hidden" name="fornecedor" value="' . $_GET['fornecedor'] . '">
                                    <input type="submit" value="Mostrar produtos">
                                </form>';


                if (isset($_GET['identificador'])) {
                    $ddd = substr($_GET['identificador'], 0, 2);

                    $produtos = '';

                    //faço uma leitura dos produtos do fornecedor 
                    $rpdo = $pdo->prepare('SELECT p.sku, p.provider, p.title, p.amount, p.price, p.min_amount, 
                                            p.max_amount, p.step, p.expiration, p.info, p.subcategory, p.section, p.type 
                                            FROM product p
                                            RIGHT JOIN product_area_code a ON p.sku = a.product_sku AND a.code = ?
                                            WHERE p.provider = ?');

                    $rpdo->execute(array($ddd, $_GET['fornecedor']));

                    while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

                        $produtos .= '<a href="/api/?fazer_recarga=true&categoria=' . $_GET['categoria'] . '&fornecedor=' . $r->provider . '&sku=' . $r->sku . '&identificador=' . $_GET['identificador'] . '">' . $r->title . '</a></br>';
                    }

                    $menu = $menu . '<br/><br/>Selecione uma recarga: <br/><br/>' . $produtos;
                }
            } else if ($_GET['categoria'] == 'TELEVISION') {


                $menu = $menu . '<br/><br/>Digite seu CPF ou código de assinante: <br/><br/>
                                <form action="/api/" method="get">
                                    <label for="lname">Seu CPF ou identificador de assinatura:</label>
                                    <input type="number" name="identificador" value="' . (isset($_GET['identificador']) ? $_GET['identificador'] : '') . '"><br><br>
                                    <input type="hidden" name="fazer_recarga" value="true">
                                    <input type="hidden" name="categoria" value="' . $_GET['categoria'] . '">
                                    <input type="hidden" name="fornecedor" value="' . $_GET['fornecedor'] . '">
                                    <input type="submit" value="Mostrar produtos">
                                </form>';


                if (isset($_GET['identificador'])) {
                    $ddd = substr($_GET['identificador'], 0, 2);

                    $produtos = '';

                    //faço uma leitura dos produtos do fornecedor 
                    $rpdo = $pdo->prepare('SELECT p.sku, p.provider, p.title, p.amount, p.price, p.min_amount, 
                                            p.max_amount, p.step, p.expiration, p.info, p.subcategory, p.section, p.type 
                                            FROM product p                                           
                                            WHERE p.provider = ?');

                    $rpdo->execute(array($_GET['fornecedor']));

                    while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

                        $produtos .= '<a href="/api/?fazer_recarga=true&categoria=' . $_GET['categoria'] . '&fornecedor=' . $r->provider . '&sku=' . $r->sku . '&identificador=' . $_GET['identificador'] . '">' . $r->title . '</a></br>';
                    }

                    $menu = $menu . '<br/><br/>Selecione uma recarga: <br/><br/>' . $produtos;
                }
            }
        }
    } catch (Exception $exc) {
        
    }

    //se há algo para imprimir
    if ($menu != '') {
        $resultado = 'Selecione uma categoria: <br/><br/>' . $menu . '';
    }


    //se for clicado em um fornecedor, exibo os produtos
    if (isset($_GET['sku'])) {

        $resultado = $resultado . '<br/><br/> <a href="/api/?fazer_recarga=true&categoria=' . $_GET['categoria'] . '&fornecedor=' . $_GET['fornecedor'] . '&sku=' . $_GET['sku'] . '&identificador=' . $_GET['identificador'] . '&gerar=true">Clique para realizar a recarga ' . str_replace('_', ' ', $_GET['sku']) . '</a>';
    }

    if (isset($_GET['gerar'])) {

        $metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
            'sku' => $_GET['sku'],
            'identifier' => $_GET['identificador'],
            'status' => 'OK'
        )));

        //se houve resposta
        if (isset($metallisson->return)) {


            if (isset($metallisson->status) && $metallisson->status == 'OK') {


                $resultado = $resultado . '<br/><br/>Recarga ' . str_replace('_', ' ', $_GET['sku']) . ' realizada com sucesso. NSU:' . $metallisson->nsu;
            } else {

                $resultado = $resultado . '<br/><br/>Erro ao fazer uma recarga com código ' . $metallisson->return;
            }
        }
    }

//menu de geração de recarga variável
} else if (isset($_GET['fazer_recarga_variavel'])) {

    $menu = '';

    $valor_minimo = 0;
    $valor_maximo = 0;
    $valor_salto = 0;
    $categoria = '';

    try {



        $fornecedores = '';

        //faço uma leitura dos fornecedores
        $rpdo = $pdo->prepare('SELECT p.provider, p.provider_name, p.logo, p.info, p.category, p.country_code, o.min_amount,o.max_amount,o.step FROM provider p, product o WHERE o.step <> ? AND p.provider = o.provider');
        $rpdo->execute(array(0));
        while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

            //substituo o underline do provider por um espaço em branco
            $nome_fornecedor = str_replace('_', ' ', $r->provider);

            $fornecedores .= '<a href="/api/?fazer_recarga_variavel=true&fornecedor=' . $r->provider . '"><img src="' . $r->logo . '" alt="' . $nome_fornecedor . '" title="' . $nome_fornecedor . '"/></a> ';

            $valor_minimo = $r->min_amount;
            $valor_maximo = $r->max_amount;
            $valor_salto = $r->step;
            $categoria = $r->category;
        }

        $menu = $menu . 'Selecione um fornecedor: <br/><br/>' . $fornecedores;


        if (isset($_GET['fornecedor'])) {
            
            //se for clicado em um fornecedor, exibo um painel solicitando o valor da recarga
            if($categoria=='GIFT_CARD'){
                $menu = $menu . '<form action="/api/" method="get">                                    
                                    <label for="lname">Digite um valor de ' . $valor_minimo . ' a ' . $valor_maximo . ':</label>
                                    <input type="number" name="valor" value="' . (isset($_GET['valor']) ? $_GET['valor'] : '') . '" min="' . $valor_minimo . '" max="' . $valor_maximo . '" step="' . $valor_salto . '"><br><br>
                                    <input type="hidden" name="fazer_recarga_variavel" value="true">
                                    <input type="hidden" name="fornecedor" value="' . $_GET['fornecedor'] . '">
                                    <input type="submit" value="Mostrar produtos">
                                </form>';


                if (isset($_GET['valor'])) {
                    
                                        
                    $produtos = '';

                    //faço uma leitura dos produtos do fornecedor 
                    $rpdo = $pdo->prepare('SELECT p.sku, p.provider, p.title, p.amount, p.price, p.min_amount, 
                                                p.max_amount, p.step, p.expiration, p.info, p.subcategory, p.section, p.type 
                                                FROM product p
                                                WHERE p.provider = ? AND p.min_amount <= ? AND p.max_amount <= ?' );

                    $rpdo->execute(array($_GET['fornecedor'],$valor_minimo,$valor_maximo));

                    while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

                        $produtos .= '<a href="/api/?fazer_recarga_variavel=true&fornecedor=' . $r->provider . '&sku=' . $r->provider . '_' . $_GET['valor'] . '&valor=' . $_GET['valor'] . '">' . $r->title . '</a></br>';
                    }

                    $menu = $menu . '<br/><br/>Selecione uma recarga: <br/><br/>' . $produtos;
                    
                }
            }else{
                $menu = $menu . '<br/><br/>Digite seu número com DDD: <br/><br/>
                                <form action="/api/" method="get">
                                    <label for="lname">Seu número com DDD:</label>
                                    <input type="number" name="identificador" value="' . (isset($_GET['identificador']) ? $_GET['identificador'] : '') . '"><br><br>
                                    <label for="lname">Digite um valor de ' . $valor_minimo . ' a ' . $valor_maximo . ':</label>
                                    <input type="number" name="valor" value="' . (isset($_GET['valor']) ? $_GET['valor'] : '') . '" min="' . $valor_minimo . '" max="' . $valor_maximo . '" step="' . $valor_salto . '"><br><br>
                                    <input type="hidden" name="fazer_recarga_variavel" value="true">
                                    <input type="hidden" name="fornecedor" value="' . $_GET['fornecedor'] . '">
                                    <input type="submit" value="Mostrar produtos">
                                </form>';


                if (isset($_GET['identificador'])) {
                    $ddd = substr($_GET['identificador'], 0, 2);

                    $produtos = '';

                    //faço uma leitura dos produtos do fornecedor 
                    $rpdo = $pdo->prepare('SELECT p.sku, p.provider, p.title, p.amount, p.price, p.min_amount, 
                                                p.max_amount, p.step, p.expiration, p.info, p.subcategory, p.section, p.type 
                                                FROM product p
                                                RIGHT JOIN product_area_code a ON p.sku = a.product_sku AND a.code = ?
                                                WHERE p.provider = ?');

                    $rpdo->execute(array($ddd, $_GET['fornecedor']));

                    while ($r = $rpdo->fetch(PDO::FETCH_OBJ)) {

                        $produtos .= '<a href="/api/?fazer_recarga_variavel=true&fornecedor=' . $r->provider . '&sku=' . $r->provider . '_' . $_GET['valor'] . '&identificador=' . $_GET['identificador'] . '&valor=' . $_GET['valor'] . '">' . $r->title . '</a></br>';
                    }

                    $menu = $menu . '<br/><br/>Selecione uma recarga: <br/><br/>' . $produtos;
                }
            }
            
        }
    } catch (Exception $exc) {
        
    }

    //se há algo para imprimir
    if ($menu != '') {
        $resultado = $menu;
    }


    //se for clicado em um fornecedor, exibo os produtos
    if (isset($_GET['sku'])) {

        $resultado = $resultado . '<br/><br/> <a href="/api/?fazer_recarga_variavel=true&fornecedor=' . $_GET['fornecedor'] . '&sku=' . $_GET['sku'] . '&identificador=' . $_GET['identificador'] . '&valor=' . $_GET['valor'] . '&gerar=true">Clique para realizar a recarga ' . str_replace('_', ' ', $_GET['sku']) . '</a>';
    }

    if (isset($_GET['gerar'])) {
        
        if($categoria=='GIFT_CARD'){
            $metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
                'sku' => $_GET['sku'],
                'status' => 'OK'
            )));

            //se houve resposta
            if (isset($metallisson->return)) {

                //verifico se foi confirmada
                if (isset($metallisson->status) && $metallisson->status == 'OK') {


                    $resultado = $resultado . '<br/><br/>Recarga ' . str_replace('_', ' ', $_GET['sku']) . ' realizada com sucesso. PIN:' . $metallisson->pin;
                } else {

                    $resultado = $resultado . '<br/><br/>Erro ao fazer uma recarga com código ' . $metallisson->return;
                }
            }
        }else{
            $metallisson = json_decode(callAPI('POST', '/orders', 'SANDBOX', array(
                'sku' => $_GET['sku'],
                'identifier' => $_GET['identificador'],
                'status' => 'OK'
            )));

            //se houve resposta
            if (isset($metallisson->return)) {

                //verifico se foi confirmada
                if (isset($metallisson->status) && $metallisson->status == 'OK') {


                    $resultado = $resultado . '<br/><br/>Recarga ' . str_replace('_', ' ', $_GET['sku']) . ' realizada com sucesso. NSU:' . $metallisson->nsu;
                } else {

                    $resultado = $resultado . '<br/><br/>Erro ao fazer uma recarga com código ' . $metallisson->return;
                }
            }
        }
        
    }
}

unset($pdo);
?>

<!doctype html>
<html lang="pt-BR">
    <head>
        <meta charset="utf-8">

        <title>Demo da API metallisson</title>

        <meta name="author" content="metallisson">

    </head>

    <body>
        <h1>Demo da API de Gift Card, Recarga de Telefonia e TV metallisson</h1>
        <br/>
        <br/>
        <a href="/api/?atualiza_tabelas=true">Atualiza tabelas</a> | <a href="/api/?fazer_recarga=true">Recarga</a> | 
        <a href="/api/?fazer_recarga_variavel=true">Recarga Variável</a> | 
        <a href="/api/?gerar_gift_card=true">Gift Card</a> | <a href="/api/?saldo=true">Ver o saldo</a>
        <br/>
        <hr/>
        <br/>
        <br/>
        <?php echo $resultado; ?>
    </body>
</html>

Depois acesse localhost/api e comece a conhecer as funcionalidades.

Observe que o script acima além de acessar diretamente as variáveis globais, não implementa as melhores práticas de segurança de desenvolvimento.

Use para fins didáticos ou implemente novas melhorias no código, disponibilizando em seu ambiente de produção.

O simulador do sandbox aceita pedidos de gift cards e recargas para as seguintes marcas:

XBOX, PAYSAFECARD, GOOGLE PLAY, STEAM, UBER, UBER EATS, NETFLIX, IFOOD, RAZER GOLD, LEVEL UP, DAZN, CLARO FIXO, LEAGUE OF LEGENDS LOL e BLIZZARD.

Qual o passo a passo para fazer uma recarga?

A forma mais segura para fazer uma recarga é seguir o seguinte script de recarga:

  1. Pergunte o número com DDD do CHIP do usuário
  2. Pergunte qual a operadora do CHIP
  3. Pergunte qual o valor de recarga
  4. Confirme os dados de recarga
  5. Efetue a recarga