Plugin Directory

Changeset 2635881


Ignore:
Timestamp:
11/26/2021 02:22:43 PM (4 years ago)
Author:
ventipay
Message:

Update to version 1.2.0 from GitHub

Location:
ventipay
Files:
4 added
2 deleted
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • ventipay/tags/1.2.0/includes/class-wc-gateway-ventipay-bnpl.php

    r2595906 r2635881  
    1717  {
    1818    $this->id = 'ventipay_bnpl';
    19     $this->icon = plugin_dir_url(__FILE__) . '../assets/images/plugin-woocommerce-icon-bnpl.png';
     19    $this->icon = 'https://pay.ventipay.com/assets/apps/woocommerce/plugin-woocommerce-icon-bnpl.svg';
    2020    $this->has_fields = false;
    2121    $this->method_title = __('Venti', 'ventipay');
     
    6262        ),
    6363        'default' => __(
    64           'Paga en cuotas con débito',
     64          'Venti: Paga en cuotas con débito',
    6565          'ventipay'
    6666        ),
     
    8080      ],
    8181      'testmode' => [
    82         'title' => __('Habilitar modo Pruebas', 'ventipay'),
    83         'label' => __('Si habilitas esta opción podrás hacer pruebas de integración sin aceptar pagos reales.', 'ventipay'),
     82        'title' => __('Habilitar Modo Pruebas', 'ventipay'),
     83        'label' => __('Atención: Si habilitas esta opción no se realizarán cargos reales a los clientes. Habilita este modo solo si necesitas realizar pruebas de integración.', 'ventipay'),
    8484        'type' => 'checkbox',
    8585        'default' => 'yes',
     
    8888        'title' => __('Credenciales API', 'ventipay'),
    8989        'type' => 'title',
    90         'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores del Dashboard', 'ventipay'),
     90        'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores > API del Dashboard', 'ventipay'),
    9191      ],
    9292      'test_api_key' => [
     
    237237  public function ventipay_process_ipn()
    238238  {
    239     try {
    240       $order = wc_get_order($_GET['order_id']);
    241 
    242       /**
    243        * Check if it's a valid order
    244        */
    245       if (!isset($order) || !$order->get_id()) {
    246         header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     239    $order = wc_get_order($_GET['order_id']);
     240
     241    /**
     242     * Check if it's a valid order
     243     */
     244    if (!isset($order) || !$order->get_id()) {
     245      header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     246      return;
     247    }
     248
     249    /**
     250     * The order is already paid so we redirect the user to a success page
     251     */
     252    if ($order->is_paid()) {
     253      header('HTTP/1.1 200 OK (Order Is Paid)');
     254      return;
     255    }
     256
     257    /**
     258     * The order is valid and it's ready to be paid
     259     */
     260    if ($order->needs_payment()) {
     261      /**
     262       * Stored loan intent ID
     263       */
     264      $meta_loan_intent_id = $order->get_meta('ventipay_loan_intent_id');
     265
     266      /**
     267       * Recieved loan intent ID
     268       */
     269      $posted_body = json_decode(file_get_contents('php://input'));
     270      $posted_loan_intent_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
     271
     272      /**
     273       * We check if the stored ID looks like a valid one and both (stored and received) are equal
     274       * This is a simple check, however it should be enough to control MITM tampering.
     275       * Eventually we could check for a valid signature just like regular webhooks
     276       */
     277      if (!empty($meta_loan_intent_id)
     278        && substr($meta_loan_intent_id, 0, 3) === 'li_'
     279        && !empty($posted_loan_intent_id)
     280        && $meta_loan_intent_id === $posted_loan_intent_id)
     281      {
     282        /**
     283         * We retrieve the loan intent
     284         */
     285        $retrieve_loan_intent = wp_remote_get(
     286          self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id,
     287          [
     288            'headers' => [
     289              'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
     290              'Content-Type' => 'application/json',
     291            ],
     292            'timeout' => 45,
     293          ]
     294        );
     295
     296        if (is_wp_error($retrieve_loan_intent)) {
     297          header('HTTP/1.1 400 Bad Request (Unable To Retrieve Payment)');
     298          return;
     299        }
     300
     301        $retrieved_loan_intent = json_decode(wp_remote_retrieve_body($retrieve_loan_intent));
     302        $amount = (int) number_format($order->get_total(), 0, ',', '');
     303
     304        /**
     305         * We run some basic checks to make sure the order data matches the loan intent data.
     306         */
     307        if (isset($retrieved_loan_intent)
     308          && !empty($retrieved_loan_intent->id)
     309          && !empty($retrieved_loan_intent->amount)
     310          && !empty($retrieved_loan_intent->currency)
     311          && !empty($order->get_currency())
     312          && !empty($retrieved_loan_intent->object)
     313          && !empty($retrieved_loan_intent->status)
     314          && 'loan_intent' === $retrieved_loan_intent->object
     315          && $retrieved_loan_intent->id === $meta_loan_intent_id)
     316        {
     317          /**
     318           * Does the payment looks good (status is approved and amount and currency matches)?
     319           */
     320          if ('approved' === $retrieved_loan_intent->status
     321            && strtolower($retrieved_loan_intent->currency) === strtolower($order->get_currency())
     322            && $retrieved_loan_intent->amount === $amount)
     323          {
     324            /**
     325             * We attempt to authorize the approved loan intent.
     326             * If it wasn't approved or it's already authorized, the API will sent an error.
     327             */
     328            $authorize_loan_intent = wp_remote_post(
     329              self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id . '/authorize',
     330              [
     331                'headers' => [
     332                  'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
     333                  'Content-Type' => 'application/json',
     334                ],
     335                'timeout' => 120,
     336              ]
     337            );
     338
     339            if (!is_wp_error($authorize_loan_intent)) {
     340              /**
     341               * Authorized payment data
     342               */
     343              $authorized_loan_intent = json_decode(wp_remote_retrieve_body($authorize_loan_intent));
     344
     345              /**
     346               * Check if the payment was properly captured and authorized
     347               */
     348              if (isset($authorized_loan_intent)
     349                && !empty($authorized_loan_intent->status)
     350                && 'authorized' === $authorized_loan_intent->status)
     351              {
     352                $order->payment_complete();
     353                header('HTTP/1.1 200 OK (Payment Completed)');
     354                return;
     355              } else {
     356                header('HTTP/1.1 400 Bad Request (Unable To Authorize');
     357                return;
     358              }
     359            } else {
     360              header('HTTP/1.1 400 Bad Request (Unable To Authorize)');
     361              return;
     362            }
     363          } elseif ('authorized' === $retrieved_loan_intent->status
     364              && strtolower($retrieved_loan_intent->currency) === strtolower($order->get_currency())
     365              && $retrieved_loan_intent->amount === $amount)
     366            {
     367            $order->payment_complete();
     368            header('HTTP/1.1 200 OK (Payment Completed)');
     369            return;
     370          } else {
     371            $order->update_status('failed');
     372            header('HTTP/1.1 400 Bad Request (Invalid Payment Status');
     373            return;
     374          }
     375        }
     376        header('HTTP/1.1 400 Bad Request (Posted Payment Data Mismatch)');
    247377        return;
    248378      }
    249 
    250       /**
    251        * The order is already paid so we redirect the user to a success page
    252        */
    253       if ($order->is_paid()) {
    254         header('HTTP/1.1 200 OK (Order Is Paid)');
    255         return;
    256       }
    257 
    258       /**
    259        * The order is valid and it's ready to be paid
    260        */
    261       if ($order->needs_payment()) {
    262         /**
    263          * Stored loan intent ID
    264          */
    265         $meta_loan_intent_id = $order->get_meta('ventipay_loan_intent_id');
    266 
    267         /**
    268          * Recieved loan intent ID
    269          */
    270         $posted_body = json_decode(file_get_contents('php://input'));
    271         $posted_loan_intent_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
    272 
    273         /**
    274          * We check if the stored ID looks like a valid one and both (stored and received) are equal
    275          * This is a simple check, however it should be enough to control MITM tampering.
    276          * Eventually we could check for a valid signature just like regular webhooks
    277          */
    278         if (!empty($meta_loan_intent_id)
    279           && substr($meta_loan_intent_id, 0, 3) === 'li_'
    280           && !empty($posted_loan_intent_id)
    281           && $meta_loan_intent_id === $posted_loan_intent_id)
    282         {
    283           /**
    284            * We retrieve the loan intent
    285            */
    286           $retrieve_loan_intent = wp_remote_get(
    287             self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id,
    288             [
    289               'headers' => [
    290                 'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
    291                 'Content-Type' => 'application/json',
    292               ],
    293               'timeout' => 45,
    294             ]
    295           );
    296 
    297           if (is_wp_error($retrieve_loan_intent)) {
    298             header('HTTP/1.1 400 Bad Request (Unable To Retrieve Payment)');
    299             return;
    300           }
    301 
    302           $retrieved_loan_intent = json_decode(wp_remote_retrieve_body($retrieve_loan_intent));
    303           $amount = (int) number_format($order->get_total(), 0, ',', '');
    304 
    305           /**
    306            * We run some checks to make sure the order data matches the loan intent data.
    307            */
    308           if (empty($retrieved_loan_intent)
    309             || empty($retrieved_loan_intent->id)
    310             || empty($retrieved_loan_intent->amount)
    311             || empty($retrieved_loan_intent->currency)
    312             || empty($order->get_currency())
    313             || empty($retrieved_loan_intent->object)
    314             || empty($retrieved_loan_intent->status)
    315             || 'loan_intent' !== $retrieved_loan_intent->object
    316             || 'approved' !== $retrieved_loan_intent->status
    317             || strtolower($retrieved_loan_intent->currency) !== strtolower($order->get_currency())
    318             || $retrieved_loan_intent->amount !== $amount
    319             || $retrieved_loan_intent->id !== $meta_loan_intent_id)
    320           {
    321             $order->update_status('failed');
    322             header('HTTP/1.1 400 Bad Request (Posted Payment Data Mismatch)');
    323             return;
    324           }
    325 
    326           /**
    327            * We attempt to authorize the approved loan intent.
    328            * If it wasn't approved or it's already authorized, the API will sent an error.
    329            */
    330           $authorize_loan_intent = wp_remote_post(
    331             self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id . '/authorize',
    332             [
    333               'headers' => [
    334                 'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
    335                 'Content-Type' => 'application/json',
    336               ],
    337               'timeout' => 120,
    338             ]
    339           );
    340 
    341           if (!is_wp_error($authorize_loan_intent)) {
    342             /**
    343              * Captured payment data
    344              */
    345             $authorized_loan_intent = json_decode(wp_remote_retrieve_body($authorize_loan_intent));
    346 
    347             /**
    348              * Check if the payment was properly captured
    349              */
    350             if (isset($authorized_loan_intent)
    351               && !empty($authorized_loan_intent->status)
    352               && 'authorized' === $authorized_loan_intent->status)
    353             {
    354               $order->payment_complete();
    355               header('HTTP/1.1 200 OK (Payment Completed)');
    356               return;
    357             }
    358           }
    359           header('HTTP/1.1 400 Bad Request (Unable To Authorize Payment)');
    360           return;
    361         }
    362         $order->update_status('failed');
    363         header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    364         return;
    365       }
    366       header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     379      header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    367380      return;
    368     } catch (Exception $e) {
    369       header('HTTP/1.1 500 Server Error');
    370381    }
     382    header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     383    return;
    371384  }
    372385
  • ventipay/tags/1.2.0/includes/class-wc-gateway-ventipay.php

    r2595906 r2635881  
    1717  {
    1818    $this->id = 'ventipay';
    19     $this->icon = plugin_dir_url(__FILE__) . '../assets/images/plugin-woocommerce-icon-cards.png';
     19    $this->icon = 'https://pay.ventipay.com/assets/apps/woocommerce/plugin-woocommerce-icon-cards.svg';
    2020    $this->has_fields = false;
    2121    $this->method_title = __('Venti', 'ventipay');
     
    6262        ),
    6363        'default' => __(
    64           'Tarjeta de Crédito/Débito/Prepago',
     64          'Venti: Tarjeta de Crédito/Débito/Prepago',
    6565          'ventipay'
    6666        ),
     
    8080      ],
    8181      'testmode' => [
    82         'title' => __('Habilitar modo Pruebas', 'ventipay'),
    83         'label' => __('Si habilitas esta opción podrás hacer pruebas de integración sin aceptar pagos reales.', 'ventipay'),
     82        'title' => __('Habilitar Modo Pruebas', 'ventipay'),
     83        'label' => __('Atención: Si habilitas esta opción no se realizarán cargos reales a los clientes. Habilita este modo solo si necesitas realizar pruebas de integración.', 'ventipay'),
    8484        'type' => 'checkbox',
    8585        'default' => 'yes',
     
    8888        'title' => __('Credenciales API', 'ventipay'),
    8989        'type' => 'title',
    90         'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores del Dashboard', 'ventipay'),
     90        'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores > API del Dashboard', 'ventipay'),
    9191      ],
    9292      'test_api_key' => [
     
    233233  public function ventipay_process_ipn()
    234234  {
    235     try {
    236       $order = wc_get_order($_GET['order_id']);
    237 
    238       /**
    239        * Check if it's a valid order
    240        */
    241       if (!isset($order) || !$order->get_id()) {
    242         header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     235    $order = wc_get_order($_GET['order_id']);
     236
     237    /**
     238     * Check if it's a valid order
     239     */
     240    if (!isset($order) || !$order->get_id()) {
     241      header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     242      return;
     243    }
     244
     245    /**
     246     * The order is already paid so we redirect the user to a success page
     247     */
     248    if ($order->is_paid()) {
     249      header('HTTP/1.1 200 OK (Order Is Paid)');
     250      return;
     251    }
     252
     253    /**
     254     * The order is valid and it's ready to be paid
     255     */
     256    if ($order->needs_payment()) {
     257      /**
     258       * Stored payment ID
     259       */
     260      $meta_payment_id = $order->get_meta('ventipay_payment_id');
     261
     262      /**
     263       * Recieved payment ID
     264       */
     265      $posted_body = json_decode(file_get_contents('php://input'));
     266      $posted_payment_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
     267
     268      /**
     269       * We check if the stored ID looks like a valid one and both (stored and received) are equal
     270       * This is a simple check, however it should be enough to control MITM tampering.
     271       * Eventually we could check for a valid signature just like regular webhooks
     272       */
     273      if (!empty($meta_payment_id)
     274        && substr($meta_payment_id, 0, 4) === 'pay_'
     275        && !empty($posted_payment_id)
     276        && $meta_payment_id === $posted_payment_id)
     277      {
     278        /**
     279         * We attempt to capture the payment.
     280         * If it wasn't authorized or it's already captured, the API will sent an error.
     281         */
     282        $capture_payment = wp_remote_post(
     283          self::API_ENDPOINT . '/payments/' . $meta_payment_id . '/capture',
     284          [
     285            'headers' => [
     286              'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
     287              'Content-Type' => 'application/json',
     288            ],
     289            'timeout' => 120,
     290          ]
     291        );
     292
     293        if (!is_wp_error($capture_payment)) {
     294          /**
     295           * Captured payment data
     296           */
     297          $captured_payment = json_decode(wp_remote_retrieve_body($capture_payment));
     298
     299          /**
     300           * Check if the payment was properly captured
     301           */
     302          if (isset($captured_payment)
     303            && !empty($captured_payment->status)
     304            && !$captured_payment->refunded
     305            && !$captured_payment->disputed
     306            && 'succeeded' === $captured_payment->status)
     307          {
     308            $order->payment_complete();
     309            header('HTTP/1.1 200 OK (Payment Completed)');
     310            return;
     311          }
     312        }
     313        header('HTTP/1.1 400 Bad Request (Unable To Capture Payment)');
    243314        return;
    244315      }
    245 
    246       /**
    247        * The order is already paid so we redirect the user to a success page
    248        */
    249       if ($order->is_paid()) {
    250         header('HTTP/1.1 200 OK (Order Is Paid)');
    251         return;
    252       }
    253 
    254       /**
    255        * The order is valid and it's ready to be paid
    256        */
    257       if ($order->needs_payment()) {
    258         /**
    259          * Stored payment ID
    260          */
    261         $meta_payment_id = $order->get_meta('ventipay_payment_id');
    262 
    263         /**
    264          * Recieved payment ID
    265          */
    266         $posted_body = json_decode(file_get_contents('php://input'));
    267         $posted_payment_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
    268 
    269         /**
    270          * We check if the stored ID looks like a valid one and both (stored and received) are equal
    271          * This is a simple check, however it should be enough to control MITM tampering.
    272          * Eventually we could check for a valid signature just like regular webhooks
    273          */
    274         if (!empty($meta_payment_id)
    275           && substr($meta_payment_id, 0, 4) === 'pay_'
    276           && !empty($posted_payment_id)
    277           && $meta_payment_id === $posted_payment_id)
    278         {
    279           /**
    280            * We attempt to capture the payment.
    281            * If it wasn't authorized or it's already captured, the API will sent an error.
    282            */
    283           $capture_payment = wp_remote_post(
    284             self::API_ENDPOINT . '/payments/' . $meta_payment_id . '/capture',
    285             [
    286               'headers' => [
    287                 'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
    288                 'Content-Type' => 'application/json',
    289               ],
    290               'timeout' => 120,
    291             ]
    292           );
    293 
    294           if (!is_wp_error($capture_payment)) {
    295             /**
    296              * Captured payment data
    297              */
    298             $captured_payment = json_decode(wp_remote_retrieve_body($capture_payment));
    299 
    300             /**
    301              * Check if the payment was properly captured
    302              */
    303             if (isset($captured_payment)
    304               && !empty($captured_payment->status)
    305               && !$captured_payment->refunded
    306               && !$captured_payment->disputed
    307               && 'succeeded' === $captured_payment->status)
    308             {
    309               $order->payment_complete();
    310               header('HTTP/1.1 200 OK (Payment Completed)');
    311               return;
    312             }
    313           }
    314           header('HTTP/1.1 400 Bad Request (Unable To Capture Payment)');
    315           return;
    316         }
    317         $order->update_status('failed');
    318         header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    319         return;
    320       }
    321       header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     316      header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    322317      return;
    323     } catch (Exception $e) {
    324       header('HTTP/1.1 500 Server Error');
    325     }
     318    }
     319    header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     320    return;
    326321  }
    327322
  • ventipay/tags/1.2.0/readme.txt

    r2634782 r2635881  
    44Requires at least: 5.7
    55Tested up to: 5.8
    6 Stable tag: 1.1.1
     6Stable tag: 1.2.0
    77Requires PHP: 7.0
    88License: MIT
  • ventipay/tags/1.2.0/ventipay.php

    r2634782 r2635881  
    66 * Author: VentiPay
    77 * Author URI: https://www.ventipay.com/
    8  * Version: 1.1.1
     8 * Version: 1.2.0
    99 * Requires at least: 5.7
    1010 * Tested up to: 5.8
     
    3737}
    3838
     39/**
     40 * Hooks
     41 */
     42add_filter('woocommerce_after_add_to_cart_button' , 'venti_show_bnpl_button_in_product_page', 5);
    3943add_filter('woocommerce_payment_gateways', 'ventipay_add_gateway_class');
     44add_action('plugins_loaded', 'ventipay_init_gateway_class');
     45add_action('wp_enqueue_scripts', 'ventipay_setup_scripts');
    4046
    41 add_action('plugins_loaded', 'ventipay_init_gateway_class');
     47/**
     48 * Add BNPL button in product page
     49 */
     50function venti_show_bnpl_button_in_product_page()
     51{
     52  global $product;
     53  $payment_gateways_obj = new WC_Payment_Gateways();
     54  $enabled_payment_gateways = $payment_gateways_obj->payment_gateways();
     55  if (isset($enabled_payment_gateways)
     56    && isset($enabled_payment_gateways['ventipay_bnpl'])
     57    && $enabled_payment_gateways['ventipay_bnpl']->enabled === 'yes'
     58  ) {
     59    $venti_min_installment_amount = ceil((int) number_format($product->get_price(), 0, ',', '') / 4);
     60    if ($venti_min_installment_amount > 0) {
     61      echo '<div class="ventipay-bnpl-product-button-container">';
     62      echo '<div class="ventipay-bnpl-product-button-image-container"><img src="https://pay.ventipay.com/assets/apps/woocommerce/plugin-woocommerce-icon-bnpl-button-product-page.svg" alt="Venti" border="0" /></div>';
     63      echo '<div class="ventipay-bnpl-product-button-text-container">Paga en cuotas con débito desde ' . wc_price($venti_min_installment_amount) . ' al mes</div>';
     64      echo '</div>';
     65    }
     66  }
     67}
    4268
     69/**
     70 * Load scripts, styles
     71 */
     72function ventipay_setup_scripts()
     73{
     74  wp_register_style('ventipay', plugin_dir_url(__FILE__) . 'assets/css/ventipay-style.css');
     75  wp_enqueue_style('ventipay');
     76}
     77
     78/**
     79 * Load Gateway classes
     80 */
    4381function ventipay_init_gateway_class()
    4482{
  • ventipay/trunk/includes/class-wc-gateway-ventipay-bnpl.php

    r2595906 r2635881  
    1717  {
    1818    $this->id = 'ventipay_bnpl';
    19     $this->icon = plugin_dir_url(__FILE__) . '../assets/images/plugin-woocommerce-icon-bnpl.png';
     19    $this->icon = 'https://pay.ventipay.com/assets/apps/woocommerce/plugin-woocommerce-icon-bnpl.svg';
    2020    $this->has_fields = false;
    2121    $this->method_title = __('Venti', 'ventipay');
     
    6262        ),
    6363        'default' => __(
    64           'Paga en cuotas con débito',
     64          'Venti: Paga en cuotas con débito',
    6565          'ventipay'
    6666        ),
     
    8080      ],
    8181      'testmode' => [
    82         'title' => __('Habilitar modo Pruebas', 'ventipay'),
    83         'label' => __('Si habilitas esta opción podrás hacer pruebas de integración sin aceptar pagos reales.', 'ventipay'),
     82        'title' => __('Habilitar Modo Pruebas', 'ventipay'),
     83        'label' => __('Atención: Si habilitas esta opción no se realizarán cargos reales a los clientes. Habilita este modo solo si necesitas realizar pruebas de integración.', 'ventipay'),
    8484        'type' => 'checkbox',
    8585        'default' => 'yes',
     
    8888        'title' => __('Credenciales API', 'ventipay'),
    8989        'type' => 'title',
    90         'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores del Dashboard', 'ventipay'),
     90        'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores > API del Dashboard', 'ventipay'),
    9191      ],
    9292      'test_api_key' => [
     
    237237  public function ventipay_process_ipn()
    238238  {
    239     try {
    240       $order = wc_get_order($_GET['order_id']);
    241 
    242       /**
    243        * Check if it's a valid order
    244        */
    245       if (!isset($order) || !$order->get_id()) {
    246         header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     239    $order = wc_get_order($_GET['order_id']);
     240
     241    /**
     242     * Check if it's a valid order
     243     */
     244    if (!isset($order) || !$order->get_id()) {
     245      header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     246      return;
     247    }
     248
     249    /**
     250     * The order is already paid so we redirect the user to a success page
     251     */
     252    if ($order->is_paid()) {
     253      header('HTTP/1.1 200 OK (Order Is Paid)');
     254      return;
     255    }
     256
     257    /**
     258     * The order is valid and it's ready to be paid
     259     */
     260    if ($order->needs_payment()) {
     261      /**
     262       * Stored loan intent ID
     263       */
     264      $meta_loan_intent_id = $order->get_meta('ventipay_loan_intent_id');
     265
     266      /**
     267       * Recieved loan intent ID
     268       */
     269      $posted_body = json_decode(file_get_contents('php://input'));
     270      $posted_loan_intent_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
     271
     272      /**
     273       * We check if the stored ID looks like a valid one and both (stored and received) are equal
     274       * This is a simple check, however it should be enough to control MITM tampering.
     275       * Eventually we could check for a valid signature just like regular webhooks
     276       */
     277      if (!empty($meta_loan_intent_id)
     278        && substr($meta_loan_intent_id, 0, 3) === 'li_'
     279        && !empty($posted_loan_intent_id)
     280        && $meta_loan_intent_id === $posted_loan_intent_id)
     281      {
     282        /**
     283         * We retrieve the loan intent
     284         */
     285        $retrieve_loan_intent = wp_remote_get(
     286          self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id,
     287          [
     288            'headers' => [
     289              'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
     290              'Content-Type' => 'application/json',
     291            ],
     292            'timeout' => 45,
     293          ]
     294        );
     295
     296        if (is_wp_error($retrieve_loan_intent)) {
     297          header('HTTP/1.1 400 Bad Request (Unable To Retrieve Payment)');
     298          return;
     299        }
     300
     301        $retrieved_loan_intent = json_decode(wp_remote_retrieve_body($retrieve_loan_intent));
     302        $amount = (int) number_format($order->get_total(), 0, ',', '');
     303
     304        /**
     305         * We run some basic checks to make sure the order data matches the loan intent data.
     306         */
     307        if (isset($retrieved_loan_intent)
     308          && !empty($retrieved_loan_intent->id)
     309          && !empty($retrieved_loan_intent->amount)
     310          && !empty($retrieved_loan_intent->currency)
     311          && !empty($order->get_currency())
     312          && !empty($retrieved_loan_intent->object)
     313          && !empty($retrieved_loan_intent->status)
     314          && 'loan_intent' === $retrieved_loan_intent->object
     315          && $retrieved_loan_intent->id === $meta_loan_intent_id)
     316        {
     317          /**
     318           * Does the payment looks good (status is approved and amount and currency matches)?
     319           */
     320          if ('approved' === $retrieved_loan_intent->status
     321            && strtolower($retrieved_loan_intent->currency) === strtolower($order->get_currency())
     322            && $retrieved_loan_intent->amount === $amount)
     323          {
     324            /**
     325             * We attempt to authorize the approved loan intent.
     326             * If it wasn't approved or it's already authorized, the API will sent an error.
     327             */
     328            $authorize_loan_intent = wp_remote_post(
     329              self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id . '/authorize',
     330              [
     331                'headers' => [
     332                  'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
     333                  'Content-Type' => 'application/json',
     334                ],
     335                'timeout' => 120,
     336              ]
     337            );
     338
     339            if (!is_wp_error($authorize_loan_intent)) {
     340              /**
     341               * Authorized payment data
     342               */
     343              $authorized_loan_intent = json_decode(wp_remote_retrieve_body($authorize_loan_intent));
     344
     345              /**
     346               * Check if the payment was properly captured and authorized
     347               */
     348              if (isset($authorized_loan_intent)
     349                && !empty($authorized_loan_intent->status)
     350                && 'authorized' === $authorized_loan_intent->status)
     351              {
     352                $order->payment_complete();
     353                header('HTTP/1.1 200 OK (Payment Completed)');
     354                return;
     355              } else {
     356                header('HTTP/1.1 400 Bad Request (Unable To Authorize');
     357                return;
     358              }
     359            } else {
     360              header('HTTP/1.1 400 Bad Request (Unable To Authorize)');
     361              return;
     362            }
     363          } elseif ('authorized' === $retrieved_loan_intent->status
     364              && strtolower($retrieved_loan_intent->currency) === strtolower($order->get_currency())
     365              && $retrieved_loan_intent->amount === $amount)
     366            {
     367            $order->payment_complete();
     368            header('HTTP/1.1 200 OK (Payment Completed)');
     369            return;
     370          } else {
     371            $order->update_status('failed');
     372            header('HTTP/1.1 400 Bad Request (Invalid Payment Status');
     373            return;
     374          }
     375        }
     376        header('HTTP/1.1 400 Bad Request (Posted Payment Data Mismatch)');
    247377        return;
    248378      }
    249 
    250       /**
    251        * The order is already paid so we redirect the user to a success page
    252        */
    253       if ($order->is_paid()) {
    254         header('HTTP/1.1 200 OK (Order Is Paid)');
    255         return;
    256       }
    257 
    258       /**
    259        * The order is valid and it's ready to be paid
    260        */
    261       if ($order->needs_payment()) {
    262         /**
    263          * Stored loan intent ID
    264          */
    265         $meta_loan_intent_id = $order->get_meta('ventipay_loan_intent_id');
    266 
    267         /**
    268          * Recieved loan intent ID
    269          */
    270         $posted_body = json_decode(file_get_contents('php://input'));
    271         $posted_loan_intent_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
    272 
    273         /**
    274          * We check if the stored ID looks like a valid one and both (stored and received) are equal
    275          * This is a simple check, however it should be enough to control MITM tampering.
    276          * Eventually we could check for a valid signature just like regular webhooks
    277          */
    278         if (!empty($meta_loan_intent_id)
    279           && substr($meta_loan_intent_id, 0, 3) === 'li_'
    280           && !empty($posted_loan_intent_id)
    281           && $meta_loan_intent_id === $posted_loan_intent_id)
    282         {
    283           /**
    284            * We retrieve the loan intent
    285            */
    286           $retrieve_loan_intent = wp_remote_get(
    287             self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id,
    288             [
    289               'headers' => [
    290                 'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
    291                 'Content-Type' => 'application/json',
    292               ],
    293               'timeout' => 45,
    294             ]
    295           );
    296 
    297           if (is_wp_error($retrieve_loan_intent)) {
    298             header('HTTP/1.1 400 Bad Request (Unable To Retrieve Payment)');
    299             return;
    300           }
    301 
    302           $retrieved_loan_intent = json_decode(wp_remote_retrieve_body($retrieve_loan_intent));
    303           $amount = (int) number_format($order->get_total(), 0, ',', '');
    304 
    305           /**
    306            * We run some checks to make sure the order data matches the loan intent data.
    307            */
    308           if (empty($retrieved_loan_intent)
    309             || empty($retrieved_loan_intent->id)
    310             || empty($retrieved_loan_intent->amount)
    311             || empty($retrieved_loan_intent->currency)
    312             || empty($order->get_currency())
    313             || empty($retrieved_loan_intent->object)
    314             || empty($retrieved_loan_intent->status)
    315             || 'loan_intent' !== $retrieved_loan_intent->object
    316             || 'approved' !== $retrieved_loan_intent->status
    317             || strtolower($retrieved_loan_intent->currency) !== strtolower($order->get_currency())
    318             || $retrieved_loan_intent->amount !== $amount
    319             || $retrieved_loan_intent->id !== $meta_loan_intent_id)
    320           {
    321             $order->update_status('failed');
    322             header('HTTP/1.1 400 Bad Request (Posted Payment Data Mismatch)');
    323             return;
    324           }
    325 
    326           /**
    327            * We attempt to authorize the approved loan intent.
    328            * If it wasn't approved or it's already authorized, the API will sent an error.
    329            */
    330           $authorize_loan_intent = wp_remote_post(
    331             self::API_ENDPOINT . '/loan-intents/' . $meta_loan_intent_id . '/authorize',
    332             [
    333               'headers' => [
    334                 'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
    335                 'Content-Type' => 'application/json',
    336               ],
    337               'timeout' => 120,
    338             ]
    339           );
    340 
    341           if (!is_wp_error($authorize_loan_intent)) {
    342             /**
    343              * Captured payment data
    344              */
    345             $authorized_loan_intent = json_decode(wp_remote_retrieve_body($authorize_loan_intent));
    346 
    347             /**
    348              * Check if the payment was properly captured
    349              */
    350             if (isset($authorized_loan_intent)
    351               && !empty($authorized_loan_intent->status)
    352               && 'authorized' === $authorized_loan_intent->status)
    353             {
    354               $order->payment_complete();
    355               header('HTTP/1.1 200 OK (Payment Completed)');
    356               return;
    357             }
    358           }
    359           header('HTTP/1.1 400 Bad Request (Unable To Authorize Payment)');
    360           return;
    361         }
    362         $order->update_status('failed');
    363         header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    364         return;
    365       }
    366       header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     379      header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    367380      return;
    368     } catch (Exception $e) {
    369       header('HTTP/1.1 500 Server Error');
    370381    }
     382    header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     383    return;
    371384  }
    372385
  • ventipay/trunk/includes/class-wc-gateway-ventipay.php

    r2595906 r2635881  
    1717  {
    1818    $this->id = 'ventipay';
    19     $this->icon = plugin_dir_url(__FILE__) . '../assets/images/plugin-woocommerce-icon-cards.png';
     19    $this->icon = 'https://pay.ventipay.com/assets/apps/woocommerce/plugin-woocommerce-icon-cards.svg';
    2020    $this->has_fields = false;
    2121    $this->method_title = __('Venti', 'ventipay');
     
    6262        ),
    6363        'default' => __(
    64           'Tarjeta de Crédito/Débito/Prepago',
     64          'Venti: Tarjeta de Crédito/Débito/Prepago',
    6565          'ventipay'
    6666        ),
     
    8080      ],
    8181      'testmode' => [
    82         'title' => __('Habilitar modo Pruebas', 'ventipay'),
    83         'label' => __('Si habilitas esta opción podrás hacer pruebas de integración sin aceptar pagos reales.', 'ventipay'),
     82        'title' => __('Habilitar Modo Pruebas', 'ventipay'),
     83        'label' => __('Atención: Si habilitas esta opción no se realizarán cargos reales a los clientes. Habilita este modo solo si necesitas realizar pruebas de integración.', 'ventipay'),
    8484        'type' => 'checkbox',
    8585        'default' => 'yes',
     
    8888        'title' => __('Credenciales API', 'ventipay'),
    8989        'type' => 'title',
    90         'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores del Dashboard', 'ventipay'),
     90        'description' => __('Podrás encontrar tus API Keys en la sección Desarrolladores > API del Dashboard', 'ventipay'),
    9191      ],
    9292      'test_api_key' => [
     
    233233  public function ventipay_process_ipn()
    234234  {
    235     try {
    236       $order = wc_get_order($_GET['order_id']);
    237 
    238       /**
    239        * Check if it's a valid order
    240        */
    241       if (!isset($order) || !$order->get_id()) {
    242         header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     235    $order = wc_get_order($_GET['order_id']);
     236
     237    /**
     238     * Check if it's a valid order
     239     */
     240    if (!isset($order) || !$order->get_id()) {
     241      header('HTTP/1.1 400 Bad Request (Order ID Not Found)');
     242      return;
     243    }
     244
     245    /**
     246     * The order is already paid so we redirect the user to a success page
     247     */
     248    if ($order->is_paid()) {
     249      header('HTTP/1.1 200 OK (Order Is Paid)');
     250      return;
     251    }
     252
     253    /**
     254     * The order is valid and it's ready to be paid
     255     */
     256    if ($order->needs_payment()) {
     257      /**
     258       * Stored payment ID
     259       */
     260      $meta_payment_id = $order->get_meta('ventipay_payment_id');
     261
     262      /**
     263       * Recieved payment ID
     264       */
     265      $posted_body = json_decode(file_get_contents('php://input'));
     266      $posted_payment_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
     267
     268      /**
     269       * We check if the stored ID looks like a valid one and both (stored and received) are equal
     270       * This is a simple check, however it should be enough to control MITM tampering.
     271       * Eventually we could check for a valid signature just like regular webhooks
     272       */
     273      if (!empty($meta_payment_id)
     274        && substr($meta_payment_id, 0, 4) === 'pay_'
     275        && !empty($posted_payment_id)
     276        && $meta_payment_id === $posted_payment_id)
     277      {
     278        /**
     279         * We attempt to capture the payment.
     280         * If it wasn't authorized or it's already captured, the API will sent an error.
     281         */
     282        $capture_payment = wp_remote_post(
     283          self::API_ENDPOINT . '/payments/' . $meta_payment_id . '/capture',
     284          [
     285            'headers' => [
     286              'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
     287              'Content-Type' => 'application/json',
     288            ],
     289            'timeout' => 120,
     290          ]
     291        );
     292
     293        if (!is_wp_error($capture_payment)) {
     294          /**
     295           * Captured payment data
     296           */
     297          $captured_payment = json_decode(wp_remote_retrieve_body($capture_payment));
     298
     299          /**
     300           * Check if the payment was properly captured
     301           */
     302          if (isset($captured_payment)
     303            && !empty($captured_payment->status)
     304            && !$captured_payment->refunded
     305            && !$captured_payment->disputed
     306            && 'succeeded' === $captured_payment->status)
     307          {
     308            $order->payment_complete();
     309            header('HTTP/1.1 200 OK (Payment Completed)');
     310            return;
     311          }
     312        }
     313        header('HTTP/1.1 400 Bad Request (Unable To Capture Payment)');
    243314        return;
    244315      }
    245 
    246       /**
    247        * The order is already paid so we redirect the user to a success page
    248        */
    249       if ($order->is_paid()) {
    250         header('HTTP/1.1 200 OK (Order Is Paid)');
    251         return;
    252       }
    253 
    254       /**
    255        * The order is valid and it's ready to be paid
    256        */
    257       if ($order->needs_payment()) {
    258         /**
    259          * Stored payment ID
    260          */
    261         $meta_payment_id = $order->get_meta('ventipay_payment_id');
    262 
    263         /**
    264          * Recieved payment ID
    265          */
    266         $posted_body = json_decode(file_get_contents('php://input'));
    267         $posted_payment_id = isset($posted_body) && !empty($posted_body->data) && !empty($posted_body->data->id) ? $posted_body->data->id : null;
    268 
    269         /**
    270          * We check if the stored ID looks like a valid one and both (stored and received) are equal
    271          * This is a simple check, however it should be enough to control MITM tampering.
    272          * Eventually we could check for a valid signature just like regular webhooks
    273          */
    274         if (!empty($meta_payment_id)
    275           && substr($meta_payment_id, 0, 4) === 'pay_'
    276           && !empty($posted_payment_id)
    277           && $meta_payment_id === $posted_payment_id)
    278         {
    279           /**
    280            * We attempt to capture the payment.
    281            * If it wasn't authorized or it's already captured, the API will sent an error.
    282            */
    283           $capture_payment = wp_remote_post(
    284             self::API_ENDPOINT . '/payments/' . $meta_payment_id . '/capture',
    285             [
    286               'headers' => [
    287                 'Authorization' => 'Basic ' . base64_encode($this->api_key . ':'),
    288                 'Content-Type' => 'application/json',
    289               ],
    290               'timeout' => 120,
    291             ]
    292           );
    293 
    294           if (!is_wp_error($capture_payment)) {
    295             /**
    296              * Captured payment data
    297              */
    298             $captured_payment = json_decode(wp_remote_retrieve_body($capture_payment));
    299 
    300             /**
    301              * Check if the payment was properly captured
    302              */
    303             if (isset($captured_payment)
    304               && !empty($captured_payment->status)
    305               && !$captured_payment->refunded
    306               && !$captured_payment->disputed
    307               && 'succeeded' === $captured_payment->status)
    308             {
    309               $order->payment_complete();
    310               header('HTTP/1.1 200 OK (Payment Completed)');
    311               return;
    312             }
    313           }
    314           header('HTTP/1.1 400 Bad Request (Unable To Capture Payment)');
    315           return;
    316         }
    317         $order->update_status('failed');
    318         header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    319         return;
    320       }
    321       header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     316      header('HTTP/1.1 400 Bad Request (Posted Payment ID Mismatch)');
    322317      return;
    323     } catch (Exception $e) {
    324       header('HTTP/1.1 500 Server Error');
    325     }
     318    }
     319    header('HTTP/1.1 400 Bad Request (Order Not Ready To Be Paid)');
     320    return;
    326321  }
    327322
  • ventipay/trunk/readme.txt

    r2634782 r2635881  
    44Requires at least: 5.7
    55Tested up to: 5.8
    6 Stable tag: 1.1.1
     6Stable tag: 1.2.0
    77Requires PHP: 7.0
    88License: MIT
  • ventipay/trunk/ventipay.php

    r2634782 r2635881  
    66 * Author: VentiPay
    77 * Author URI: https://www.ventipay.com/
    8  * Version: 1.1.1
     8 * Version: 1.2.0
    99 * Requires at least: 5.7
    1010 * Tested up to: 5.8
     
    3737}
    3838
     39/**
     40 * Hooks
     41 */
     42add_filter('woocommerce_after_add_to_cart_button' , 'venti_show_bnpl_button_in_product_page', 5);
    3943add_filter('woocommerce_payment_gateways', 'ventipay_add_gateway_class');
     44add_action('plugins_loaded', 'ventipay_init_gateway_class');
     45add_action('wp_enqueue_scripts', 'ventipay_setup_scripts');
    4046
    41 add_action('plugins_loaded', 'ventipay_init_gateway_class');
     47/**
     48 * Add BNPL button in product page
     49 */
     50function venti_show_bnpl_button_in_product_page()
     51{
     52  global $product;
     53  $payment_gateways_obj = new WC_Payment_Gateways();
     54  $enabled_payment_gateways = $payment_gateways_obj->payment_gateways();
     55  if (isset($enabled_payment_gateways)
     56    && isset($enabled_payment_gateways['ventipay_bnpl'])
     57    && $enabled_payment_gateways['ventipay_bnpl']->enabled === 'yes'
     58  ) {
     59    $venti_min_installment_amount = ceil((int) number_format($product->get_price(), 0, ',', '') / 4);
     60    if ($venti_min_installment_amount > 0) {
     61      echo '<div class="ventipay-bnpl-product-button-container">';
     62      echo '<div class="ventipay-bnpl-product-button-image-container"><img src="https://pay.ventipay.com/assets/apps/woocommerce/plugin-woocommerce-icon-bnpl-button-product-page.svg" alt="Venti" border="0" /></div>';
     63      echo '<div class="ventipay-bnpl-product-button-text-container">Paga en cuotas con débito desde ' . wc_price($venti_min_installment_amount) . ' al mes</div>';
     64      echo '</div>';
     65    }
     66  }
     67}
    4268
     69/**
     70 * Load scripts, styles
     71 */
     72function ventipay_setup_scripts()
     73{
     74  wp_register_style('ventipay', plugin_dir_url(__FILE__) . 'assets/css/ventipay-style.css');
     75  wp_enqueue_style('ventipay');
     76}
     77
     78/**
     79 * Load Gateway classes
     80 */
    4381function ventipay_init_gateway_class()
    4482{
Note: See TracChangeset for help on using the changeset viewer.