Skip to content

Commit

Permalink
Merge pull request #14 from khipu/heads/4.0
Browse files Browse the repository at this point in the history
Versión 4.0
  • Loading branch information
JKacicM authored Jul 19, 2024
2 parents 8db8bca + e5118e5 commit 52091d9
Show file tree
Hide file tree
Showing 39 changed files with 141 additions and 8,164 deletions.
191 changes: 107 additions & 84 deletions includes/abstract-wc-gateway-khipu.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

abstract class WC_Gateway_khipu_abstract extends WC_Payment_Gateway
{


function comm_error($exception = null)
{
if (!$exception) {
Expand All @@ -29,79 +27,89 @@ function comm_error($exception = null)
function create_payment($order_id)
{
$order = new WC_Order($order_id);

$item_names = array();

if (sizeof($order->get_items()) > 0) {
foreach ($order->get_items() as $item) {
if ($item['qty']) {
$item_names[] = $item['name'] . ' x ' . $item['qty'];
$item_names[] = $item['qty'] . ' x ' . $item['name'];
}
}
}

$configuration = new Khipu\Configuration();
$configuration->setSecret($this->secret);
$configuration->setReceiverId($this->receiver_id);
$configuration->setPlatform('woocommerce-khipu', '3.6');
// $configuration->setDebug(true);

$client = new Khipu\ApiClient($configuration);
$payments = new Khipu\Client\PaymentsApi($client);

$headers = [
'x-api-key' => $this->api_key,
'Content-Type' => 'application/json'
];
$payments_url = 'https://payment-api.khipu.com/v3/payments';
$cartProductsKhipu = '';
foreach ($item_names as $product) {
$cartProductsKhipu .= "\n".$product;
$cartProductsKhipu .= "\n\r" . $product;
}

$options = array(
'transaction_id' => ltrim($order->get_order_number(), '#')
, 'custom' => serialize(array($order_id, $order->get_order_key()))
, 'body' => 'Productos incluidos en la compra:'.$cartProductsKhipu
, 'return_url' => $this->get_return_url($order)
, 'cancel_url' => $order->get_checkout_payment_url()
, 'notify_url' => $this->notify_url
, 'notify_api_version' => '1.3'
, 'payer_email' => $order->get_billing_email()
);
$data = [
'subject' => 'Orden ' . $order->get_order_number() . ' - ' . get_bloginfo('name'),
'currency' => $order->get_currency(),
'amount' => (float) number_format($order->get_total(), absint(get_option('woocommerce_price_num_decimals', 2)), '.', ''),
'transaction_id' => ltrim($order->get_order_number(), '#'),
'custom' => serialize([$order_id, $order->get_order_key()]),
'body' => 'Productos incluidos en la compra:' . $cartProductsKhipu,
'return_url' => $this->get_return_url($order),
'cancel_url' => $order->get_checkout_payment_url(),
'notify_url' => $this->notify_url,
'notify_api_version' => '3.0',
'payer_email' => $order->get_billing_email()
];

$held_duration = get_option('woocommerce_hold_stock_minutes');

if ($held_duration > 1 && 'yes' == get_option('woocommerce_manage_stock')) {
$interval = new DateInterval('PT' . $held_duration . 'M');
$timeout = new DateTime('now');
$timeout->add($interval);
$options['expires_date'] = $timeout;
$data['expires_date'] = $timeout->format(DateTime::ATOM);
}

try {
$createPaymentResponse = $payments->paymentsPost(
'Orden ' . $order->get_order_number() . ' - ' . get_bloginfo('name')
, $order->get_currency()
, number_format($order->get_total(), absint(get_option('woocommerce_price_num_decimals', 2)), '.', '')
, $options
);
} catch (\Khipu\ApiException $e) {
return $this->comm_error($e->getResponseObject());
$response = wp_remote_post($payments_url, [
'headers' => $headers,
'body' => json_encode($data),
'method' => 'POST'
]);

if (is_wp_error($response)) {
$error_message = $response->get_error_message();
return $this->comm_error($error_message);
}

$response_body = wp_remote_retrieve_body($response);
$createPaymentResponse = json_decode($response_body);

if (empty($createPaymentResponse) || isset($createPaymentResponse->error)) {
$error_message = json_encode($createPaymentResponse->error);
return "<div class='woocommerce-error'>Error ab: No se pudo crear el pago. " . $error_message . "</div>";
}

return $createPaymentResponse;
}


private function get_payment_response($notification_token)
private function get_payment_response($payment_id)
{
$configuration = new Khipu\Configuration();
$configuration->setSecret($this->secret);
$configuration->setReceiverId($this->receiver_id);
$configuration->setPlatform('woocommerce-khipu', '3.1');

$client = new Khipu\ApiClient($configuration);
$payments = new Khipu\Client\PaymentsApi($client);
try {
$paymentsResponse = $payments->paymentsGet($notification_token);
} catch (\Khipu\ApiException $e) {
$headers = [
'x-api-key' => $this->api_key,
'Content-Type' => 'application/json'
];

$payments_url = 'https://payment-api.khipu.com/v3/payments/' . $payment_id;

$response = wp_remote_get($payments_url, [
'headers' => $headers
]);

if (is_wp_error($response)) {
return null;
}
return $paymentsResponse;

return json_decode(wp_remote_retrieve_body($response));
}

/**
Expand All @@ -110,43 +118,57 @@ private function get_payment_response($notification_token)
function check_ipn_response()
{
@ob_clean();
http_response_code(400);
http_response_code(401);

if (empty($_POST)) {
exit("No POST data");
$raw_post = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_KHIPU_SIGNATURE'];
if (empty($_SERVER['HTTP_X_KHIPU_SIGNATURE'])) {
http_response_code(401);
exit("Missing signature");
}
if (empty($_POST['api_version']) || $_POST['api_version'] != '1.3') {
exit("Invalid API version");

$signature_parts = explode(',', $signature,2);
foreach ($signature_parts as $part) {
[$key, $value] = explode('=', $part,2);
if ($key === 't') {
$t_value = $value;
} elseif ($key === 's') {
$s_value = $value;
}
}
if (empty($_POST['notification_token'])) {
exit("Missing notification token");
$to_hash = $t_value . '.' . $raw_post;
$hash_bytes = hash_hmac('sha256', $to_hash, $this->secret, true);
$hmac_base64 = base64_encode($hash_bytes);

if ($hmac_base64 !== $s_value) {
http_response_code(401);
exit("Invalid signature");
}

$paymentResponse = $this->get_payment_response($_POST['notification_token']);
$paymentResponse = json_decode($raw_post);
if (!$paymentResponse) {
exit("No payment response for token");
http_response_code(401);
exit("No payment response for payment ID");
}

$order = $this->get_order($paymentResponse);
if (!$order) {
http_response_code(401);
exit("No order for payment response");
}

if ($paymentResponse->getStatus() != 'done') {
exit("Payment status not done");
}

if ($paymentResponse->getAmount() != floatval(number_format($order->get_total(), absint(get_option('woocommerce_price_num_decimals', 2)), '.', ''))) {
exit("Wrong amount. Expected: " . floatval(number_format($order->get_total(), absint(get_option('woocommerce_price_num_decimals', 2)), '.', '')) . ' got ' . $paymentResponse->getAmount());
if ($paymentResponse->amount != floatval(number_format($order->get_total(), absint(get_option('woocommerce_price_num_decimals', 2)), '.', ''))) {
http_response_code(401);
exit("Wrong amount. Expected: " . floatval(number_format($order->get_total(), absint(get_option('woocommerce_price_num_decimals', 2)), '.', '')) . ' got ' . $paymentResponse->amount);
}

if ($order) {
http_response_code(200);
if ($order->get_status() == 'completed' || $order->get_status() == 'processing') {
exit('Notification already processed');
}
$order->add_order_note(sprintf(__('Pago verificado con código único de verificación khipu %s', 'woocommerce-gateway-khipu'), $paymentResponse->getPaymentId()));
$order->payment_complete($paymentResponse->getPaymentId());
$order->add_order_note(sprintf(__('Pago verificado con código único de verificación khipu %s', 'woocommerce-gateway-khipu'), $paymentResponse->payment_id));
$order->payment_complete($paymentResponse->payment_id);
$defined_status = $this->get_option('after_payment_status');
if ($defined_status) {
$order->update_status($defined_status);
Expand All @@ -158,14 +180,14 @@ function check_ipn_response()
/**
* get_khipu_order function.
*/
private function get_order(Khipu\Model\PaymentsResponse $paymentResponse)
private function get_order($paymentResponse)
{
$custom = maybe_unserialize($paymentResponse->getCustom());
$custom = maybe_unserialize($paymentResponse->custom);

// Backwards comp for IPN requests
if (is_numeric($custom)) {
$order_id = (int)$custom;
$order_key = $paymentResponse->getTransactionId();
$order_key = $paymentResponse->transaction_id;
} elseif (is_string($custom)) {
$order_id = (int)str_replace($this->invoice_prefix, '', $custom);
$order_key = $custom;
Expand Down Expand Up @@ -209,21 +231,23 @@ function get_payment_methods()

if (!$response || !$response['ts'] || (time() - (int)$response['ts']) > 30) {
unset($response);
$configuration = new Khipu\Configuration();
$configuration->setSecret($this->secret);
$configuration->setReceiverId($this->receiver_id);
$configuration->setPlatform('woocommerce-khipu', '3.2');
$headers = [
'x-api-key' => $this->api_key,
'Content-Type' => 'application/json'
];

$client = new Khipu\ApiClient($configuration);
$paymentMethodsApi = new Khipu\Client\PaymentMethodsApi($client);
$payments_url = 'https://payment-api.khipu.com/v3/merchants/' . $this->receiver_id . '/paymentMethods';

try {
$paymentsMethodsResponse = $paymentMethodsApi->merchantsIdPaymentMethodsGet($this->receiver_id);
$response = wp_remote_get($payments_url, [
'headers' => $headers
]);

if (!is_wp_error($response)) {
$paymentsMethodsResponse = json_decode(wp_remote_retrieve_body($response));
$response['methods'] = $paymentsMethodsResponse;
} catch (\Khipu\ApiException $e) {
$response['ts'] = time();
update_option('woocommerce_gateway_khipu_payment_methods', $response);
}
$response['ts'] = time();
update_option('woocommerce_gateway_khipu_payment_methods', $response);
}
return $response['methods'];
}
Expand All @@ -234,22 +258,21 @@ function get_payment_method_icon($id)
if (!$methods) {
return '';
}
foreach ($methods->getPaymentMethods() as $paymentMethod) {
if (strcmp($paymentMethod->getId(), $id) == 0) {
return $paymentMethod->getLogoUrl();
foreach ($methods->paymentMethods as $paymentMethod) {
if (strcmp($paymentMethod->id, $id) == 0) {
return $paymentMethod->logo_url;
}
}
}


function is_payment_method_available_in_khipu($id)
{
$methods = $this->get_payment_methods();
if (!$methods) {
return false;
}
foreach ($methods->getPaymentMethods() as $paymentMethod) {
if (strcmp($paymentMethod->getId(), $id) == 0) {
foreach ($methods->paymentMethods as $paymentMethod) {
if (strcmp($paymentMethod->id, $id) == 0) {
return true;
}
}
Expand Down
22 changes: 12 additions & 10 deletions includes/class-wc-gateway-khipu-regular-transfer.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<?php


class WC_Gateway_khipu_regular_transfer extends WC_Gateway_khipu_abstract
{

var $notify_url;

/**
Expand All @@ -27,10 +25,10 @@ public function __construct()
$this->description = $this->get_option('description');
$this->receiver_id = $this->get_option('receiver_id');
$this->secret = $this->get_option('secret');
$this->api_key = $this->get_option('api_key');
$this->icon = $this->get_payment_method_icon('REGULAR_TRANSFER');
$this->after_payment_status = $this->get_option('after_payment_status');


add_action('woocommerce_receipt_' . $this->id, array($this, 'receipt_page'));
add_action('woocommerce_update_options_payment_gateways_' . $this->id,
array($this, 'process_admin_options'));
Expand Down Expand Up @@ -74,10 +72,9 @@ function is_valid_currency() {
}

function is_configured() {
return $this->secret && $this->receiver_id;
return $this->secret && $this->receiver_id && $this->api_key;
}


/**
* Initialise Gateway Settings Form Fields
*/
Expand Down Expand Up @@ -106,6 +103,13 @@ function init_form_fields()
'default' => '',
'desc_tip' => true
),
'api_key' => array(
'title' => __('Api Key', 'woocommerce-gateway-khipu'),
'type' => 'text',
'description' => __('Ingrese su Api Key. Se obtiene en https://khipu.com/merchant/profile ', 'woocommerce-gateway-khipu'),
'default' => '',
'desc_tip' => true
),
'after_payment_status' => array(
'title' => __('Estado del pedido pagado.'),
'description' => __('Seleccione estado con el que desea dejar sus órdenes luego de pagadas.', 'woocommerce-gateway-khipu'),
Expand Down Expand Up @@ -135,7 +139,6 @@ function init_form_fields()
);
}


/**
* Process the payment and return the result
*/
Expand All @@ -151,11 +154,10 @@ function process_payment($order_id)
function receipt_page($order)
{
$response = $this->create_payment($order);
if (method_exists($response, 'getTransferUrl')) {
wp_redirect($response->getTransferUrl());
if ($response && isset($response->transfer_url)) {
wp_redirect($response->transfer_url);
} else {
echo $response;
echo $response ? json_encode($response) : 'Error: No se pudo crear el pago.';
}
}
}

Loading

0 comments on commit 52091d9

Please sign in to comment.