@@ -199,6 +199,92 @@ protected function generate_customer_request( $args = [] ) {
199
199
return wp_parse_args ( $ args , $ defaults );
200
200
}
201
201
202
+ /**
203
+ * Validate that we have valid data before we try to create a customer.
204
+ *
205
+ * @param array $create_customer_request
206
+ *
207
+ * @throws WC_Stripe_Exception
208
+ */
209
+ private function validate_create_customer_request ( $ create_customer_request ) {
210
+ $ checkout_billing_fields = WC_Checkout::instance ()->get_checkout_fields ( 'billing ' );
211
+ $ required_billing_fields = array_filter (
212
+ $ checkout_billing_fields ,
213
+ function ( $ field_data ) {
214
+ return $ field_data ['required ' ] ?? false ;
215
+ }
216
+ );
217
+
218
+ $ required_fields = [];
219
+
220
+ if ( isset ( $ required_billing_fields ['billing_email ' ] ) ) {
221
+ $ required_fields ['email ' ] = true ;
222
+ }
223
+
224
+ if ( isset ( $ required_billing_fields ['billing_first_name ' ] ) || isset ( $ required_billing_fields ['billing_last_name ' ] ) ) {
225
+ $ required_fields ['name ' ] = true ;
226
+ }
227
+
228
+ $ required_address_fields = [];
229
+ $ address_field_mapping = [
230
+ 'billing_address_1 ' => 'line1 ' ,
231
+ 'billing_address_2 ' => 'line2 ' ,
232
+ 'billing_city ' => 'city ' ,
233
+ 'billing_country ' => 'country ' ,
234
+ 'billing_postcode ' => 'postal_code ' ,
235
+ 'billing_state ' => 'state ' ,
236
+ ];
237
+
238
+ foreach ( $ address_field_mapping as $ field => $ stripe_field_name ) {
239
+ if ( isset ( $ required_billing_fields [ $ field ] ) ) {
240
+ $ required_address_fields [ $ stripe_field_name ] = true ;
241
+ }
242
+ }
243
+
244
+ if ( [] !== $ required_address_fields ) {
245
+ $ required_fields ['address ' ] = $ required_address_fields ;
246
+ }
247
+
248
+ /**
249
+ * Filters the required customer fields when creating a customer in Stripe.
250
+ *
251
+ * @since 9.7.0
252
+ * @param array $required_fields The required customer fields as derived from the required billing fields in checkout.
253
+ */
254
+ $ required_fields = apply_filters ( 'wc_stripe_create_customer_required_fields ' , $ required_fields );
255
+
256
+ foreach ( $ required_fields as $ field => $ field_requirements ) {
257
+ if ( true === $ field_requirements ) {
258
+ if ( empty ( trim ( $ create_customer_request [ $ field ] ?? '' ) ) ) {
259
+ throw new WC_Stripe_Exception (
260
+ sprintf ( 'missing_required_customer_field: %s ' , $ field ),
261
+ /* translators: %s is a field name, e.g. 'email' or 'name'. */
262
+ sprintf ( __ ( 'Missing required customer field: %s ' , 'woocommerce-gateway-stripe ' ), $ field )
263
+ );
264
+ }
265
+ }
266
+ if ( is_array ( $ field_requirements ) ) {
267
+ if ( ! isset ( $ create_customer_request [ $ field ] ) || ! is_array ( $ create_customer_request [ $ field ] ) ) {
268
+ throw new WC_Stripe_Exception (
269
+ sprintf ( 'missing_required_customer_field: %s ' , $ field ),
270
+ /* translators: %s is a field name, e.g. 'email' or 'name'. */
271
+ sprintf ( __ ( 'Missing required customer field: %s ' , 'woocommerce-gateway-stripe ' ), $ field )
272
+ );
273
+ }
274
+
275
+ foreach ( $ field_requirements as $ sub_field => $ sub_field_requirements ) {
276
+ if ( true === $ sub_field_requirements && empty ( trim ( $ create_customer_request [ $ field ][ $ sub_field ] ?? '' ) ) ) {
277
+ throw new WC_Stripe_Exception (
278
+ sprintf ( 'missing_required_customer_field: %s->%s ' , $ field , $ sub_field ),
279
+ /* translators: %1$s is a field name, e.g. address, and %2$s is a secondary field name, e.g. line1 or city. */
280
+ sprintf ( __ ( 'Missing required customer field: %1$s->%2$s ' , 'woocommerce-gateway-stripe ' ), $ field , $ sub_field )
281
+ );
282
+ }
283
+ }
284
+ }
285
+ }
286
+ }
287
+
202
288
/**
203
289
* Get value of billing data field, either from POST or order object.
204
290
*
@@ -311,6 +397,8 @@ public function get_existing_customer( $email, $name ) {
311
397
*
312
398
* @param array $args
313
399
* @return WP_Error|int
400
+ *
401
+ * @throws WC_Stripe_Exception
314
402
*/
315
403
public function create_customer ( $ args = [] ) {
316
404
$ args = $ this ->generate_customer_request ( $ args );
@@ -321,9 +409,24 @@ public function create_customer( $args = [] ) {
321
409
}
322
410
323
411
if ( empty ( $ response ) ) {
324
- $ response = WC_Stripe_API::request ( apply_filters ( 'wc_stripe_create_customer_args ' , $ args ), 'customers ' );
412
+ /**
413
+ * Filters the arguments used to create a customer.
414
+ *
415
+ * @since 4.0.0
416
+ *
417
+ * @param array $args The arguments used to create a customer.
418
+ */
419
+ $ create_customer_args = apply_filters ( 'wc_stripe_create_customer_args ' , $ args );
420
+
421
+ $ this ->validate_create_customer_request ( $ create_customer_args );
422
+
423
+ $ response = WC_Stripe_API::request ( $ create_customer_args , 'customers ' );
325
424
} else {
326
- $ response = WC_Stripe_API::request ( apply_filters ( 'wc_stripe_update_customer_args ' , $ args ), 'customers/ ' . $ response ->id );
425
+ /**
426
+ * This filter is documented in includes/class-wc-stripe-customer.php.
427
+ */
428
+ $ update_customer_args = apply_filters ( 'wc_stripe_update_customer_args ' , $ args );
429
+ $ response = WC_Stripe_API::request ( $ update_customer_args , 'customers/ ' . $ response ->id );
327
430
}
328
431
329
432
if ( ! empty ( $ response ->error ) ) {
@@ -358,7 +461,15 @@ public function update_customer( $args = [], $is_retry = false ) {
358
461
throw new WC_Stripe_Exception ( 'id_required_to_update_user ' , __ ( 'Attempting to update a Stripe customer without a customer ID. ' , 'woocommerce-gateway-stripe ' ) );
359
462
}
360
463
361
- $ args = $ this ->generate_customer_request ( $ args );
464
+ $ args = $ this ->generate_customer_request ( $ args );
465
+
466
+ /**
467
+ * Filters the arguments used to update a customer.
468
+ *
469
+ * @since 4.3.1
470
+ *
471
+ * @param array $args The arguments used to update a customer.
472
+ */
362
473
$ args = apply_filters ( 'wc_stripe_update_customer_args ' , $ args );
363
474
$ response = WC_Stripe_API::request ( $ args , 'customers/ ' . $ this ->get_id () );
364
475
0 commit comments