api = new RedsysAPI(); } /** * Process standard payment */ public function process_standard_payment($booking_data) { try { $params = $this->prepare_payment_params($booking_data); return $this->send_payment_request($params); } catch (Exception $e) { $this->log_error($e->getMessage()); return false; } } /** * Process future dated payment */ public function process_future_payment($booking_data) { try { $params = $this->prepare_payment_params($booking_data); // Add future payment parameters $params['DS_MERCHANT_TRANSACTIONTYPE'] = 'L'; // Deferred payment $params['DS_MERCHANT_DATEFRECUENCY'] = '1'; // Daily $params['DS_MERCHANT_CHARGEEXPIRYDATE'] = date('d/m/Y', strtotime($booking_data['check_in_date'])); return $this->send_payment_request($params); } catch (Exception $e) { $this->log_error($e->getMessage()); return false; } } /** * Process subscription payment */ public function process_subscription_payment($booking_data) { try { $params = $this->prepare_payment_params($booking_data); // Add subscription parameters $params['DS_MERCHANT_TRANSACTIONTYPE'] = 'L'; $params['DS_MERCHANT_COF_INI'] = 'S'; // Initial recurring payment $params['DS_MERCHANT_COF_TYPE'] = 'R'; // Recurring payment type return $this->send_payment_request($params); } catch (Exception $e) { $this->log_error($e->getMessage()); return false; } } /** * Process subsequent subscription payment */ public function process_subscription_renewal($booking_data, $reference_id) { try { $params = $this->prepare_payment_params($booking_data); // Add subsequent payment parameters $params['DS_MERCHANT_TRANSACTIONTYPE'] = '0'; $params['DS_MERCHANT_IDENTIFIER'] = $reference_id; $params['DS_MERCHANT_DIRECTPAYMENT'] = 'true'; return $this->send_payment_request($params); } catch (Exception $e) { $this->log_error($e->getMessage()); return false; } } /** * Prepare common payment parameters */ private function prepare_payment_params($booking_data) { return array( 'DS_MERCHANT_AMOUNT' => $this->format_amount($booking_data['amount']), 'DS_MERCHANT_ORDER' => $this->generate_order_number($booking_data['booking_id']), 'DS_MERCHANT_MERCHANTCODE' => get_option('eb_redsys_merchant_code'), 'DS_MERCHANT_CURRENCY' => '978', // EUR 'DS_MERCHANT_TERMINAL' => get_option('eb_redsys_terminal'), 'DS_MERCHANT_MERCHANTURL' => $this->get_notification_url($booking_data['booking_id']), 'DS_MERCHANT_URLOK' => $this->get_return_url($booking_data['booking_id'], 'success'), 'DS_MERCHANT_URLKO' => $this->get_return_url($booking_data['booking_id'], 'failure') ); } /** * Send payment request to Redsys */ private function send_payment_request($params) { $version = "HMAC_SHA256_V1"; $key = get_option('eb_redsys_encryption_key'); // Create merchant parameters $merchant_params = $this->api->createMerchantParameters($params); // Create merchant signature $signature = $this->api->createMerchantSignature($key, $merchant_params); return array( 'endpoint' => $this->get_endpoint(), 'params' => array( 'Ds_SignatureVersion' => $version, 'Ds_MerchantParameters' => $merchant_params, 'Ds_Signature' => $signature ) ); } /** * Process Redsys notification */ public function process_notification($data) { try { $key = get_option('eb_redsys_encryption_key'); $merchant_params = $data['Ds_MerchantParameters']; $signature = $data['Ds_Signature']; // Validate signature if (!$this->api->check_signature($merchant_params, $signature, $key)) { throw new Exception('Invalid signature'); } // Decode parameters $decoded_params = $this->api->decodeMerchantParameters($merchant_params); // Check response code $response_code = $decoded_params['Ds_Response']; if ($response_code < 100) { // Payment successful $order_id = $this->extract_booking_id($decoded_params['Ds_Order']); $transaction_id = $decoded_params['Ds_AuthorisationCode']; // Store card reference for future payments if available if (isset($decoded_params['Ds_Merchant_Identifier'])) { $this->store_card_reference( $order_id, $decoded_params['Ds_Merchant_Identifier'] ); } return array( 'success' => true, 'booking_id' => $order_id, 'transaction_id' => $transaction_id ); } throw new Exception("Payment failed with code: $response_code"); } catch (Exception $e) { $this->log_error($e->getMessage()); return array('success' => false, 'error' => $e->getMessage()); } } /** * Store card reference for future payments */ private function store_card_reference($booking_id, $reference) { update_post_meta($booking_id, '_redsys_card_reference', $reference); } /** * Get stored card reference */ public function get_card_reference($booking_id) { return get_post_meta($booking_id, '_redsys_card_reference', true); } /** * Get Redsys endpoint based on mode */ private function get_endpoint() { return (get_option('eb_redsys_test_mode') === 'yes') ? 'https://sis-t.redsys.es:25443/sis/realizarPago' : 'https://sis.redsys.es/sis/realizarPago'; } /** * Format amount for Redsys (in cents) */ private function format_amount($amount) { return number_format($amount * 100, 0, '', ''); } /** * Generate unique order number */ private function generate_order_number($booking_id) { return sprintf('%010d', $booking_id) . date('is'); } /** * Get notification URL */ private function get_notification_url($booking_id) { return add_query_arg(array( 'eb-api' => 'redsys', 'booking_id' => $booking_id ), home_url('/')); } /** * Get return URL */ private function get_return_url($booking_id, $result) { return add_query_arg(array( 'booking_id' => $booking_id, 'result' => $result ), eb_get_checkout_url()); } /** * Extract booking ID from order number */ private function extract_booking_id($order_number) { return intval(substr($order_number, 0, 10)); } /** * Log error message */ private function log_error($message) { if (function_exists('eb_log')) { eb_log('Redsys Error: ' . $message); } } } // Initialize payment functions function eb_redsys_payment() { return EB_Redsys_Payment_Functions::get_instance(); }