Files
carpseeds.pl/wp-content/plugins/przelewy24/includes/class-p24-rest-server.php
2024-07-15 11:28:08 +02:00

244 lines
7.0 KiB
PHP

<?php
/**
* File that define P24_Rest_Server class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Base class for REST API transaction.
*/
class P24_Rest_Server {
/**
* Config factory.
*
* @var callable
*/
protected $config_factory;
/**
* The P24_Core instance
*
* @var P24_Core
*/
private $plugin_core;
/**
* Przelewy24RestAbstract constructor.
*
* @param callable $config_factory Config factory.
* @param P24_Core $plugin_core Plugin core instance.
*/
public function __construct( $config_factory, $plugin_core ) {
$this->config_factory = $config_factory;
$this->plugin_core = $plugin_core;
}
/**
* Support REST api.
*/
public function support_status() {
$status_payload = $this->get_json_from_body();
$cf = $this->get_config( $status_payload['currency'] );
$reg_session = '/^[0-9a-zA-Z_\.]+$/D';
if ( ! preg_match( $reg_session, $status_payload['sessionId'] ) ) {
return;
}
$session_id = explode( '_', $status_payload['sessionId'] );
$order_id = $session_id[0];
$order = new WC_Order( $order_id );
$verified = $this->verify( $order, $status_payload, $cf );
if ( $verified ) {
/* This value mey be not set yet. */
$order->update_meta_data( P24_Core::ORDER_P24_ID, $status_payload['orderId'] );
$verified = $this->external_verify( $order, $status_payload, $cf );
}
if ( ! $verified ) {
http_response_code( 400 );
$answer = wp_json_encode( array( 'success' => false ) );
exit( esc_js( "\n" . $answer ) );
} else {
$order->add_order_note( __( 'IPN payment completed', 'woocommerce' ) );
$card_ref = null;
$currency = $order->get_currency();
$decorator = $this->plugin_core->get_status_decorator_instance();
$decorator->try_set_decoration_mode( true, $currency );
$order->payment_complete();
$decorator->try_set_decoration_mode( false, $currency );
if ( (int) $status_payload['methodId'] ) {
$user_id = $order->get_user_id();
$method_id = (int) $status_payload['methodId'];
Przelewy24Helpers::setCustomData( 'user', $user_id, 'lastmethod', $method_id );
Przelewy24Helpers::setCustomData( 'user', $user_id, 'accept', 1 );
$card_ref = $this->try_save_card_reference_id( $status_payload['orderId'], $status_payload['methodId'], $user_id, $cf );
}
$order->update_meta_data( P24_Core::ORDER_SESSION_ID_KEY, $status_payload['sessionId'] );
$order->save_meta_data();
do_action( 'p24_payment_complete', $order, $card_ref );
}
$answer = wp_json_encode( array( 'success' => true ) );
exit( esc_js( "\n" . $answer ) );
}
/**
* Save card id reference number (to allow one click payments).
*
* It returns internal key of inserted the card reference.
*
* @param int $order_id P24 order id.
* @param int $method_id Method id (in p24).
* @param int $user_id Id of order owner.
* @param P24_Config_Accessor $cf Plugin configuration.
* @return string|null
*/
public function try_save_card_reference_id( $order_id, $method_id, $user_id, $cf ) {
if ( ! in_array( (int) $method_id, Przelewy24Class::getChannelsCard(), true ) ) {
return null;
}
if ( WC_Gateway_Przelewy24::get_cc_forget( $user_id ) ) {
return null;
}
if ( ! $cf->get_p24_payinshop() || ! $cf->get_p24_oneclick() ) {
return null;
}
$api_rest_card = new P24_Rest_Card( $cf );
$res = $api_rest_card->info( $order_id );
if ( ! isset( $res['data']['refId'] ) ) {
/* Not expected. */
error_log( __METHOD__ . ' brak numeru referencyjnego karty użytkownika' ); #phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
return null;
}
$ref = $res['data']['refId'];
$expires = substr( $res['data']['cardDate'], 2 ) . substr( $res['data']['cardDate'], 0, 2 );
if ( gmdate( 'Ym' ) > $expires ) {
/* Not expected. */
error_log( __METHOD__ . ' termin ważności ' . $expires ); #phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
return null;
}
$key = md5( $res['data']['mask'] . '|' . $res['data']['cardType'] . '|' . substr( $expires, 2 ) );
Przelewy24Helpers::setCustomData(
'user_cards',
$user_id,
$key,
array(
'ref' => $ref,
'exp' => substr( $expires, 2 ),
'mask' => $res['data']['mask'],
'type' => $res['data']['cardType'],
'time' => gmdate( 'Y-m-d H:i.s' ),
)
);
return $key;
}
/**
* Verify payload.
*
* @param WC_Order $order Order.
* @param array $payload Payload.
* @param P24_Config_Accessor $config Config accessor.
* @return bool
*/
private function verify( $order, $payload, $config ) {
$total_amount = number_format( $order->get_total() * 100, 0, '', '' );
$saved_p24_order_id = $order->get_meta( P24_Core::ORDER_P24_ID );
if ( $payload['merchantId'] !== (int) $config->get_merchant_id() ) {
return false;
} elseif ( $payload['posId'] !== (int) $config->get_shop_id() ) {
return false;
} elseif ( (string) $payload['amount'] !== $total_amount ) {
return false;
} elseif ( $payload['currency'] !== $config->get_currency() ) {
return false;
} elseif ( $saved_p24_order_id && (int) $saved_p24_order_id !== (int) $payload['orderId'] ) {
return false;
} elseif ( $this->sign( $payload, $config ) !== $payload['sign'] ) {
return false;
}
return true;
}
/**
* External_verify.
*
* @param WC_Order $order Order.
* @param array $data Additional data.
* @param P24_Config_Accessor $config Config accessor.
*
* @return bool
*/
private function external_verify( $order, $data, $config ) {
$rest_transaction = new P24_Rest_Transaction( $config );
$payload = array(
'merchantId' => (int) $config->get_merchant_id(),
'posId' => (int) $config->get_shop_id(),
'sessionId' => $data['sessionId'],
'amount' => (int) number_format( $order->get_total() * 100, 0, '', '' ),
'currency' => $config->get_currency(),
'orderId' => (int) $order->get_meta( P24_Core::ORDER_P24_ID ),
);
return $rest_transaction->verify_bool( $payload );
}
/**
* Sign
*
* @param array $payload Payload.
* @param P24_Config_Accessor $config Config accessor.
* @return string
*/
private function sign( $payload, $config ) {
unset( $payload['sign'] );
$payload['crc'] = $config->get_salt();
$string = wp_json_encode( $payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
$sign = hash( 'sha384', $string );
return $sign;
}
/**
* Get JSON from body.
*
* @return array
*/
private function get_json_from_body() {
$body = file_get_contents( 'php://input' );
$json = json_decode( $body, true );
if ( ! is_array( $json ) ) {
$json = (array) $json;
}
return $json;
}
/**
* Get_config.
*
* @param string|null $currency Currency.
* @return P24_Config_Accessor Config accessor.
*/
private function get_config( $currency = null ) {
$factory = $this->config_factory;
$cf = $factory( $currency );
$cf->access_mode_to_strict();
return $cf;
}
}