wip upgrade and clean payment process
This commit is contained in:
@@ -2,42 +2,39 @@
|
|||||||
import { resultMessage } from './result_message.js';
|
import { resultMessage } from './result_message.js';
|
||||||
import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js';
|
import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js';
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
//async function createOrder() {
|
|
||||||
export async function createOrder() {
|
export async function createOrder() {
|
||||||
try {
|
try {
|
||||||
//const fetch_create_url = PLGNTLS_data.fetch_url + "/cipf_plugin/api/v1/orders";
|
|
||||||
//console.log("fetch_create_url:", fetch_create_url);
|
|
||||||
//const response = await fetch(fetch_create_url, {
|
|
||||||
const response = await PLGNTLS_fetch('/cipf_plugin/api/v1/orders', {
|
const response = await PLGNTLS_fetch('/cipf_plugin/api/v1/orders', {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
//// use the "body" param to optionally pass additional order information
|
|
||||||
//// like product ids and quantities
|
|
||||||
//body: JSON.stringify({
|
|
||||||
// cart: [
|
|
||||||
// {
|
|
||||||
// id: "1234",
|
|
||||||
// quantity: "1",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
//}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const orderData = await response.json();
|
const orderData = await response.json();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* is it necessary since the error is catched according to the presence of id ?
|
||||||
|
* -> i think yes, because we want to know the type of http error, right ?
|
||||||
|
* -> actually the http error code will be shown in the console anyway, so...
|
||||||
|
*
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok : ' + orderData.data.status + ' message : ' + orderData.message);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (orderData.id) {
|
if (orderData.id) {
|
||||||
return orderData.id;
|
return orderData.id;
|
||||||
} else {
|
}
|
||||||
|
else { // throw an error
|
||||||
const errorDetail = orderData?.details?.[0];
|
const errorDetail = orderData?.details?.[0];
|
||||||
const errorMessage = errorDetail
|
const errorMessage = errorDetail
|
||||||
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
|
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
|
||||||
: JSON.stringify(orderData);
|
: JSON.stringify(orderData);
|
||||||
|
|
||||||
throw new Error(errorMessage);
|
throw new Error(errorMessage);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -2,24 +2,22 @@
|
|||||||
import { resultMessage } from './result_message.js';
|
import { resultMessage } from './result_message.js';
|
||||||
import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js';
|
import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js';
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
//async function onApprove(data, actions) {
|
|
||||||
export async function onApprove(data, actions) {
|
export async function onApprove(data, actions) {
|
||||||
try {
|
try {
|
||||||
const fetch_approve_url = PLGNTLS_data.fetch_url + "/cipf_plugin/api/v1/orders/" + data.orderID + "/capture";
|
const fetch_approve_url = PLGNTLS_data.fetch_url + "/cipf_plugin/api/v1/orders/" + data.orderID + "/capture";
|
||||||
console.log("fetch_approve_url:", fetch_approve_url);
|
|
||||||
//const response = await fetch(fetch_approve_url, {
|
|
||||||
const response = await PLGNTLS_fetch('/cipf_plugin/api/v1/orders/' + data.orderID + '/capture', {
|
const response = await PLGNTLS_fetch('/cipf_plugin/api/v1/orders/' + data.orderID + '/capture', {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
//"X-WP-Nonce": PLGNTLS_data.rest_nonce,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const orderData = await response.json();
|
const orderData = await response.json();
|
||||||
|
|
||||||
// Three cases to handle:
|
// Three cases to handle:
|
||||||
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
|
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
|
||||||
// (2) Other non-recoverable errors -> Show a failure message
|
// (2) Other non-recoverable errors -> Show a failure message
|
||||||
@@ -31,15 +29,15 @@ export async function onApprove(data, actions) {
|
|||||||
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
|
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
|
||||||
// recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
|
// recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
|
||||||
return actions.restart();
|
return actions.restart();
|
||||||
} else if (errorDetail) {
|
}
|
||||||
|
else if (errorDetail) {
|
||||||
// (2) Other non-recoverable errors -> Show a failure message
|
// (2) Other non-recoverable errors -> Show a failure message
|
||||||
console.log("errorDetail:");
|
|
||||||
console.log(errorDetail);
|
|
||||||
throw new Error(`${errorDetail.description} (${orderData.debug_id})`);
|
throw new Error(`${errorDetail.description} (${orderData.debug_id})`);
|
||||||
} else if (!orderData.purchase_units) {
|
}
|
||||||
|
else if (!orderData.purchase_units) {
|
||||||
throw new Error(JSON.stringify(orderData));
|
throw new Error(JSON.stringify(orderData));
|
||||||
} else {
|
}
|
||||||
try {
|
else {
|
||||||
// (3) Successful transaction -> Show confirmation or thank you message
|
// (3) Successful transaction -> Show confirmation or thank you message
|
||||||
// Or go to another URL: actions.redirect('thank_you.html');
|
// Or go to another URL: actions.redirect('thank_you.html');
|
||||||
const transaction =
|
const transaction =
|
||||||
@@ -48,15 +46,7 @@ export async function onApprove(data, actions) {
|
|||||||
// to show a message on page
|
// to show a message on page
|
||||||
//resultMessage(`Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`);
|
//resultMessage(`Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`);
|
||||||
resultMessage(eval(PLGNTLS_data.paypal_message_success));
|
resultMessage(eval(PLGNTLS_data.paypal_message_success));
|
||||||
console.log(
|
|
||||||
"Capture result",
|
|
||||||
orderData,
|
|
||||||
JSON.stringify(orderData, null, 2),
|
|
||||||
);
|
|
||||||
actions.redirect(PLGNTLS_data.paypal_redirection_success);
|
actions.redirect(PLGNTLS_data.paypal_redirection_success);
|
||||||
} catch (error) {
|
|
||||||
console.error("payment ok but error on traitment afterwards : ", error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -66,49 +56,3 @@ export async function onApprove(data, actions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see https://developer.paypal.com/demo/checkout/#/pattern/server
|
|
||||||
*
|
|
||||||
// Call your server to finalize the transaction
|
|
||||||
function onApprove (data, actions) {
|
|
||||||
const fetch_approve_url = PLGNTLS_data.fetch_url + "/cipf_plugin/api/v1/orders/" + data.orderID + "/capture";
|
|
||||||
console.log("fetch_approve_url:", fetch_approve_url);
|
|
||||||
return fetch(fetch_approve_url, {
|
|
||||||
method: 'post'
|
|
||||||
}).then(function(res) {
|
|
||||||
return res.json();
|
|
||||||
}).then(function(orderData) {
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// This example reads a v2/checkout/orders capture response, propagated from the server
|
|
||||||
// You could use a different API or structure for your 'orderData'
|
|
||||||
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
|
|
||||||
|
|
||||||
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
|
|
||||||
return actions.restart(); // Recoverable state, per:
|
|
||||||
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorDetail) {
|
|
||||||
var msg = 'Sorry, your transaction could not be processed.';
|
|
||||||
if (errorDetail.description) msg += '\n\n' + errorDetail.description;
|
|
||||||
if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
|
|
||||||
return alert(msg); // Show a failure message (try to avoid alerts in production environments)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Successful capture! For demo purposes:
|
|
||||||
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
|
|
||||||
var transaction = orderData.purchase_units[0].payments.captures[0];
|
|
||||||
alert('Transaction '+ transaction.status + ': ' + transaction.id + '\n\nSee console for all available details');
|
|
||||||
|
|
||||||
// Replace the above to show a success message within this page, e.g.
|
|
||||||
// const element = document.getElementById('paypal-button-container');
|
|
||||||
// element.innerHTML = '';
|
|
||||||
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
|
|
||||||
// Or go to another URL: actions.redirect('thank_you.html');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* it means someone outside wp is accessing the file, in this case kill it.
|
* it means someone outside wp is accessing the file, in this case kill it.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
if (!defined('ABSPATH')) {
|
if (!defined('ABSPATH')) {
|
||||||
die('You can not access this file!');
|
die('You can not access this file!');
|
||||||
@@ -9,52 +10,96 @@ if (!defined('ABSPATH')) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
|
* this function runs before the paiement, it initiate the order
|
||||||
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
||||||
|
*
|
||||||
|
* in this function and the insides functions,
|
||||||
|
* explicit errors are thrown with HttpException,
|
||||||
|
* otherwise it's an unexpected error to catch with Exception
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
function handle_orders_request_CIPF($request_data) {
|
function handle_orders_request_CIPF($request_data) {
|
||||||
|
|
||||||
|
// declaring outside the try..catch scope
|
||||||
|
$order_response = array();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* - check if user can pay, according to conditions
|
||||||
|
* - process the order and get the response
|
||||||
|
* if it fails here : the order was not created
|
||||||
|
*
|
||||||
|
*/
|
||||||
try {
|
try {
|
||||||
// Extract cart information from request body
|
$can_pay = check_can_pay_CIPF();
|
||||||
//$cart = $request_data['cart'];
|
if (is_wp_error($can_pay))
|
||||||
|
throw new HttpException('not allowed to pay : ' . $can_pay->get_error_message(), 403);
|
||||||
|
|
||||||
$can_pay = can_pay_now_CIPF();
|
|
||||||
if ($can_pay['success'] === false)
|
|
||||||
throw new HttpErrorException($can_pay['message'], 403);
|
|
||||||
|
|
||||||
// Process the order and get the response
|
|
||||||
//$order_response = create_order_CIPF($cart);
|
|
||||||
$order_response = create_order_CIPF();
|
$order_response = create_order_CIPF();
|
||||||
$json_response = $order_response['json_response'];
|
$json_response = $order_response['json_response'];
|
||||||
$http_status_code = $order_response['http_status_code'];
|
$http_status_code = $order_response['http_status_code'];
|
||||||
|
|
||||||
update_user_payment_CIPF($json_response, 'start');
|
|
||||||
|
|
||||||
// Return response
|
|
||||||
return new WP_REST_Response($json_response, $http_status_code);
|
|
||||||
}
|
}
|
||||||
catch (HttpErrorException $error) {
|
catch (HttpException $error) {
|
||||||
$status_code = $error->getStatusCode();
|
$status_code = $error->getStatusCode();
|
||||||
return new WP_Error($status_code, 'Failed to create order in server :' . $error->getMessage(), array('status' => $status_code));
|
$message = 'Failed to create order in server :' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, $status_code);
|
||||||
}
|
}
|
||||||
catch (Exception $error) {
|
catch (Exception $error) {
|
||||||
return new WP_Error('500', 'Failed to create order in server :' . $error->getMessage(), array('status' => 500));
|
$message = 'Failed to create order in server :' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* - add infos of the initiated order into user profil
|
||||||
|
* - return the created order to the front
|
||||||
|
* if it fails here : the order was created in paypal
|
||||||
|
* but a pbm occured in treating it with the user
|
||||||
|
*
|
||||||
|
* order status : https://developer.paypal.com/docs/api/orders/v2/#orders_capture!c=201&path=status&t=response
|
||||||
|
* CREATED
|
||||||
|
* SAVED
|
||||||
|
* APPROVED ?
|
||||||
|
* VOIDED
|
||||||
|
* - COMPLETED
|
||||||
|
* PAYER_ACTION_REQUIRED
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
update_user_pre_order_CIPF($json_response, 'start');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* https://developer.wordpress.org/reference/classes/wp_rest_response/
|
||||||
|
* extends from https://developer.wordpress.org/reference/classes/wp_http_response/
|
||||||
|
* __construct( $data = null, $status = 200, $headers = array() )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
return new WP_REST_Response($json_response, $http_status_code);
|
||||||
|
}
|
||||||
|
catch (HttpException $error) {
|
||||||
|
$status_code = $error->getStatusCode();
|
||||||
|
$message = 'Order created, but failed in treatment :' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, $status_code);
|
||||||
|
}
|
||||||
|
catch (Exception $error) {
|
||||||
|
$message = 'Order created, but failed in treatment :' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Create an order to start the transaction.
|
* Create an order to start the transaction.
|
||||||
* @see https://developer.paypal.com/docs/api/orders/v2/#orders_create
|
* @see https://developer.paypal.com/docs/api/orders/v2/#orders_create
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
//function create_order_CIPF($cart)
|
|
||||||
function create_order_CIPF()
|
function create_order_CIPF()
|
||||||
{
|
{
|
||||||
$paypal_api_base_url = PLGNTLS_class::PAYPAL_API_BASE_URL;
|
$paypal_api_base_url = PLGNTLS_class::PAYPAL_API_BASE_URL;
|
||||||
|
|
||||||
// use the cart information passed from the front-end to calculate the purchase unit details
|
|
||||||
|
|
||||||
$access_token = generate_access_token_CIPF();
|
$access_token = generate_access_token_CIPF();
|
||||||
|
|
||||||
$user_id = get_current_user_id();
|
$user_id = get_current_user_id();
|
||||||
@@ -64,7 +109,6 @@ function create_order_CIPF()
|
|||||||
$url = $paypal_api_base_url . '/v2/checkout/orders';
|
$url = $paypal_api_base_url . '/v2/checkout/orders';
|
||||||
$payload = array(
|
$payload = array(
|
||||||
'intent' => "CAPTURE",
|
'intent' => "CAPTURE",
|
||||||
'note' => 'ERRPYO005',
|
|
||||||
'purchase_units' => array(
|
'purchase_units' => array(
|
||||||
array(
|
array(
|
||||||
'amount' => array(
|
'amount' => array(
|
||||||
@@ -94,15 +138,15 @@ function create_order_CIPF()
|
|||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
// Execute cURL session and get the response
|
// Execute cURL session and get the response
|
||||||
$response = curl_exec($ch);
|
$response_json = curl_exec($ch);
|
||||||
|
|
||||||
|
// in utils
|
||||||
|
$response = handle_json_response_CIPF($response_json, $ch);
|
||||||
|
|
||||||
if ($response === false)
|
|
||||||
throw new Exception('cURL error: ' . curl_error($ch));
|
|
||||||
// Close cURL session
|
// Close cURL session
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
// in utils
|
return $response;
|
||||||
return handle_response_CIPF($response);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,22 +12,60 @@ if (!defined('ABSPATH')) {
|
|||||||
|
|
||||||
function handle_orders_capture_request_CIPF($request) {
|
function handle_orders_capture_request_CIPF($request) {
|
||||||
$order_id = $request['orderID'];
|
$order_id = $request['orderID'];
|
||||||
|
// declaring outside the try..catch scope
|
||||||
|
$response_json = array();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ask paypal about the finished order
|
||||||
|
*
|
||||||
|
*/
|
||||||
try {
|
try {
|
||||||
// Implement captureOrder function logic here
|
$response_json = capture_order_cipf($order_id);
|
||||||
// Make sure you implement captureOrder function similar to the Node.js code
|
$http_status_code = $response_json['http_status_code'];
|
||||||
|
$json_response = $response_json['json_response'];
|
||||||
|
}
|
||||||
|
catch (HttpException $error) {
|
||||||
|
$status_code = $error->getStatusCode();
|
||||||
|
$message = 'Failed to capture order in server :' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, $status_code);
|
||||||
|
}
|
||||||
|
catch (Exception $error) {
|
||||||
|
$message = 'Failed to capture order in server : ' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, 500);
|
||||||
|
}
|
||||||
|
|
||||||
$response_data = capture_order_cipf($order_id);
|
|
||||||
$http_status_code = $response_data['http_status_code'];
|
|
||||||
$json_response = $response_data['json_response'];
|
|
||||||
|
|
||||||
update_user_payment_CIPF($json_response, 'end');
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* update the client situation
|
||||||
|
* and return the response of paypal
|
||||||
|
*
|
||||||
|
* order status : https://developer.paypal.com/docs/api/orders/v2/#orders_capture!c=201&path=status&t=response
|
||||||
|
* CREATED
|
||||||
|
* SAVED
|
||||||
|
* APPROVED ?
|
||||||
|
* VOIDED
|
||||||
|
* - COMPLETED
|
||||||
|
* PAYER_ACTION_REQUIRED
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
update_user_post_capture_CIPF($json_response, 'end');
|
||||||
|
|
||||||
return new WP_REST_Response($json_response, $http_status_code);
|
return new WP_REST_Response($json_response, $http_status_code);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (HttpException $error) {
|
||||||
return new WP_REST_Response(array('error' => 'Failed to capture order.'), 500);
|
$status_code = $error->getStatusCode();
|
||||||
|
$message = 'Failed to handle order after capture in server :' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, $status_code);
|
||||||
}
|
}
|
||||||
|
catch (Exception $error) {
|
||||||
|
$message = 'Failed to handle order after capture in server :' . $error->getMessage();
|
||||||
|
return new WP_REST_Response($message, 500);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,15 +96,15 @@ function capture_order_CIPF($order_id) {
|
|||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
|
||||||
// Execute cURL session and get the response
|
// Execute cURL session and get the response
|
||||||
$response = curl_exec($ch);
|
$response_json = curl_exec($ch);
|
||||||
|
|
||||||
|
// in utils
|
||||||
|
$response = handle_json_response_CIPF($response_json, $ch);
|
||||||
|
|
||||||
if ($response === false)
|
|
||||||
throw new Exception('cURL error: ' . curl_error($ch));
|
|
||||||
// Close cURL session
|
// Close cURL session
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
// in utils
|
return $response;
|
||||||
return handle_response_CIPF($response);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,28 @@ if (!defined('ABSPATH')) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
function handle_json_response_CIPF($response, $ch) {
|
||||||
|
if ($response === false)
|
||||||
|
throw new HttpException('cURL error: ' . curl_error($ch), 502);
|
||||||
|
|
||||||
|
// Decode JSON response
|
||||||
|
$json_response = json_decode($response);
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/2348152/detect-bad-json-data-in-php-json-decode
|
||||||
|
if ($json_response === null && json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
throw new HttpException('JSON decoding error: ' . json_last_error_msg(), 502);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return response data along with HTTP status code
|
||||||
|
return array(
|
||||||
|
'json_response' => $json_response,
|
||||||
|
'http_status_code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
|
||||||
|
);
|
||||||
|
}
|
||||||
function handle_response_CIPF($response) {
|
function handle_response_CIPF($response) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -30,22 +49,6 @@ function handle_response_CIPF($response) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
async function handleResponse(response) {
|
|
||||||
try {
|
|
||||||
const jsonResponse = await response.json();
|
|
||||||
return {
|
|
||||||
jsonResponse,
|
|
||||||
httpStatusCode: response.status,
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
const errorMessage = await response.text();
|
|
||||||
throw new Error(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -59,10 +62,13 @@ function generate_access_token_CIPF()
|
|||||||
$paypal_client_id = PLGNTLS_class::PAYPAL_CLIENT_ID;
|
$paypal_client_id = PLGNTLS_class::PAYPAL_CLIENT_ID;
|
||||||
$paypal_client_secret = PLGNTLS_class::PAYPAL_CLIENT_SECRET;
|
$paypal_client_secret = PLGNTLS_class::PAYPAL_CLIENT_SECRET;
|
||||||
$paypal_api_base_url = PLGNTLS_class::PAYPAL_API_BASE_URL;
|
$paypal_api_base_url = PLGNTLS_class::PAYPAL_API_BASE_URL;
|
||||||
|
|
||||||
|
/*
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
*/
|
||||||
if ( !$paypal_client_id || !$paypal_client_secret ) {
|
if ( !$paypal_client_id || !$paypal_client_secret ) {
|
||||||
throw new Exception( "MISSING_API_CREDENTIALS" );
|
throw new HttpException("MISSING_API_CREDENTIALS", 403);
|
||||||
}
|
}
|
||||||
$credentials = $paypal_client_id . ":" . $paypal_client_secret;
|
$credentials = $paypal_client_id . ":" . $paypal_client_secret;
|
||||||
$auth = base64_encode($credentials);
|
$auth = base64_encode($credentials);
|
||||||
@@ -79,11 +85,30 @@ function generate_access_token_CIPF()
|
|||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||||
'Authorization: Basic ' . $auth,
|
'Authorization: Basic ' . $auth,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
|
||||||
|
// Execute cURL session and get the response
|
||||||
|
$data_json = curl_exec($ch);
|
||||||
|
|
||||||
|
// in utils
|
||||||
|
$data = handle_json_response_CIPF($data_json, $ch);
|
||||||
|
|
||||||
|
// Close cURL session
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return $data['json_response']->access_token;
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
// Execute curl and get the response
|
// Execute curl and get the response
|
||||||
$data_json = curl_exec($ch);
|
$data_json = curl_exec($ch);
|
||||||
|
|
||||||
if ( $data_json === false)
|
if ( $data_json === false)
|
||||||
throw new Exception('cURL error: ' . curl_error($ch));
|
throw new Exception('cURL error: ' . curl_error($ch));
|
||||||
|
|
||||||
// Close curl
|
// Close curl
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
@@ -96,6 +121,7 @@ function generate_access_token_CIPF()
|
|||||||
error_log("Failed to generate Access Token:");
|
error_log("Failed to generate Access Token:");
|
||||||
error_log($error->getMessage());
|
error_log($error->getMessage());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -28,67 +28,94 @@ if (!defined('ABSPATH')) {
|
|||||||
* $del_ret = delete_user_meta('user_id', 'cipf_order_id', 'bbbbbb');
|
* $del_ret = delete_user_meta('user_id', 'cipf_order_id', 'bbbbbb');
|
||||||
* ['aaaaaa'] - $del_ret === false
|
* ['aaaaaa'] - $del_ret === false
|
||||||
*
|
*
|
||||||
* order status : https://developer.paypal.com/docs/api/orders/v2/#orders_capture!c=201&path=status&t=response
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function update_user_pre_order_CIPF($message) {
|
||||||
|
$meta_payement_status = PLGNTLS_class::META_PAYEMENT_STATUS;
|
||||||
|
|
||||||
|
$order_id = $message->id;
|
||||||
|
$user_id = get_current_user_id();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* - delete previous order ids
|
||||||
|
* ->if we are here it's because a new order will try to be created
|
||||||
|
* - addind order_id to cipf_order_id meta field
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
delete_user_meta($user_id, 'cipf_order_id');
|
||||||
|
add_user_meta($user_id, 'cipf_order_id', $order_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create a meta field to check states of payements on prof author page :
|
||||||
|
* - 'started' -> at order creation
|
||||||
|
* - 'success' -> at capture success (on author page, it means success, then make it empty)
|
||||||
|
* - 'failure' -> at capture failure (on author page, it means failure, then make it empty)
|
||||||
|
* - 'nothing' -> output nothing on author page
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
delete_user_meta($user_id, $meta_payement_status);
|
||||||
|
add_user_meta($user_id, $meta_payement_status, 'started');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function update_user_post_capture_CIPF($message) {
|
||||||
|
$meta_payement_status = PLGNTLS_class::META_PAYEMENT_STATUS;
|
||||||
|
|
||||||
|
$order_id = $message->id;
|
||||||
|
$user_id = get_current_user_id();
|
||||||
|
$status = null;
|
||||||
|
if (is_object($message) && isset($message->status))
|
||||||
|
$status = $message->status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* order status : https://developer.paypal.com/docs/api/orders/v2/#definition-order
|
||||||
* CREATED
|
* CREATED
|
||||||
* SAVED
|
* SAVED
|
||||||
* APPROVED ?
|
* APPROVED ?
|
||||||
* VOIDED
|
* VOIDED
|
||||||
* - COMPLETED
|
* - COMPLETED
|
||||||
* PAYER_ACTION_REQUIRED
|
* PAYER_ACTION_REQUIRED
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
function update_user_payment_CIPF($message, $step) {
|
|
||||||
$meta_payement_status = PLGNTLS_class::META_PAYEMENT_STATUS;
|
|
||||||
|
|
||||||
$order_id = $message->id;
|
|
||||||
$user_id = get_current_user_id();
|
|
||||||
$status = $message->status;
|
|
||||||
|
|
||||||
// addind order_id to cipf_order_id meta field
|
|
||||||
// it can duplicate, it's not a problem : delete_user_meta will delete all
|
|
||||||
add_user_meta($user_id, 'cipf_order_id', $order_id);
|
|
||||||
// add a schedule event to delete this order_id
|
|
||||||
schedule_delete_orderid_CIPF($user_id, $order_id);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create a meta field to check states of payements on prof author page :
|
* delete order_id and update user
|
||||||
* - 'started' -> payement started | at order creation (if seen on author page, it means failure)
|
* -> is it necessary to delete order_id since we delete it when creating a new order ?
|
||||||
* - 'success' -> success payement | at order success (on author page, it means success, then empty it)
|
* -> it is at least necessary to find the user who did the purchase
|
||||||
* - '' -> no message to output | on author page (after set to empty on author page)
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
delete_user_meta($user_id, $meta_payement_status);
|
|
||||||
add_user_meta($user_id, $meta_payement_status, 'started');
|
|
||||||
|
|
||||||
// if transaction is COMPLETED, then delete order_id and update user
|
|
||||||
if ($status === 'COMPLETED') {
|
|
||||||
// find the user containing the order_id and delete this order_id
|
// find the user containing the order_id and delete this order_id
|
||||||
$user_id_to_update = delete_order_id_on_success_CIPF($user_id, $order_id);
|
$user_id_to_update = delete_order_id_on_success_CIPF($user_id, $order_id);
|
||||||
// change payement status to success
|
if ($status === 'COMPLETED') {
|
||||||
update_user_meta($user_id_to_update, $meta_payement_status, 'success');
|
|
||||||
// proceed to validate payment for user
|
// proceed to validate payment for user
|
||||||
validate_payment_for_user_CIPF($user_id_to_update, $order_id);
|
validate_payment_for_user_CIPF($user_id_to_update, $order_id);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
failure_payement_for_user_CIPF($user_id_to_update, $order_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* things to do when a payment has failed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function failure_payment_for_user_CIPF($user_id, $order_id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* const CARD_IS_VALID : acf field 'true false' [carte_est_valide](validite)
|
* things to do when a payment is a success
|
||||||
* const CARD_DATE_PURCHASE : acf field 'date picker' [date_d_achat](achat)
|
|
||||||
* const CARD_DATE_VALIDITY : acf field 'date picker' [date_fin_validite](echance)
|
|
||||||
*
|
|
||||||
* - change CARD_IS_VALID to true
|
|
||||||
* - change CARD_DATE_PURCHASE to now
|
|
||||||
* - change CARD_DATE_VALIDITY to previous value + 1 year
|
|
||||||
*
|
|
||||||
* - create scheduled emails to inform of end of validity
|
|
||||||
*
|
|
||||||
* acf uses 'Y-m-d H:i:s' format :
|
|
||||||
* -> https://www.advancedcustomfields.com/resources/date-time-picker/
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function validate_payment_for_user_CIPF($user_id, $order_id) {
|
function validate_payment_for_user_CIPF($user_id, $order_id) {
|
||||||
@@ -97,11 +124,23 @@ function validate_payment_for_user_CIPF($user_id, $order_id) {
|
|||||||
$acf_prof_can_renew = PLGNTLS_class::ACF_PROF_CAN_RENEW;
|
$acf_prof_can_renew = PLGNTLS_class::ACF_PROF_CAN_RENEW;
|
||||||
$card_duration = PLGNTLS_class::CARD_VALIDITY_TIME;
|
$card_duration = PLGNTLS_class::CARD_VALIDITY_TIME;
|
||||||
$prof_is_activ = PLGNTLS_class::ACF_PROF_IS_ACTIV;
|
$prof_is_activ = PLGNTLS_class::ACF_PROF_IS_ACTIV;
|
||||||
|
$meta_payement_status = PLGNTLS_class::META_PAYEMENT_STATUS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* change payement status to success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
update_user_meta($user_id, $meta_payement_status, 'success');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* acf uses 'Y-m-d H:i:s' format : https://www.advancedcustomfields.com/resources/date-time-picker/
|
||||||
|
*
|
||||||
|
*/
|
||||||
$acf_date_format = 'Y-m-d H:i:s';
|
$acf_date_format = 'Y-m-d H:i:s';
|
||||||
$acf_id = 'user_'.$user_id;
|
$acf_id = 'user_'.$user_id;
|
||||||
|
|
||||||
$date_now = date_create('today');
|
$date_now = date_create('today');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* update purchase date to now
|
* update purchase date to now
|
||||||
*
|
*
|
||||||
@@ -114,7 +153,7 @@ function validate_payment_for_user_CIPF($user_id, $order_id) {
|
|||||||
* if paste date, use now
|
* if paste date, use now
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
$current_date_limit_object = get_field_object($acf_card_expiration, $acf_id);
|
$current_date_limit_object = get_field_object($acf_card_expiration['_name'], $acf_id);
|
||||||
|
|
||||||
if ($current_date_limit_object === false) {
|
if ($current_date_limit_object === false) {
|
||||||
$current_date_limit = $date_now;
|
$current_date_limit = $date_now;
|
||||||
@@ -142,7 +181,7 @@ function validate_payment_for_user_CIPF($user_id, $order_id) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
$date_plus_one_year = $current_date_limit->add(date_interval_create_from_date_string('+'.$card_duration));
|
$date_plus_one_year = $current_date_limit->add(date_interval_create_from_date_string('+'.$card_duration));
|
||||||
update_field($acf_card_expiration, $date_plus_one_year->format($acf_date_format), $acf_id);
|
update_field($acf_card_expiration['_name'], $date_plus_one_year->format($acf_date_format), $acf_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* change user profil :
|
* change user profil :
|
||||||
@@ -153,15 +192,13 @@ function validate_payment_for_user_CIPF($user_id, $order_id) {
|
|||||||
*/
|
*/
|
||||||
update_field($prof_is_activ['_name'], $prof_is_activ['activ'], $acf_id);
|
update_field($prof_is_activ['_name'], $prof_is_activ['activ'], $acf_id);
|
||||||
update_field($acf_card_state['_name'], $acf_card_state['renew'], $acf_id);
|
update_field($acf_card_state['_name'], $acf_card_state['renew'], $acf_id);
|
||||||
update_field($acf_prof_can_renew['_name'], $acf_prof_can_renew['cannot'] , $acf_id);
|
//update_field($acf_prof_can_renew['_name'], $acf_prof_can_renew['cannot'] , $acf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add a schedule event to delete this order_id
|
* add a schedule event to delete this order_id
|
||||||
* after 3 days ?
|
* after 3 days ?
|
||||||
@@ -170,22 +207,22 @@ function validate_payment_for_user_CIPF($user_id, $order_id) {
|
|||||||
* -> https://codex.wordpress.org/Easier_Expression_of_Time_Constants
|
* -> https://codex.wordpress.org/Easier_Expression_of_Time_Constants
|
||||||
* -> also strtotime : https://www.php.net/manual/en/function.strtotime.php
|
* -> also strtotime : https://www.php.net/manual/en/function.strtotime.php
|
||||||
*
|
*
|
||||||
*/
|
|
||||||
function schedule_delete_orderid_CIPF($user_id, $order_id)
|
function schedule_delete_orderid_CIPF($user_id, $order_id)
|
||||||
{
|
{
|
||||||
$delay = time() + MINUTE_IN_SECONDS;
|
$delay = time() + MINUTE_IN_SECONDS;
|
||||||
wp_schedule_single_event($delay, 'orderid_deletion_event_CIPF', array($user_id, $order_id));
|
wp_schedule_single_event($delay, 'orderid_deletion_event_CIPF', array($user_id, $order_id));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
* action hook for the scheduled event
|
* action hook for the scheduled event
|
||||||
* TODO: ne marche pas je ne sais pas pourquoi, pas urgent a resoudre
|
* TODO: ne marche pas je ne sais pas pourquoi, pas urgent a resoudre
|
||||||
*
|
*
|
||||||
*/
|
|
||||||
function delete_order_id_later_CIPF($user_id, $order_id)
|
function delete_order_id_later_CIPF($user_id, $order_id)
|
||||||
{
|
{
|
||||||
delete_user_meta($user_id, 'cipf_order_id', $order_id);
|
delete_user_meta($user_id, 'cipf_order_id', $order_id);
|
||||||
}
|
}
|
||||||
add_action('orderid_deletion_event_CIPF', 'delete_order_id_later_CIPF', 5, 2);
|
add_action('orderid_deletion_event_CIPF', 'delete_order_id_later_CIPF', 5, 2);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,10 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* can pay in certain conditions
|
* can pay in certain conditions
|
||||||
* default true
|
* @return true / wp_error
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
function can_pay_now_CIPF() {
|
function check_can_pay_CIPF() {
|
||||||
$acf_card_payment_method = PLGNTLS_class::ACF_CARD_PAYMENT_METHOD;
|
$acf_card_payment_method = PLGNTLS_class::ACF_CARD_PAYMENT_METHOD;
|
||||||
$acf_card_price_choice = PLGNTLS_class::ACF_CARD_PRICE_CHOICE;
|
$acf_card_price_choice = PLGNTLS_class::ACF_CARD_PRICE_CHOICE;
|
||||||
$acf_card_price_delivery = PLGNTLS_class::ACF_CARD_PRICE_DELIVERY;
|
$acf_card_price_delivery = PLGNTLS_class::ACF_CARD_PRICE_DELIVERY;
|
||||||
@@ -45,10 +46,10 @@ function can_pay_now_CIPF() {
|
|||||||
*/
|
*/
|
||||||
$price = get_field($acf_card_price_total, $acf_id);
|
$price = get_field($acf_card_price_total, $acf_id);
|
||||||
if (empty($price)) {
|
if (empty($price)) {
|
||||||
return array('success' => false, 'message' => "error: no price selected");
|
return WP_Error('cannot_purchase', "no price selected");
|
||||||
}
|
}
|
||||||
if ($price === 0) {
|
if ($price === 0) {
|
||||||
return array('success' => false, 'message' => "error: price is 0, nothing to purchase");
|
return WP_Error('cannot_purchase', "price is 0, nothing to purchase");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -56,17 +57,16 @@ function can_pay_now_CIPF() {
|
|||||||
* or is paste
|
* or is paste
|
||||||
* or is less than 1 month
|
* or is less than 1 month
|
||||||
*
|
*
|
||||||
*/
|
|
||||||
$validity_field = get_field_object($acf_card_expiration, $acf_id);
|
$validity_field = get_field_object($acf_card_expiration, $acf_id);
|
||||||
|
|
||||||
if ($validity_field === false)
|
if ($validity_field === false)
|
||||||
return array('success' => true);
|
return true;
|
||||||
|
|
||||||
$validity = $validity_field['value'];
|
$validity = $validity_field['value'];
|
||||||
$format_field = $validity_field['return_format'];
|
$format_field = $validity_field['return_format'];
|
||||||
|
|
||||||
if (empty($validity))
|
if (empty($validity))
|
||||||
return array('success' => true);
|
return true;
|
||||||
|
|
||||||
$date_validity = date_create_from_format($format_field, $validity);
|
$date_validity = date_create_from_format($format_field, $validity);
|
||||||
|
|
||||||
@@ -74,18 +74,19 @@ function can_pay_now_CIPF() {
|
|||||||
$diff = date_diff($date_now, $date_validity)->format('%R%a');
|
$diff = date_diff($date_now, $date_validity)->format('%R%a');
|
||||||
if ((int)$diff <= 0) {
|
if ((int)$diff <= 0) {
|
||||||
// date end of validity in the past
|
// date end of validity in the past
|
||||||
return array('success' => true);
|
return true;
|
||||||
}
|
}
|
||||||
else if ((int)$diff <= $card_renew_period) {
|
else if ((int)$diff <= $card_renew_period) {
|
||||||
// date expiration is in less that renew period time (ex: 30 days)
|
// date expiration is in less that renew period time (ex: 30 days)
|
||||||
return array('success' => true);
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// date end of validity is in more than renew perdio (ex: 3 month)
|
// date end of validity is in more than renew perdio (ex: 3 month)
|
||||||
return array('success' => false, 'message' => "error: it's too soon to renew your card");
|
return WP_Error('cannot_purchase', "it's too soon to renew your card");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return array('success' => true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ if (!defined('ABSPATH')) {
|
|||||||
|
|
||||||
|
|
||||||
// Define a custom exception class for HTTP errors
|
// Define a custom exception class for HTTP errors
|
||||||
class HttpErrorException extends Exception {
|
class HttpException extends Exception {
|
||||||
// HTTP status code
|
// HTTP status code
|
||||||
private $statusCode;
|
private $statusCode;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user