<?php
$loader = $this->registry->get('load');
$loader->controller('payment/payment_info');

class ControllerPaymentPagarme extends ControllerPaymentPaymentInfo
{
  public function __construct($registry)
  {
    parent::__construct($registry);
    $this->load();

    $this->paymentInfo = new PaymentInfo();
    $this->paymentInfo->clearParams();

    if (isset($this->session->data['payment_method']['code_type']) && isset($this->session->data['payment_method']['code'])) {
      $code_type = $this->session->data['payment_method']['code_type'];
      $code = $this->session->data['payment_method']['code']; // nome do controller

      $this->data['paymentRoute'] = "$code/pay_$code_type";
      $this->data['paymentName'] = $code;

      $this->load->dmodel('checkout/order');
      $lastOrderId = $this->dmodel_checkout_order->getLastOrderId() + 1;

      $this->session->data['pagarme_fingerprint_id'] = $lastOrderId;

    }
  }

  public function load()
  {
    $this->load->dmodel('checkout/order');

    $language = $this->language->load('payment/pagarme');
    $this->data = array_merge($this->data, $language);

    $this->data['back'] = $this->url->link('checkout/checkout', '', 'SSL');
    $this->data['continue'] = $this->url->link('checkout/success');
  }

  public function credit_card()
  {
    $order_info = $this->dmodel_checkout_order->getOrder($this->session->data['order_id']);
    $this->load->helper('ftr_geral');
    $credit_card_config = $this->config->get('pagarme_credit_card');
    if ($this->config->get('pagarme_config_parcelamento') != Type_ConfigParcelamento::PorBandeira) {
      foreach ($credit_card_config as &$value) {
        $value['valor_minimo'] = '';
      }
    }
    $this->data['credit_cards'] = ftr_geral::getPaymentMethods($credit_card_config, $order_info['total']);

    $setting = [
      'display_cpf' => true,
      'Type_PaymentOption' => Type_PaymentOption::Tp_CreditCard,
      'payment_name' => 'Pagar Me'
    ];

    $this->data['payment_address'] = $this->getChild('payment/pagarme_payment_address', $setting);
    $this->data['captcha_tpl'] = $this->getChild('payment/captcha');

    if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/pagarme/credit_card.twig')) {
      $this->template = $this->config->get('config_template') . '/template/payment/pagarme/credit_card.twig';
    } else {
      $this->template = 'default/template/payment/pagarme/credit_card.twig';
    }

    if ($this->ftrgeralregistry->isApp()) {
      $this->document->addScriptApp(array(
        'https://static.traycheckout.com.br/js/finger_print.js',
        'catalog/view/javascript/jquery.payment/jquery.payment.js',
        'catalog/view/theme/appmobile/js/payment.pagarme_credit_card.js'
      ));
      $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
    }

    $this->response->setOutput($this->render());

  }

  public function success()
  {
    if (isset($this->session->data['payment_session']['code']) && ($this->session->data['payment_session']['code'] == Type_pagarmeConfigs::Tp_NameModule)) {

      $this->load->dmodel('payment/payment_info');
      $this->load->language('payment/' . $this->session->data['payment_session']['code']);

      switch ($this->session->data['payment_session']['code_type']) {
        case Type_PaymentOption::Tp_CreditCard:
          $query = $this->db->query('SELECT pcc.tid, o.order_status_id  FROM oc_order o LEFT JOIN oc_payment_credit_card pcc ON (o.order_id = pcc.order_id) WHERE o.order_id = ' . $this->session->data['payment_session']['order_id'])->row;
          if (isset($query['tid'])) {
            $this->data['tid'] = $query['tid'];
          }
          break;
        case Type_PaymentOption::Tp_Billet:
          $query = $this->db->query('SELECT pb.link_barcode, pb.link_qrcode, pb.link_boleto, pb.link_digitavel, o.order_status_id  FROM oc_order o LEFT JOIN oc_payment_billet pb ON (o.order_id = pb.order_id) WHERE o.order_id = ' . $this->session->data['payment_session']['order_id'])->row;
          if (isset($query['link_boleto'])) {
            $this->data['link_boleto'] = $query['link_boleto'];
          }
          if (isset($query['link_digitavel'])) {
            $this->data['link_digitavel'] = $query['link_digitavel'];
          }

          if (isset($query['link_barcode'])) {
            $this->data['link_barcode'] = $query['link_barcode'];
          }
          if (isset($query['link_qrcode'])) {
            $this->data['link_qrcode'] = $query['link_qrcode'];
          }

          $this->data['link_order'] = $this->url->link('account/order/info', 'order_id=' . $this->session->data['payment_session']['order_id']);
          break;
        case Type_PaymentOption::Tp_BankTransfer:
          $query = $this->db->query('SELECT pbt.link_payment, o.order_status_id  FROM oc_order o LEFT JOIN oc_payment_bank_transfer pbt ON (o.order_id = pbt.order_id) WHERE o.order_id = ' . $this->session->data['payment_session']['order_id'])->row;
          if (isset($query['link_payment'])) {
            $this->data['link_payment'] = $query['link_payment'];
          }
          break;
        case Type_PaymentOption::Tp_Pix:
          $query = $this->db->query('  SELECT p.link_qrcode,
                                              p.link_qrcodeurl,
                                              p.payment_id,
                                              o.order_status_id
                                         FROM oc_order o
                                    LEFT JOIN oc_payment_pix p
                                           ON (o.order_id = p.order_id)
                                        WHERE o.order_id =' . $this->session->data['payment_session']['order_id'])->row;

          if (isset($query['link_qrcode'])) {
            $this->data['link_qrcode'] = $query['link_qrcode'];
          }
          if (isset($query['link_qrcodeurl'])) {
            $this->data['link_qrcodeurl'] = $query['link_qrcodeurl'];
          }
          if (isset($query['payment_id'])) {
            $this->data['payment_id'] = $query['payment_id'];
          }

          $this->data['reloadPayment'] = false;

          $this->data['link_order'] = $this->url->link('account/order/info', 'order_id=' . $this->session->data['payment_session']['order_id']);

          break;
      }

      $this->load->dmodel('checkout/order');
      $status_info = $this->dmodel_checkout_order->getOrderStatus($query['order_status_id']);
      $this->data['status_descricao'] = $status_info['descricao'];
      if ($status_info['order_status_id'] == $this->config->get('pagarme_order_status_canceled')) {
        $this->session->data['orderPaymentCanceled'] = 'Pedido cancelado';
      }

      $this->template = $this->config->get('config_template') . '/template/success/' . $this->session->data['payment_session']['code_type'] . '.twig';
      $this->response->setOutput($this->render());

    } else {
      return false;
    }
  }

  public function parcelamento($module = 'pagarme', $html = true, $flag_params = array())
  {
    if ($this->config->get('pagarme_config_parcelamento') == Type_ConfigParcelamento::PorBandeira) {
      $json = array();
      $bandeira = '';
      $this->load->helper('ftr_geral');

      if (isset($this->request->get['bandeira'])) {
        $bandeira = $this->request->get['bandeira'];
      } else if (isset($flag_params['bandeira']) and $flag_params['bandeira'] != '') {
        $bandeira = $flag_params['bandeira'];
      } else {
        $json['bandeira'] = 'Não foi possivel fazer o cálculo da parcela pois nenhuma bandeira foi encontrada!';
      }
      $credit_cards = $this->config->get('pagarme_credit_card');

      $bandeira = current(array_filter($credit_cards, function ($item) use ($bandeira) {
        return $item['descricao'] == $bandeira;
      }));

      $flag_params['juros'] = ftr_geral::isIsset($this->config->get('pagarme_parcela_juros')) ? $this->config->get('pagarme_parcela_juros') : 0;
      $flag_params['parcela_sem_juros'] = (isset($bandeira['parcela_juros']) && ($bandeira['parcela_juros'] != '')) ? $bandeira['parcela_juros'] : 0;
      $flag_params['parcela_maxima_qtd'] = (isset($bandeira['total_parcela']) && ($bandeira['total_parcela'] != '')) ? $bandeira['total_parcela'] : $this->config->get('pagarme_parcela_qtdmax');
      $flag_params['parcela_minima_val'] = isset($bandeira['valor_minimo']) ? (float) preg_replace("/[^\.|,|0-9]/", "", $bandeira['valor_minimo']) : $this->config->get('pagarme_parcela_minima');
    }
    return parent::parcelamento($module, $html, $flag_params);
  }

  public function validate()
  {

    $this->load->controller('payment/payment_address');

    $error = parent::validate();
    $error = $error ? $error : array();

    if (!isset($this->request->post['qtd_parcela']) || $this->request->post['qtd_parcela'] < 1) {
      $error['qtd_parcela'] = $this->language->get('error_parcelas');
    }

    if ($error) {
      return $error;
    } else {
      return false;
    }

  }
  public function billet()
  {
    $setting = [
      'display_cpf' => true,
      'payment_name' => 'pagarme',
      'load_customer_info' => true,
      'display_titular' => false
    ];

    $this->data['payment_address'] = $this->getChild('payment/payment_address', $setting);
    $this->data['captcha_tpl'] = $this->getChild('payment/captcha');

    if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/pagarme/billet.twig')) {
      $this->template = $this->config->get('config_template') . '/template/payment/pagarme/billet.twig';
    } else {
      $this->template = 'default/template/payment/pagarme/billet.twig';
    }

    if ($this->ftrgeralregistry->isApp()) {
      $this->document->addScriptApp(array(
        'catalog/view/theme/appmobile/js/payment.pagarme_billet.js'
      ));
      $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
    }

    $this->response->setOutput($this->render());

  }

  public function pix()
  {
    $setting = [
      'display_cpf' => true,
      'payment_name' => 'pagarme',
      'load_customer_info' => true,
      'display_titular' => false
    ];

    $this->data['payment_address'] = $this->getChild('payment/payment_address', $setting);
    $this->data['captcha_tpl'] = $this->getChild('payment/captcha');

    if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/pagarme/pix.twig')) {
      $this->template = $this->config->get('config_template') . '/template/payment/pagarme/pix.twig';
    } else {
      $this->template = 'default/template/payment/pagarme/pix.twig';
    }

    if ($this->ftrgeralregistry->isApp()) {
      $this->document->addScriptApp(array(
        'catalog/view/theme/appmobile/js/payment.pagarme_pix.js'
      ));
      $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
    }

    $this->response->setOutput($this->render());

  }

  public function pay_credit_card()
  {

    $this->load->helper('Ftr_sql');
    $this->language->load('payment/pagarme');

    $json['error'] = $this->validate();

    if (!$json['error']) {
      try {
        $this->saveRequiedCustomerInfos();

        //validação feita somente para cartão de credito
        if (isset($this->request->post['creditcard_cctype'])) {

          $payment_method_id = Type_PagarmeBandeira::getConstFromNickValue($this->request->post['creditcard_cctype']);
          $pagarme_credit_card = $this->config->get('pagarme_credit_card');
          $qtd_parcela = $this->request->post['qtd_parcela'];

          if (isset($pagarme_credit_card[$payment_method_id])) {

            if (($this->config->get('pagarme_config_parcelamento') == Type_ConfigParcelamento::PorBandeira) && ($this->request->post['qtd_parcela'] > $pagarme_credit_card[$payment_method_id]['total_parcela'])) {
              throw new exception('Quantidade de parcela não suportada para a bandeira' . $this->request->post['creditcard_cctype']);
            }

            $parcelas = $this->parcelamento(Type_CreditCardModule::getNickFromConstValue(Type_CreditCardModule::Pagarme), false, array("bandeira" => $this->request->post['creditcard_cctype']));

            if (!in_array($this->request->post['qtd_parcela'], array_keys($parcelas))) {
              throw new exception('Quantidade de parcela não suportada para a bandeira' . $this->request->post['creditcard_cctype']);
            }

          } else {
            throw new exception('Bandeira ' . $this->request->post['creditcard_cctype'] . ' não habilitado para Pagar Me.');
          }

        } else {
          throw new exception('Bandeira não encontrada.');
        }

        $order_info = $this->getOrder();

        //calcula novamente as parcelas para evitar que venha valor modificado do javascript
        $cartao_recalculo = $this->parcelamento(Type_CreditCardModule::getNickFromConstValue(Type_CreditCardModule::Pagarme), false);
        $valor = $cartao_recalculo[$qtd_parcela]['valor_parcela'];
        $valorPedido = number_format($valor * $qtd_parcela, 2, '.', '');
        $this->paymentInfo->setParam('amount', $valorPedido);
        $this->paymentInfo->setParam('shipping_method', $order_info['shipping_method']);

        //calcula o juros das parcelas
        $juros_parcela = 0;
        $desconto_parcela = 0;
        if (isset($parcelas[$this->request->post['qtd_parcela']])) {
          $total_parcelas = $parcelas[$this->request->post['qtd_parcela']]['valor_parcela'] * $this->request->post['qtd_parcela'];
          if ($total_parcelas > $order_info['total']) {
            $juros_parcela = number_format($total_parcelas - $order_info['total'], 2, '.', '');
          } else if ($total_parcelas < $order_info['total']) {
            $desconto_parcela = $order_info['total'] - $total_parcelas;
          }
        }

        $total_sobra = $order_info['total'] % $this->request->post['qtd_parcela'] / 100;

        if (parent::setOrderIncrease($this->order_info['order_id']) || $juros_parcela) {
          $juros_total = $juros_parcela + parent::getOrderIncreaseValue();
          $this->paymentInfo->setParam('price_additional', $juros_total);
        }

        if (parent::setOrderDiscount($this->order_info['order_id']) || $desconto_parcela) {
          $desconto_total = $desconto_parcela + parent::getOrderDiscountValue();
          $this->paymentInfo->setParam('price_discount', $desconto_total);
        }

        if (isset($this->request->post['cpf'])) {
          $this->paymentInfo->setParam('cpf', $this->request->post['cpf']);
        }

        //seta a opção escolhida pelo usuario
        $this->paymentInfo->setParam('payment_method_id', $payment_method_id);
        //seta as opções de pagamentos disponiveis
        $this->paymentInfo->setParam('available_payment_methods', implode(',', Type_PagarmeBandeira::getEnumListConst()));

        $paymentData = $this->getTransactionInfo();
        parent::setPaymentCreditCard();

        $cardData = array(
          'card_number' => $this->paymentInfo->getCreditCard()->getNumero(),
          'customer_id' => $order_info['customer_id'],
        );

        $result = $this->pagarme->sendPaymentCreditCard($paymentData, $this->paymentInfo);

        $this->load->model('payment/pagarme');
        $this->model_payment_pagarme->setStatusOrder($order_info['order_id'], $result->status);

        $sqlUpdParam = Ftr_sql::generateUpdate('oc_order', ['codigo_integracao_pagamento'], 'order_id = ' . $order_info['order_id']);
        $this->db->executeSql($sqlUpdParam, [$result->id]);

        $data = $result->created_at;
        $creditcard_ccno = str_replace(' ', '', $this->request->post['creditcard_ccno']);

        $paymentinfo = array();
        $paymentinfo['tid'] = $result->charges[0]->last_transaction->acquirer_tid;
        $paymentinfo['payment_id'] = $result->id;
        $paymentinfo['numero_autorizacao'] = $result->charges[0]->last_transaction->acquirer_auth_code;
        $paymentinfo['cod_autorizacao'] = $result->charges[0]->last_transaction->acquirer_auth_code;
        $paymentinfo['mensagem_retorno'] = $result->charges[0]->last_transaction->acquirer_message;
        $paymentinfo['order_id'] = $order_info['order_id'];
        $paymentinfo['valor_pagamento'] = $result->charges[0]->amount / 100;
        $paymentinfo['data_pagamento'] = $data;
        $paymentinfo['tipo_cartao'] = Type_Card::Tp_Credito;
        $paymentinfo['cartao_mascara'] = ftr_geral::MaskCard(strlen($creditcard_ccno), substr($creditcard_ccno, 0, 6), substr($creditcard_ccno, 12, strlen($creditcard_ccno)));
        $paymentinfo['cartao_bandeira'] = Type_PagarmeBandeira::getConstFromNickValue(strtolower($this->request->post['creditcard_cctype']));
        $paymentinfo['cartao_bandeira_text'] = ucfirst($this->request->post['creditcard_cctype']);
        $paymentinfo['qtd_parcela'] = $qtd_parcela;
        $paymentinfo['valor_acrescimo'] = (isset($juros_parcela) && ($juros_parcela > 0)) ? $juros_parcela : null;
        $paymentinfo['moeda'] = $result->currency;
        $paymentinfo['nsu'] = $result->charges[0]->last_transaction->acquirer_nsu;

        $this->load->dmodel('payment/payment_info');
        $this->dmodel_payment_payment_info->addPaymentCreditCard($paymentinfo);

        if ($juros_parcela) {
          $valorPedido = $order_info['total'] + $juros_parcela;
          $this->dmodel_checkout_order->InsertOrderTotal($this->session->data['order_id'], array(
            'module_code' => 'pagarme_acrescimo',
            'module_title' => 'Acréscimo Pagarme (' . $parcelas[$this->request->post['qtd_parcela']]['percentual_calculo'] . '% de juros ao mês no parcelamento)',
            'value' => $juros_parcela,
            'order' => '2'
          ));
          $this->dmodel_checkout_order->updateTotalOrder($this->session->data['order_id'], $valorPedido);
          $this->dmodel_checkout_order->updateApportionment($this->session->data['order_id'], $juros_parcela, Type_Apportionment::Increase);
        }
        if ($desconto_parcela) {
          $valorPedido = $order_info['total'] - $desconto_parcela;
          $this->dmodel_checkout_order->InsertOrderTotal($this->session->data['order_id'], array(
            'module_code' => 'pagarme_desconto',
            'module_title' => 'Desconto Pagarme (' . $parcelas[$this->request->post['qtd_parcela']]['percentual_calculo'] . '% de desconto)',
            'value' => $desconto_parcela * -1,
            'order' => '2'
          ));
          $this->dmodel_checkout_order->updateTotalOrder($this->session->data['order_id'], $valorPedido);
          $this->dmodel_checkout_order->updateApportionment($this->session->data['order_id'], $desconto_parcela, Type_Apportionment::Discount);
        }

      } catch (Exception $e) {

        $this->dmodel_checkout_order->update($this->session->data['order_id'], $this->config->get('pagarme_order_status_canceled'), '');
      }

      $json['redirect'] = $this->url->link('checkout/success');
    }

    $this->response->setOutputJson($json);

  }

  public function getOrder()
  {

    $this->load->dmodel('checkout/order');

    $this->order_info = $this->dmodel_checkout_order->getOrder($this->session->data['order_id']);

    $this->dmodel_checkout_order->confirm($this->order_info['order_id'], $this->config->get('pagarme_order_status_pending'), '');

    return $this->order_info;
  }

  public function getTransactionInfo()
  {
    parent::setPaymentInfo();
    parent::setPaymentProducts();

    $customerData = array(
      'customer_id' => $this->paymentInfo->getId(),
      'first_name' => $this->paymentInfo->getPrimeiroNome(),
      'last_name' => $this->paymentInfo->getUltimoNome(),
      'gender' => $this->paymentInfo->getGender(),
      'name' => $this->paymentInfo->getNome() != '' ? $this->paymentInfo->getNome() : '',
      'email' => $this->paymentInfo->getEmail() != '' ? $this->paymentInfo->getEmail() : '',
      'document_type' => isset($this->paymentInfo->getDocumento()->tipo) ? $this->paymentInfo->getDocumento()->tipo : '',
      'document_number' => isset($this->paymentInfo->getDocumento()->numero) ? $this->paymentInfo->getDocumento()->numero : '',
      'phone_number' => preg_replace("/[^0-9]/", "", $this->paymentInfo->getTelefone()->completo),
    );

    $customerData['billing_address'] = array(
      'postal_code' => $this->paymentInfo->getPaymentAddress()->getPostcode(),
      'street' => $this->paymentInfo->getPaymentAddress()->getRua(),
      'number' => $this->paymentInfo->getPaymentAddress()->getNumero(),
      'complement' => $this->paymentInfo->getPaymentAddress()->getComplemento() ?? '',
      'district' => $this->paymentInfo->getPaymentAddress()->getBairro(),
      'city' => $this->paymentInfo->getPaymentAddress()->getCidade(),
      'state' => $this->paymentInfo->getPaymentAddress()->getUf(),
      'country' => Type_PaisId::getNickFromConstValue(Type_PaisId::Tp_Brasil)
    );

    $shippingAddress = array(
      'postal_code' => $this->paymentInfo->getShippingAddress()->getPostcode(),
      'street' => $this->paymentInfo->getShippingAddress()->getRua(),
      'number' => $this->paymentInfo->getShippingAddress()->getNumero(),
      'complement' => $this->paymentInfo->getShippingAddress()->getComplemento() ?? '',
      'district' => $this->paymentInfo->getShippingAddress()->getBairro(),
      'city' => $this->paymentInfo->getShippingAddress()->getCidade(),
      'state' => $this->paymentInfo->getShippingAddress()->getUf(),
      'country' => Type_PaisId::getNickFromConstValue(Type_PaisId::Tp_Brasil)
    );

    $shipping = array(
      'first_name' => $this->paymentInfo->getPrimeiroNome(),
      'name' => $this->paymentInfo->getNome(),
      'email' => $this->paymentInfo->getEmail(),
      'phone_number' => preg_replace("/[^0-9]/", "", $this->paymentInfo->getTelefone()->completo),
      'address' => $shippingAddress,
    );
    ;

    foreach ($this->paymentInfo->getProducts() as $product) {
      $productData[] = array(
        'description' => $product->getDescricao(),
        'quantity' => $product->getQuantity(),
        'price_unit' => number_format($product->getPrice(), 2, '.', '')
      );
    }

    $value = $this->paymentInfo->getParam('amount') * 100;
    $transaction = array(
      'customer_ip' => $this->order_info['ip'],
      'shipping_type' => $this->order_info['shipping_method'],
      'shipping_price' => number_format($this->paymentInfo->getFrete(), 2, '.', ''),
      'amount' => intval("$value"), // Preço em centavos, essas aspas na variavel é necessário porque o PHP tem um bug pra converter float para integer :[
      'currency' => 'BRL',
    );

    if ($this->paymentInfo->hasParam('price_additional')) {
      $transaction['price_additional'] = number_format($this->paymentInfo->getParam('price_additional'), 2, '.', '');
    }

    if ($this->paymentInfo->hasParam('price_discount')) {
      $transaction['price_discount'] = number_format($this->paymentInfo->getParam('price_discount'), 2, '.', '');
    }

    $device = array(
      'ip_address' => $this->order_info['ip'],
      'device_id' => (preg_replace("/[^0-9]/", "", $this->config->get('config_cnpj')) . $this->session->data['pagarme_fingerprint_id']),
    );

    $order['order_id'] = $this->order_info['order_id'];

    $data = array(
      'customer' => $customerData,
      'transaction_product' => $productData,
      'transaction' => $transaction,
      'order' => $order,
      'device' => $device,
      'shipping' => $shipping,
    );

    $billet = $this->getBilletObject($data);
    $credit_card = $this->getCreditCardObject($data);

    return [
      'billet' => $billet,
      'credit_card' => $credit_card,
    ];

  }

  private function getBilletObject($data)
  {
    return [
      'seller_id' => $this->config->get('pagarme_seller_id'),
      'amount' => $data['transaction']['amount'],
      'currency' => $data['transaction']['currency'],
      'customer' => $data['customer'],
      'order' => $data['order'],
    ];
  }

  private function getCreditCardObject($data)
  {
    return [
      'seller_id' => $this->config->get('pagarme_seller_id'),
      'amount' => $data['transaction']['amount'],
      'currency' => $data['transaction']['currency'],
      'order' => $data['order'],
      'customer' => $data['customer'],
      'device' => $data['device'],
      'shippings' => [$data['shipping']],
    ];
  }


  public function pay_billet()
  {
    $this->load->helper('Ftr_sql');
    $this->load->controller('payment/payment_address');
    $controllerPaymentPaymentAddress = new ControllerPaymentPaymentAddress($this->registry);

    $json['error'] = $controllerPaymentPaymentAddress->validate();

    if (!$json['error']) {
      try {
        $order_info = $this->getOrder();

        //seta as opções de pagamentos disponiveis
        if (isset($this->request->post['cpf'])) {
          $this->paymentInfo->setParam('cpf', $this->request->post['cpf']);
        }

        $this->paymentInfo->setParam('shipping_method', $order_info['shipping_method']);

        if (parent::setOrderIncrease($order_info['order_id'])) {
          $this->paymentInfo->setParam('price_additional', number_format(parent::getOrderIncreaseValue(), 2, '.', ''));
        }

        if (parent::setOrderDiscount($order_info['order_id'])) {
          $this->paymentInfo->setParam('price_discount', number_format(parent::getOrderDiscountValue(), 2, '.', ''));
        }

        $valor = $order_info['total'];
        $valorPedido = number_format($valor, 2, '.', '');
        $this->paymentInfo->setParam('amount', $valorPedido);

        $paymentData = $this->getTransactionInfo();

        $pagarme_billet = $this->config->get('pagarme_billet');

        $paymentData['billet']['boleto'] = [];
        if (isset($pagarme_billet['validade']) && (!empty($pagarme_billet['validade']))) {
          $date = new DateTime('+' . $pagarme_billet['validade'] . ' day');
          $paymentData['billet']['boleto']['expiration_date'] = $date;
        }
        $result = $this->pagarme->sendPaymentBillet($paymentData, $this->paymentInfo);

        $json['boleto'] = $result->charges[0]->last_transaction;

        $this->load->model('payment/pagarme');
        $this->model_payment_pagarme->setStatusOrder($order_info['order_id'], $result->status);

        $sqlUpdParam = Ftr_sql::generateUpdate('oc_order', ['codigo_integracao_pagamento'], 'order_id = ' . $order_info['order_id']);
        $this->db->executeSql($sqlUpdParam, [$result->charges[0]->last_transaction->id]);

        $paymentInfo = array();
        $paymentInfo['data_criacao'] = $result->charges[0]->last_transaction->created_at;
        $paymentInfo['data_vencimento'] = $result->charges[0]->last_transaction->due_at;
        $paymentInfo['link_boleto'] = $result->charges[0]->last_transaction->url;
        $paymentInfo['link_barCode'] = $result->charges[0]->last_transaction->barcode;
        $paymentInfo['link_qrCode'] = $result->charges[0]->last_transaction->qr_code;
        $paymentInfo['link_digitavel'] = $result->charges[0]->last_transaction->line;
        $paymentInfo['order_id'] = $order_info['order_id'];

        $this->load->dmodel('payment/payment_info');
        $this->dmodel_payment_payment_info->addPaymentBillit($paymentInfo);

      } catch (Exception $e) {
        $this->dmodel_checkout_order->update($this->session->data['order_id'], $this->config->get('pagarme_order_status_canceled'), '');
      }

      $json['redirect'] = $this->url->link('checkout/success');
    }

    $this->response->setOutputJson($json);
  }

  public function pay_pix()
  {
    $this->load->helper('Ftr_sql');
    $this->load->controller('payment/payment_address');
    $controllerPaymentPaymentAddress = new ControllerPaymentPaymentAddress($this->registry);

    $json['error'] = $controllerPaymentPaymentAddress->validate();

    if (!$json['error']) {
      try {
        $order_info = $this->getOrder();

        //seta as opções de pagamentos disponiveis
        if (isset($this->request->post['cpf'])) {
          $this->paymentInfo->setParam('cpf', $this->request->post['cpf']);
        }

        $this->paymentInfo->setParam('shipping_method', $order_info['shipping_method']);

        if (parent::setOrderIncrease($order_info['order_id'])) {
          $this->paymentInfo->setParam('price_additional', number_format(parent::getOrderIncreaseValue(), 2, '.', ''));
        }

        if (parent::setOrderDiscount($order_info['order_id'])) {
          $this->paymentInfo->setParam('price_discount', number_format(parent::getOrderDiscountValue(), 2, '.', ''));
        }

        $valor = $order_info['total'];
        $valorPedido = number_format($valor, 2, '.', '');
        $this->paymentInfo->setParam('amount', $valorPedido);

        $paymentData = $this->getTransactionInfo();

        $pagarme_pix = $this->config->get('pagarme_pix');

        $paymentData['pix']['informations'] = [];

        if (isset($pagarme_pix['status']) && (!empty($pagarme_pix['expires_at']))) {
          $date = new DateTime('+' . $pagarme_pix['expires_at'] . ' day');
          $paymentData['pix']['informations']['expiration_date'] = $date;
        }
        
        $result = $this->pagarme->sendPaymentPix($paymentData, $this->paymentInfo);

        //Verificar informações abaixo
        $this->load->model('payment/pagarme');
        $this->model_payment_pagarme->setStatusOrder($order_info['order_id'], $result->status);

        $sqlUpdParam = Ftr_sql::generateUpdate('oc_order', ['codigo_integracao_pagamento'], 'order_id = ' . $order_info['order_id']);
        $this->db->executeSql($sqlUpdParam, [$result->charges[0]->code]);

        $paymentInfo = array();
        $paymentInfo['order_id'] = $order_info['order_id'];
        $paymentInfo['payment_id'] = $result->charges[0]->last_transaction->id;
        $paymentInfo['data_criacao'] = $result->charges[0]->last_transaction->created_at;
        $paymentInfo['data_vencimento'] = $result->charges[0]->last_transaction->expires_at;
        $paymentInfo['status_pagamento'] = $result->charges[0]->last_transaction->qr_code;
        $paymentInfo['link_qrcodeurl'] = $result->charges[0]->last_transaction->qr_code_url;
        $paymentInfo['link_qrcode'] = $result->charges[0]->last_transaction->qr_code;

        $this->load->dmodel('payment/payment_info');
        $this->dmodel_payment_payment_info->addPaymentPix($paymentInfo);

      } catch (Exception $e) {
        $this->dmodel_checkout_order->update($this->session->data['order_id'], $this->config->get('pagarme_order_status_canceled'), '');
      }

      $json['redirect'] = $this->url->link('checkout/success');
    }

    $this->response->setOutputJson($json);
  }

  public function callback()
  {
    $body = file_get_contents("php://input");

    $paymentData = json_decode($body);

    if (isset($paymentData) && $paymentData) {
      $payment_method = isset($paymentData->data->charges[0]->payment_method) ? $paymentData->data->charges[0] : $paymentData->data;

      if ($payment_method->payment_method == Type_PaymentOption::Tp_Pix) {
        $code = $payment_method->code;
        $status = $payment_method->status;
      } else if ($payment_method->payment_method == Type_PaymentOption::Tp_CreditCard) {
        $code = $payment_method->code;
        $status = $payment_method->status;
      } else if ($payment_method->payment_method == 'boleto') {
        $code = $payment_method->code;
        $status = $payment_method->status;
      }

      if (isset($code)) {
        $this->load->dmodel('payment/payment_info');

        $results['order_id'] = $code;

        if ($results) {
          try {
            $this->load->model('payment/pagarme');
            $this->model_payment_pagarme->setStatusOrder($results['order_id'], $status);

            ob_start();
            header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
            ob_end_flush();
            echo "Header Sent to Pagarme";
          } catch (Exception $e) {
            $logData = [
                'event'    => 'PaymentPagarme::callback',
                'message'  => 'Erro retorno callback Pagarme',
                'order_id' => $results['order_id'],
                'exception'=> [
                    'type'    => get_class($e),
                    'message' => $e->getMessage(),
                    'code'    => $e->getCode(),
                    'file'    => $e->getFile(),
                    'line'    => $e->getLine(),
                    'trace'   => $e->getTraceAsString()
                ],
                'datetime' => date('c'), // data/hora no padrão ISO
            ];
            $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
          }
        }
      }
    } else {
      ob_start();
      header($_SERVER["SERVER_PROTOCOL"] . " 401 error");
      ob_end_flush();
      echo "Header Not Sent to Pagarme";
    }

  }
}