Simple Membership - Version 4.2.0

Version Description

  • Braintree SDK updated for the Braintree payment gateway.
  • Google reCAPTCHA enterprise option is now available as a free addon.
Download this release

Release Info

Developer mra13
Plugin Icon 128x128 Simple Membership
Version 4.2.0
Comparing to
See all releases

Code changes from version 4.1.8 to 4.2.0

classes/class.swpm-ajax.php CHANGED
@@ -8,6 +8,8 @@ class SwpmAjax {
8
  public static function validate_email_ajax() {
9
  global $wpdb;
10
  $field_value = isset($_GET['fieldValue']) ? sanitize_text_field($_GET['fieldValue']) : '';
 
 
11
  $field_id = isset($_GET['fieldId']) ? sanitize_text_field($_GET['fieldId']) : '';
12
  $member_id = isset($_GET['member_id']) ? sanitize_text_field($_GET['member_id']) : '';
13
  if (!check_ajax_referer( 'swpm-rego-form-ajax-nonce', 'nonce', false )) {
8
  public static function validate_email_ajax() {
9
  global $wpdb;
10
  $field_value = isset($_GET['fieldValue']) ? sanitize_text_field($_GET['fieldValue']) : '';
11
+ $field_value = stripslashes($field_value);//Clean the email address value (so it can work with values like: test.de'souz@exaple.com)
12
+
13
  $field_id = isset($_GET['fieldId']) ? sanitize_text_field($_GET['fieldId']) : '';
14
  $member_id = isset($_GET['member_id']) ? sanitize_text_field($_GET['member_id']) : '';
15
  if (!check_ajax_referer( 'swpm-rego-form-ajax-nonce', 'nonce', false )) {
classes/class.swpm-auth.php CHANGED
@@ -1,402 +1,408 @@
1
- <?php
2
-
3
- class SwpmAuth {
4
-
5
- public $protected;
6
- public $permitted;
7
- private $isLoggedIn;
8
- private $lastStatusMsg;
9
- private static $_this;
10
- public $userData;
11
-
12
- private function __construct() {
13
- //check if we need to display custom message on the login form
14
- $custom_msg = filter_input( INPUT_COOKIE, 'swpm-login-form-custom-msg', FILTER_SANITIZE_STRING );
15
- if ( ! empty( $custom_msg ) ) {
16
- $this->lastStatusMsg = $custom_msg;
17
- //let's 'unset' the cookie
18
- setcookie( 'swpm-login-form-custom-msg', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN );
19
- }
20
- $this->isLoggedIn = false;
21
- $this->userData = null;
22
- $this->protected = SwpmProtection::get_instance();
23
- }
24
-
25
- private function init() {
26
- $valid = $this->validate();
27
- //SwpmLog::log_auth_debug("init:". ($valid? "valid": "invalid"), true);
28
- if ( ! $valid ) {
29
- $this->authenticate();
30
- }
31
- }
32
-
33
- public static function get_instance() {
34
- if ( empty( self::$_this ) ) {
35
- self::$_this = new SwpmAuth();
36
- self::$_this->init();
37
- }
38
- return self::$_this;
39
- }
40
-
41
- private function authenticate( $user = null, $pass = null ) {
42
- global $wpdb;
43
- $swpm_password = empty( $pass ) ? filter_input( INPUT_POST, 'swpm_password' ) : $pass;
44
- $swpm_user_name = empty( $user ) ? apply_filters( 'swpm_user_name', filter_input( INPUT_POST, 'swpm_user_name' ) ) : $user;
45
-
46
- if ( ! empty( $swpm_user_name ) && ! empty( $swpm_password ) ) {
47
- //SWPM member login request.
48
- //Trigger action hook that can be used to check stuff before the login request is processed by the plugin.
49
- $args = array(
50
- 'username' => $swpm_user_name,
51
- 'password' => $swpm_password,
52
- );
53
- do_action( 'swpm_before_login_request_is_processed', $args );
54
-
55
- //First, lets make sure this user is not already logged into the site as an "Admin" user. We don't want to override that admin login session.
56
- if ( current_user_can( 'administrator' ) ) {
57
- //This user is logged in as ADMIN then trying to do another login as a member. Stop the login request processing (we don't want to override your admin login session).
58
- $wp_profile_page = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/wp-admin/profile.php';
59
- $error_msg = '';
60
- $error_msg .= '<p>' . SwpmUtils::_( 'Warning! Simple Membership plugin cannot process this login request to prevent you from getting logged out of WP Admin accidentally.' ) . '</p>';
61
- $error_msg .= '<p><a href="' . $wp_profile_page . '" target="_blank">' . SwpmUtils::_( 'Click here' ) . '</a>' . SwpmUtils::_( ' to see the profile you are currently logged into in this browser.' ) . '</p>';
62
- $error_msg .= '<p>' . SwpmUtils::_( 'You are logged into the site as an ADMIN user in this browser. First, logout from WP Admin then you will be able to log in as a normal member.' ) . '</p>';
63
- $error_msg .= '<p>' . SwpmUtils::_( 'Alternatively, you can use a different browser (where you are not logged-in as ADMIN) to test the membership login.' ) . '</p>';
64
- $error_msg .= '<p>' . SwpmUtils::_( 'Your normal visitors or members will never see this message. This message is ONLY for ADMIN user.' ) . '</p>';
65
- wp_die( $error_msg );
66
- }
67
-
68
- //If captcha is present and validation failed, it returns an error string. If validation succeeds, it returns an empty string.
69
- $captcha_validation_output = apply_filters( 'swpm_validate_login_form_submission', '' );
70
- if ( ! empty( $captcha_validation_output ) ) {
71
- $this->lastStatusMsg = SwpmUtils::_( 'Captcha validation failed on login form.' );
72
- return;
73
- }
74
-
75
- if ( is_email( $swpm_user_name ) ) {//User is trying to log-in using an email address
76
- $email = sanitize_email( $swpm_user_name );
77
- $query = $wpdb->prepare( 'SELECT user_name FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE email = %s', $email );
78
- $username = $wpdb->get_var( $query );
79
- if ( $username ) {//Found a user record
80
- $swpm_user_name = $username; //Grab the usrename value so it can be used in the authentication process.
81
- SwpmLog::log_auth_debug( 'Authentication request using email address: ' . $email . ', Found a user record with username: ' . $swpm_user_name, true );
82
- }
83
- }
84
-
85
- //Lets process the request. Check username and password
86
- $user = sanitize_user( $swpm_user_name );
87
- $pass = trim( $swpm_password );
88
- SwpmLog::log_auth_debug( 'Authentication request - Username: ' . $swpm_user_name, true );
89
-
90
- $query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE user_name = %s';
91
- $userData = $wpdb->get_row( $wpdb->prepare( $query, $user ) );
92
- $this->userData = $userData;
93
- if ( ! $userData ) {
94
- $this->isLoggedIn = false;
95
- $this->userData = null;
96
- $this->lastStatusMsg = SwpmUtils::_( 'User Not Found.' );
97
- return false;
98
- }
99
- $check = $this->check_password( $pass, $userData->password );
100
- if ( ! $check ) {
101
- $this->isLoggedIn = false;
102
- $this->userData = null;
103
- $this->lastStatusMsg = SwpmUtils::_( 'Password Empty or Invalid.' );
104
- return false;
105
- }
106
- if ( $this->check_constraints() ) {
107
- $rememberme = filter_input( INPUT_POST, 'rememberme' );
108
- $remember = empty( $rememberme ) ? false : true;
109
- $this->set_cookie( $remember );
110
- $this->isLoggedIn = true;
111
- $this->lastStatusMsg = 'Logged In.';
112
- SwpmLog::log_auth_debug( 'Authentication successful for username: ' . $user . '. Executing swpm_login action hook.', true );
113
- do_action( 'swpm_login', $user, $pass, $remember );
114
- return true;
115
- }
116
- }
117
- return false;
118
- }
119
-
120
- private function check_constraints() {
121
- if ( empty( $this->userData ) ) {
122
- return false;
123
- }
124
- global $wpdb;
125
- $enable_expired_login = SwpmSettings::get_instance()->get_value( 'enable-expired-account-login', '' );
126
-
127
- //Update the last accessed date and IP address for this login attempt. $wpdb->update(table, data, where, format, where format)
128
- $last_accessed_date = current_time( 'mysql' );
129
- $last_accessed_ip = SwpmUtils::get_user_ip_address();
130
- $wpdb->update(
131
- $wpdb->prefix . 'swpm_members_tbl',
132
- array(
133
- 'last_accessed' => $last_accessed_date,
134
- 'last_accessed_from_ip' => $last_accessed_ip,
135
- ),
136
- array( 'member_id' => $this->userData->member_id ),
137
- array( '%s', '%s' ),
138
- array( '%d' )
139
- );
140
-
141
- //Check the member's account status.
142
- $can_login = true;
143
- if ( $this->userData->account_state == 'inactive' && empty( $enable_expired_login ) ) {
144
- $this->lastStatusMsg = SwpmUtils::_( 'Account is inactive.' );
145
- $can_login = false;
146
- } elseif ( ( $this->userData->account_state == 'expired' ) && empty( $enable_expired_login ) ) {
147
- $this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
148
- $can_login = false;
149
- } elseif ( $this->userData->account_state == 'pending' ) {
150
- $this->lastStatusMsg = SwpmUtils::_( 'Account is pending.' );
151
- $can_login = false;
152
- } elseif ( $this->userData->account_state == 'activation_required' ) {
153
- $resend_email_url = add_query_arg(
154
- array(
155
- 'swpm_resend_activation_email' => '1',
156
- 'swpm_member_id' => $this->userData->member_id,
157
- ),
158
- get_home_url()
159
- );
160
- $msg = sprintf( SwpmUtils::_( 'You need to activate your account. If you didn\'t receive an email then %s to resend the activation email.' ), '<a href="' . $resend_email_url . '">' . SwpmUtils::_( 'click here' ) . '</a>' );
161
- $this->lastStatusMsg = $msg;
162
- $can_login = false;
163
- }
164
-
165
- if ( ! $can_login ) {
166
- $this->isLoggedIn = false;
167
- $this->userData = null;
168
- return false;
169
- }
170
-
171
- if ( SwpmUtils::is_subscription_expired( $this->userData ) ) {
172
- if ( $this->userData->account_state == 'active' ) {
173
- $wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'account_state' => 'expired' ), array( 'member_id' => $this->userData->member_id ), array( '%s' ), array( '%d' ) );
174
- }
175
- if ( empty( $enable_expired_login ) ) {
176
- $this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
177
- $this->isLoggedIn = false;
178
- $this->userData = null;
179
- return false;
180
- }
181
- }
182
-
183
- $this->permitted = SwpmPermission::get_instance( $this->userData->membership_level );
184
- $this->lastStatusMsg = SwpmUtils::_( 'You are logged in as:' ) . $this->userData->user_name;
185
- $this->isLoggedIn = true;
186
- return true;
187
- }
188
-
189
- private function check_password( $plain_password, $hashed_pw ) {
190
- global $wp_hasher;
191
- if ( empty( $plain_password ) ) {
192
- return false;
193
- }
194
- if ( empty( $wp_hasher ) ) {
195
- require_once ABSPATH . 'wp-includes/class-phpass.php';
196
- $wp_hasher = new PasswordHash( 8, true );
197
- }
198
- return $wp_hasher->CheckPassword( $plain_password, $hashed_pw );
199
- }
200
-
201
- public function match_password( $password ) {
202
- if ( ! $this->is_logged_in() ) {
203
- return false;
204
- }
205
- return $this->check_password( $password, $this->get( 'password' ) );
206
- }
207
-
208
- public function login_to_swpm_using_wp_user( $user ) {
209
- if ( $this->isLoggedIn ) {
210
- return false;
211
- }
212
- $email = $user->user_email;
213
- $member = SwpmMemberUtils::get_user_by_email( $email );
214
- if ( empty( $member ) ) {
215
- //There is no swpm profile with this email.
216
- return false;
217
- }
218
- $this->userData = $member;
219
- $this->isLoggedIn = true;
220
- $this->set_cookie();
221
- SwpmLog::log_auth_debug( 'Member has been logged in using WP User object.', true );
222
- $this->check_constraints();
223
- return true;
224
- }
225
-
226
- public function login( $user, $pass, $remember = '', $secure = '' ) {
227
- SwpmLog::log_auth_debug( 'SwpmAuth::login()', true );
228
- if ( $this->isLoggedIn ) {
229
- return;
230
- }
231
- if ( $this->authenticate( $user, $pass ) && $this->validate() ) {
232
- $this->set_cookie( $remember, $secure );
233
- } else {
234
- $this->isLoggedIn = false;
235
- $this->userData = null;
236
- }
237
- return $this->lastStatusMsg;
238
- }
239
-
240
- public function logout() {
241
- if ( ! $this->isLoggedIn ) {
242
- return;
243
- }
244
- setcookie( SIMPLE_WP_MEMBERSHIP_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
245
- setcookie( SIMPLE_WP_MEMBERSHIP_SEC_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
246
- $this->userData = null;
247
- $this->isLoggedIn = false;
248
- $this->lastStatusMsg = SwpmUtils::_( 'Logged Out Successfully.' );
249
- do_action( 'swpm_logout' );
250
- }
251
-
252
- private function set_cookie( $remember = '', $secure = '' ) {
253
- if ( $remember ) {
254
- $expiration = time() + 1209600; //14 days
255
- $expire = $expiration + 43200; //12 hours grace period
256
- } else {
257
- $expiration = time() + 259200; //3 days.
258
- $expire = $expiration; //The minimum cookie expiration should be at least a few days.
259
- }
260
-
261
- $expire = apply_filters( 'swpm_auth_cookie_expiry_value', $expire );
262
-
263
- setcookie( 'swpm_in_use', 'swpm_in_use', $expire, COOKIEPATH, COOKIE_DOMAIN );
264
-
265
- $expiration_timestamp = SwpmUtils::get_expiration_timestamp( $this->userData );
266
- $enable_expired_login = SwpmSettings::get_instance()->get_value( 'enable-expired-account-login', '' );
267
- // make sure cookie doesn't live beyond account expiration date.
268
- // but if expired account login is enabled then ignore if account is expired
269
- $expiration = empty( $enable_expired_login ) ? min( $expiration, $expiration_timestamp ) : $expiration;
270
- $pass_frag = substr( $this->userData->password, 8, 4 );
271
- $scheme = 'auth';
272
- if ( ! $secure ) {
273
- $secure = is_ssl();
274
- }
275
- $key = self::b_hash( $this->userData->user_name . $pass_frag . '|' . $expiration, $scheme );
276
- $hash = hash_hmac( 'md5', $this->userData->user_name . '|' . $expiration, $key );
277
- $auth_cookie = $this->userData->user_name . '|' . $expiration . '|' . $hash;
278
- $auth_cookie_name = $secure ? SIMPLE_WP_MEMBERSHIP_SEC_AUTH : SIMPLE_WP_MEMBERSHIP_AUTH;
279
- setcookie( $auth_cookie_name, $auth_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
280
- }
281
-
282
- private function validate() {
283
- $auth_cookie_name = is_ssl() ? SIMPLE_WP_MEMBERSHIP_SEC_AUTH : SIMPLE_WP_MEMBERSHIP_AUTH;
284
- if ( ! isset( $_COOKIE[ $auth_cookie_name ] ) || empty( $_COOKIE[ $auth_cookie_name ] ) ) {
285
- return false;
286
- }
287
- $cookie_elements = explode( '|', $_COOKIE[ $auth_cookie_name ] );
288
- if ( count( $cookie_elements ) != 3 ) {
289
- return false;
290
- }
291
-
292
- //SwpmLog::log_auth_debug("validate() - " . $_COOKIE[$auth_cookie_name], true);
293
- list($username, $expiration, $hmac) = $cookie_elements;
294
- $expired = $expiration;
295
- // Allow a grace period for POST and AJAX requests
296
- if ( defined( 'DOING_AJAX' ) || 'POST' == $_SERVER['REQUEST_METHOD'] ) {
297
- $expired += HOUR_IN_SECONDS;
298
- }
299
- // Quick check to see if an honest cookie has expired
300
- if ( $expired < time() ) {
301
- $this->lastStatusMsg = SwpmUtils::_( 'Session Expired.' ); //do_action('auth_cookie_expired', $cookie_elements);
302
- SwpmLog::log_auth_debug( 'validate() - Session Expired', true );
303
- return false;
304
- }
305
-
306
- global $wpdb;
307
- $query = ' SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE user_name = %s';
308
- $user = $wpdb->get_row( $wpdb->prepare( $query, $username ) );
309
- if ( empty( $user ) ) {
310
- $this->lastStatusMsg = SwpmUtils::_( 'Invalid Username' );
311
- return false;
312
- }
313
-
314
- $pass_frag = substr( $user->password, 8, 4 );
315
- $key = self::b_hash( $username . $pass_frag . '|' . $expiration );
316
- $hash = hash_hmac( 'md5', $username . '|' . $expiration, $key );
317
- if ( $hmac != $hash ) {
318
- $this->lastStatusMsg = SwpmUtils::_( 'Please login again.' );
319
- SwpmLog::log_auth_debug( 'validate() - Bad Hash', true );
320
- do_action('swpm_validate_login_hash_mismatch');
321
- wp_logout(); //Force logout of WP user session to clear the bad hash.
322
- return false;
323
- }
324
-
325
- if ( $expiration < time() ) {
326
- $GLOBALS['login_grace_period'] = 1;
327
- }
328
- $this->userData = $user;
329
- return $this->check_constraints();
330
- }
331
-
332
- public static function b_hash( $data, $scheme = 'auth' ) {
333
- $salt = wp_salt( $scheme ) . 'j4H!B3TA,J4nIn4.';
334
- return hash_hmac( 'md5', $data, $salt );
335
- }
336
-
337
- public function is_logged_in() {
338
- return $this->isLoggedIn;
339
- }
340
-
341
- public function get( $key, $default = '' ) {
342
- if ( isset( $this->userData->$key ) ) {
343
- return $this->userData->$key;
344
- }
345
- if ( isset( $this->permitted->$key ) ) {
346
- return $this->permitted->$key;
347
- }
348
- if ( ! empty( $this->permitted ) ) {
349
- return $this->permitted->get( $key, $default );
350
- }
351
- return $default;
352
- }
353
-
354
- public function get_message() {
355
- return $this->lastStatusMsg;
356
- }
357
-
358
- public function get_expire_date() {
359
- if ( $this->isLoggedIn ) {
360
- return SwpmUtils::get_formatted_expiry_date( $this->get( 'subscription_starts' ), $this->get( 'subscription_period' ), $this->get( 'subscription_duration_type' ) );
361
- }
362
- return '';
363
- }
364
-
365
- public function delete() {
366
- if ( ! $this->is_logged_in() ) {
367
- return;
368
- }
369
- $user_name = $this->get( 'user_name' );
370
- $user_id = $this->get( 'member_id' );
371
- $subscr_id = $this->get( 'subscr_id' );
372
- $email = $this->get( 'email' );
373
-
374
- $this->logout();
375
- wp_clear_auth_cookie();
376
-
377
- SwpmMembers::delete_swpm_user_by_id( $user_id );
378
- SwpmMembers::delete_wp_user( $user_name );
379
- }
380
-
381
- public function reload_user_data() {
382
- if ( ! $this->is_logged_in() ) {
383
- return;
384
- }
385
- global $wpdb;
386
- $query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE member_id = %d';
387
- $this->userData = $wpdb->get_row( $wpdb->prepare( $query, $this->userData->member_id ) );
388
- }
389
-
390
- public function is_expired_account() {
391
- if ( ! $this->is_logged_in() ) {
392
- return null;
393
- }
394
- $account_status = $this->get( 'account_state' );
395
- if ( $account_status == 'expired' || $account_status == 'inactive' ) {
396
- //Expired or Inactive accounts are both considered to be expired.
397
- return true;
398
- }
399
- return false;
400
- }
401
-
402
- }
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class SwpmAuth {
4
+
5
+ public $protected;
6
+ public $permitted;
7
+ private $isLoggedIn;
8
+ private $lastStatusMsg;
9
+ private static $_this;
10
+ public $userData;
11
+
12
+ private function __construct() {
13
+ //check if we need to display custom message on the login form
14
+ $custom_msg = filter_input( INPUT_COOKIE, 'swpm-login-form-custom-msg', FILTER_SANITIZE_STRING );
15
+ if ( ! empty( $custom_msg ) ) {
16
+ $this->lastStatusMsg = $custom_msg;
17
+ //let's 'unset' the cookie
18
+ setcookie( 'swpm-login-form-custom-msg', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN );
19
+ }
20
+ $this->isLoggedIn = false;
21
+ $this->userData = null;
22
+ $this->protected = SwpmProtection::get_instance();
23
+ }
24
+
25
+ private function init() {
26
+ $valid = $this->validate();
27
+ //SwpmLog::log_auth_debug("init:". ($valid? "valid": "invalid"), true);
28
+ if ( ! $valid ) {
29
+ $this->authenticate();
30
+ }
31
+ }
32
+
33
+ public static function get_instance() {
34
+ if ( empty( self::$_this ) ) {
35
+ self::$_this = new SwpmAuth();
36
+ self::$_this->init();
37
+ }
38
+ return self::$_this;
39
+ }
40
+
41
+ private function authenticate( $user = null, $pass = null ) {
42
+ global $wpdb;
43
+ $swpm_password = empty( $pass ) ? filter_input( INPUT_POST, 'swpm_password' ) : $pass;
44
+ $swpm_user_name = empty( $user ) ? apply_filters( 'swpm_user_name', filter_input( INPUT_POST, 'swpm_user_name' ) ) : $user;
45
+
46
+ if ( ! empty( $swpm_user_name ) && ! empty( $swpm_password ) ) {
47
+ //SWPM member login request.
48
+ //Trigger action hook that can be used to check stuff before the login request is processed by the plugin.
49
+ $args = array(
50
+ 'username' => $swpm_user_name,
51
+ 'password' => $swpm_password,
52
+ );
53
+ do_action( 'swpm_before_login_request_is_processed', $args );
54
+
55
+ //First, lets make sure this user is not already logged into the site as an "Admin" user. We don't want to override that admin login session.
56
+ if ( current_user_can( 'administrator' ) ) {
57
+ //This user is logged in as ADMIN then trying to do another login as a member. Stop the login request processing (we don't want to override your admin login session).
58
+ $wp_profile_page = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/wp-admin/profile.php';
59
+ $error_msg = '';
60
+ $error_msg .= '<p>' . SwpmUtils::_( 'Warning! Simple Membership plugin cannot process this login request to prevent you from getting logged out of WP Admin accidentally.' ) . '</p>';
61
+ $error_msg .= '<p><a href="' . $wp_profile_page . '" target="_blank">' . SwpmUtils::_( 'Click here' ) . '</a>' . SwpmUtils::_( ' to see the profile you are currently logged into in this browser.' ) . '</p>';
62
+ $error_msg .= '<p>' . SwpmUtils::_( 'You are logged into the site as an ADMIN user in this browser. First, logout from WP Admin then you will be able to log in as a normal member.' ) . '</p>';
63
+ $error_msg .= '<p>' . SwpmUtils::_( 'Alternatively, you can use a different browser (where you are not logged-in as ADMIN) to test the membership login.' ) . '</p>';
64
+ $error_msg .= '<p>' . SwpmUtils::_( 'Your normal visitors or members will never see this message. This message is ONLY for ADMIN user.' ) . '</p>';
65
+ wp_die( $error_msg );
66
+ }
67
+
68
+ //If captcha is present and validation failed, it returns an error string. If validation succeeds, it returns an empty string.
69
+ $captcha_validation_output = apply_filters( 'swpm_validate_login_form_submission', '' );
70
+ if ( ! empty( $captcha_validation_output ) ) {
71
+ $this->lastStatusMsg = SwpmUtils::_( 'Captcha validation failed on login form.' );
72
+ return;
73
+ }
74
+
75
+ if ( is_email( $swpm_user_name ) ) {//User is trying to log-in using an email address
76
+ $email = sanitize_email( $swpm_user_name );
77
+ $query = $wpdb->prepare( 'SELECT user_name FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE email = %s', $email );
78
+ $username = $wpdb->get_var( $query );
79
+ if ( $username ) {//Found a user record
80
+ $swpm_user_name = $username; //Grab the usrename value so it can be used in the authentication process.
81
+ SwpmLog::log_auth_debug( 'Authentication request using email address: ' . $email . ', Found a user record with username: ' . $swpm_user_name, true );
82
+ }
83
+ }
84
+
85
+ //Lets process the request. Check username and password
86
+ $user = sanitize_user( $swpm_user_name );
87
+ $pass = trim( $swpm_password );
88
+ SwpmLog::log_auth_debug( 'Authentication request - Username: ' . $swpm_user_name, true );
89
+
90
+ $query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE user_name = %s';
91
+ $userData = $wpdb->get_row( $wpdb->prepare( $query, $user ) );
92
+ $this->userData = $userData;
93
+ if ( ! $userData ) {
94
+ $this->isLoggedIn = false;
95
+ $this->userData = null;
96
+ $this->lastStatusMsg = SwpmUtils::_( 'User Not Found.' );
97
+ return false;
98
+ }
99
+ $check = $this->check_password( $pass, $userData->password );
100
+ if ( ! $check ) {
101
+ $this->isLoggedIn = false;
102
+ $this->userData = null;
103
+ $this->lastStatusMsg = SwpmUtils::_( 'Password Empty or Invalid.' );
104
+ return false;
105
+ }
106
+ if ( $this->check_constraints() ) {
107
+ $rememberme = filter_input( INPUT_POST, 'rememberme' );
108
+ $remember = empty( $rememberme ) ? false : true;
109
+ $this->set_cookie( $remember );
110
+ $this->isLoggedIn = true;
111
+ $this->lastStatusMsg = 'Logged In.';
112
+ SwpmLog::log_auth_debug( 'Authentication successful for username: ' . $user . '. Executing swpm_login action hook.', true );
113
+ do_action( 'swpm_login', $user, $pass, $remember );
114
+ return true;
115
+ }
116
+ }
117
+ return false;
118
+ }
119
+
120
+ private function check_constraints() {
121
+ if ( empty( $this->userData ) ) {
122
+ return false;
123
+ }
124
+ global $wpdb;
125
+ $enable_expired_login = SwpmSettings::get_instance()->get_value( 'enable-expired-account-login', '' );
126
+
127
+ //Update the last accessed date and IP address for this login attempt. $wpdb->update(table, data, where, format, where format)
128
+ $last_accessed_date = current_time( 'mysql' );
129
+ $last_accessed_ip = SwpmUtils::get_user_ip_address();
130
+ $wpdb->update(
131
+ $wpdb->prefix . 'swpm_members_tbl',
132
+ array(
133
+ 'last_accessed' => $last_accessed_date,
134
+ 'last_accessed_from_ip' => $last_accessed_ip,
135
+ ),
136
+ array( 'member_id' => $this->userData->member_id ),
137
+ array( '%s', '%s' ),
138
+ array( '%d' )
139
+ );
140
+
141
+ //Check the member's account status.
142
+ $can_login = true;
143
+ if ( $this->userData->account_state == 'inactive' && empty( $enable_expired_login ) ) {
144
+ $this->lastStatusMsg = SwpmUtils::_( 'Account is inactive.' );
145
+ $can_login = false;
146
+ } elseif ( ( $this->userData->account_state == 'expired' ) && empty( $enable_expired_login ) ) {
147
+ $this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
148
+ $can_login = false;
149
+ } elseif ( $this->userData->account_state == 'pending' ) {
150
+ $this->lastStatusMsg = SwpmUtils::_( 'Account is pending.' );
151
+ $can_login = false;
152
+ } elseif ( $this->userData->account_state == 'activation_required' ) {
153
+ $resend_email_url = add_query_arg(
154
+ array(
155
+ 'swpm_resend_activation_email' => '1',
156
+ 'swpm_member_id' => $this->userData->member_id,
157
+ ),
158
+ get_home_url()
159
+ );
160
+ $msg = sprintf( SwpmUtils::_( 'You need to activate your account. If you didn\'t receive an email then %s to resend the activation email.' ), '<a href="' . $resend_email_url . '">' . SwpmUtils::_( 'click here' ) . '</a>' );
161
+ $this->lastStatusMsg = $msg;
162
+ $can_login = false;
163
+ }
164
+
165
+ if ( ! $can_login ) {
166
+ $this->isLoggedIn = false;
167
+ $this->userData = null;
168
+ return false;
169
+ }
170
+
171
+ if ( SwpmUtils::is_subscription_expired( $this->userData ) ) {
172
+ if ( $this->userData->account_state == 'active' ) {
173
+ $wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'account_state' => 'expired' ), array( 'member_id' => $this->userData->member_id ), array( '%s' ), array( '%d' ) );
174
+ }
175
+ if ( empty( $enable_expired_login ) ) {
176
+ $this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
177
+ $this->isLoggedIn = false;
178
+ $this->userData = null;
179
+ return false;
180
+ }
181
+ }
182
+
183
+ $this->permitted = SwpmPermission::get_instance( $this->userData->membership_level );
184
+ $this->lastStatusMsg = SwpmUtils::_( 'You are logged in as:' ) . $this->userData->user_name;
185
+ $this->isLoggedIn = true;
186
+ return true;
187
+ }
188
+
189
+ private function check_password( $plain_password, $hashed_pw ) {
190
+ global $wp_hasher;
191
+ if ( empty( $plain_password ) ) {
192
+ return false;
193
+ }
194
+ if ( empty( $wp_hasher ) ) {
195
+ require_once ABSPATH . 'wp-includes/class-phpass.php';
196
+ $wp_hasher = new PasswordHash( 8, true );
197
+ }
198
+ return $wp_hasher->CheckPassword( $plain_password, $hashed_pw );
199
+ }
200
+
201
+ public function match_password( $password ) {
202
+ if ( ! $this->is_logged_in() ) {
203
+ return false;
204
+ }
205
+ return $this->check_password( $password, $this->get( 'password' ) );
206
+ }
207
+
208
+ public function login_to_swpm_using_wp_user( $user ) {
209
+ if ( $this->isLoggedIn ) {
210
+ return false;
211
+ }
212
+ $email = $user->user_email;
213
+ $member = SwpmMemberUtils::get_user_by_email( $email );
214
+ if ( empty( $member ) ) {
215
+ //There is no swpm profile with this email.
216
+ return false;
217
+ }
218
+ $this->userData = $member;
219
+ $this->isLoggedIn = true;
220
+ $this->set_cookie();
221
+ SwpmLog::log_auth_debug( 'Member has been logged in using WP User object.', true );
222
+ $this->check_constraints();
223
+ return true;
224
+ }
225
+
226
+ public function login( $user, $pass, $remember = '', $secure = '' ) {
227
+ SwpmLog::log_auth_debug( 'SwpmAuth::login()', true );
228
+ if ( $this->isLoggedIn ) {
229
+ return;
230
+ }
231
+ if ( $this->authenticate( $user, $pass ) && $this->validate() ) {
232
+ $this->set_cookie( $remember, $secure );
233
+ } else {
234
+ $this->isLoggedIn = false;
235
+ $this->userData = null;
236
+ }
237
+ return $this->lastStatusMsg;
238
+ }
239
+
240
+ public function logout() {
241
+ if ( ! $this->isLoggedIn ) {
242
+ return;
243
+ }
244
+ setcookie( SIMPLE_WP_MEMBERSHIP_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
245
+ setcookie( SIMPLE_WP_MEMBERSHIP_SEC_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
246
+ $this->userData = null;
247
+ $this->isLoggedIn = false;
248
+ $this->lastStatusMsg = SwpmUtils::_( 'Logged Out Successfully.' );
249
+ do_action( 'swpm_logout' );
250
+ }
251
+
252
+ private function set_cookie( $remember = '', $secure = '' ) {
253
+ if ( $remember ) {
254
+ $expiration = time() + 1209600; //14 days
255
+ $expire = $expiration + 43200; //12 hours grace period
256
+ } else {
257
+ $expiration = time() + 259200; //3 days.
258
+ $expire = $expiration; //The minimum cookie expiration should be at least a few days.
259
+ }
260
+
261
+ $expire = apply_filters( 'swpm_auth_cookie_expiry_value', $expire );
262
+
263
+ setcookie( 'swpm_in_use', 'swpm_in_use', $expire, COOKIEPATH, COOKIE_DOMAIN );//Switch this to the following one.
264
+ setcookie( 'wp_swpm_in_use', 'wp_swpm_in_use', $expire, COOKIEPATH, COOKIE_DOMAIN );//Prefix the cookie with 'wp' to exclude Batcache caching.
265
+ if ( function_exists( 'wp_cache_serve_cache_file' ) ) {//WP Super cache workaround
266
+ $author_value = isset( $this->userData->user_name ) ? $this->userData->user_name : 'wp_swpm';
267
+ $author_value = apply_filters( 'swpm_comment_author_cookie_value', $author_value );
268
+ setcookie( "comment_author_", $author_value, $expire, COOKIEPATH, COOKIE_DOMAIN );
269
+ }
270
+
271
+ $expiration_timestamp = SwpmUtils::get_expiration_timestamp( $this->userData );
272
+ $enable_expired_login = SwpmSettings::get_instance()->get_value( 'enable-expired-account-login', '' );
273
+ // make sure cookie doesn't live beyond account expiration date.
274
+ // but if expired account login is enabled then ignore if account is expired
275
+ $expiration = empty( $enable_expired_login ) ? min( $expiration, $expiration_timestamp ) : $expiration;
276
+ $pass_frag = substr( $this->userData->password, 8, 4 );
277
+ $scheme = 'auth';
278
+ if ( ! $secure ) {
279
+ $secure = is_ssl();
280
+ }
281
+ $key = self::b_hash( $this->userData->user_name . $pass_frag . '|' . $expiration, $scheme );
282
+ $hash = hash_hmac( 'md5', $this->userData->user_name . '|' . $expiration, $key );
283
+ $auth_cookie = $this->userData->user_name . '|' . $expiration . '|' . $hash;
284
+ $auth_cookie_name = $secure ? SIMPLE_WP_MEMBERSHIP_SEC_AUTH : SIMPLE_WP_MEMBERSHIP_AUTH;
285
+ setcookie( $auth_cookie_name, $auth_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
286
+ }
287
+
288
+ private function validate() {
289
+ $auth_cookie_name = is_ssl() ? SIMPLE_WP_MEMBERSHIP_SEC_AUTH : SIMPLE_WP_MEMBERSHIP_AUTH;
290
+ if ( ! isset( $_COOKIE[ $auth_cookie_name ] ) || empty( $_COOKIE[ $auth_cookie_name ] ) ) {
291
+ return false;
292
+ }
293
+ $cookie_elements = explode( '|', $_COOKIE[ $auth_cookie_name ] );
294
+ if ( count( $cookie_elements ) != 3 ) {
295
+ return false;
296
+ }
297
+
298
+ //SwpmLog::log_auth_debug("validate() - " . $_COOKIE[$auth_cookie_name], true);
299
+ list($username, $expiration, $hmac) = $cookie_elements;
300
+ $expired = $expiration;
301
+ // Allow a grace period for POST and AJAX requests
302
+ if ( defined( 'DOING_AJAX' ) || 'POST' == $_SERVER['REQUEST_METHOD'] ) {
303
+ $expired += HOUR_IN_SECONDS;
304
+ }
305
+ // Quick check to see if an honest cookie has expired
306
+ if ( $expired < time() ) {
307
+ $this->lastStatusMsg = SwpmUtils::_( 'Session Expired.' ); //do_action('auth_cookie_expired', $cookie_elements);
308
+ SwpmLog::log_auth_debug( 'validate() - Session Expired', true );
309
+ return false;
310
+ }
311
+
312
+ global $wpdb;
313
+ $query = ' SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE user_name = %s';
314
+ $user = $wpdb->get_row( $wpdb->prepare( $query, $username ) );
315
+ if ( empty( $user ) ) {
316
+ $this->lastStatusMsg = SwpmUtils::_( 'Invalid Username' );
317
+ return false;
318
+ }
319
+
320
+ $pass_frag = substr( $user->password, 8, 4 );
321
+ $key = self::b_hash( $username . $pass_frag . '|' . $expiration );
322
+ $hash = hash_hmac( 'md5', $username . '|' . $expiration, $key );
323
+ if ( $hmac != $hash ) {
324
+ $this->lastStatusMsg = SwpmUtils::_( 'Please login again.' );
325
+ SwpmLog::log_auth_debug( 'validate() - Bad Hash', true );
326
+ do_action('swpm_validate_login_hash_mismatch');
327
+ wp_logout(); //Force logout of WP user session to clear the bad hash.
328
+ return false;
329
+ }
330
+
331
+ if ( $expiration < time() ) {
332
+ $GLOBALS['login_grace_period'] = 1;
333
+ }
334
+ $this->userData = $user;
335
+ return $this->check_constraints();
336
+ }
337
+
338
+ public static function b_hash( $data, $scheme = 'auth' ) {
339
+ $salt = wp_salt( $scheme ) . 'j4H!B3TA,J4nIn4.';
340
+ return hash_hmac( 'md5', $data, $salt );
341
+ }
342
+
343
+ public function is_logged_in() {
344
+ return $this->isLoggedIn;
345
+ }
346
+
347
+ public function get( $key, $default = '' ) {
348
+ if ( isset( $this->userData->$key ) ) {
349
+ return $this->userData->$key;
350
+ }
351
+ if ( isset( $this->permitted->$key ) ) {
352
+ return $this->permitted->$key;
353
+ }
354
+ if ( ! empty( $this->permitted ) ) {
355
+ return $this->permitted->get( $key, $default );
356
+ }
357
+ return $default;
358
+ }
359
+
360
+ public function get_message() {
361
+ return $this->lastStatusMsg;
362
+ }
363
+
364
+ public function get_expire_date() {
365
+ if ( $this->isLoggedIn ) {
366
+ return SwpmUtils::get_formatted_expiry_date( $this->get( 'subscription_starts' ), $this->get( 'subscription_period' ), $this->get( 'subscription_duration_type' ) );
367
+ }
368
+ return '';
369
+ }
370
+
371
+ public function delete() {
372
+ if ( ! $this->is_logged_in() ) {
373
+ return;
374
+ }
375
+ $user_name = $this->get( 'user_name' );
376
+ $user_id = $this->get( 'member_id' );
377
+ $subscr_id = $this->get( 'subscr_id' );
378
+ $email = $this->get( 'email' );
379
+
380
+ $this->logout();
381
+ wp_clear_auth_cookie();
382
+
383
+ SwpmMembers::delete_swpm_user_by_id( $user_id );
384
+ SwpmMembers::delete_wp_user( $user_name );
385
+ }
386
+
387
+ public function reload_user_data() {
388
+ if ( ! $this->is_logged_in() ) {
389
+ return;
390
+ }
391
+ global $wpdb;
392
+ $query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE member_id = %d';
393
+ $this->userData = $wpdb->get_row( $wpdb->prepare( $query, $this->userData->member_id ) );
394
+ }
395
+
396
+ public function is_expired_account() {
397
+ if ( ! $this->is_logged_in() ) {
398
+ return null;
399
+ }
400
+ $account_status = $this->get( 'account_state' );
401
+ if ( $account_status == 'expired' || $account_status == 'inactive' ) {
402
+ //Expired or Inactive accounts are both considered to be expired.
403
+ return true;
404
+ }
405
+ return false;
406
+ }
407
+
408
+ }
classes/class.swpm-form.php CHANGED
@@ -88,7 +88,7 @@ class SwpmForm {
88
  $this->errors['password'] = SwpmUtils::_('Password mismatch');
89
  }
90
  $this->sanitized['plain_password'] = $password;
91
- $this->sanitized['password'] = SwpmUtils::encrypt_password(trim($password)); //should use $saned??;
92
  }
93
  }
94
 
88
  $this->errors['password'] = SwpmUtils::_('Password mismatch');
89
  }
90
  $this->sanitized['plain_password'] = $password;
91
+ $this->sanitized['password'] = SwpmUtils::encrypt_password(trim($saned));
92
  }
93
  }
94
 
classes/class.swpm-front-registration.php CHANGED
@@ -221,6 +221,10 @@ class SwpmFrontRegistration extends SwpmRegistration {
221
  unset( $member_info['plain_password'] );
222
 
223
  if ( SwpmUtils::is_paid_registration() ) {
 
 
 
 
224
  $member_info['reg_code'] = '';
225
  $member_id = filter_input( INPUT_GET, 'member_id', FILTER_SANITIZE_NUMBER_INT );
226
  $code = filter_input( INPUT_GET, 'code', FILTER_SANITIZE_STRING );
@@ -410,7 +414,7 @@ class SwpmFrontRegistration extends SwpmRegistration {
410
  //Trigger a hook
411
  $password = apply_filters( 'swpm_password_reset_generated_pass', $password );
412
 
413
- $password_hash = SwpmUtils::encrypt_password( trim( $password ) ); //should use $saned??;
414
  $wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'password' => $password_hash ), array( 'member_id' => $user->member_id ) );
415
 
416
  //Update wp user password
221
  unset( $member_info['plain_password'] );
222
 
223
  if ( SwpmUtils::is_paid_registration() ) {
224
+ //Remove any empty values from the array. This will preserve address information if it was received via the payment gateway.
225
+ $member_info = array_filter($member_info);
226
+
227
+ //Handle DB insert for paid registration scenario.
228
  $member_info['reg_code'] = '';
229
  $member_id = filter_input( INPUT_GET, 'member_id', FILTER_SANITIZE_NUMBER_INT );
230
  $code = filter_input( INPUT_GET, 'code', FILTER_SANITIZE_STRING );
414
  //Trigger a hook
415
  $password = apply_filters( 'swpm_password_reset_generated_pass', $password );
416
 
417
+ $password_hash = SwpmUtils::encrypt_password( trim( $password ) );
418
  $wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'password' => $password_hash ), array( 'member_id' => $user->member_id ) );
419
 
420
  //Update wp user password
classes/class.swpm-members.php CHANGED
@@ -59,7 +59,8 @@ class SwpmMembers extends WP_List_Table {
59
  }
60
 
61
  function column_default( $item, $column_name ) {
62
- $column_data = apply_filters( 'swpm_admin_members_table_column_' . $column_name, $item[ $column_name ], $item );
 
63
  return $column_data;
64
  }
65
 
59
  }
60
 
61
  function column_default( $item, $column_name ) {
62
+ $column_value = isset( $item[ $column_name ] ) ? $item[ $column_name ] : '';
63
+ $column_data = apply_filters( 'swpm_admin_members_table_column_' . $column_name, $column_value, $item );
64
  return $column_data;
65
  }
66
 
classes/class.swpm-utils.php CHANGED
@@ -630,9 +630,9 @@ abstract class SwpmUtils {
630
  }
631
 
632
  public static function csv_equal_match( $needle, $haystack_csv ) {
633
- //converting to lowercase
634
  if($haystack_csv && strlen($haystack_csv)>0) {
635
- $haystack_csv = strtolower($haystack_csv);
 
636
  $haystack_csv_array = explode(",",$haystack_csv);
637
 
638
  foreach($haystack_csv_array as $value) {
@@ -647,9 +647,17 @@ abstract class SwpmUtils {
647
 
648
  public static function csv_pattern_match( $needle, $haystack_csv ) {
649
  if($haystack_csv && strlen($haystack_csv)>0) {
650
- if(stripos($needle,$haystack_csv)!==false) {
651
- return true;
652
- }
 
 
 
 
 
 
 
 
653
  }
654
  return false;
655
  }
630
  }
631
 
632
  public static function csv_equal_match( $needle, $haystack_csv ) {
 
633
  if($haystack_csv && strlen($haystack_csv)>0) {
634
+ //Converting to lowercase for better matching
635
+ $haystack_csv = strtolower($haystack_csv);
636
  $haystack_csv_array = explode(",",$haystack_csv);
637
 
638
  foreach($haystack_csv_array as $value) {
647
 
648
  public static function csv_pattern_match( $needle, $haystack_csv ) {
649
  if($haystack_csv && strlen($haystack_csv)>0) {
650
+ //For pattern match, we need to check if any of the individual pattern matches with any part/full of the entered user email address.
651
+ $user_email_address = $needle;//We need to search each pattern entry within this user email address value to see if there is any match.
652
+ $haystack_csv = strtolower($haystack_csv);
653
+ $haystack_csv_array = explode(",",$haystack_csv);
654
+ foreach($haystack_csv_array as $findme) {
655
+ $findme = trim($findme);
656
+ if(stripos($user_email_address, $findme)!==false) {
657
+ //Found a match for the pattern.
658
+ return true;
659
+ }
660
+ }
661
  }
662
  return false;
663
  }
images/addons/swpm-mailerlite-integration.png ADDED
Binary file
ipn/swpm-braintree-buy-now-ipn.php CHANGED
@@ -60,11 +60,14 @@ class SwpmBraintreeBuyNowIpnHandler {
60
 
61
  $braintree_merc_acc_name = get_post_meta($button_id, 'braintree_merchant_acc_name', true);
62
 
 
63
 
64
  // Create the charge on Braintree's servers - this will charge the user's card
65
 
66
  $nonce = sanitize_text_field($_POST['payment_method_nonce']);
67
 
 
 
68
  $result = Braintree_Transaction::sale([
69
  'amount' => $payment_amount,
70
  'paymentMethodNonce' => $nonce,
@@ -80,7 +83,9 @@ class SwpmBraintreeBuyNowIpnHandler {
80
  }
81
 
82
  if (!$result->success) {
83
- SwpmLog::log_simple_debug("Braintree transaction error occurred: " . $result->transaction->status . ", button ID: " . $button_id, false);
 
 
84
  wp_die("Braintree transaction error occurred: " . $result->transaction->status);
85
  } else {
86
 
60
 
61
  $braintree_merc_acc_name = get_post_meta($button_id, 'braintree_merchant_acc_name', true);
62
 
63
+
64
 
65
  // Create the charge on Braintree's servers - this will charge the user's card
66
 
67
  $nonce = sanitize_text_field($_POST['payment_method_nonce']);
68
 
69
+
70
+
71
  $result = Braintree_Transaction::sale([
72
  'amount' => $payment_amount,
73
  'paymentMethodNonce' => $nonce,
83
  }
84
 
85
  if (!$result->success) {
86
+
87
+
88
+ SwpmLog::log_simple_debug("Braintree transaction error occurred: " . $result->transaction->status . ", message: ".$result->message." , button ID: " . $button_id, false);
89
  wp_die("Braintree transaction error occurred: " . $result->transaction->status);
90
  } else {
91
 
ipn/swpm-stripe-sca-buy-now-ipn.php CHANGED
@@ -1,381 +1,392 @@
1
- <?php
2
-
3
- class SwpmStripeSCABuyNowIpnHandler {
4
-
5
- public function __construct() {
6
- //check if this is session create request
7
- if ( wp_doing_ajax() ) {
8
- $action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
9
- if ( 'swpm_stripe_sca_create_checkout_session' === $action ) {
10
- add_action( 'wp_ajax_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
11
- add_action( 'wp_ajax_nopriv_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
12
- }
13
- return;
14
- }
15
-
16
- require_once SIMPLE_WP_MEMBERSHIP_PATH . 'ipn/swpm_handle_subsc_ipn.php';
17
- $this->handle_stripe_ipn();
18
- }
19
-
20
- public function handle_stripe_ipn() {
21
- SwpmLog::log_simple_debug( 'Stripe SCA Buy Now IPN received. Processing request...', true );
22
- // SwpmLog::log_simple_debug(print_r($_REQUEST, true), true);//Useful for debugging purpose
23
-
24
- // Read and sanitize the request parameters.
25
-
26
- $ref_id = filter_input( INPUT_GET, 'ref_id', FILTER_SANITIZE_STRING );
27
-
28
- if ( empty( $ref_id ) ) {
29
- //no ref id provided, cannot proceed
30
- SwpmLog::log_simple_debug( 'Fatal Error! No ref_id provied.', false );
31
- wp_die( esc_html( 'Fatal Error! No ref_id provied.' ) );
32
-
33
- }
34
-
35
- $trans_info = explode( '|', $ref_id );
36
- $button_id = isset( $trans_info[1] ) ? absint( $trans_info[1] ) : false;
37
-
38
- // Retrieve the CPT for this button
39
- $button_cpt = get_post( $button_id );
40
- if ( ! $button_cpt ) {
41
- // Fatal error. Could not find this payment button post object.
42
- SwpmLog::log_simple_debug( 'Fatal Error! Failed to retrieve the payment button post object for the given button ID: ' . $button_id, false );
43
- wp_die( esc_html( sprintf( 'Fatal Error! Payment button (ID: %d) does not exist. This request will fail.', $button_id ) ) );
44
- }
45
-
46
- $settings = SwpmSettings::get_instance();
47
- $sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
48
-
49
- //API keys
50
- $api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
51
-
52
- // Include the Stripe library.
53
- SwpmMiscUtils::load_stripe_lib();
54
-
55
- try {
56
- \Stripe\Stripe::setApiKey( $api_keys['secret'] );
57
-
58
- $events = \Stripe\Event::all(
59
- array(
60
- 'type' => 'checkout.session.completed',
61
- 'created' => array(
62
- 'gte' => time() - 60 * 60,
63
- ),
64
- )
65
- );
66
-
67
- $sess = false;
68
-
69
- foreach ( $events->autoPagingIterator() as $event ) {
70
- $session = $event->data->object;
71
- if ( isset( $session->client_reference_id ) && $session->client_reference_id === $ref_id ) {
72
- $sess = $session;
73
- break;
74
- }
75
- }
76
-
77
- if ( false === $sess ) {
78
- // Can't find session.
79
- $error_msg = sprintf( "Fatal error! Payment with ref_id %s can't be found", $ref_id );
80
- SwpmLog::log_simple_debug( $error_msg, false );
81
- wp_die( esc_html( $error_msg ) );
82
- }
83
-
84
- $pi_id = $sess->payment_intent;
85
-
86
- $pi = \Stripe\PaymentIntent::retrieve( $pi_id );
87
- } catch ( Exception $e ) {
88
- $error_msg = 'Error occurred: ' . $e->getMessage();
89
- SwpmLog::log_simple_debug( $error_msg, false );
90
- wp_die( esc_html( $error_msg ) );
91
- }
92
-
93
- $charge = $pi->charges;
94
-
95
- // Grab the charge ID and set it as the transaction ID.
96
- $txn_id = $charge->data[0]->id;
97
- // The charge ID can be used to retrieve the transaction details using hte following call.
98
- // \Stripe\Charge::retrieve($charge->$data[0]->id);
99
-
100
- //check if this payment has already been processed
101
- $payment = get_posts(
102
- array(
103
- 'meta_key' => 'txn_id',
104
- 'meta_value' => $txn_id,
105
- 'posts_per_page' => 1,
106
- 'offset' => 0,
107
- 'post_type' => 'swpm_transactions',
108
- )
109
- );
110
- wp_reset_postdata();
111
-
112
- if ( $payment ) {
113
- //payment has already been processed. Redirecting user to return_url
114
- $return_url = get_post_meta( $button_id, 'return_url', true );
115
- if ( empty( $return_url ) ) {
116
- $return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
117
- }
118
- SwpmMiscUtils::redirect_to_url( $return_url );
119
- return;
120
- }
121
-
122
- $price_in_cents = floatval( $pi->amount_received );
123
- $currency_code = strtoupper( $pi->currency );
124
-
125
- $zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
126
- if ( in_array( $currency_code, $zero_cents, true ) ) {
127
- $payment_amount = $price_in_cents;
128
- } else {
129
- $payment_amount = $price_in_cents / 100;// The amount (in cents). This value is used in Stripe API.
130
- }
131
-
132
- $payment_amount = floatval( $payment_amount );
133
-
134
- $stripe_email = $charge->data[0]->billing_details->email;
135
-
136
- $membership_level_id = get_post_meta( $button_id, 'membership_level_id', true );
137
-
138
- // Validate and verify some of the main values.
139
- $true_payment_amount = get_post_meta( $button_id, 'payment_amount', true );
140
- $true_payment_amount = apply_filters( 'swpm_payment_amount_filter', $true_payment_amount, $button_id );
141
- $true_payment_amount = floatval( $true_payment_amount );
142
-
143
- if ( $payment_amount !== $true_payment_amount ) {
144
- // Fatal error. Payment amount may have been tampered with.
145
- $error_msg = 'Fatal Error! Received payment amount (' . $payment_amount . ') does not match with the original amount (' . $true_payment_amount . ')';
146
- SwpmLog::log_simple_debug( $error_msg, false );
147
- wp_die( esc_html( $error_msg ) );
148
- }
149
- $true_currency_code = get_post_meta( $button_id, 'payment_currency', true );
150
- if ( $currency_code !== $true_currency_code ) {
151
- // Fatal error. Currency code may have been tampered with.
152
- $error_msg = 'Fatal Error! Received currency code (' . $currency_code . ') does not match with the original code (' . $true_currency_code . ')';
153
- SwpmLog::log_simple_debug( $error_msg, false );
154
- wp_die( esc_html( $error_msg ) );
155
- }
156
-
157
- // Everything went ahead smoothly with the charge.
158
- SwpmLog::log_simple_debug( 'Stripe SCA Buy Now charge successful.', true );
159
-
160
- $user_ip = SwpmUtils::get_user_ip_address();
161
-
162
- //Custom field data
163
- $custom_field_value = 'subsc_ref=' . $membership_level_id;
164
- $custom_field_value .= '&user_ip=' . $user_ip;
165
- if ( SwpmMemberUtils::is_member_logged_in() ) {
166
- $custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
167
- }
168
- $custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
169
-
170
- $custom = $custom_field_value;
171
-
172
- $custom_var = SwpmTransactions::parse_custom_var( $custom );
173
- $swpm_id = isset( $custom_var['swpm_id'] ) ? $custom_var['swpm_id'] : '';
174
-
175
- // Let's try to get first_name and last_name from full name
176
- $name = trim( $charge->data[0]->billing_details->name );
177
- $last_name = ( strpos( $name, ' ' ) === false ) ? '' : preg_replace( '#.*\s([\w-]*)$#', '$1', $name );
178
- $first_name = trim( preg_replace( '#' . $last_name . '#', '', $name ) );
179
-
180
- // Create the $ipn_data array.
181
- $ipn_data = array();
182
- $ipn_data['mc_gross'] = $payment_amount;
183
- $ipn_data['first_name'] = $first_name;
184
- $ipn_data['last_name'] = $last_name;
185
- $ipn_data['payer_email'] = $stripe_email;
186
- $ipn_data['membership_level'] = $membership_level_id;
187
- $ipn_data['txn_id'] = $txn_id;
188
- $ipn_data['subscr_id'] = $txn_id;/* Set the txn_id as subscriber_id so it is similar to PayPal buy now. Also, it can connect to the profile in the "payments" menu. */
189
- $ipn_data['swpm_id'] = $swpm_id;
190
- $ipn_data['ip'] = $custom_var['user_ip'];
191
- $ipn_data['custom'] = $custom;
192
- $ipn_data['gateway'] = 'stripe-sca';
193
- $ipn_data['status'] = 'completed';
194
-
195
- $bd_addr = $charge->data[0]->billing_details->address;
196
-
197
- $ipn_data['address_street'] = isset( $bd_addr->line1 ) ? $bd_addr->line1 : '';
198
- $ipn_data['address_city'] = isset( $bd_addr->city ) ? $bd_addr->city : '';
199
- $ipn_data['address_state'] = isset( $bd_addr->state ) ? $bd_addr->state : '';
200
- $ipn_data['address_zipcode'] = isset( $bd_addr->postal_code ) ? $bd_addr->postal_code : '';
201
- $ipn_data['address_country'] = isset( $bd_addr->country ) ? $bd_addr->country : '';
202
-
203
- $ipn_data['payment_button_id'] = $button_id;
204
- $ipn_data['is_live'] = ! $sandbox_enabled;
205
-
206
- // Handle the membership signup related tasks.
207
- swpm_handle_subsc_signup_stand_alone( $ipn_data, $membership_level_id, $txn_id, $swpm_id );
208
-
209
- // Save the transaction record
210
- SwpmTransactions::save_txn_record( $ipn_data );
211
- SwpmLog::log_simple_debug( 'Transaction data saved.', true );
212
-
213
- // Trigger the stripe IPN processed action hook (so other plugins can can listen for this event).
214
- do_action( 'swpm_stripe_sca_ipn_processed', $ipn_data );
215
-
216
- do_action( 'swpm_payment_ipn_processed', $ipn_data );
217
-
218
- // Redirect the user to the return URL (or to the homepage if a return URL is not specified for this payment button).
219
- $return_url = get_post_meta( $button_id, 'return_url', true );
220
- if ( empty( $return_url ) ) {
221
- $return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
222
- }
223
- SwpmLog::log_simple_debug( 'Redirecting customer to: ' . $return_url, true );
224
- SwpmLog::log_simple_debug( 'End of Stripe SCA Buy Now IPN processing.', true, true );
225
- SwpmMiscUtils::redirect_to_url( $return_url );
226
-
227
- }
228
-
229
- public function handle_session_create() {
230
- $button_id = filter_input( INPUT_POST, 'swpm_button_id', FILTER_SANITIZE_NUMBER_INT );
231
- if ( empty( $button_id ) ) {
232
- wp_send_json( array( 'error' => 'No button ID provided' ) );
233
- }
234
-
235
- $uniqid = filter_input( INPUT_POST, 'swpm_uniqid', FILTER_SANITIZE_STRING );
236
- $uniqid = ! empty( $uniqid ) ? $uniqid : '';
237
-
238
- $settings = SwpmSettings::get_instance();
239
- $button_cpt = get_post( $button_id ); //Retrieve the CPT for this button
240
- $item_name = htmlspecialchars( $button_cpt->post_title );
241
-
242
- $plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
243
-
244
- if ( empty( $plan_id ) ) {
245
- //Payment amount and currency
246
- $payment_amount = get_post_meta( $button_id, 'payment_amount', true );
247
- if ( ! is_numeric( $payment_amount ) ) {
248
- wp_send_json( array( 'error' => 'Error! The payment amount value of the button must be a numeric number. Example: 49.50' ) );
249
- }
250
-
251
- $payment_currency = get_post_meta( $button_id, 'payment_currency', true );
252
- $payment_amount = round( $payment_amount, 2 ); //round the amount to 2 decimal place.
253
-
254
- $payment_amount = apply_filters( 'swpm_payment_amount_filter', $payment_amount, $button_id );
255
-
256
- $zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
257
- if ( in_array( $payment_currency, $zero_cents ) ) {
258
- //this is zero-cents currency, amount shouldn't be multiplied by 100
259
- $price_in_cents = $payment_amount;
260
- } else {
261
- $price_in_cents = $payment_amount * 100; //The amount (in cents). This value is passed to Stripe API.
262
- }
263
- $payment_amount_formatted = SwpmMiscUtils::format_money( $payment_amount, $payment_currency );
264
- }
265
-
266
- //$button_image_url = get_post_meta($button_id, 'button_image_url', true);//Stripe doesn't currenty support button image for their standard checkout.
267
- //User's IP address
268
- $user_ip = SwpmUtils::get_user_ip_address();
269
- $_SESSION['swpm_payment_button_interaction'] = $user_ip;
270
-
271
- //Custom field data
272
- $custom_field_value = 'subsc_ref=' . $membership_level_id;
273
- $custom_field_value .= '&user_ip=' . $user_ip;
274
- if ( SwpmMemberUtils::is_member_logged_in() ) {
275
- $custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
276
- }
277
- $custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
278
-
279
- //Sandbox settings
280
- $sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
281
-
282
- //API keys
283
- $api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
284
-
285
- //Billing address
286
- $billing_address = isset( $args['billing_address'] ) ? '1' : '';
287
- //By default don't show the billing address in the checkout form.
288
- //if billing_address parameter is not present in the shortcode, let's check button option
289
- if ( $billing_address === '' ) {
290
- $collect_address = get_post_meta( $button_id, 'stripe_collect_address', true );
291
- if ( $collect_address === '1' ) {
292
- //Collect Address enabled in button settings
293
- $billing_address = 1;
294
- }
295
- }
296
-
297
- $ref_id = 'swpm_' . $uniqid . '|' . $button_id;
298
-
299
- //Return, cancel, notifiy URLs
300
- if ( empty( $plan_id ) ) {
301
- $notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=%s', $ref_id );
302
- } else {
303
- $notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=%s', $ref_id );
304
- }
305
-
306
- $current_url_posted = filter_input( INPUT_POST, 'swpm_page_url', FILTER_SANITIZE_URL );
307
-
308
- $current_url = ! empty( $current_url_posted ) ? $current_url_posted : SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
309
-
310
- //prefill member email
311
- $prefill_member_email = $settings->get_value( 'stripe-prefill-member-email' );
312
-
313
- if ( $prefill_member_email ) {
314
- $auth = SwpmAuth::get_instance();
315
- $member_email = $auth->get( 'email' );
316
- }
317
-
318
- SwpmMiscUtils::load_stripe_lib();
319
-
320
- try {
321
- \Stripe\Stripe::setApiKey( $api_keys['secret'] );
322
-
323
- if ( empty( $plan_id ) ) {
324
- //this is one-off payment
325
- $opts = array(
326
- 'payment_method_types' => array( 'card' ),
327
- 'client_reference_id' => $ref_id,
328
- 'billing_address_collection' => $billing_address ? 'required' : 'auto',
329
- 'line_items' => array(
330
- array(
331
- 'name' => $item_name,
332
- 'description' => $payment_amount_formatted,
333
- 'amount' => $price_in_cents,
334
- 'currency' => $payment_currency,
335
- 'quantity' => 1,
336
- ),
337
- ),
338
- 'success_url' => $notify_url,
339
- 'cancel_url' => $current_url,
340
- );
341
- } else {
342
- //this is subscription payment
343
- $opts = array(
344
- 'payment_method_types' => array( 'card' ),
345
- 'client_reference_id' => $ref_id,
346
- 'billing_address_collection' => $billing_address ? 'required' : 'auto',
347
- 'subscription_data' => array(
348
- 'items' => array( array( 'plan' => $plan_id ) ),
349
- ),
350
- 'success_url' => $notify_url,
351
- 'cancel_url' => $current_url,
352
- );
353
-
354
- $trial_period = get_post_meta( $button_id, 'stripe_trial_period', true );
355
- $trial_period = absint( $trial_period );
356
- if ( $trial_period ) {
357
- $opts['subscription_data']['trial_period_days'] = $trial_period;
358
- }
359
- }
360
-
361
- if ( ! empty( $item_logo ) ) {
362
- $opts['line_items'][0]['images'] = array( $item_logo );
363
- }
364
-
365
- if ( ! empty( $member_email ) ) {
366
- $opts['customer_email'] = $member_email;
367
- }
368
-
369
- $opts = apply_filters( 'swpm_stripe_sca_session_opts', $opts, $button_id );
370
-
371
- $session = \Stripe\Checkout\Session::create( $opts );
372
- } catch ( Exception $e ) {
373
- $err = $e->getMessage();
374
- wp_send_json( array( 'error' => 'Error occurred: ' . $err ) );
375
- }
376
- wp_send_json( array( 'session_id' => $session->id ) );
377
- }
378
-
379
- }
380
-
381
- new SwpmStripeSCABuyNowIpnHandler();
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class SwpmStripeSCABuyNowIpnHandler {
4
+
5
+ public function __construct() {
6
+ //check if this is session create request
7
+ if ( wp_doing_ajax() ) {
8
+ $action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
9
+ if ( 'swpm_stripe_sca_create_checkout_session' === $action ) {
10
+ add_action( 'wp_ajax_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
11
+ add_action( 'wp_ajax_nopriv_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
12
+ }
13
+ return;
14
+ }
15
+
16
+ require_once SIMPLE_WP_MEMBERSHIP_PATH . 'ipn/swpm_handle_subsc_ipn.php';
17
+ $this->handle_stripe_ipn();
18
+ }
19
+
20
+ public function handle_stripe_ipn() {
21
+ SwpmLog::log_simple_debug( 'Stripe SCA Buy Now IPN received. Processing request...', true );
22
+ // SwpmLog::log_simple_debug(print_r($_REQUEST, true), true);//Useful for debugging purpose
23
+
24
+ // Read and sanitize the request parameters.
25
+
26
+ $ref_id = filter_input( INPUT_GET, 'ref_id', FILTER_SANITIZE_STRING );
27
+
28
+ if ( empty( $ref_id ) ) {
29
+ //no ref id provided, cannot proceed
30
+ SwpmLog::log_simple_debug( 'Fatal Error! No ref_id provied.', false );
31
+ wp_die( esc_html( 'Fatal Error! No ref_id provied.' ) );
32
+
33
+ }
34
+
35
+ $trans_info = explode( '|', $ref_id );
36
+ $button_id = isset( $trans_info[1] ) ? absint( $trans_info[1] ) : false;
37
+
38
+ // Retrieve the CPT for this button
39
+ $button_cpt = get_post( $button_id );
40
+ if ( ! $button_cpt ) {
41
+ // Fatal error. Could not find this payment button post object.
42
+ SwpmLog::log_simple_debug( 'Fatal Error! Failed to retrieve the payment button post object for the given button ID: ' . $button_id, false );
43
+ wp_die( esc_html( sprintf( 'Fatal Error! Payment button (ID: %d) does not exist. This request will fail.', $button_id ) ) );
44
+ }
45
+
46
+ $settings = SwpmSettings::get_instance();
47
+ $sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
48
+
49
+ //API keys
50
+ $api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
51
+
52
+ // Include the Stripe library.
53
+ SwpmMiscUtils::load_stripe_lib();
54
+
55
+ try {
56
+ \Stripe\Stripe::setApiKey( $api_keys['secret'] );
57
+
58
+ $events = \Stripe\Event::all(
59
+ array(
60
+ 'type' => 'checkout.session.completed',
61
+ 'created' => array(
62
+ 'gte' => time() - 60 * 60,
63
+ ),
64
+ )
65
+ );
66
+
67
+ $sess = false;
68
+
69
+ foreach ( $events->autoPagingIterator() as $event ) {
70
+ $session = $event->data->object;
71
+ if ( isset( $session->client_reference_id ) && $session->client_reference_id === $ref_id ) {
72
+ $sess = $session;
73
+ break;
74
+ }
75
+ }
76
+
77
+ if ( false === $sess ) {
78
+ // Can't find session.
79
+ $error_msg = sprintf( "Fatal error! Payment with ref_id %s can't be found", $ref_id );
80
+ SwpmLog::log_simple_debug( $error_msg, false );
81
+ wp_die( esc_html( $error_msg ) );
82
+ }
83
+
84
+ $pi_id = $sess->payment_intent;
85
+
86
+ $pi = \Stripe\PaymentIntent::retrieve( $pi_id );
87
+ } catch ( Exception $e ) {
88
+ $error_msg = 'Error occurred: ' . $e->getMessage();
89
+ SwpmLog::log_simple_debug( $error_msg, false );
90
+ wp_die( esc_html( $error_msg ) );
91
+ }
92
+
93
+ $charge = $pi->charges;
94
+
95
+ // Grab the charge ID and set it as the transaction ID.
96
+ $txn_id = $charge->data[0]->id;
97
+ // The charge ID can be used to retrieve the transaction details using hte following call.
98
+ // \Stripe\Charge::retrieve($charge->$data[0]->id);
99
+
100
+ //check if this payment has already been processed
101
+ $payment = get_posts(
102
+ array(
103
+ 'meta_key' => 'txn_id',
104
+ 'meta_value' => $txn_id,
105
+ 'posts_per_page' => 1,
106
+ 'offset' => 0,
107
+ 'post_type' => 'swpm_transactions',
108
+ )
109
+ );
110
+ wp_reset_postdata();
111
+
112
+ if ( $payment ) {
113
+ //payment has already been processed. Redirecting user to return_url
114
+ $return_url = get_post_meta( $button_id, 'return_url', true );
115
+ if ( empty( $return_url ) ) {
116
+ $return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
117
+ }
118
+ SwpmMiscUtils::redirect_to_url( $return_url );
119
+ return;
120
+ }
121
+
122
+ $price_in_cents = floatval( $pi->amount_received );
123
+ $currency_code = strtoupper( $pi->currency );
124
+
125
+ $zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
126
+ if ( in_array( $currency_code, $zero_cents, true ) ) {
127
+ $payment_amount = $price_in_cents;
128
+ } else {
129
+ $payment_amount = $price_in_cents / 100;// The amount (in cents). This value is used in Stripe API.
130
+ }
131
+
132
+ $payment_amount = floatval( $payment_amount );
133
+
134
+ $stripe_email = $charge->data[0]->billing_details->email;
135
+
136
+ $membership_level_id = get_post_meta( $button_id, 'membership_level_id', true );
137
+
138
+ // Validate and verify some of the main values.
139
+ $true_payment_amount = get_post_meta( $button_id, 'payment_amount', true );
140
+ $true_payment_amount = apply_filters( 'swpm_payment_amount_filter', $true_payment_amount, $button_id );
141
+ $true_payment_amount = floatval( $true_payment_amount );
142
+
143
+ if ( $payment_amount !== $true_payment_amount ) {
144
+ // Fatal error. Payment amount may have been tampered with.
145
+ $error_msg = 'Fatal Error! Received payment amount (' . $payment_amount . ') does not match with the original amount (' . $true_payment_amount . ')';
146
+ SwpmLog::log_simple_debug( $error_msg, false );
147
+ wp_die( esc_html( $error_msg ) );
148
+ }
149
+ $true_currency_code = get_post_meta( $button_id, 'payment_currency', true );
150
+ if ( $currency_code !== $true_currency_code ) {
151
+ // Fatal error. Currency code may have been tampered with.
152
+ $error_msg = 'Fatal Error! Received currency code (' . $currency_code . ') does not match with the original code (' . $true_currency_code . ')';
153
+ SwpmLog::log_simple_debug( $error_msg, false );
154
+ wp_die( esc_html( $error_msg ) );
155
+ }
156
+
157
+ // Everything went ahead smoothly with the charge.
158
+ SwpmLog::log_simple_debug( 'Stripe SCA Buy Now charge successful.', true );
159
+
160
+ $user_ip = SwpmUtils::get_user_ip_address();
161
+
162
+ //Custom field data
163
+ $custom_field_value = 'subsc_ref=' . $membership_level_id;
164
+ $custom_field_value .= '&user_ip=' . $user_ip;
165
+ if ( SwpmMemberUtils::is_member_logged_in() ) {
166
+ $custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
167
+ }
168
+ $custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
169
+
170
+ $custom = $custom_field_value;
171
+
172
+ $custom_var = SwpmTransactions::parse_custom_var( $custom );
173
+ $swpm_id = isset( $custom_var['swpm_id'] ) ? $custom_var['swpm_id'] : '';
174
+
175
+ // Let's try to get first_name and last_name from full name
176
+ $name = trim( $charge->data[0]->billing_details->name );
177
+ $last_name = ( strpos( $name, ' ' ) === false ) ? '' : preg_replace( '#.*\s([\w-]*)$#', '$1', $name );
178
+ $first_name = trim( preg_replace( '#' . $last_name . '#', '', $name ) );
179
+
180
+ // Create the $ipn_data array.
181
+ $ipn_data = array();
182
+ $ipn_data['mc_gross'] = $payment_amount;
183
+ $ipn_data['first_name'] = $first_name;
184
+ $ipn_data['last_name'] = $last_name;
185
+ $ipn_data['payer_email'] = $stripe_email;
186
+ $ipn_data['membership_level'] = $membership_level_id;
187
+ $ipn_data['txn_id'] = $txn_id;
188
+ $ipn_data['subscr_id'] = $txn_id;/* Set the txn_id as subscriber_id so it is similar to PayPal buy now. Also, it can connect to the profile in the "payments" menu. */
189
+ $ipn_data['swpm_id'] = $swpm_id;
190
+ $ipn_data['ip'] = $custom_var['user_ip'];
191
+ $ipn_data['custom'] = $custom;
192
+ $ipn_data['gateway'] = 'stripe-sca';
193
+ $ipn_data['status'] = 'completed';
194
+
195
+ $bd_addr = $charge->data[0]->billing_details->address;
196
+
197
+ $ipn_data['address_street'] = isset( $bd_addr->line1 ) ? $bd_addr->line1 : '';
198
+ $ipn_data['address_city'] = isset( $bd_addr->city ) ? $bd_addr->city : '';
199
+ $ipn_data['address_state'] = isset( $bd_addr->state ) ? $bd_addr->state : '';
200
+ $ipn_data['address_zipcode'] = isset( $bd_addr->postal_code ) ? $bd_addr->postal_code : '';
201
+ $ipn_data['address_country'] = isset( $bd_addr->country ) ? $bd_addr->country : '';
202
+
203
+ $ipn_data['payment_button_id'] = $button_id;
204
+ $ipn_data['is_live'] = ! $sandbox_enabled;
205
+
206
+ // Handle the membership signup related tasks.
207
+ swpm_handle_subsc_signup_stand_alone( $ipn_data, $membership_level_id, $txn_id, $swpm_id );
208
+
209
+ // Save the transaction record
210
+ SwpmTransactions::save_txn_record( $ipn_data );
211
+ SwpmLog::log_simple_debug( 'Transaction data saved.', true );
212
+
213
+ // Trigger the stripe IPN processed action hook (so other plugins can can listen for this event).
214
+ do_action( 'swpm_stripe_sca_ipn_processed', $ipn_data );
215
+
216
+ do_action( 'swpm_payment_ipn_processed', $ipn_data );
217
+
218
+ // Redirect the user to the return URL (or to the homepage if a return URL is not specified for this payment button).
219
+ $return_url = get_post_meta( $button_id, 'return_url', true );
220
+ if ( empty( $return_url ) ) {
221
+ $return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
222
+ }
223
+ SwpmLog::log_simple_debug( 'Redirecting customer to: ' . $return_url, true );
224
+ SwpmLog::log_simple_debug( 'End of Stripe SCA Buy Now IPN processing.', true, true );
225
+ SwpmMiscUtils::redirect_to_url( $return_url );
226
+
227
+ }
228
+
229
+ public function handle_session_create() {
230
+ $button_id = filter_input( INPUT_POST, 'swpm_button_id', FILTER_SANITIZE_NUMBER_INT );
231
+ if ( empty( $button_id ) ) {
232
+ wp_send_json( array( 'error' => 'No button ID provided' ) );
233
+ }
234
+
235
+ $uniqid = filter_input( INPUT_POST, 'swpm_uniqid', FILTER_SANITIZE_STRING );
236
+ $uniqid = ! empty( $uniqid ) ? $uniqid : '';
237
+
238
+ $settings = SwpmSettings::get_instance();
239
+ $button_cpt = get_post( $button_id ); //Retrieve the CPT for this button
240
+ $item_name = htmlspecialchars( $button_cpt->post_title );
241
+
242
+ $plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
243
+
244
+ if ( empty( $plan_id ) ) {
245
+ //Payment amount and currency
246
+ $payment_amount = get_post_meta( $button_id, 'payment_amount', true );
247
+ if ( ! is_numeric( $payment_amount ) ) {
248
+ wp_send_json( array( 'error' => 'Error! The payment amount value of the button must be a numeric number. Example: 49.50' ) );
249
+ }
250
+
251
+ $payment_currency = get_post_meta( $button_id, 'payment_currency', true );
252
+ $payment_amount = round( $payment_amount, 2 ); //round the amount to 2 decimal place.
253
+
254
+ $payment_amount = apply_filters( 'swpm_payment_amount_filter', $payment_amount, $button_id );
255
+
256
+ $zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
257
+ if ( in_array( $payment_currency, $zero_cents ) ) {
258
+ //this is zero-cents currency, amount shouldn't be multiplied by 100
259
+ $price_in_cents = $payment_amount;
260
+ } else {
261
+ $price_in_cents = $payment_amount * 100; //The amount (in cents). This value is passed to Stripe API.
262
+ }
263
+ $payment_amount_formatted = SwpmMiscUtils::format_money( $payment_amount, $payment_currency );
264
+ }
265
+
266
+ //$button_image_url = get_post_meta($button_id, 'button_image_url', true);//Stripe doesn't currenty support button image for their standard checkout.
267
+ //User's IP address
268
+ $user_ip = SwpmUtils::get_user_ip_address();
269
+ $_SESSION['swpm_payment_button_interaction'] = $user_ip;
270
+
271
+ //Custom field data
272
+ $custom_field_value = 'subsc_ref=' . $membership_level_id;
273
+ $custom_field_value .= '&user_ip=' . $user_ip;
274
+ if ( SwpmMemberUtils::is_member_logged_in() ) {
275
+ $custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
276
+ }
277
+ $custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
278
+
279
+ //Sandbox settings
280
+ $sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
281
+
282
+ //API keys
283
+ $api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
284
+
285
+ //Billing address
286
+ $billing_address = isset( $args['billing_address'] ) ? '1' : '';
287
+ //By default don't show the billing address in the checkout form.
288
+ //if billing_address parameter is not present in the shortcode, let's check button option
289
+ if ( $billing_address === '' ) {
290
+ $collect_address = get_post_meta( $button_id, 'stripe_collect_address', true );
291
+ if ( $collect_address === '1' ) {
292
+ //Collect Address enabled in button settings
293
+ $billing_address = 1;
294
+ }
295
+ }
296
+
297
+ $ref_id = 'swpm_' . $uniqid . '|' . $button_id;
298
+
299
+ //Return, cancel, notifiy URLs
300
+ if ( empty( $plan_id ) ) {
301
+ $notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=%s', $ref_id );
302
+ } else {
303
+ $notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=%s', $ref_id );
304
+ }
305
+
306
+ $current_url_posted = filter_input( INPUT_POST, 'swpm_page_url', FILTER_SANITIZE_URL );
307
+
308
+ $current_url = ! empty( $current_url_posted ) ? $current_url_posted : SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
309
+
310
+ //prefill member email
311
+ $prefill_member_email = $settings->get_value( 'stripe-prefill-member-email' );
312
+
313
+ if ( $prefill_member_email ) {
314
+ $auth = SwpmAuth::get_instance();
315
+ $member_email = $auth->get( 'email' );
316
+ }
317
+
318
+ SwpmMiscUtils::load_stripe_lib();
319
+
320
+ try {
321
+ \Stripe\Stripe::setApiKey( $api_keys['secret'] );
322
+ \Stripe\Stripe::setApiVersion("2022-08-01");
323
+
324
+ if ( empty( $plan_id ) ) {
325
+ //this is one-off payment
326
+ $opts = array(
327
+ 'payment_method_types' => array( 'card' ),
328
+ 'client_reference_id' => $ref_id,
329
+ 'billing_address_collection' => $billing_address ? 'required' : 'auto',
330
+ 'line_items' => array(
331
+ array(
332
+ 'price_data' => array(
333
+ 'currency' => $payment_currency,
334
+ 'unit_amount' => $price_in_cents,
335
+ 'product_data' => array(
336
+ 'name' => $item_name,
337
+ 'description' => $payment_amount_formatted,
338
+ ),
339
+ ),
340
+ 'quantity' => 1
341
+ )
342
+ ),
343
+ 'mode' => 'payment',
344
+ 'success_url' => $notify_url,
345
+ 'cancel_url' => $current_url,
346
+ );
347
+ } else {
348
+ //this is subscription payment
349
+ $opts = array(
350
+ 'payment_method_types' => array('card'),
351
+ 'client_reference_id' => $ref_id,
352
+ 'billing_address_collection' => $billing_address ? 'required' : 'auto',
353
+ 'line_items' => array(
354
+ array(
355
+ 'price' => $plan_id,
356
+ 'quantity' => 1
357
+ ),
358
+
359
+ ),
360
+ 'mode' => 'subscription',
361
+ 'success_url' => $notify_url,
362
+ 'cancel_url' => $current_url,
363
+ );
364
+
365
+ $trial_period = get_post_meta( $button_id, 'stripe_trial_period', true );
366
+ $trial_period = absint( $trial_period );
367
+ if ( $trial_period ) {
368
+ $opts['subscription_data']['trial_period_days'] = $trial_period;
369
+ }
370
+ }
371
+
372
+ if ( ! empty( $item_logo ) ) {
373
+ $opts['line_items'][0]["product_data"]['images'] = array( $item_logo );
374
+ }
375
+
376
+ if ( ! empty( $member_email ) ) {
377
+ $opts['customer_email'] = $member_email;
378
+ }
379
+
380
+ $opts = apply_filters( 'swpm_stripe_sca_session_opts', $opts, $button_id );
381
+
382
+ $session = \Stripe\Checkout\Session::create( $opts );
383
+ } catch ( Exception $e ) {
384
+ $err = $e->getMessage();
385
+ wp_send_json( array( 'error' => 'Error occurred: ' . $err ) );
386
+ }
387
+ wp_send_json( array( 'session_id' => $session->id ) );
388
+ }
389
+
390
+ }
391
+
392
+ new SwpmStripeSCABuyNowIpnHandler();
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: https://simple-membership-plugin.com/
4
  Tags: member, members, members only, membership, memberships, register, WordPress membership plugin, content, content protection, paypal, restrict, restrict access, Restrict content, admin, access control, subscription, teaser, protection, profile, login, login page, bbpress, stripe, braintree
5
  Requires at least: 5.0
6
  Requires PHP: 5.6
7
- Tested up to: 6.0
8
- Stable tag: 4.1.8
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -163,6 +163,19 @@ https://simple-membership-plugin.com/
163
 
164
  == Changelog ==
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  = 4.1.8 =
167
  - Improved the view debug log operation to check if the file exists before trying to open the file. If the file doesn't exist, it will show a message to reset the debug file.
168
 
4
  Tags: member, members, members only, membership, memberships, register, WordPress membership plugin, content, content protection, paypal, restrict, restrict access, Restrict content, admin, access control, subscription, teaser, protection, profile, login, login page, bbpress, stripe, braintree
5
  Requires at least: 5.0
6
  Requires PHP: 5.6
7
+ Tested up to: 6.1
8
+ Stable tag: 4.2.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
163
 
164
  == Changelog ==
165
 
166
+ = 4.2.0 =
167
+ - Braintree SDK updated for the Braintree payment gateway.
168
+ - Google reCAPTCHA enterprise option is now [available as a free addon](https://simple-membership-plugin.com/simple-membership-google-recaptcha-enterprise-option/).
169
+
170
+ = 4.1.9 =
171
+ - Stripe Button's code updated to use the latest Stripe API version.
172
+ - Allow apostrophe character in the email address field of the registration form.
173
+ - Preserve address information of a profile when submitting the registration form (if the data was received from the payment gateway).
174
+ - Added a workaround for sites using the Batcache caching system.
175
+ - Updated the swpm_admin_members_table_column_<column_name> filter hook to check if the column value exists.
176
+ - Fixed an issue with the email address whitelisting pattern feature.
177
+ - Improved how the current_page URL value is retrieved for the Stripe payment buttons.
178
+
179
  = 4.1.8 =
180
  - Improved the view debug log operation to check if the file exists before trying to open the file. If the file doesn't exist, it will show a message to reset the debug file.
181
 
simple-wp-membership.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /*
3
  Plugin Name: Simple WordPress Membership
4
- Version: 4.1.8
5
  Plugin URI: https://simple-membership-plugin.com/
6
  Author: smp7, wp.insider
7
  Author URI: https://simple-membership-plugin.com/
@@ -20,7 +20,7 @@ include_once( 'classes/class.simple-wp-membership.php' );
20
  include_once( 'classes/class.swpm-cronjob.php' );
21
  include_once( 'swpm-compat.php' );
22
 
23
- define( 'SIMPLE_WP_MEMBERSHIP_VER', '4.1.8' );
24
  define( 'SIMPLE_WP_MEMBERSHIP_DB_VER', '1.3' );
25
  define( 'SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL', home_url() );
26
  define( 'SIMPLE_WP_MEMBERSHIP_PATH', dirname( __FILE__ ) . '/' );
1
  <?php
2
  /*
3
  Plugin Name: Simple WordPress Membership
4
+ Version: 4.2.0
5
  Plugin URI: https://simple-membership-plugin.com/
6
  Author: smp7, wp.insider
7
  Author URI: https://simple-membership-plugin.com/
20
  include_once( 'classes/class.swpm-cronjob.php' );
21
  include_once( 'swpm-compat.php' );
22
 
23
+ define( 'SIMPLE_WP_MEMBERSHIP_VER', '4.2.0' );
24
  define( 'SIMPLE_WP_MEMBERSHIP_DB_VER', '1.3' );
25
  define( 'SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL', home_url() );
26
  define( 'SIMPLE_WP_MEMBERSHIP_PATH', dirname( __FILE__ ) . '/' );
views/admin_add_ons_page.php CHANGED
@@ -238,6 +238,14 @@ echo '<link type="text/css" rel="stylesheet" href="' . SIMPLE_WP_MEMBERSHIP_URL
238
  );
239
  array_push($addons_data, $addon_28);
240
 
 
 
 
 
 
 
 
 
241
  /*** Show the addons list ***/
242
  foreach ($addons_data as $addon) {
243
  $output .= '<div class="swpm_addon_item_canvas">';
238
  );
239
  array_push($addons_data, $addon_28);
240
 
241
+ $addon_29 = array(
242
+ 'name' => 'MailerLite Integration',
243
+ 'thumbnail' => SIMPLE_WP_MEMBERSHIP_URL . '/images/addons/swpm-mailerlite-integration.png',
244
+ 'description' => 'Allows you to automatically signup your members to a group in your MailerLite account.',
245
+ 'page_url' => 'https://simple-membership-plugin.com/simple-membership-mailerlite-integration-addon/',
246
+ );
247
+ array_push($addons_data, $addon_29);
248
+
249
  /*** Show the addons list ***/
250
  foreach ($addons_data as $addon) {
251
  $output .= '<div class="swpm_addon_item_canvas">';
views/payments/payment-gateway/braintree_button_shortcode_view.php CHANGED
@@ -40,7 +40,7 @@ function swpm_render_braintree_buy_now_button_sc_output($button_code, $args)
40
  $payment_amount = round($payment_amount, 2); //round the amount to 2 decimal place.
41
  $payment_currency = get_post_meta($button_id, 'currency_code', true);
42
 
43
- $payment_amount_formatted = SwpmMiscUtils::format_money($payment_amount,$payment_currency);
44
 
45
  //Return, cancel, notifiy URLs
46
  $return_url = get_post_meta($button_id, 'return_url', true);
@@ -107,54 +107,89 @@ function swpm_render_braintree_buy_now_button_sc_output($button_code, $args)
107
  if (!empty($coupon_input)) {
108
  $output .= $coupon_input;
109
  }
110
- $output .= '<div id="swpm-braintree-amount-container-' . $uniqid . '" class="swpm-braintree-amount-container"><p>' . $payment_amount_formatted.'</p></div>';
111
  $output .= '</div>';
112
  $output .= '<button id="swpm-show-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-show-form-button-' . $button_id . ' ' . $class . '" type="button" onclick="swpm_braintree_show_form_' . $uniqid . '();"><span>' . $button_text . '</span></button>';
113
  $output .= '<button id="swpm-submit-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-submit-form-button-' . $button_id . ' ' . $class . '" type="submit" style="display: none;"><span>' . $button_text . '</span></button>';
114
- $output .= '<script src="https://js.braintreegateway.com/js/braintree-2.32.1.min.js"></script>';
 
 
 
 
115
  ob_start();
116
- ?>
 
 
 
 
 
117
  <script>
118
  function swpm_braintree_show_form__uniqid_() {
119
  document.getElementById('swpm-show-form-btn-_uniqid_').style.display = "none";
120
  document.getElementById('swpm-submit-form-btn-_uniqid_').style.display = "block";
121
  document.getElementById('swpm-form-cont-_uniqid_').style.display = "block";
122
  var clientToken = '_token_';
123
- braintree.setup(clientToken, 'dropin', {
124
- container: 'swpm-form-cont-_uniqid_',
125
- onReady: function(obj) {
126
- document.getElementById('swpm-braintree-additional-fields-container-_uniqid_').style.display = "block";
127
- },
128
- onPaymentMethodReceived: function(obj) {
129
- document.getElementById('swpm-submit-form-btn-_uniqid_').disabled = true;
130
- var client = new braintree.api.Client({
131
- clientToken: clientToken
132
- });
133
- if (obj.type !== 'CreditCard') {
134
- document.getElementById('swpm-braintree-nonce-field-_uniqid_').value = obj.nonce;
135
- document.getElementById('swpm-braintree-payment-form-_uniqid_').submit();
136
- return true;
137
- }
138
- var form = document.getElementById('swpm-braintree-payment-form-_uniqid_');
139
- var amount = form.querySelector('[name="item_price"]').value;
140
- client.verify3DS({
141
- amount: amount,
142
- creditCard: obj.nonce
143
- }, function(err, response) {
144
- if (!err) {
145
- document.getElementById('swpm-braintree-nonce-field-_uniqid_').value = response.nonce;
146
- document.getElementById('swpm-braintree-payment-form-_uniqid_').submit();
147
- } else {
148
- alert(err.message);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  document.getElementById('swpm-submit-form-btn-_uniqid_').disabled = false;
150
- return false;
 
 
 
 
 
 
 
 
151
  }
 
 
 
152
  });
153
- }
154
  });
 
155
  }
156
  </script>
157
- <?php
158
 
159
  $scr = ob_get_clean();
160
  $scr = str_replace(array('_uniqid_', '_token_', '_amount_'), array($uniqid, $clientToken, $payment_amount), $scr);
40
  $payment_amount = round($payment_amount, 2); //round the amount to 2 decimal place.
41
  $payment_currency = get_post_meta($button_id, 'currency_code', true);
42
 
43
+ $payment_amount_formatted = SwpmMiscUtils::format_money($payment_amount, $payment_currency);
44
 
45
  //Return, cancel, notifiy URLs
46
  $return_url = get_post_meta($button_id, 'return_url', true);
107
  if (!empty($coupon_input)) {
108
  $output .= $coupon_input;
109
  }
110
+ $output .= '<div id="swpm-braintree-amount-container-' . $uniqid . '" class="swpm-braintree-amount-container"><p>' . $payment_amount_formatted . '</p></div>';
111
  $output .= '</div>';
112
  $output .= '<button id="swpm-show-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-show-form-button-' . $button_id . ' ' . $class . '" type="button" onclick="swpm_braintree_show_form_' . $uniqid . '();"><span>' . $button_text . '</span></button>';
113
  $output .= '<button id="swpm-submit-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-submit-form-button-' . $button_id . ' ' . $class . '" type="submit" style="display: none;"><span>' . $button_text . '</span></button>';
114
+
115
+ $output .= '<script src="https://js.braintreegateway.com/web/3.88.2/js/client.min.js"></script>';
116
+ $output .= '<script src="https://js.braintreegateway.com/web/dropin/1.33.4/js/dropin.min.js"></script>';
117
+
118
+
119
  ob_start();
120
+ ?>
121
+ <style>
122
+ .braintree-sheet__content--form .braintree-form__flexible-fields{
123
+ display:inherit;
124
+ }
125
+ </style>
126
  <script>
127
  function swpm_braintree_show_form__uniqid_() {
128
  document.getElementById('swpm-show-form-btn-_uniqid_').style.display = "none";
129
  document.getElementById('swpm-submit-form-btn-_uniqid_').style.display = "block";
130
  document.getElementById('swpm-form-cont-_uniqid_').style.display = "block";
131
  var clientToken = '_token_';
132
+ var submitButton = document.getElementById('swpm-submit-form-btn-_uniqid_');
133
+ var form = document.getElementById('swpm-braintree-payment-form-_uniqid_');
134
+ var additional_fields = document.getElementById('swpm-braintree-additional-fields-container-_uniqid_');
135
+ var amount = form.querySelector('[name="item_price"]').value;
136
+
137
+ //creating dropin
138
+ braintree.dropin.create({
139
+ authorization: clientToken,
140
+ container: '#swpm-form-cont-_uniqid_',
141
+ threeDSecure: true
142
+ }, function(err, dropinInstance) {
143
+ if (err) {
144
+ // Handle any errors that might've occurred when creating Drop-in
145
+ console.error(err);
146
+ alert("Error creating payment form. Try again or check console logs");
147
+ return;
148
+ }
149
+
150
+ document.getElementById('swpm-braintree-additional-fields-container-_uniqid_').style.display = "block";
151
+
152
+ submitButton.addEventListener('click', function(e) {
153
+ e.preventDefault();
154
+
155
+ var first_name = additional_fields.querySelector('[name="first_name"]').value;
156
+ var last_name = additional_fields.querySelector('[name="last_name"]').value;
157
+ var member_email = additional_fields.querySelector('[name="member_email"]').value;
158
+
159
+ dropinInstance.requestPaymentMethod({
160
+ threeDSecure: {
161
+ amount: amount,
162
+ email: member_email,
163
+ billingAddress: {
164
+ givenName: first_name,
165
+ surname: last_name,
166
+ }
167
+ }
168
+ }, function(err, payload) {
169
+ if (err) {
170
+ // Handle errors in requesting payment method
171
+ console.log(err);
172
  document.getElementById('swpm-submit-form-btn-_uniqid_').disabled = false;
173
+ alert("Error in requesting payment. Try again or check console logs");
174
+ }
175
+
176
+ document.getElementById('swpm-submit-form-btn-_uniqid_').disabled = true;
177
+
178
+ if (payload.type !== 'CreditCard') {
179
+ document.getElementById('swpm-braintree-nonce-field-_uniqid_').value = payload.nonce;
180
+ document.getElementById('swpm-braintree-payment-form-_uniqid_').submit();
181
+ return true;
182
  }
183
+
184
+ document.getElementById('swpm-braintree-nonce-field-_uniqid_').value = payload.nonce;
185
+ document.getElementById('swpm-braintree-payment-form-_uniqid_').submit();
186
  });
187
+ });
188
  });
189
+
190
  }
191
  </script>
192
+ <?php
193
 
194
  $scr = ob_get_clean();
195
  $scr = str_replace(array('_uniqid_', '_token_', '_amount_'), array($uniqid, $clientToken, $payment_amount), $scr);
views/payments/payment-gateway/stripe_sca_button_shortcode_view.php CHANGED
@@ -64,7 +64,7 @@ function swpm_render_stripe_sca_buy_now_button_sc_output( $button_code, $args )
64
  //Return, cancel, notifiy URLs
65
  $notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
66
 
67
- $current_url = ( isset( $_SERVER['HTTPS'] ) ? 'https' : 'http' ) . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
68
 
69
  /* === Stripe Buy Now Button Form === */
70
  $output = '';
@@ -201,7 +201,7 @@ function swpm_render_stripe_sca_subscription_button_sc_output( $button_code, $ar
201
  //Return, cancel, notifiy URLs
202
  $notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
203
 
204
- $current_url = ( isset( $_SERVER['HTTPS'] ) ? 'https' : 'http' ) . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
205
 
206
  $plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
207
 
64
  //Return, cancel, notifiy URLs
65
  $notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
66
 
67
+ $current_url = SwpmMiscUtils::get_current_page_url();
68
 
69
  /* === Stripe Buy Now Button Form === */
70
  $output = '';
201
  //Return, cancel, notifiy URLs
202
  $notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
203
 
204
+ $current_url = SwpmMiscUtils::get_current_page_url();
205
 
206
  $plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
207