diff --git a/plugins/fipfcard_plugin/fipfcard_plugin.php b/plugins/fipfcard_plugin/fipfcard_plugin.php index 6154d57..b3d25e5 100644 --- a/plugins/fipfcard_plugin/fipfcard_plugin.php +++ b/plugins/fipfcard_plugin/fipfcard_plugin.php @@ -39,6 +39,7 @@ inclusions include_once(PLGNTLS_class::get_path() . '/php/utils/globals.php'); include_once(PLGNTLS_class::get_path() . '/php/utils/console_log.php'); include_once(PLGNTLS_class::get_path() . '/php/menu/example_menu.php'); +include_once(PLGNTLS_class::get_path() . '/php/paypal/paypal.php'); //include_once(PLGNTLS_class::get_path() . '/php/images/image_edit_shortcode.php'); //include_once(PLGNTLS_class::get_path() . '/php/images/image-edit.php'); @@ -162,6 +163,7 @@ add_shortcode('custom_frontend_posting_form', 'custom_frontend_posting_form'); +/* function check_paypal_request() { error_log("----"); @@ -181,29 +183,25 @@ function check_paypal_request() // error_log(json_encode($_COOKIE)); } add_action('template_redirect', 'check_paypal_request'); +*/ function paypal_shortcode_content() { $fipfcard_paypal = new PLGNTLS_class(); /* - */ - $pp_live_client_id = "Aedn5e8z__hPBvKirqw5bwlhI9ChG8_N6c1xbgybYyBr4B4oP8uVzmVdH1QVKdPQKf6bWg7orPV4PDrO"; - $pp_sandbox_client_id = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl"; - $pp_client_id = $pp_live_client_id; - $pp_client_id = $pp_sandbox_client_id; $pp_sdk_currency = "EUR"; $pp_sdk_debug = "true"; $pp_sdk_base_url="https://sandbox.paypal.com"; $pp_sdk_base_url="https://www.paypal.com"; - $pp_sdk_client_token="abc123xyz=="; - $pp_sdk_src="$pp_sdk_base_url/sdk/js?client-id=$pp_client_id¤cy=$pp_sdk_currency&debug=$pp_sdk_debug"; - $pp_sdk_src="$pp_sdk_base_url/sdk/js?client-id=$pp_client_id"; - $pp_sdk_attributes="src='$pp_sdk_src' data-client-token='$pp_sdk_client_token'"; - $pp_sdk_attributes="src='$pp_sdk_src'"; - $pp_sdk_html_script=""; +// $pp_sdk_client_token="abc123xyz=="; + $pp_sdk_src="$pp_sdk_base_url/sdk/js?client-id=" . PAYPAL_CLIENT_ID . "¤cy=$pp_sdk_currency&debug=$pp_sdk_debug"; + $pp_sdk_src="$pp_sdk_base_url/sdk/js?client-id=" . PAYPAL_CLIENT_ID ; +// $pp_sdk_attributes="src='$pp_sdk_src' data-client-token='$pp_sdk_client_token'"; +// $pp_sdk_attributes="src='$pp_sdk_src'"; +// $pp_sdk_html_script=""; return $fipfcard_paypal->add_to_front( array( @@ -211,8 +209,6 @@ function paypal_shortcode_content() "js/paypal/paypal.js", "html/paypal/paypal.html", ), - compact( - ), ); } add_shortcode('fipf_paypal_shortcode', 'paypal_shortcode_content'); @@ -493,5 +489,4 @@ function fipfcard_ajax_handler() } add_action( 'wp_ajax_get_data', 'fipfcard_ajax_handler' ); - ?> diff --git a/plugins/fipfcard_plugin/js/menu/example_menu.js b/plugins/fipfcard_plugin/js/menu/example_menu.js index d02b6dc..8c9dc06 100644 --- a/plugins/fipfcard_plugin/js/menu/example_menu.js +++ b/plugins/fipfcard_plugin/js/menu/example_menu.js @@ -5,14 +5,18 @@ sendButton.addEventListener('click', () => { const inputValue = inputElement.value; console.log("inputValue:"); console.log(inputValue); - PLGNTLS_ajax(inputValue, 'get_data') - .then((response) => response.json()) - .then((data) => { - console.log("dataaa: "); - console.log(data); - }) - .catch((error) => { - console.log("error: "); - console.log(error); - }); + //PLGNTLS_ajax('get_data', inputValue) + PLGNTLS_fetch('get_data', { + body: {inputValue}, + }) + .then((response) => response.json()) + .then((data) => { + console.log("dataaa: "); + console.log(data); + }) + .catch((error) => { + console.log("error: "); + console.log(error); + }); }); + diff --git a/plugins/fipfcard_plugin/js/paypal/paypal.js b/plugins/fipfcard_plugin/js/paypal/paypal.js index 6caf1bf..3ead6df 100644 --- a/plugins/fipfcard_plugin/js/paypal/paypal.js +++ b/plugins/fipfcard_plugin/js/paypal/paypal.js @@ -30,6 +30,7 @@ paypal.Buttons({ }).render('#paypal-button-container'); */ +/* paypal.Buttons({ style: { layout: 'vertical', @@ -61,4 +62,106 @@ paypal.Buttons({ } }).render('#paypal-button-container'); //This function displays Smart Payment Buttons on your web page. +*/ + + +window.paypal.Buttons({ + //createOrder: function(data, actions) { + createOrder: function() { + PLGNTLS_fetch("paypal_orders", { + //method: "POST", + //headers: {"Content-Type": "application/json"}, + //body: { + body: JSON.stringify({ + cart: [ + { + id: "YOUR_PRODUCT_ID", + quantity: "YOUR_PRODUCT_QUANTITY", + }, + ], + }), + }) + .then((response) => response.json()) + .then((orderData) => + { + console.log("orderData:"); + console.log(orderData); + if (orderData.id) + return orderData.id; + else + { + const errorDetail = orderData?.details?.[0]; + const errorMessage = errorDetail + ? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})` + : JSON.stringify(orderData); + + throw new Error(errorMessage); + } + }) + .catch((error) => { + console.error(error); + resultMessage(`Could not initiate PayPal Checkout...

${error}`); + }) + }, + +/* + + async onApprove(data, actions) { + try { + const response = await fetch(`/api/orders/${data.orderID}/capture`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + }); + + const orderData = await response.json(); + // Three cases to handle: + // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart() + // (2) Other non-recoverable errors -> Show a failure message + // (3) Successful transaction -> Show confirmation or thank you message + + const errorDetail = orderData?.details?.[0]; + + if (errorDetail?.issue === "INSTRUMENT_DECLINED") { + // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart() + // recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/ + return actions.restart(); + } else if (errorDetail) { + // (2) Other non-recoverable errors -> Show a failure message + throw new Error(`${errorDetail.description} (${orderData.debug_id})`); + } else if (!orderData.purchase_units) { + throw new Error(JSON.stringify(orderData)); + } else { + // (3) Successful transaction -> Show confirmation or thank you message + // Or go to another URL: actions.redirect('thank_you.html'); + const transaction = + orderData?.purchase_units?.[0]?.payments?.captures?.[0] || + orderData?.purchase_units?.[0]?.payments?.authorizations?.[0]; + resultMessage( + `Transaction ${transaction.status}: ${transaction.id}

See console for all available details`, + ); + console.log( + "Capture result", + orderData, + JSON.stringify(orderData, null, 2), + ); + } + } catch (error) { + console.error(error); + resultMessage( + `Sorry, your transaction could not be processed...

${error}`, + ); + } + }, +*/ +}) +.render("#paypal-button-container"); + +// Example function to show a result to the user. Your site's UI library can be used instead. +function resultMessage(message) { + const container = document.querySelector("#result-message"); + container.innerHTML = message; +} + diff --git a/plugins/fipfcard_plugin/php/paypal/paypal.php b/plugins/fipfcard_plugin/php/paypal/paypal.php new file mode 100644 index 0000000..2b53fb2 --- /dev/null +++ b/plugins/fipfcard_plugin/php/paypal/paypal.php @@ -0,0 +1,168 @@ +cart; + error_log( "cart" ); + error_log( json_encode( $cart ) ); + create_order($cart); + + wp_send_json_success( + array( + 'from paypal_order', + "data_received" => $data_received, + ), + 200 + ); +} +add_action( 'wp_ajax_paypal_orders', 'fipfcard_paypal_order' ); + + + + + + +/** + * Generate an OAuth 2.0 access token for authenticating with PayPal REST APIs. + * @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend + * @see https://developer.paypal.com/api/rest/authentication/ + */ +function generate_access_token( ) +{ + $base = "https://api-m.sandbox.paypal.com"; + + try { + if ( !PAYPAL_CLIENT_ID || !PAYPAL_CLIENT_SECRET ) { + throw new Error( "MISSING_API_CREDENTIALS" ); + } + $credentials = PAYPAL_CLIENT_ID . ":" . PAYPAL_CLIENT_SECRET; + $auth = base64_encode($credentials); + + $url = $base . '/v1/oauth2/token'; + $body = http_build_query(array('grant_type' => 'client_credentials')); + // Initialize curl + $ch = curl_init(); + // Set curl options + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + 'Authorization: Basic ' . $auth, + )); + // Execute curl and get the response + $data_json = curl_exec($ch); + + if ( $data_json === false) + throw new Error('cURL error: ' . curl_error($ch)); + // Close curl + curl_close($ch); + + $data = json_decode($data_json); + + return $data->access_token; + } + catch (Throwable $error) { + error_log("Failed to generate Access Token:"); + error_log($error->getMessage()); + } +}; +/* +*/ + + + +/** + * Create an order to start the transaction. + * @see https://developer.paypal.com/docs/api/orders/v2/#orders_create + */ + +function create_order( $cart ) +{ + + // use the cart information passed from the front-end to calculate the purchase unit details + + $access_token = generate_access_token(); + error_log("access_token:"); + error_log($access_token); + +/* + + + const url = `${base}/v2/checkout/orders`; + + const payload = { + + intent: "CAPTURE", + + purchase_units: [ + + { + + amount: { + + currency_code: "USD", + + value: "100.00", + + }, + + }, + + ], + + }; + + + + const response = await fetch(url, { + + headers: { + + "Content-Type": "application/json", + + Authorization: `Bearer ${accessToken}`, + + // Uncomment one of these to force an error for negative testing (in sandbox mode only). Documentation: + + // https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/ + + // "PayPal-Mock-Response": '{"mock_application_codes": "MISSING_REQUIRED_PARAMETER"}' + + // "PayPal-Mock-Response": '{"mock_application_codes": "PERMISSION_DENIED"}' + + // "PayPal-Mock-Response": '{"mock_application_codes": "INTERNAL_SERVER_ERROR"}' + + }, + + method: "POST", + + body: JSON.stringify(payload), + + }); + + + + return handleResponse(response); + +*/ +}; + + + +?> diff --git a/plugins/fipfcard_plugin/php/utils/console_log.php b/plugins/fipfcard_plugin/php/utils/console_log.php index 151aab6..bf18325 100644 --- a/plugins/fipfcard_plugin/php/utils/console_log.php +++ b/plugins/fipfcard_plugin/php/utils/console_log.php @@ -4,12 +4,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * https://stackify.com/how-to-log-to-console-in-php/ */ -function console_log($output) { +function console_log(...$outputs) { if (FIPFCARD_CONSOLE_OFF) return; - $json_output = json_encode($output, JSON_HEX_TAG); - $js_code = ''; - echo $js_code; + foreach($outputs as $output) + { + $json_output = json_encode($output, JSON_HEX_TAG); + $js_code = ''; + echo $js_code; + } } diff --git a/plugins/fipfcard_plugin/php/utils/globals.php b/plugins/fipfcard_plugin/php/utils/globals.php index 14260f2..faafd95 100644 --- a/plugins/fipfcard_plugin/php/utils/globals.php +++ b/plugins/fipfcard_plugin/php/utils/globals.php @@ -11,12 +11,28 @@ const CONSOLE_OFF = true; */ const FIPFCARD_CONSOLE_OFF = false; -/* a variable that will contain the name of the first script enqueued -*/ +/** + * a variable that will contain the name of the first script enqueued + */ $fipfcard_first_script = null; -/* path to ajax.js file, from root of js dir -*/ + +/** + * path to ajax.js file, from root of js dir + */ $fipfcard_ajax_file = "utils/ajax.js"; + +/** + * + * LIVE : +const PAYPAL_CLIENT_ID = "Aedn5e8z__hPBvKirqw5bwlhI9ChG8_N6c1xbgybYyBr4B4oP8uVzmVdH1QVKdPQKf6bWg7orPV4PDrO"; +const PAYPAL_CLIENT_SECRET = "EGeGwfHGxHxsjnC-tH8W0IL4nN3_xlc3sXFRPCQOw5uUoWae3eOgghuDKMnZc5DVGTbP6yIjVJ1BaAra"; + * SANBOX : +const PAYPAL_CLIENT_ID = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl"; +const PAYPAL_CLIENT_SECRET = "EGunIhGRjPvn0Z8wXO0JsdhET30OStTAH_IyRsmhimEN23_qiRSFD-ql4tvnulKJw6TitZ-vU-ytc4A-"; + */ +const PAYPAL_CLIENT_ID = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl"; +const PAYPAL_CLIENT_SECRET = "EGunIhGRjPvn0Z8wXO0JsdhET30OStTAH_IyRsmhimEN23_qiRSFD-ql4tvnulKJw6TitZ-vU-ytc4A-"; + ?> diff --git a/plugins/fipfcard_plugin/utils/plugin_ajax.js b/plugins/fipfcard_plugin/utils/plugin_ajax.js index 9b6762c..d80b7ec 100644 --- a/plugins/fipfcard_plugin/utils/plugin_ajax.js +++ b/plugins/fipfcard_plugin/utils/plugin_ajax.js @@ -3,9 +3,12 @@ * - PLGNTLS_data.ajax_nonce and PLGNTLS_data.ajax_url * are passed from the class PLGNTLS_class */ + +/* +// OLD VERSION console.log("PLGNTLS_data"); console.log(PLGNTLS_data); -function PLGNTLS_ajax(data_obj, action) { +function PLGNTLS_ajax(action, data_obj) { const data = new FormData(); data.append("action", action); data.append("_ajax_nonce", PLGNTLS_data.ajax_nonce); @@ -15,6 +18,101 @@ function PLGNTLS_ajax(data_obj, action) { return fetch(PLGNTLS_data.ajax_url, { method: "POST", credentials: "same-origin", - body: data + body: data, }); } +*/ + +// https://stackoverflow.com/q/52657814/9497573 +function is_plain_object(obj) +{ + if (!obj) + return false; + if (obj.constructor !== Object) + return false; + if (Object.getPrototypeOf(obj) !== Object.prototype) + return false; + return true; +} + +function PLGNTLS_fetch(src = null, options = null) +{ + if (src === null) + return null; + if (options === null) + { + const data = new FormData(); + data.append('action', src); + data.append('_ajax_nonce', PLGNTLS_data.ajax_nonce); + + options = { + method: 'POST', + credentials: 'same-origin', + body: data, + }; + } + else if (is_plain_object(options)) + { + // check for method, default POST + if (!Object.hasOwn(options, 'method')) + options.method = 'POST'; + // check for credentials, default same-origin + if (!Object.hasOwn(options, 'credentials')) + options.credentials = 'same-origin'; + + // check for body, default contains action and nonce + if (!Object.hasOwn(options, 'body')) + options.body = new FormData(); + // add action and nonce in options.body + if (options.body instanceof FormData) + { + // dont check if action and nonce already exist, need new anyway + options.body.set('action', src); + options.body.set('_ajax_nonce', PLGNTLS_data.ajax_nonce); + } + else + { + // should think a better strategy : https://stackoverflow.com/q/20295080/9497573 + // const data = {}; + // if (is_plain_object(options.body)) + // { + // for (const key in options.body) + // data[key] = options.body[key]; + // } + // else + // data.data = options.body; + // data.action = src; + // data._ajax_nonce = PLGNTLS_data.ajax_nonce; + // options.body = JSON.stringify(data); + + // cannot work if fetch use : + // headers: {"Content-Type": "application/json"}, + const data = new FormData( ); + data.append( 'action', src ); + data.append( '_ajax_nonce', PLGNTLS_data.ajax_nonce ); + if ( is_plain_object( options.body ) ) + { + console.log( "1" ); + for ( const key in options.body ) + data.append( key, JSON.stringify(options.body[key]) ); + } + // is string : https://stackoverflow.com/q/4059147/9497573 + else if ( typeof options.body === 'string' || options.body instanceof String ) + { + console.log( "2" ); + data.append( 'data', options.body ); + } + else + { + console.log( "3" ); + data.append('data', JSON.stringify(options.body)); + } + options.body = data; + } + } + else + throw new Error('options not plain object or formData'); + + console.log("options: ", options); + return fetch(PLGNTLS_data.ajax_url, options); +} diff --git a/plugins/fipfcard_plugin/utils/plugin_tools.php b/plugins/fipfcard_plugin/utils/plugin_tools.php index 9a0f95d..0febca2 100644 --- a/plugins/fipfcard_plugin/utils/plugin_tools.php +++ b/plugins/fipfcard_plugin/utils/plugin_tools.php @@ -54,10 +54,13 @@ class PLGNTLS_class public function add_to_front($scripts_arr = null, $vars = null) { if (!is_null($scripts_arr)) { + console_log("in is null scripts_arr"); // add ajax file at beginning of files list array_unshift($scripts_arr, "utils/plugin_ajax.js"); $nonce = array("ajax_nonce" => wp_create_nonce('wp-pageviews-nonce')); $url = array("ajax_url" => admin_url('admin-ajax.php')); + if (!is_array($vars)) + $vars = array(); $vars = array_merge($vars, $nonce); $vars = array_merge($vars, $url); } @@ -68,6 +71,9 @@ class PLGNTLS_class } if (!is_null($scripts_arr)) $this->add_scripts_to_front($scripts); + + console_log("vars:"); + console_log($vars); if (!is_null($vars)) $this->add_vars_to_front($vars); return $this->create_html($scripts, $vars); @@ -248,8 +254,6 @@ class PLGNTLS_class else $script->basename = pathinfo($script_name, PATHINFO_BASENAME); $script->handle = "PLGNTLS_" . str_replace(".", "_", $script->basename); - console_log("script->handle:"); - console_log($script->handle); if ($script->ext === "url") { $script->url = $script_name; diff --git a/private b/private index 42499ed..d4c3e0c 160000 --- a/private +++ b/private @@ -1 +1 @@ -Subproject commit 42499ed5b473b3a849c7f26d9152f295ee9b239c +Subproject commit d4c3e0c142cc62c878e97fbc5d3c7633688c48df