PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | stripe/controllers/FrmStrpLiteActionsController.php +61 -4 6.31 → trunk View file →
@@ -127,9 +127,9 @@
127 127 $response['error'] = __( 'Stripe still needs to be configured.', 'formidable' );
128 128 return $response;
129 129 }
130 130
131 - $customer = self::set_customer_with_token( $atts );
131 + $customer = self::set_customer_with_token( $atts, self::get_customer_id_from_posted_setup_intents( $form->id ) );
132 132
133 133 if ( ! is_object( $customer ) ) {
134 134 $response['error'] = $customer;
135 135 return $response;
@@ -155,15 +155,56 @@
155 155 return FrmStrpLiteAppHelper::call_stripe_helper_class( 'initialize_api' );
156 156 }
157 157
158 158 /**
159 + * Get the customer id from a setup intent that was created for this submission.
160 + * A Stripe Link subscription builds its subscription from the setup intent's customer,
161 + * so reusing that customer here avoids creating a duplicate customer for guests.
162 + *
163 + * @since 6.35
164 + *
165 + * @param int|string $form_id
166 + *
167 + * @return false|string The Stripe customer id, or false if it can't be found.
168 + */
169 + public static function get_customer_id_from_posted_setup_intents( $form_id ) {
170 + $posted_intents = FrmStrpLiteAuth::get_payment_intents( 'frmintent' . $form_id );
171 +
172 + if ( ! is_array( $posted_intents ) || ! $posted_intents ) {
173 + return false;
174 + }
175 +
176 + $setup_intent_ids = array_filter(
177 + $posted_intents,
178 + function ( $intent_id ) {
179 + return str_starts_with( $intent_id, 'seti_' );
180 + }
181 + );
182 +
183 + if ( ! $setup_intent_ids ) {
184 + return false;
185 + }
186 +
187 + $first_setup_intent_id = reset( $setup_intent_ids );
188 + $first_setup_intent_id = explode( '_secret_', $first_setup_intent_id )[0];
189 + $setup_intent = FrmStrpLiteAppHelper::call_stripe_helper_class( 'get_setup_intent', $first_setup_intent_id );
190 +
191 + if ( ! is_object( $setup_intent ) || empty( $setup_intent->customer ) ) {
192 + return false;
193 + }
194 +
195 + return $setup_intent->customer;
196 + }
197 +
198 + /**
159 199 * Set a customer object to $_POST['customer'] to use later.
160 200 *
161 - * @param array $atts
201 + * @param array $atts The action, entry, and form for the payment.
202 + * @param false|string $customer_id The Stripe customer id when it is already known.
162 203 *
163 204 * @return object|string
164 205 */
165 - private static function set_customer_with_token( $atts ) {
206 + private static function set_customer_with_token( $atts, $customer_id = false ) {
166 207 if ( isset( self::$customer ) ) {
167 208 // It's an object if this isn't the first Stripe action running.
168 209 return self::$customer;
169 210 }
@@ -171,8 +212,12 @@
171 212 $payment_info = array(
172 213 'user_id' => FrmTransLiteAppHelper::get_user_id_for_current_payment(),
173 214 );
174 215
216 + if ( $customer_id ) {
217 + $payment_info['customer_id'] = $customer_id;
218 + }
219 +
175 220 if ( ! empty( $atts['action']->post_content['email'] ) ) {
176 221 $payment_info['email'] = apply_filters( 'frm_content', $atts['action']->post_content['email'], $atts['form'], $atts['entry'] );
177 222 $payment_info['email'] = self::replace_email_shortcode( $payment_info['email'] );
178 223 }
@@ -370,9 +415,21 @@
370 415 * @return string
371 416 */
372 417 public static function create_plan_id( $settings ) {
373 418 $amount = self::prepare_amount( $settings['amount'], $settings );
374 - return sanitize_title_with_dashes( $settings['description'] ) . '_' . $amount . '_' . $settings['interval_count'] . $settings['interval'] . '_' . $settings['currency'];
419 + $parts = array(
420 + sanitize_title_with_dashes( $settings['description'] ),
421 + $amount,
422 + $settings['interval_count'] . $settings['interval'],
423 + $settings['currency'],
424 + );
425 +
426 + if ( isset( $settings['trial_interval_count'] ) && '' !== $settings['trial_interval_count'] ) {
427 + // Include the trial so two actions that differ only by trial length don't share a plan.
428 + $parts[] = $settings['trial_interval_count'];
429 + }
430 +
431 + return implode( '_', $parts );
375 432 }
376 433
377 434 /**
378 435 * If this form submits with ajax, load the scripts on the first page.