display_payment_requests_table(); ?>

%

prefix . 'eb_payment_requests'; $requests = $wpdb->get_results( "SELECT * FROM {$table_name} ORDER BY created_at DESC LIMIT 20" ); if (empty($requests)) { echo '

' . __('No payment requests found.', 'informatiq-eb-redsys') . '

'; return; } ?>
id; ?> #booking_id; ?> customer_email); ?> €amount, 2); ?> status); ?> created_at)); ?> expires_at)); ?> status === 'pending'): ?> status !== 'paid'): ?>
create_payment_request( $booking_id, $customer_email, $amount, $description, $expires_in ); if ($request_id) { // Send email $sent = $this->send_payment_request_email($request_id); if ($sent) { wp_send_json_success(__('Payment request sent successfully', 'informatiq-eb-redsys')); } else { wp_send_json_error(__('Payment request created but email failed to send', 'informatiq-eb-redsys')); } } else { wp_send_json_error(__('Failed to create payment request', 'informatiq-eb-redsys')); } } /** * Create payment request in database */ private function create_payment_request($booking_id, $customer_email, $amount, $description, $expires_in) { global $wpdb; $table_name = $wpdb->prefix . 'eb_payment_requests'; // Generate unique token $token = wp_generate_password(32, false); // Create payment link $payment_link = home_url('/?eb_payment_request=' . $token); // Calculate expiry date $expires_at = date('Y-m-d H:i:s', strtotime("+{$expires_in} hours")); $result = $wpdb->insert( $table_name, array( 'booking_id' => $booking_id, 'customer_email' => $customer_email, 'amount' => $amount, 'description' => $description, 'token' => $token, 'payment_link' => $payment_link, 'status' => 'pending', 'created_at' => current_time('mysql'), 'expires_at' => $expires_at ), array('%d', '%s', '%f', '%s', '%s', '%s', '%s', '%s', '%s') ); return $result ? $wpdb->insert_id : false; } /** * Send payment request email */ private function send_payment_request_email($request_id) { global $wpdb; $table_name = $wpdb->prefix . 'eb_payment_requests'; $request = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $request_id) ); if (!$request) { return false; } // Get booking details $booking = get_post($request->booking_id); $subject = sprintf( __('Payment Request for Booking #%d - Hotel Raxa', 'informatiq-eb-redsys'), $request->booking_id ); $message = $this->get_payment_request_email_template($request, $booking); $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: Hotel Raxa ' ); $sent = wp_mail($request->customer_email, $subject, $message, $headers); if ($sent) { // Update status $wpdb->update( $table_name, array('status' => 'sent', 'sent_at' => current_time('mysql')), array('id' => $request_id), array('%s', '%s'), array('%d') ); } return $sent; } /** * Get payment request email template */ private function get_payment_request_email_template($request, $booking) { $template = ' Payment Request - Hotel Raxa

Hotel Raxa

Payment Request

Dear Guest,

We hope you are looking forward to your stay at Hotel Raxa. This is a payment request for your upcoming booking.

Booking Details

Booking ID: #' . $request->booking_id . '

Amount Requested: €' . number_format($request->amount, 2) . '

' . ($request->description ? '

Description: ' . esc_html($request->description) . '

' : '') . '

Payment Due: ' . date_i18n(get_option('date_format'), strtotime($request->expires_at)) . '

Pay Now - €' . number_format($request->amount, 2) . '

Important: This payment link will expire on ' . date_i18n(get_option('datetime_format'), strtotime($request->expires_at)) . '. Please complete your payment before this date to secure your reservation.

If you have any questions about this payment request or your booking, please contact us immediately.

Thank you for choosing Hotel Raxa!

Hotel Raxa | For questions, please contact: info@hotelraxa.com

This email was sent automatically. Please do not reply to this email.

'; return $template; } /** * Handle payment link processing */ public function handle_payment_link() { if (!isset($_GET['eb_payment_request'])) { return; } $token = sanitize_text_field($_GET['eb_payment_request']); global $wpdb; $table_name = $wpdb->prefix . 'eb_payment_requests'; $request = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$table_name} WHERE token = %s", $token) ); if (!$request) { wp_die(__('Invalid payment request', 'informatiq-eb-redsys')); } // Check if expired if (strtotime($request->expires_at) < time()) { wp_die(__('This payment request has expired', 'informatiq-eb-redsys')); } // Check if already paid if ($request->status === 'paid') { wp_die(__('This payment request has already been completed', 'informatiq-eb-redsys')); } // Process payment with Redsys $this->process_payment_request($request); } /** * Process payment request */ private function process_payment_request($request) { // Get Redsys settings $merchant_code = get_option('eb_redsys_merchant_code'); $terminal = get_option('eb_redsys_terminal'); $encryption_key = get_option('eb_redsys_encryption_key'); $test_mode = get_option('eb_redsys_test_mode') === 'yes'; // Include Redsys API require_once dirname(__FILE__) . '/../api/class-redsys-api.php'; $redsys = new Redsys_API(); // Generate order number $order_number = 'PR' . str_pad($request->id, 8, '0', STR_PAD_LEFT); // Set payment parameters $redsys->setParameter('DS_MERCHANT_AMOUNT', $request->amount * 100); // Amount in cents $redsys->setParameter('DS_MERCHANT_ORDER', $order_number); $redsys->setParameter('DS_MERCHANT_MERCHANTCODE', $merchant_code); $redsys->setParameter('DS_MERCHANT_CURRENCY', '978'); // EUR $redsys->setParameter('DS_MERCHANT_TRANSACTIONTYPE', '0'); // Authorization $redsys->setParameter('DS_MERCHANT_TERMINAL', $terminal); $redsys->setParameter('DS_MERCHANT_MERCHANTURL', home_url('/?eb-redsys-callback=payment-request')); $redsys->setParameter('DS_MERCHANT_URLOK', home_url('/?eb_payment_success=' . $request->token)); $redsys->setParameter('DS_MERCHANT_URLKO', home_url('/?eb_payment_error=' . $request->token)); // Generate signature $signature = $redsys->createMerchantSignature($encryption_key); // Get Redsys URL $redsys_url = $test_mode ? 'https://sis-t.redsys.es:25443/sis/realizarPago' : 'https://sis.redsys.es/sis/realizarPago'; // Display payment form $this->display_payment_form($redsys_url, $redsys, $signature, $request); } /** * Display payment form */ private function display_payment_form($redsys_url, $redsys, $signature, $request) { ?> <?php _e('Payment Request - Hotel Raxa', 'informatiq-eb-redsys'); ?>

Hotel Raxa

Secure Payment Request

#booking_id; ?>

description ?: __('Hotel booking payment', 'informatiq-eb-redsys')); ?>

expires_at)); ?>

€amount, 2); ?>

prefix . 'eb_payment_requests'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE {$table_name} ( id int(11) NOT NULL AUTO_INCREMENT, booking_id int(11) NOT NULL, customer_email varchar(255) NOT NULL, amount decimal(10,2) NOT NULL, description text, token varchar(32) NOT NULL, payment_link text NOT NULL, status varchar(20) DEFAULT 'pending', created_at datetime NOT NULL, sent_at datetime, expires_at datetime NOT NULL, paid_at datetime, redsys_order varchar(20), redsys_auth_code varchar(20), PRIMARY KEY (id), UNIQUE KEY token (token), KEY booking_id (booking_id), KEY status (status), KEY expires_at (expires_at) ) {$charset_collate};"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta($sql); } /** * Process scheduled payment requests */ public function process_scheduled_payment_requests() { if (get_option('eb_redsys_auto_requests_enabled') !== '1') { return; } $days_before = intval(get_option('eb_redsys_days_before', 14)); $percentage = intval(get_option('eb_redsys_auto_percentage', 50)); // Get bookings that need payment requests global $wpdb; $target_date = date('Y-m-d', strtotime("+{$days_before} days")); $bookings = $wpdb->get_results($wpdb->prepare(" SELECT p.ID, p.post_title, pm1.meta_value as checkin_date, pm2.meta_value as customer_email, pm3.meta_value as total_price, pm4.meta_value as payment_status FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_eb_checkin_date' LEFT JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_eb_customer_email' LEFT JOIN {$wpdb->postmeta} pm3 ON p.ID = pm3.post_id AND pm3.meta_key = '_eb_total_price' LEFT JOIN {$wpdb->postmeta} pm4 ON p.ID = pm4.post_id AND pm4.meta_key = '_eb_payment_status' WHERE p.post_type = 'eagle_booking' AND p.post_status = 'publish' AND pm1.meta_value = %s AND pm4.meta_value = 'pending' ", $target_date)); foreach ($bookings as $booking) { // Check if payment request already sent $existing_request = $wpdb->get_var($wpdb->prepare(" SELECT id FROM {$wpdb->prefix}eb_payment_requests WHERE booking_id = %d AND status != 'failed' ", $booking->ID)); if ($existing_request) { continue; // Skip if already sent } // Calculate amount $amount = ($booking->total_price * $percentage) / 100; // Create payment request $description = sprintf( __('Payment for your stay at Hotel Raxa (Booking #%d) - %d%% of total amount', 'informatiq-eb-redsys'), $booking->ID, $percentage ); $request_id = $this->create_payment_request( $booking->ID, $booking->customer_email, $amount, $description, 72 // 3 days expiry ); if ($request_id) { $this->send_payment_request_email($request_id); } } } /** * Add payment request metabox to booking edit page */ public function add_booking_metabox() { add_meta_box( 'eb-payment-requests', __('Payment Requests', 'informatiq-eb-redsys'), array($this, 'booking_metabox_callback'), 'eagle_booking', 'side', 'default' ); } /** * Booking metabox callback */ public function booking_metabox_callback($post) { global $wpdb; $table_name = $wpdb->prefix . 'eb_payment_requests'; $requests = $wpdb->get_results($wpdb->prepare( "SELECT * FROM {$table_name} WHERE booking_id = %d ORDER BY created_at DESC", $post->ID )); ?>

€amount, 2); ?>

status); ?>

created_at)); ?>

expires_at)); ?>

status !== 'paid'): ?>

admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('payment_request_nonce'), 'strings' => array( 'confirmSend' => __('Are you sure you want to send this payment request?', 'informatiq-eb-redsys'), 'linkCopied' => __('Payment link copied to clipboard!', 'informatiq-eb-redsys'), 'copyFailed' => __('Failed to copy link. Please copy manually.', 'informatiq-eb-redsys') ) )); } } } // Initialize the class new EB_Redsys_Payment_Requests();