admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('wpdd-paypal-nonce'), 'mode' => $mode )); } public static function create_order() { check_ajax_referer('wpdd-paypal-nonce', 'nonce'); $product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0; if (!$product_id) { wp_send_json_error('Invalid product'); } $product = get_post($product_id); if (!$product || $product->post_type !== 'wpdd_product') { wp_send_json_error('Product not found'); } $price = get_post_meta($product_id, '_wpdd_price', true); $sale_price = get_post_meta($product_id, '_wpdd_sale_price', true); $final_price = ($sale_price && $sale_price < $price) ? $sale_price : $price; $order_data = array( 'intent' => 'CAPTURE', 'purchase_units' => array( array( 'reference_id' => 'wpdd_' . $product_id . '_' . time(), 'description' => substr($product->post_title, 0, 127), 'amount' => array( 'currency_code' => 'USD', 'value' => number_format($final_price, 2, '.', '') ) ) ), 'application_context' => array( 'brand_name' => get_bloginfo('name'), 'return_url' => add_query_arg('wpdd_paypal_return', '1', get_permalink(get_option('wpdd_thank_you_page_id'))), 'cancel_url' => add_query_arg('wpdd_paypal_cancel', '1', get_permalink(get_option('wpdd_checkout_page_id'))) ) ); $paypal_order = self::api_request('/v2/checkout/orders', $order_data, 'POST'); if (isset($paypal_order['id'])) { $_SESSION['wpdd_paypal_order_' . $paypal_order['id']] = array( 'product_id' => $product_id, 'amount' => $final_price, 'customer_email' => sanitize_email($_POST['customer_email'] ?? ''), 'customer_name' => sanitize_text_field($_POST['customer_name'] ?? '') ); wp_send_json_success(array('orderID' => $paypal_order['id'])); } else { wp_send_json_error('Failed to create PayPal order'); } } public static function capture_order() { check_ajax_referer('wpdd-paypal-nonce', 'nonce'); $paypal_order_id = isset($_POST['orderID']) ? sanitize_text_field($_POST['orderID']) : ''; if (!$paypal_order_id) { wp_send_json_error('Invalid order ID'); } $capture_response = self::api_request('/v2/checkout/orders/' . $paypal_order_id . '/capture', array(), 'POST'); if (isset($capture_response['status']) && $capture_response['status'] === 'COMPLETED') { $session_data = $_SESSION['wpdd_paypal_order_' . $paypal_order_id] ?? array(); // Add error logging for debugging session issues if (empty($session_data)) { error_log('WPDD PayPal Error: No session data found for PayPal order ' . $paypal_order_id); error_log('WPDD PayPal Debug: Session ID: ' . session_id()); error_log('WPDD PayPal Debug: Available sessions: ' . print_r($_SESSION ?? array(), true)); wp_send_json_error('Session data not found - order cannot be processed'); return; } $order_number = 'WPDD-' . strtoupper(uniqid()); global $wpdb; $customer_id = 0; $customer_email = $session_data['customer_email']; $customer_name = $session_data['customer_name']; if (is_user_logged_in()) { $current_user = wp_get_current_user(); $customer_id = $current_user->ID; $customer_email = $current_user->user_email; $customer_name = $current_user->display_name; } elseif (!empty($_POST['create_account']) && !empty($customer_email)) { $username = strstr($customer_email, '@', true) . '_' . wp_rand(1000, 9999); $password = wp_generate_password(); $user_id = wp_create_user($username, $password, $customer_email); if (!is_wp_error($user_id)) { $customer_id = $user_id; wp_update_user(array( 'ID' => $user_id, 'display_name' => $customer_name, 'first_name' => $customer_name )); $user = new WP_User($user_id); $user->set_role('wpdd_customer'); wp_new_user_notification($user_id, null, 'both'); } } $product = get_post($session_data['product_id']); $wpdb->insert( $wpdb->prefix . 'wpdd_orders', array( 'order_number' => $order_number, 'product_id' => $session_data['product_id'], 'customer_id' => $customer_id, 'creator_id' => $product->post_author, 'status' => 'completed', 'payment_method' => 'paypal', 'transaction_id' => $capture_response['id'], 'amount' => $session_data['amount'], 'currency' => 'USD', 'customer_email' => $customer_email, 'customer_name' => $customer_name, 'purchase_date' => current_time('mysql') ), array('%s', '%d', '%d', '%d', '%s', '%s', '%s', '%f', '%s', '%s', '%s', '%s') ); $order_id = $wpdb->insert_id; self::generate_download_link($order_id); self::send_purchase_email($order_id); update_post_meta($session_data['product_id'], '_wpdd_sales_count', intval(get_post_meta($session_data['product_id'], '_wpdd_sales_count', true)) + 1); unset($_SESSION['wpdd_paypal_order_' . $paypal_order_id]); wp_send_json_success(array( 'redirect_url' => add_query_arg( 'order_id', $order_number, get_permalink(get_option('wpdd_thank_you_page_id')) ) )); } else { wp_send_json_error('Payment capture failed'); } } private static function api_request($endpoint, $data = array(), $method = 'GET') { $mode = get_option('wpdd_paypal_mode', 'sandbox'); $client_id = get_option('wpdd_paypal_client_id'); $secret = get_option('wpdd_paypal_secret'); if (!$client_id || !$secret) { return false; } $base_url = $mode === 'live' ? 'https://api.paypal.com' : 'https://api.sandbox.paypal.com'; $auth = base64_encode($client_id . ':' . $secret); $args = array( 'method' => $method, 'headers' => array( 'Authorization' => 'Basic ' . $auth, 'Content-Type' => 'application/json' ), 'timeout' => 30 ); if (!empty($data)) { $args['body'] = json_encode($data); } $response = wp_remote_request($base_url . $endpoint, $args); if (is_wp_error($response)) { return false; } $body = wp_remote_retrieve_body($response); return json_decode($body, true); } private static function generate_download_link($order_id) { global $wpdb; $token = wp_hash(uniqid() . $order_id . time()); $expires_at = date('Y-m-d H:i:s', strtotime('+7 days')); $wpdb->insert( $wpdb->prefix . 'wpdd_download_links', array( 'order_id' => $order_id, 'token' => $token, 'expires_at' => $expires_at, 'max_downloads' => 5, 'created_at' => current_time('mysql') ), array('%d', '%s', '%s', '%d', '%s') ); return $token; } private static function send_purchase_email($order_id) { global $wpdb; $order = $wpdb->get_row($wpdb->prepare( "SELECT o.*, p.post_title as product_name, dl.token FROM {$wpdb->prefix}wpdd_orders o LEFT JOIN {$wpdb->posts} p ON o.product_id = p.ID LEFT JOIN {$wpdb->prefix}wpdd_download_links dl ON o.id = dl.order_id WHERE o.id = %d", $order_id )); if (!$order) { return; } $download_url = add_query_arg(array( 'wpdd_download_token' => $order->token ), home_url()); $subject = sprintf(__('Your Purchase from %s', 'wp-digital-download'), get_bloginfo('name')); $message = sprintf( __("Hi %s,\n\nThank you for your purchase!\n\n", 'wp-digital-download'), $order->customer_name ); $message .= sprintf(__("Order Number: %s\n", 'wp-digital-download'), $order->order_number); $message .= sprintf(__("Product: %s\n", 'wp-digital-download'), $order->product_name); $message .= sprintf(__("Amount: $%s\n\n", 'wp-digital-download'), number_format($order->amount, 2)); $message .= __("Download your product here:\n", 'wp-digital-download'); $message .= $download_url . "\n\n"; $message .= __("This download link will expire in 7 days.\n\n", 'wp-digital-download'); $message .= sprintf(__("Best regards,\n%s", 'wp-digital-download'), get_bloginfo('name')); wp_mail($order->customer_email, $subject, $message); } }