src/includes/gateways/CreditPayment.php
<?php
namespace VindiPaymentGateways;
use WC_Subscriptions_Cart;
if (!defined('ABSPATH')) {
exit;
}
/**
* Vindi Payment Credit Card Gateway class.
*
* Extended by individual payment gateways to handle payments.
*
* @class VindiCreditGateway
* @extends VindiPaymentGateway
*/
class VindiCreditGateway extends VindiPaymentGateway
{
/**
* @var VindiSettings
*/
public $vindi_settings;
/**
* @var VindiControllers
*/
public $controllers;
/**
* @var int
*/
private $max_installments = 12;
/**
* @var int
*/
public $interest_rate;
public $smallest_installment;
public $installments;
public $verify_method;
public $enable_interest_rate;
public function __construct(VindiSettings $vindi_settings, VindiControllers $controllers)
{
global $woocommerce;
$this->id = 'vindi-credit-card';
$this->icon = apply_filters('vindi_woocommerce_credit_card_icon', '');
$this->method_title = __('Vindi - Cartão de Crédito', VINDI);
$this->method_description = __('Aceitar pagamentos via cartão de crédito utilizando a Vindi.', VINDI);
$this->has_fields = true;
$this->supports = array(
'subscriptions',
'products',
'subscription_cancellation',
'subscription_reactivation',
'subscription_suspension',
'subscription_amount_changes',
'subscription_payment_method_change',
'subscription_payment_method_change_customer',
'subscription_payment_method_change_admin',
'subscription_date_changes',
'multiple_subscriptions',
'refunds',
'pre-orders'
);
$this->init_form_fields();
$this->init_settings();
$this->smallest_installment = $this->get_option('smallest_installment');
$this->installments = $this->get_option('installments');
$this->verify_method = $this->get_option('verify_method');
$this->enable_interest_rate = $this->get_option('enable_interest_rate');
$this->interest_rate = $this->get_option('interest_rate');
parent::__construct($vindi_settings, $controllers);
}
/**
* Should return payment type for payment processing.
* @return string
*/
public function type()
{
return 'cc';
}
public function init_form_fields()
{
$this->form_fields = array(
'enabled' => array(
'title' => __('Habilitar/Desabilitar', VINDI),
'label' => __('Habilitar pagamento via Cartão de Crédito com a Vindi', VINDI),
'type' => 'checkbox',
'default' => 'no',
),
'title' => array(
'title' => __('Título', VINDI),
'type' => 'text',
'description' => __('Título que o cliente verá durante o processo de pagamento.', VINDI),
'default' => __('Cartão de Crédito', VINDI),
),
'verify_method' => array(
'title' => __('Transação de Verificação', VINDI),
'type' => 'checkbox',
'description' => __(' Realiza a transação de verificação em todos os novos pedidos. (Taxas adicionais por verificação poderão ser cobradas).', VINDI),
'default' => 'no',
),
'single_charge' => array(
'title' => __('Vendas Avulsas', VINDI),
'type' => 'title',
),
'smallest_installment' => array(
'title' => __('Valor mínimo da parcela', VINDI),
'type' => 'text',
'description' => __('Valor mínimo da parcela, não deve ser inferior a R$ 5,00.', VINDI),
'default' => '5',
),
'installments' => array(
'title' => __('Número máximo de parcelas', VINDI),
'type' => 'select',
'description' => __('Número máximo de parcelas para vendas avulsas. Deixe em 1x para desativar o parcelamento.', VINDI),
'default' => '1',
'options' => array(
'1' => '1x',
'2' => '2x',
'3' => '3x',
'4' => '4x',
'5' => '5x',
'6' => '6x',
'7' => '7x',
'8' => '8x',
'9' => '9x',
'10' => '10x',
'11' => '11x',
'12' => '12x',
),
),
'enable_interest_rate' => array(
'title' => __('Habilitar juros', VINDI),
'type' => 'checkbox',
'description' => __('Habilitar juros no parcelamento do pedido.', VINDI),
'default' => 'no',
),
'interest_rate' => array(
'title' => __('Taxa de juros ao mês (%)', VINDI),
'type' => 'text',
'description' => __('Taxa de juros que será adicionada aos pagamentos parcelados.', VINDI),
'default' => '0.1',
)
);
}
public function payment_fields()
{
$cart = $this->vindi_settings->woocommerce->cart;
$total = $this->get_cart_total($cart);
$installments = $this->build_cart_installments($total);
$user_payment_profile = $this->build_user_payment_profile();
$payment_methods = $this->routes->getPaymentMethods();
if ($payment_methods === false || empty($payment_methods) || !count($payment_methods['credit_card'])) {
_e(
'Estamos enfrentando problemas técnicos no momento. Tente novamente mais tarde ou entre em contato.',
VINDI
);
return;
}
$is_trial = false;
if (isset($this->is_trial) && $this->is_trial == $this->vindi_settings->get_is_active_sandbox()) {
$is_trial = $this->routes->isMerchantStatusTrialOrSandbox();
}
$this->vindi_settings->get_template('creditcard-checkout.html.php', compact(
'installments',
'is_trial',
'user_payment_profile',
'payment_methods'
));
}
public function build_cart_installments($total)
{
$max_times = $this->get_order_max_installments($total);
$installments = [];
if ($max_times > 1) {
for ($times = 1; $times <= $max_times; $times++) {
$installments[$times] = $this->get_cart_installments($times, $total);
}
}
return $installments;
}
public function get_cart_installments($times, $total)
{
if ($this->is_interest_rate_enabled()) {
return ($total * (1 + (($this->get_interest_rate() / 100) * ($times - 1)))) / $times;
}
return ceil($total / $times * 100) / 100;
}
public function get_cart_total($cart)
{
$total = $cart->total;
$recurring = end($cart->recurring_carts);
if (floatval($cart->total) == 0 && is_object($recurring)) {
$total = $recurring->total;
}
foreach ($cart->get_fees() as $index => $fee) {
if ($fee->name == __('Juros', VINDI)) {
$total -= $fee->amount;
}
}
return $total;
}
public function verify_user_payment_profile()
{
$old_payment_profile = (int) filter_input(
INPUT_POST,
'vindi-old-cc-data-check',
FILTER_SANITIZE_NUMBER_INT
);
return 1 === $old_payment_profile;
}
public function verify_method()
{
return 'yes' === $this->verify_method;
}
public function is_interest_rate_enabled()
{
return 'yes' === $this->enable_interest_rate;
}
public function get_interest_rate()
{
return floatval($this->interest_rate);
}
protected function get_order_max_installments($order_total)
{
if ($this->is_single_order()) {
$order_max_times = floor($order_total / $this->smallest_installment);
$max_times = empty($order_max_times) ? 1 : $order_max_times;
return min($this->max_installments, $max_times, $this->get_installments());
}
return $this->get_installments();
}
private function build_user_payment_profile()
{
$user_payment_profile = array();
$user_vindi_id = get_user_meta(wp_get_current_user()->ID, 'vindi_customer_id', true);
$payment_profile = WC()->session->get('current_payment_profile');
$current_customer = WC()->session->get('current_customer');
if (!isset($payment_profile) || ($current_customer['code'] ?? null) != $user_vindi_id) {
$payment_profile = $this->routes->getPaymentProfile($user_vindi_id);
}
if (($payment_profile['type'] ?? null) !== 'PaymentProfile::CreditCard') {
return $user_payment_profile;
}
if (false === empty($payment_profile)) {
$user_payment_profile['holder_name'] = $payment_profile['holder_name'];
$user_payment_profile['payment_company'] = $payment_profile['payment_company']['code'];
$user_payment_profile['card_number'] = sprintf('**** **** **** %s', $payment_profile['card_number_last_four']);
}
WC()->session->set('current_payment_profile', $payment_profile);
return $user_payment_profile;
}
protected function get_installments()
{
if ($this->is_single_order())
return $this->installments;
$installments = 0;
foreach ($this->vindi_settings->woocommerce->cart->cart_contents as $item) {
$plan_id = $item['data']->get_meta('vindi_plan_id');
if (!empty($plan_id)) {
$plan = $this->routes->getPlan($plan_id);
if ($installments == 0) {
$installments = $plan['installments'];
} elseif ($plan['installments'] < $installments) {
$installments = $plan['installments'];
}
}
}
if ($installments != 0)
return $installments;
else
return 1;
}
}