diff --git a/classes/class.pmprogateway_payfast.php b/classes/class.pmprogateway_payfast.php index ab0fff1..3bfbe35 100644 --- a/classes/class.pmprogateway_payfast.php +++ b/classes/class.pmprogateway_payfast.php @@ -42,25 +42,11 @@ static function init() { add_filter( 'pmpro_required_billing_fields', array( 'PMProGateway_PayFast', 'pmpro_required_billing_fields' ) ); add_filter( 'pmpro_checkout_before_submit_button', array( 'PMProGateway_PayFast', 'pmpro_checkout_before_submit_button' ) ); - add_filter( 'pmpro_checkout_before_change_membership_level', array( 'PMProGateway_PayFast', 'pmpro_checkout_before_change_membership_level' ), 10, 2 ); // itn handler add_action( 'wp_ajax_nopriv_pmpro_payfast_itn_handler', array( 'PMProGateway_PayFast', 'wp_ajax_pmpro_payfast_itn_handler' ) ); add_action( 'wp_ajax_pmpro_payfast_itn_handler', array( 'PMProGateway_PayFast', 'wp_ajax_pmpro_payfast_itn_handler' ) ); - add_filter( 'pmpro_gateways_with_pending_status', array( 'PMProGateway_PayFast', 'pmpro_gateways_with_pending_status' ) ); - } - - - /** - * Add PayFast to the list of allowed gateways. - * - * @return array - */ - static function pmpro_gateways_with_pending_status( $gateways ) { - $gateways[] = 'payfast'; - - return $gateways; } /** @@ -294,51 +280,6 @@ static function pmpro_checkout_before_submit_button() { gateway ) { - return; - } - - $morder->user_id = $user_id; - $morder->saveOrder(); - - // if global is empty by query is available. - if ( empty( $discount_code_id ) && isset( $_REQUEST['discount_code'] ) ) { - $discount_code_id = $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_discount_codes WHERE code = '" . esc_sql( sanitize_text_field( $_REQUEST['discount_code'] ) ) . "'" ); - } - - // save discount code use - if ( ! empty( $discount_code_id ) ) { - $wpdb->query( - $wpdb->prepare( - "INSERT INTO $wpdb->pmpro_discount_codes_uses - (code_id, user_id, order_id, timestamp) - VALUES( %d , %d, %d, %s )", - $discount_code_id, - $user_id, - $morder->id, - current_time( 'mysql' ) - ) - ); - } - - do_action( 'pmpro_before_send_to_payfast', $user_id, $morder ); - - $morder->Gateway->sendToPayFast( $morder ); - } /** * Send traffic to wp-admin/admin-ajax.php?action=pmpro_payfast_itn_handler to the itn handler @@ -360,11 +301,14 @@ function process( &$order ) { $order->payment_type = 'PayFast'; $order->CardType = ''; $order->cardtype = ''; - - $order->status = "review"; + $order->status = 'token'; $order->saveOrder(); - return true; + pmpro_save_checkout_data_to_order( $order ); + + do_action( 'pmpro_before_send_to_payfast', $order->user_id, $order ); + + $this->sendToPayFast( $order ); } /** diff --git a/pmpro-payfast.php b/pmpro-payfast.php index a252ecd..6f8ae39 100644 --- a/pmpro-payfast.php +++ b/pmpro-payfast.php @@ -3,7 +3,7 @@ Plugin Name: Paid Memberships Pro - PayFast Gateway Plugin URI: https://www.paidmembershipspro.com/add-ons/payfast-payment-gateway/ Description: Adds PayFast as a gateway option for Paid Memberships Pro. -Version: 1.5.2 +Version: 1.5.3 Author: Paid Memberships Pro Author URI: https://www.paidmembershipspro.com Text Domain: pmpro-payfast @@ -254,51 +254,3 @@ function pmpro_payfast_discount_code_result( $discount_code, $discount_code_id, } add_action( 'pmpro_applydiscountcode_return_js', 'pmpro_payfast_discount_code_result', 10, 4 ); - - -/** - * Store the checkout vars in the order meta before sending to PayFast. - * - * @since 1.4 - */ -function pmpro_payfast_before_send_to_payfast_save_data( $user_id, $morder ) { - - $submit_values = $_REQUEST; - - // We don't need to store the password fields for this fix. - if ( isset( $submit_values['password'] ) ) { - unset( $submit_values['password'] ); - } - - if ( isset( $submit_values['password2'] ) ) { - unset( $submit_values['password2'] ); - } - - $submit_values = array_map( 'sanitize_text_field', $submit_values ); - - - update_pmpro_membership_order_meta( $morder->id, 'checkout_vars', $submit_values ); - -} -add_action( 'pmpro_before_send_to_payfast', 'pmpro_payfast_before_send_to_payfast_save_data', 1, 2 ); - -/** - * Load the checkout vars from the order meta into the - * $_REQUEST variable so that everything in the after_checkout - * hook can access the data. - * - * @since 1.4 - */ -function pmpro_payfast_after_checkout_clean_data( $user_id, $morder ) { - - $checkout_vars = get_pmpro_membership_order_meta( $morder->id, 'checkout_vars', true ); - - // Merge these values into $_REQUEST so that everything in the after_checkout. - if ( ! empty( $checkout_vars ) ) { - $_REQUEST = array_merge( $_REQUEST, $checkout_vars ); - } - - delete_pmpro_membership_order_meta( $morder->id, 'checkout_vars' ); //Delete afterwards as we don't need it. - -} -add_action( 'pmpro_after_checkout', 'pmpro_payfast_after_checkout_clean_data', 1, 2 ); diff --git a/readme.txt b/readme.txt index 2210a2d..1954737 100644 --- a/readme.txt +++ b/readme.txt @@ -2,8 +2,8 @@ Contributors: strangerstudios, andrewza, paidmembershipspro Tags: paid memberships pro, pmpro, payfast, gateway, credit card Requires at least: 5.0 -Tested up to: 6.5 -Stable tag: 1.5.1 +Tested up to: 6.6 +Stable tag: 1.5.3 License: GPLv2 License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -52,6 +52,10 @@ To test Payfast payments without being billed in sandbox mode requires a sandbox == Changelog == += 1.5.3 - 2024-09-30 = +* BUG FIX/ENHANCEMENT: Added better support for User Fields not saving correctly during checkout. (@andrewlimaza) +* REFACTOR: Refactored the `pmpro_itnChangeMembershipLevel` (@andrewlimaza) + = 1.5.2 - 2024-07-18 = * ENHANCEMENT: Added improved support for Paid Memberships Pro V3.1+ (@andrewlimaza) * ENHANCEMENT: Added improved compatibility with screen readers for the help text on the checkout page (@andrewlimaza) diff --git a/services/payfast_itn_handler.php b/services/payfast_itn_handler.php index cc29719..b2b20c5 100644 --- a/services/payfast_itn_handler.php +++ b/services/payfast_itn_handler.php @@ -323,109 +323,33 @@ function pmpro_payfast_ipnExit() { exit; } -/* - Change the membership level. We also update the membership order to include filtered valus. -*/ +/** + * Change the membership level. We also update the membership order to include filtered values. + * NOTE: Some legacy code has stayed within this function to ensure backwards compatibility. + * + */ function pmpro_itnChangeMembershipLevel( $txn_id, &$morder ) { - global $wpdb; - // filter for level - $morder->membership_level = apply_filters( 'pmpro_payfast_itnhandler_level', $morder->membership_level, $morder->user_id ); - // fix expiration date - if ( ! empty( $morder->membership_level->expiration_number ) ) { - $enddate = "'" . date( 'Y-m-d', strtotime( '+ ' . $morder->membership_level->expiration_number . ' ' . $morder->membership_level->expiration_period ) ) . "'"; - } else { - $enddate = 'NULL'; - } - // get discount code (NOTE: but discount_code isn't set here. How to handle discount codes for PayPal Standard?) - $morder->getDiscountCode(); - if ( ! empty( $morder->discount_code ) ) { - // update membership level - $morder->getMembershipLevel( true ); - $discount_code_id = $morder->discount_code->id; - } else { - $discount_code_id = ''; - } - // set the start date to current_time('timestamp') but allow filters - $startdate = apply_filters( 'pmpro_checkout_start_date', "'" . current_time( 'mysql' ) . "'", $morder->user_id, $morder->membership_level ); - // custom level to change user to - $custom_level = array( - 'user_id' => $morder->user_id, - 'membership_id' => $morder->membership_level->id, - 'code_id' => $discount_code_id, - 'initial_payment' => $morder->membership_level->initial_payment, - 'billing_amount' => $morder->membership_level->billing_amount, - 'cycle_number' => $morder->membership_level->cycle_number, - 'cycle_period' => $morder->membership_level->cycle_period, - 'billing_limit' => $morder->membership_level->billing_limit, - 'trial_amount' => $morder->membership_level->trial_amount, - 'trial_limit' => $morder->membership_level->trial_limit, - 'startdate' => $startdate, - 'enddate' => $enddate, - ); - global $pmpro_error; - if ( ! empty( $pmpro_error ) ) { - echo $pmpro_error; - pmpro_payfast_itnlog( $pmpro_error ); - } - // change level and continue "checkout" - if ( pmpro_changeMembershipLevel( $custom_level, $morder->user_id ) !== false ) { - // update order status and transaction ids - $morder->status = 'success'; - $morder->payment_transaction_id = $txn_id; - if ( ! empty( $_POST['token'] ) ) { - $morder->subscription_transaction_id = sanitize_text_field( $_POST['m_payment_id'] ); - } else { - $morder->subscription_transaction_id = ''; - } - $morder->saveOrder(); - // add discount code use - if ( ! empty( $discount_code ) && ! empty( $use_discount_code ) ) { - $wpdb->query( - $wpdb->prepare( - "INSERT INTO $wpdb->pmpro_discount_codes_uses - (code_id, user_id, order_id, timestamp) - VALUES( %d, %d, %d, %s )", - $discount_code_id, - $morder->user_id, - $morder->id, - current_time( 'mysql' ) - ) - ); - } - // save first and last name fields - if ( ! empty( $_POST['first_name'] ) ) { - $old_firstname = get_user_meta( $morder->user_id, 'first_name', true ); - if ( ! empty( $old_firstname ) ) { - update_user_meta( $morder->user_id, 'first_name', sanitize_text_field( $_POST['first_name'] ) ); - } - } - if ( ! empty( $_POST['last_name'] ) ) { - $old_lastname = get_user_meta( $morder->user_id, 'last_name', true ); - if ( ! empty( $old_lastname ) ) { - update_user_meta( $morder->user_id, 'last_name', sanitize_text_field( $_POST['last_name'] ) ); - } - } - // hook - do_action( 'pmpro_after_checkout', $morder->user_id, $morder ); - // setup some values for the emails - if ( ! empty( $morder ) ) { - $invoice = new MemberOrder( $morder->id ); - } else { - $invoice = null; - } - $user = get_userdata( $morder->user_id ); - $user->membership_level = $morder->membership_level; // make sure they have the right level info - // send email to member - $pmproemail = new PMProEmail(); - $pmproemail->sendCheckoutEmail( $user, $invoice ); - // send email to admin - $pmproemail = new PMProEmail(); - $pmproemail->sendCheckoutAdminEmail( $user, $invoice ); + + /** + * Filter the membership level before processing the payment. This filter is not used anywhere and is now deprecated. + * @deprecated 1.5.3 + */ + $morder->membership_level = apply_filters_deprecated( 'pmpro_payfast_itnhandler_level', $morder->membership_level, $morder->user_id, '1.6' ); - return true; + // update order status and transaction ids + $morder->payment_transaction_id = $txn_id; + + if ( ! empty( $_POST['token'] ) ) { + $morder->subscription_transaction_id = sanitize_text_field( $_POST['m_payment_id'] ); } else { - return false; + $morder->subscription_transaction_id = ''; } + $morder->saveOrder(); // Temporarily save the order before processing it. + + // Change level and complete the order. + pmpro_pull_checkout_data_from_order( $morder ); + return pmpro_complete_async_checkout( $morder ); + } function pmpro_ipnSaveOrder( $txn_id, $last_order ) {