302 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			302 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
if (!defined('ABSPATH')) {
 | 
						|
    exit;
 | 
						|
}
 | 
						|
 | 
						|
class WPDD_PayPal {
 | 
						|
    
 | 
						|
    public static function init() {
 | 
						|
        add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_paypal_sdk'));
 | 
						|
        add_action('wp_ajax_wpdd_create_paypal_order', array(__CLASS__, 'create_order'));
 | 
						|
        add_action('wp_ajax_nopriv_wpdd_create_paypal_order', array(__CLASS__, 'create_order'));
 | 
						|
        add_action('wp_ajax_wpdd_capture_paypal_order', array(__CLASS__, 'capture_order'));
 | 
						|
        add_action('wp_ajax_nopriv_wpdd_capture_paypal_order', array(__CLASS__, 'capture_order'));
 | 
						|
    }
 | 
						|
    
 | 
						|
    public static function enqueue_paypal_sdk() {
 | 
						|
        if (!is_page(get_option('wpdd_checkout_page_id'))) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        
 | 
						|
        $client_id = get_option('wpdd_paypal_client_id');
 | 
						|
        $mode = get_option('wpdd_paypal_mode', 'sandbox');
 | 
						|
        
 | 
						|
        if (!$client_id) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        
 | 
						|
        wp_enqueue_script(
 | 
						|
            'paypal-sdk',
 | 
						|
            'https://www.paypal.com/sdk/js?client-id=' . $client_id . '¤cy=USD',
 | 
						|
            array(),
 | 
						|
            null,
 | 
						|
            true
 | 
						|
        );
 | 
						|
        
 | 
						|
        wp_enqueue_script(
 | 
						|
            'wpdd-paypal',
 | 
						|
            WPDD_PLUGIN_URL . 'assets/js/paypal.js',
 | 
						|
            array('jquery', 'paypal-sdk'),
 | 
						|
            WPDD_VERSION,
 | 
						|
            true
 | 
						|
        );
 | 
						|
        
 | 
						|
        wp_localize_script('wpdd-paypal', 'wpdd_paypal', array(
 | 
						|
            'ajax_url' => 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);
 | 
						|
    }
 | 
						|
} |