710 lines
29 KiB
PHP
710 lines
29 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Class ASP_PP_Ajax
|
|
* Hanldes various Ajax request for the payment popup.
|
|
* 1) The following two files are relevant (these files render hte HTML and handles hte JS code for sending the Ajax request):
|
|
* - public/views/templates/payment-popup.php
|
|
* - public/js/payment-popup.js
|
|
* 2) After the payment intent is confirmed, the "ASP_Process_IPN_NG->process_ipn()" is called which does the post payment processing on our end.
|
|
*/
|
|
|
|
class ASP_PP_Ajax {
|
|
|
|
protected $asp_main;
|
|
|
|
public function __construct() {
|
|
if ( wp_doing_ajax() ) {
|
|
// ASP_Utils::set_custom_lang_if_needed();
|
|
$this->asp_main = AcceptStripePayments::get_instance();
|
|
add_action( 'init', array( $this, 'add_ajax_handlers' ), 2147483647 );
|
|
}
|
|
}
|
|
|
|
public function add_ajax_handlers() {
|
|
add_action( 'wp_ajax_asp_pp_create_pi', array( $this, 'handle_create_pi' ) );
|
|
add_action( 'wp_ajax_nopriv_asp_pp_create_pi', array( $this, 'handle_create_pi' ) );
|
|
|
|
add_action( 'wp_ajax_asp_pp_confirm_pi', array( $this, 'handle_confirm_pi' ) );
|
|
add_action( 'wp_ajax_nopriv_asp_pp_confirm_pi', array( $this, 'handle_confirm_pi' ) );
|
|
|
|
add_action( 'wp_ajax_asp_3ds_result', array( $this, 'handle_3ds_result' ) );
|
|
add_action( 'wp_ajax_nopriv_asp_3ds_result', array( $this, 'handle_3ds_result' ) );
|
|
|
|
add_action( 'wp_ajax_asp_pp_save_form_data', array( $this, 'save_form_data' ) );
|
|
add_action( 'wp_ajax_nopriv_asp_pp_save_form_data', array( $this, 'save_form_data' ) );
|
|
|
|
add_action( 'wp_ajax_asp_pp_payment_error', array( $this, 'pp_payment_error' ) );
|
|
add_action( 'wp_ajax_nopriv_asp_pp_payment_error', array( $this, 'pp_payment_error' ) );
|
|
|
|
add_action( 'wp_ajax_asp_pp_check_coupon', array( $this, 'handle_check_coupon' ) );
|
|
add_action( 'wp_ajax_nopriv_asp_pp_check_coupon', array( $this, 'handle_check_coupon' ) );
|
|
}
|
|
|
|
public function handle_3ds_result() {
|
|
$pi_cs = isset( $_GET['payment_intent_client_secret'] ) ? sanitize_text_field( stripslashes ( $_GET['payment_intent_client_secret'] ) ) : '';
|
|
$pi_cs = empty( $pi_cs ) ? '' : $pi_cs;
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
body,html {
|
|
background-color: transparent !important;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
parent.ThreeDSCompleted('<?php echo esc_js( $pi_cs ); ?>');
|
|
</script>
|
|
</body>
|
|
</html>
|
|
<?php
|
|
exit;
|
|
}
|
|
|
|
public function handle_confirm_pi() {
|
|
|
|
if ( ! check_ajax_referer( 'asp_pp_ajax_nonce', 'nonce', false ) ) {
|
|
$out['err'] = __( 'Error occurred: Nonce verification failed.', 'stripe-payments' );
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
$asp_daily_txn_counter_obj = new ASP_Daily_Txn_Counter();
|
|
$captcha_type = $this->asp_main->get_setting('captcha_type');
|
|
if (empty( $captcha_type ) || $captcha_type == 'none' ) {
|
|
//Captcha is not enabled. Lets check txn rate limiting.
|
|
if($asp_daily_txn_counter_obj->asp_is_daily_txn_limit_reached()) {
|
|
$out['err'] = __( 'Error occurred: The transaction limit that you have set in settings has been reached for the day.', 'stripe-payments' );
|
|
ASP_Debug_Logger::log($out['err'], false );
|
|
|
|
if($this->asp_main->get_setting("send_email_on_daily_txn_rate_limit")) {
|
|
ASP_Utils::send_daily_txn_rate_limit_email($out['err']);
|
|
}
|
|
wp_send_json( $out );
|
|
}
|
|
}
|
|
else if($asp_daily_txn_counter_obj->asp_is_daily_tnx_limit_with_captcha_enabled()){
|
|
//Captcha is enabled. Lets check txn rate limiting.
|
|
if ($asp_daily_txn_counter_obj->asp_is_daily_txn_limit_reached(true)) {
|
|
$out['err'] = __('Error occurred: The transaction limit that you have set in settings (with captcha) has been reached for the day.', 'stripe-payments');
|
|
ASP_Debug_Logger::log($out['err'], false);
|
|
|
|
if ($this->asp_main->get_setting("send_email_on_daily_txn_rate_limit")) {
|
|
ASP_Utils::send_daily_txn_rate_limit_email($out['err']);
|
|
}
|
|
wp_send_json($out);
|
|
}
|
|
}
|
|
|
|
$product_id = filter_input( INPUT_POST, 'product_id', FILTER_SANITIZE_NUMBER_INT );
|
|
|
|
$item = new ASP_Product_Item( $product_id );
|
|
|
|
if ( $item->get_last_error() ) {
|
|
$out['err'] = __( 'Error occurred:', 'stripe-payments' ) . ' ' . $item->get_last_error();
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
//Log initial confirm_pi debug logging data (if debug feature is enabled).
|
|
$txn_counter_args = $asp_daily_txn_counter_obj->asp_get_daily_txn_counter_args();
|
|
$txn_counter_val = isset($txn_counter_args['counter'])? $txn_counter_args['counter'] : '-';
|
|
$request_ip = ASP_Utils::get_user_ip_address();
|
|
$confirm_pi_initial_debug = 'handle_confirm_pi() - Product ID: ' . $product_id . ', Captcha Type: ' . $captcha_type . ', Txn Counter: ' . $txn_counter_val . ', IP: ' . $request_ip;
|
|
ASP_Debug_Logger::log( $confirm_pi_initial_debug, true );
|
|
//End initial confirm_pi debug logging.
|
|
|
|
//Check page load signature data
|
|
if( !ASP_Utils_Bot_Mitigation::is_page_load_signature_data_valid($product_id) ){
|
|
//Signature is invalid.
|
|
//Exit out if feature is enabled
|
|
$disable_signature_check = $this->asp_main->get_setting( 'disable_page_load_signature_check' );
|
|
if ( $disable_signature_check ) {
|
|
//The signature check feature is disabled. We will allow this request to go through.
|
|
ASP_Debug_Logger::log( 'Notice! The page load signature check feature is disabled in the advanced settings menu so this request will not be blocked.', false );
|
|
} else {
|
|
$out['err'] = __( 'Error! Page load signature check failed.', 'stripe-payments' );
|
|
wp_send_json( $out );
|
|
}
|
|
}
|
|
|
|
//Check request limit count per IP address
|
|
if( !ASP_Utils_Bot_Mitigation::is_request_limit_reached_for_ip() ){
|
|
//Request limit reached for this IP.
|
|
//Exit out if feature is enabled
|
|
$disable_request_limit_check = $this->asp_main->get_setting( 'disable_request_limit_per_ip_check' );
|
|
if ( $disable_request_limit_check ) {
|
|
//The request limit check feature is disabled. We will allow this request to go through.
|
|
ASP_Debug_Logger::log( 'Notice! The transaction request limit per IP address feature is disabled in the advanced settings menu so this request will not be blocked.', false );
|
|
} else {
|
|
$out['err'] = __( 'Error! Transaction request limit reached for this IP address.', 'stripe-payments' );
|
|
wp_send_json( $out );
|
|
}
|
|
}
|
|
|
|
$item = apply_filters( 'asp_ng_pp_product_item_override', $item );
|
|
|
|
//Trigger some action hooks (useful for other checks).
|
|
do_action( 'asp_ng_before_token_request', $item );
|
|
//ASP_Debug_Logger::log( 'handle_confirm_pi() - Captcha response checked.', true );
|
|
|
|
//This hook will be used to do additional captcha (if enabled) parameter checks for bot mitigation.
|
|
$params = array();
|
|
do_action( 'asp_ng_do_additional_captcha_response_check', $item, $params );
|
|
|
|
do_action( 'asp_ng_product_mode_keys', $product_id );
|
|
|
|
$pi_id = isset( $_POST['pi_id'] ) ? sanitize_text_field( stripslashes ( $_POST['pi_id'] ) ) : '';
|
|
$opts = isset( $_POST['opts'] ) ? sanitize_text_field( stripslashes ( $_POST['opts'] ) ) : '';
|
|
|
|
if ( ! empty( $opts ) ) {
|
|
$opts = html_entity_decode( $opts );
|
|
$opts = json_decode( $opts, true );
|
|
} else {
|
|
$opts = array();
|
|
}
|
|
|
|
$opts['use_stripe_sdk'] = false;
|
|
|
|
$home_url = admin_url( 'admin-ajax.php' );
|
|
|
|
$disable_3ds_iframe = $this->asp_main->get_setting( 'disable_3ds_iframe' );
|
|
|
|
if ( ! $disable_3ds_iframe ) {
|
|
$url_opts = array( 'action' => 'asp_3ds_result' );
|
|
} else {
|
|
$url_opts = array(
|
|
'action' => 'asp_next_action_results',
|
|
'is_live' => $this->asp_main->is_live,
|
|
);
|
|
}
|
|
|
|
$return_url = add_query_arg( $url_opts, $home_url );
|
|
|
|
$opts['return_url'] = $return_url;
|
|
|
|
$opts = apply_filters( 'asp_ng_confirm_pi_opts', $opts, $pi_id );
|
|
|
|
try {
|
|
ASP_Utils::load_stripe_lib();
|
|
$key = $this->asp_main->is_live ? $this->asp_main->APISecKey : $this->asp_main->APISecKeyTest;
|
|
\Stripe\Stripe::setApiKey( $key );
|
|
|
|
$api = ASP_Stripe_API::get_instance();
|
|
$api->set_param( 'throw_exception', true );
|
|
$api->set_api_key( $key );
|
|
|
|
if ( ! ASP_Utils::use_internal_api() ) {
|
|
$pi = \Stripe\PaymentIntent::retrieve( $pi_id );
|
|
} else {
|
|
$pi = $api->get( 'payment_intents/' . $pi_id );
|
|
if ( false === $pi ) {
|
|
$err = $api->get_last_error();
|
|
throw new \Exception( $err['message'], isset( $err['error_code'] ) ? $err['error_code'] : null );
|
|
}
|
|
}
|
|
if ( 'succeeded' === $pi->status ) {
|
|
$out['pi_id'] = $pi->id;
|
|
wp_send_json( $out );
|
|
}
|
|
if ( ! ASP_Utils::use_internal_api() ) {
|
|
$pi->confirm( $opts );
|
|
} else {
|
|
$pi = $api->post(
|
|
'payment_intents/' . $pi_id . '/confirm',
|
|
$opts
|
|
);
|
|
if ( false === $pi ) {
|
|
$err = $api->get_last_error();
|
|
throw new \Exception( $err['message'], isset( $err['error_code'] ) ? $err['error_code'] : null );
|
|
}
|
|
}
|
|
} catch ( \Throwable $e ) {
|
|
$out['err'] = __( 'Stripe API error occurred:', 'stripe-payments' ) . ' ' . $e->getMessage();
|
|
$order = new ASP_Order_Item();
|
|
if ( false !== $order->find( 'pi_id', $pi_id ) ) {
|
|
$order->change_status( 'error', $out['err'] );
|
|
}
|
|
$body = __( 'Following error occurred during payment processing:', 'stripe-payments' ) . "\r\n\r\n";
|
|
$body .= $out['err'] . "\r\n\r\n";
|
|
$body .= __( 'Debug data:', 'stripe-payments' ) . "\r\n";
|
|
$post_data = filter_var( $_POST, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY );
|
|
$post_data_str = http_build_query( $post_data, '', '; ' );
|
|
$body .= sanitize_text_field( stripslashes($post_data_str));
|
|
ASP_Debug_Logger::log( __( 'Following error occurred during payment processing:', 'stripe-payments' ) . ' ' . $out['err'], false );
|
|
ASP_Utils::send_error_email( $body );
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
$out['pi_id'] = $pi->id;
|
|
|
|
if ( isset( $pi->next_action ) ) {
|
|
$out['redirect_to'] = $pi->next_action->redirect_to_url->url;
|
|
$out['use_iframe'] = ! $disable_3ds_iframe;
|
|
}
|
|
|
|
$out = apply_filters( 'asp_ng_confirm_pi_result_out', $out, $pi_id );
|
|
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
public function handle_create_pi() {
|
|
|
|
$out = array();
|
|
$out['success'] = false;
|
|
$product_id = filter_input( INPUT_POST, 'product_id', FILTER_SANITIZE_NUMBER_INT );
|
|
$amount = filter_input( INPUT_POST, 'amount', FILTER_SANITIZE_NUMBER_FLOAT );
|
|
$surcharge_amount = filter_input( INPUT_POST, 'surcharge_amount', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
|
|
$curr = isset( $_POST['curr'] ) ? sanitize_text_field( stripslashes ( $_POST['curr'] ) ) : '';
|
|
$pi_id = isset( $_POST['pi'] ) ? sanitize_text_field( stripslashes ( $_POST['pi'] ) ) : '';
|
|
$cust_id = isset( $_POST['cust_id'] ) ? sanitize_text_field( stripslashes ( $_POST['cust_id'] ) ) : '';
|
|
$quantity = isset( $_POST['quantity'] ) ? sanitize_text_field( stripslashes ( $_POST['quantity'] ) ) : '';
|
|
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( stripslashes ( $_POST['nonce'] ) ) : '';
|
|
$coupon_code = isset( $_POST['coupon'] ) ? sanitize_text_field( stripslashes ( $_POST['coupon'] ) ) : '';
|
|
$price_variation = isset( $_POST['pvar'] ) ? sanitize_text_field( stripslashes ( $_POST['pvar'] ) ) : '';
|
|
$post_billing_details = isset( $_POST['billing_details'] ) ? sanitize_text_field( stripslashes ( $_POST['billing_details'] ) ) : '';
|
|
$post_shipping_details = isset( $_POST['shipping_details'] ) ? sanitize_text_field( stripslashes ( $_POST['shipping_details'] ) ) : '';
|
|
$post_customer_details = isset( $_POST['customer_details'] ) ? sanitize_text_field( stripslashes ( $_POST['customer_details'] ) ) : '';
|
|
|
|
//Check create_pi nonce
|
|
if ( ! wp_verify_nonce( $nonce, 'asp_pp_ajax_create_pi_nonce' ) ) {
|
|
$out['err'] = __( 'Error occurred: Nonce security verification failed.', 'stripe-payments' );
|
|
wp_send_json( $out );
|
|
}
|
|
$asp_daily_txn_counter_obj = new ASP_Daily_Txn_Counter();
|
|
$captcha_type = $this->asp_main->get_setting('captcha_type');
|
|
if (empty($captcha_type) || $captcha_type == 'none') {
|
|
//Captcha is not enabled. Lets check txn rate limiting.
|
|
if ($asp_daily_txn_counter_obj->asp_is_daily_txn_limit_reached()) {
|
|
$out['err'] = __('Error occurred: The transaction limit that you have set in settings has been reached for the day.', 'stripe-payments');
|
|
ASP_Debug_Logger::log($out['err'], false);
|
|
|
|
if ($this->asp_main->get_setting("send_email_on_daily_txn_rate_limit")) {
|
|
ASP_Utils::send_daily_txn_rate_limit_email($out['err']);
|
|
}
|
|
wp_send_json($out);
|
|
}
|
|
} else if ($asp_daily_txn_counter_obj->asp_is_daily_tnx_limit_with_captcha_enabled()) {
|
|
//Captcha is enabled. Lets check txn rate limiting.
|
|
if ($asp_daily_txn_counter_obj->asp_is_daily_txn_limit_reached(true)) {
|
|
$out['err'] = __('Error occurred: The transaction limit that you have set in settings (with captcha) has been reached for the day.', 'stripe-payments');
|
|
ASP_Debug_Logger::log($out['err'], false);
|
|
|
|
if ($this->asp_main->get_setting("send_email_on_daily_txn_rate_limit")) {
|
|
ASP_Utils::send_daily_txn_rate_limit_email($out['err']);
|
|
}
|
|
wp_send_json($out);
|
|
}
|
|
}
|
|
|
|
//Log initial create_pi debug logging data (if debug feature is enabled).
|
|
$txn_counter_args = $asp_daily_txn_counter_obj->asp_get_daily_txn_counter_args();
|
|
$txn_counter_val = isset($txn_counter_args['counter'])? $txn_counter_args['counter'] : '-';
|
|
$request_ip = ASP_Utils::get_user_ip_address();
|
|
$create_pi_initial_debug = 'handle_create_pi() - Product ID: ' . $product_id . ', Captcha Type: ' . $captcha_type . ', Txn Counter: ' . $txn_counter_val . ', IP: ' . $request_ip;
|
|
ASP_Debug_Logger::log( $create_pi_initial_debug, true );
|
|
//End initial create_pi debug logging.
|
|
|
|
//Check page load signature data
|
|
if( !ASP_Utils_Bot_Mitigation::is_page_load_signature_data_valid($product_id) ){
|
|
//Signature is invalid.
|
|
//Exit out if feature is enabled
|
|
$disable_signature_check = $this->asp_main->get_setting( 'disable_page_load_signature_check' );
|
|
if ( $disable_signature_check ) {
|
|
//The signature check feature is disabled. We will allow this request to go through.
|
|
ASP_Debug_Logger::log( 'Notice! The page load signature check feature is disabled in the advanced settings menu so this request will not be blocked.', false );
|
|
} else {
|
|
$out['err'] = __( 'Error! Page load signature check failed.', 'stripe-payments' );
|
|
wp_send_json( $out );
|
|
}
|
|
}
|
|
|
|
//Check request usage count per IP address
|
|
if( !ASP_Utils_Bot_Mitigation::is_request_limit_reached_for_ip() ){
|
|
//Request limit reached for this IP.
|
|
//Exit out if feature is enabled
|
|
$disable_request_limit_check = $this->asp_main->get_setting( 'disable_request_limit_per_ip_check' );
|
|
if ( $disable_request_limit_check ) {
|
|
//The request limit check feature is disabled. We will allow this request to go through.
|
|
ASP_Debug_Logger::log( 'Notice! The transaction request limit per IP address feature is disabled in the advanced settings menu so this request will not be blocked.', false );
|
|
} else {
|
|
$out['err'] = __( 'Error! Transaction request limit reached for this IP address.', 'stripe-payments' );
|
|
wp_send_json( $out );
|
|
}
|
|
}
|
|
|
|
// >>>> Start of pre API submission validation.
|
|
$item_for_validation = new ASP_Product_Item( $product_id );
|
|
//Do the API pre-submission price/amount validation.
|
|
if ( $item_for_validation->get_type() === 'one_time' ) {
|
|
//It's a one-time payment product.
|
|
|
|
$custom_inputs = array(
|
|
'coupon_code' => $coupon_code,
|
|
'price_variation' => $price_variation,
|
|
'billing_details' => json_decode( html_entity_decode( $post_billing_details ) , true),
|
|
'shipping_details' => json_decode( html_entity_decode( $post_shipping_details ) , true),
|
|
);
|
|
|
|
if( ! $item_for_validation->validate_total_amount( $amount, $quantity, $custom_inputs) ){
|
|
//Error condition. The validation function already set the error message which we will send back to the client.
|
|
$out['err'] = __( 'Error occurred:', 'stripe-payments' ) . ' ' . $item_for_validation->get_last_error();
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
//Validation passed.
|
|
|
|
} else if ( $item_for_validation->get_type() === 'donation' ) {
|
|
//It's a donation product. Don't need to validate the amount since the user can enter any amount to donate.
|
|
ASP_Debug_Logger::log( "This is a donation type product. API pre-submission amount validation is not required.", true );
|
|
}
|
|
//Trigger action hook that can be used to do additional API pre-submission validation from an addon.
|
|
do_action( 'asp_ng_before_api_pre_submission_validation', $item_for_validation );
|
|
// <<<< End of pre API submission validation.
|
|
|
|
$item = new ASP_Product_Item( $product_id );
|
|
|
|
if ( $item->get_last_error() ) {
|
|
$out['err'] = __( 'Error occurred:', 'stripe-payments' ) . ' ' . $item->get_last_error();
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
if ( $item->stock_control_enabled() ) {
|
|
$stock_items = $item->get_stock_items();
|
|
$out['stock_items'] = $stock_items;
|
|
if ( $quantity > $stock_items ) {
|
|
// translators: %d is number of items in stock
|
|
$msg = apply_filters( 'asp_customize_text_msg', __( 'You cannot order more items than available: %d', 'stripe-payments' ), 'stock_not_available' );
|
|
$out['err'] = sprintf( $msg, $stock_items );
|
|
wp_send_json( $out );
|
|
}
|
|
}
|
|
|
|
$min_amount = $item->get_min_amount( true );
|
|
$prod_type = $item->get_type();
|
|
$configured_currency = $item->get_currency();
|
|
$is_currency_variable = $item->is_currency_variable();
|
|
|
|
//Check configured currency matches with the request currency.
|
|
//Trigger filter that can be used to check this from the subscription addon (if needed).
|
|
$configured_currency = apply_filters( 'asp_create_pi_check_currency_configured', $configured_currency, $curr, $item );
|
|
if ( $configured_currency !== $curr ) {
|
|
//Check if the currency variable option is enabled.
|
|
//Trigger filter that can be used to check this from the subscription addon (if needed).
|
|
$is_currency_variable = apply_filters( 'asp_create_pi_is_currency_variable', $is_currency_variable, $item );
|
|
if ( $is_currency_variable ){
|
|
//The currency variable option is enabled. We will allow this request to go through.
|
|
ASP_Debug_Logger::log( 'Note: The currency variable option is enabled in the product settings for this product.', true );
|
|
} else {
|
|
//Error condition
|
|
ASP_Debug_Logger::log( 'Currency mismatch. The expected currency is: '.$configured_currency.', Received: '.$curr, false );
|
|
$msg = apply_filters( 'asp_customize_text_msg', __( 'Currency mismatch. The product is configured to use', 'stripe-payments' ), 'currency_mismatch' );
|
|
$out['err'] = $msg . ' ' . $configured_currency;
|
|
wp_send_json( $out );
|
|
}
|
|
}
|
|
|
|
//Check minimum amount.
|
|
if ( 'donation' === $prod_type && 0 !== $min_amount && $min_amount > $amount ) {
|
|
ASP_Debug_Logger::log( 'Minimum amount is: ' . $min_amount . ' ' . $curr, false );
|
|
$msg = apply_filters( 'asp_customize_text_msg', __( 'Minimum amount is', 'stripe-payments' ), 'min_amount_is' );
|
|
$out['err'] = $msg . ' ' . ASP_Utils::formatted_price( $min_amount, $curr, true );
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
//Trigger some action hooks (useful for other checks).
|
|
do_action( 'asp_ng_before_token_request', $item );
|
|
//ASP_Debug_Logger::log( 'handle_create_pi() - Captcha response checked.', true );
|
|
|
|
//This hook will be used to do additional captcha (if enabled) parameter checks for bot mitigation.
|
|
$params = array();
|
|
do_action( 'asp_ng_do_additional_captcha_response_check', $item, $params );
|
|
|
|
do_action( 'asp_ng_product_mode_keys', $product_id );
|
|
|
|
try {
|
|
ASP_Utils::load_stripe_lib();
|
|
$key = $this->asp_main->is_live ? $this->asp_main->APISecKey : $this->asp_main->APISecKeyTest;
|
|
\Stripe\Stripe::setApiKey( $key );
|
|
|
|
$api = ASP_Stripe_API::get_instance();
|
|
$api->set_param( 'throw_exception', true );
|
|
$api->set_api_key( $key );
|
|
|
|
} catch ( \Exception $e ) {
|
|
$out['err'] = __( 'Stripe API error occurred:', 'stripe-payments' ) . ' ' . $e->getMessage();
|
|
wp_send_json( $out );
|
|
} catch ( \Throwable $e ) {
|
|
$out['err'] = __( 'Stripe API error occurred:', 'stripe-payments' ) . ' ' . $e->getMessage();
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
$metadata = array();
|
|
|
|
try {
|
|
|
|
$pi_params = array(
|
|
'amount' => $amount,
|
|
'currency' => $curr,
|
|
'confirmation_method' => 'manual',
|
|
);
|
|
|
|
if ( isset( $post_billing_details ) ) {
|
|
$post_billing_details = html_entity_decode( $post_billing_details );
|
|
|
|
$billing_details = json_decode( $post_billing_details );
|
|
}
|
|
|
|
if ( isset( $post_customer_details ) ) {
|
|
$post_customer_details = html_entity_decode( $post_customer_details );
|
|
|
|
$customer_details = json_decode( $post_customer_details );
|
|
}
|
|
|
|
$dont_save_card = $this->asp_main->get_setting( 'dont_save_card' );
|
|
|
|
if ( ! $dont_save_card ) {
|
|
$customer_opts = array();
|
|
|
|
if ( isset( $billing_details ) ) {
|
|
|
|
if ( ! empty( $billing_details->name ) ) {
|
|
$customer_opts['name'] = $billing_details->name;
|
|
}
|
|
|
|
if ( ! empty( $billing_details->email ) ) {
|
|
$customer_opts['email'] = $billing_details->email;
|
|
}
|
|
|
|
if ( isset( $billing_details->address ) && isset( $billing_details->address->line1 ) ) {
|
|
//we have address
|
|
$addr = array(
|
|
'line1' => $billing_details->address->line1,
|
|
'state' => isset( $billing_details->address->state ) ? $billing_details->address->state : null,
|
|
'city' => isset( $billing_details->address->city ) ? $billing_details->address->city : null,
|
|
'country' => isset( $billing_details->address->country ) ? $billing_details->address->country : null,
|
|
);
|
|
|
|
if ( isset( $billing_details->address->postal_code ) ) {
|
|
$addr['postal_code'] = $billing_details->address->postal_code;
|
|
}
|
|
|
|
$customer_opts['address'] = $addr;
|
|
}
|
|
}
|
|
|
|
if ( isset( $post_shipping_details ) ) {
|
|
$post_shipping_details = html_entity_decode( $post_shipping_details );
|
|
|
|
$shipping_details = json_decode( $post_shipping_details );
|
|
|
|
$shipping = array();
|
|
|
|
if ( isset($shipping_details->name) && $shipping_details->name ) {
|
|
$shipping['name'] = $shipping_details->name;
|
|
} elseif ( ! empty( $customer_opts['name'] ) ) {
|
|
$shipping['name'] = $customer_opts['name'];
|
|
}
|
|
|
|
if ( isset( $shipping_details->address ) && isset( $shipping_details->address->line1 ) ) {
|
|
//we have address
|
|
$addr = array(
|
|
'line1' => $shipping_details->address->line1,
|
|
'state' => isset( $shipping_details->address->state ) ? $shipping_details->address->state : null,
|
|
'city' => isset( $shipping_details->address->city ) ? $shipping_details->address->city : null,
|
|
'country' => isset( $shipping_details->address->country ) ? $shipping_details->address->country : null,
|
|
);
|
|
|
|
if ( isset( $shipping_details->address->postal_code ) ) {
|
|
$addr['postal_code'] = $shipping_details->address->postal_code;
|
|
}
|
|
|
|
$shipping['address'] = $addr;
|
|
|
|
if ( ! empty( $shipping['name'] ) ) {
|
|
$customer_opts['shipping'] = $shipping;
|
|
}
|
|
}
|
|
}
|
|
|
|
$is_use_separate_name_fields_enabled = \AcceptStripePayments::get_instance()->get_setting('use_separate_name_fields_enabled', false);
|
|
if ($is_use_separate_name_fields_enabled){
|
|
$customer_opts['metadata'] = array(
|
|
'First Name' => isset($customer_details->firstName) ? sanitize_text_field($customer_details->firstName) : '',
|
|
'Last Name' => isset($customer_details->lastName) ? sanitize_text_field($customer_details->lastName) : '',
|
|
);
|
|
}
|
|
$customer_opts = apply_filters( 'asp_ng_before_customer_create_update', $customer_opts, empty( $cust_id ) ? false : $cust_id );
|
|
|
|
if ( empty( $cust_id ) ) {
|
|
if ( ASP_Utils::use_internal_api() ) {
|
|
$api = ASP_Stripe_API::get_instance();
|
|
$api->set_param( 'throw_exception', true );
|
|
|
|
$customer = $api->post( 'customers', $customer_opts );
|
|
|
|
} else {
|
|
$customer = \Stripe\Customer::create( $customer_opts );
|
|
}
|
|
|
|
$cust_id = $customer->id;
|
|
} else {
|
|
|
|
if ( ASP_Utils::use_internal_api() ) {
|
|
$api = ASP_Stripe_API::get_instance();
|
|
$api->set_param( 'throw_exception', true );
|
|
|
|
$customer = $api->post( 'customers/' . $cust_id, $customer_opts );
|
|
|
|
} else {
|
|
$customer = \Stripe\Customer::update( $cust_id, $customer_opts );
|
|
}
|
|
}
|
|
$pi_params['customer'] = $cust_id;
|
|
}
|
|
|
|
$metadata['Product Name'] = $item->get_name();
|
|
$metadata['Product ID'] = $product_id;
|
|
|
|
$metadata['Surcharge Amount'] = $surcharge_amount;
|
|
$metadata['Surcharge Label'] = $item->get_surcharge_label();
|
|
|
|
$tax_amount = $item->get_tax_amount();
|
|
if (!empty($tax_amount)){
|
|
$metadata['Tax Amount'] = \ASP_Utils::formatted_price( $tax_amount, $curr );
|
|
}
|
|
|
|
if ( isset( $metadata ) && ! empty( $metadata ) ) {
|
|
$pi_params['metadata'] = $metadata;
|
|
}
|
|
$description = $item->get_description();
|
|
if ( ! empty( $description ) ) {
|
|
$pi_params['description'] = $description;
|
|
} else {
|
|
$pi_params['description'] = $item->get_name();
|
|
}
|
|
|
|
$stripe_receipt_email = $this->asp_main->get_setting( 'stripe_receipt_email' );
|
|
|
|
if ( $stripe_receipt_email ) {
|
|
if ( isset( $billing_details ) && isset( $billing_details->email ) && ! empty( $billing_details->email ) ) {
|
|
$pi_params['receipt_email'] = $billing_details->email;
|
|
}
|
|
}
|
|
|
|
$order = new ASP_Order_Item();
|
|
|
|
if ( $order->can_create( $product_id ) ) {
|
|
|
|
if ( ! $pi_id ) {
|
|
//create new incomplete order for this payment
|
|
$order->create( $product_id, $pi_id );
|
|
} else {
|
|
//find order for this PaymentIntent
|
|
$order->find( 'pi_id', $pi_id );
|
|
}
|
|
}
|
|
|
|
$pi_params = apply_filters( 'asp_ng_before_pi_create_update', $pi_params );
|
|
if ( $pi_id ) {
|
|
if ( ASP_Utils::use_internal_api() ) {
|
|
$api = ASP_Stripe_API::get_instance();
|
|
$api->set_param( 'throw_exception', true );
|
|
|
|
$intent = $api->post( 'payment_intents/' . $pi_id, $pi_params );
|
|
} else {
|
|
$intent = \Stripe\PaymentIntent::update( $pi_id, $pi_params );
|
|
}
|
|
} else {
|
|
if ( ASP_Utils::use_internal_api() ) {
|
|
$api = ASP_Stripe_API::get_instance();
|
|
$api->set_param( 'throw_exception', true );
|
|
|
|
$intent = $api->post( 'payment_intents', $pi_params );
|
|
} else {
|
|
$intent = \Stripe\PaymentIntent::create( $pi_params );
|
|
}
|
|
}
|
|
} catch ( \Exception $e ) {
|
|
$out['shipping'] = isset( $shipping ) ? wp_json_encode( $shipping ) : null;
|
|
$out['err'] = __( 'Error occurred:', 'stripe-payments' ) . ' ' . $e->getMessage();
|
|
wp_send_json( $out );
|
|
} catch ( \Throwable $e ) {
|
|
$out['shipping'] = isset( $shipping ) ? wp_json_encode( $shipping ) : null;
|
|
$out['err'] = __( 'Error occurred:', 'stripe-payments' ) . ' ' . $e->getMessage();
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
if ( $order->get_id() ) {
|
|
update_post_meta( $order->get_id(), 'pi_id', $intent->id );
|
|
}
|
|
|
|
$out['success'] = true;
|
|
$out['clientSecret'] = $intent->client_secret;
|
|
$out['pi_id'] = $intent->id;
|
|
$out['cust_id'] = $cust_id;
|
|
$out = apply_filters( 'asp_ng_before_pi_result_send', $out, $intent );
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
public function save_form_data() {
|
|
if ( ! check_ajax_referer( 'asp_pp_ajax_nonce', 'nonce', false ) ) {
|
|
$out['err'] = __( 'Error occurred: Nonce verification failed on save_form_data().', 'stripe-payments' );
|
|
wp_send_json( $out );
|
|
}
|
|
$out['success'] = true;
|
|
$sess = ASP_Session::get_instance();
|
|
|
|
wp_parse_str( $_POST['form_data'], $form_data );
|
|
$filtered_form_data = $this->sanitize_nested_form_data($form_data);
|
|
|
|
$sess->set_transient_data( 'asp_pp_form_data', $filtered_form_data );
|
|
//ASP_Debug_Logger::log( 'Saved form data: ' . json_encode( $filtered_form_data ) );
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
public function sanitize_nested_form_data($data) {
|
|
foreach ($data as $key => $value) {
|
|
if (is_array($value)) {
|
|
$data[$key] = $this->sanitize_nested_form_data($value);
|
|
} else {
|
|
$data[$key] = sanitize_text_field($value);
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
|
|
public function handle_check_coupon() {
|
|
$product_id = filter_input( INPUT_POST, 'product_id', FILTER_SANITIZE_NUMBER_INT );
|
|
$item = new ASP_Product_Item( $product_id );
|
|
|
|
if ( $item->get_last_error() ) {
|
|
$out['err'] = __( 'Error occurred:', 'stripe-payments' ) . ' ' . $item->get_last_error();
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
$coupon_code = isset( $_POST['coupon_code'] ) ? sanitize_text_field( stripslashes ( $_POST['coupon_code'] ) ) : '';
|
|
|
|
$coupon_valid = $item->check_coupon( $coupon_code );
|
|
if ( ! $coupon_valid ) {
|
|
$out['err'] = $item->get_last_error();
|
|
wp_send_json( $out );
|
|
}
|
|
|
|
$coupon = $item->get_coupon();
|
|
|
|
$zero_value_id = str_replace( '.', '', uniqid( 'free_', true ) );
|
|
$coupon['zero_value_id'] = $zero_value_id;
|
|
|
|
wp_send_json( $coupon );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new ASP_PP_Ajax();
|