Skip to content
Draft
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* Fix - Detect WooCommerce Subscriptions staging sites when checking if payments can be detached
* Fix - Fix saved ACH payment methods sending unsupported capture_method parameter causing checkout failures
* Dev - Add Stripe's masked API key to API request/response logs
* Update - Add `wc_stripe_customer_data_preferred_source` to make it possible to get customer details from WooCommerce customer object

= 10.0.1 - 2025-10-15 =
* Fix - Remove persistent reconnection notices
Expand Down
153 changes: 113 additions & 40 deletions includes/class-wc-stripe-customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,27 @@ public function set_user_id( $user_id ) {
/**
* Get user object.
*
* @return WP_User
* @return WP_User|false
*/
protected function get_user() {
return $this->get_user_id() ? get_user_by( 'id', $this->get_user_id() ) : false;
}

/**
* Get the current WooCommerce customer object.
*
* @return WC_Customer|null
*/
protected function get_wc_customer(): ?WC_Customer {
$wc_customer = WC()->customer;

if ( $wc_customer instanceof WC_Customer ) {
return $wc_customer;
}

return null;
}

/**
* Store data from the Stripe API about this customer
*/
Expand All @@ -154,8 +169,40 @@ public function set_customer_data( $data ) {
* @return array
*/
protected function generate_customer_request( $args = [] ) {
$user = $this->get_user();
if ( $user ) {
$user = $this->get_user();
$wc_customer = $this->get_wc_customer();

if ( ! is_array( $args ) ) {
$args = [];
}

/**
* Filter to control the preferred source of customer data between user meta fields
* and the WC_Customer object. Defaults to 'user_meta' for backwards compatibility,
* but 'wc_customer' can be used to get data from the WC_Customer object.
* The 'wc_customer' option may be most useful for sites that create customers during checkout.
*
* @since 10.1.0
* @param string $preferred_source The preferred source of customer data.
* @param WP_User|false $user The user object or false.
* @param WC_Customer|null $wc_customer The WooCommerce customer object or null.
*/
$preferred_customer_source = apply_filters( 'wc_stripe_customer_data_preferred_source', 'user_meta', $user, $wc_customer );

// Validate $preferred_customer_source.
if ( ! in_array( $preferred_customer_source, [ 'user_meta', 'wc_customer' ], true ) ) {
// Default to 'user_meta' if we don't have a valid value.
$preferred_customer_source = 'user_meta';
}

$billing_first_name = '';
$billing_last_name = '';
$email = '';
$username = '';
$user_or_customer = null;

if ( $user && 'user_meta' === $preferred_customer_source ) {
$user_or_customer = $user;
$billing_first_name = get_user_meta( $user->ID, 'billing_first_name', true );
$billing_last_name = get_user_meta( $user->ID, 'billing_last_name', true );

Expand All @@ -169,66 +216,92 @@ protected function generate_customer_request( $args = [] ) {
$billing_last_name = get_user_meta( $user->ID, 'last_name', true );
}

$email = $user->user_email;

// If the user email is not set, use the billing email.
if ( empty( $email ) ) {
$email = $this->get_billing_data_field( 'billing_email', $args );
}

// translators: %1$s First name, %2$s Second name, %3$s Username.
$description = sprintf( __( 'Name: %1$s %2$s, Username: %3$s', 'woocommerce-gateway-stripe' ), $billing_first_name, $billing_last_name, $user->user_login );

$defaults = [
'email' => $email,
'description' => $description,
];

$billing_full_name = trim( $billing_first_name . ' ' . $billing_last_name );
if ( ! empty( $billing_full_name ) ) {
$defaults['name'] = $billing_full_name;
}
$email = $user->user_email;
$username = $user->user_login;
} elseif ( $wc_customer && 'wc_customer' === $preferred_customer_source ) {
$user_or_customer = $wc_customer;
$billing_first_name = $wc_customer->get_first_name();
$billing_last_name = $wc_customer->get_last_name();
$email = $wc_customer->get_email();
$username = $wc_customer->get_username();
} else {
$billing_email = $this->get_billing_data_field( 'billing_email', $args );
$billing_first_name = $this->get_billing_data_field( 'billing_first_name', $args );
$billing_last_name = $this->get_billing_data_field( 'billing_last_name', $args );
$email = $this->get_billing_data_field( 'billing_email', $args );
}

if ( empty( $username ) ) {
// translators: %1$s First name, %2$s Second name.
$description = sprintf( __( 'Name: %1$s %2$s, Guest', 'woocommerce-gateway-stripe' ), $billing_first_name, $billing_last_name );
} else {
// translators: %1$s First name, %2$s Second name, %3$s Username.
$description = sprintf( __( 'Name: %1$s %2$s, Username: %3$s', 'woocommerce-gateway-stripe' ), $billing_first_name, $billing_last_name, $username );
}

$defaults = [
'email' => $billing_email,
'description' => $description,
];
$defaults = [
'email' => $email,
'description' => $description,
];

$billing_full_name = trim( $billing_first_name . ' ' . $billing_last_name );
if ( ! empty( $billing_full_name ) ) {
$defaults['name'] = $billing_full_name;
}
$billing_full_name = trim( $billing_first_name . ' ' . $billing_last_name );
if ( ! empty( $billing_full_name ) ) {
$defaults['name'] = $billing_full_name;
}

$metadata = [];
$defaults['metadata'] = apply_filters( 'wc_stripe_customer_metadata', $metadata, $user );
$defaults['preferred_locales'] = $this->get_customer_preferred_locale( $user );

// Add customer address default values.
$address_fields = [
$defaults['address'] = $this->generate_customer_address_fields( $args, $user_or_customer );

return wp_parse_args( $args, $defaults );
}

/**
* Helper function to build the address fields for the customer request.
*
* @param array $args Additional arguments.
* @param WP_User|WC_Customer|null $user_or_customer The user object, WC_Customer object, or null.
*
* @return array The address fields.
*/
private function generate_customer_address_fields( array $args, $user_or_customer ): array {
$address_field_map = [
'line1' => 'billing_address_1',
'line2' => 'billing_address_2',
'postal_code' => 'billing_postcode',
'city' => 'billing_city',
'state' => 'billing_state',
'country' => 'billing_country',
];
foreach ( $address_fields as $key => $field ) {
if ( $user ) {
$defaults['address'][ $key ] = get_user_meta( $user->ID, $field, true );
} else {
$defaults['address'][ $key ] = $this->get_billing_data_field( $field, $args );

$address_fields = [];

$source = 'billing';
if ( $user_or_customer instanceof WC_Customer ) {
$source = 'wc_customer';
} elseif ( $user_or_customer instanceof WP_User ) {
$source = 'user_meta';
}

foreach ( $address_field_map as $key => $field ) {
$value = '';

if ( 'user_meta' === $source ) {
$value = get_user_meta( $user_or_customer->ID, $field, true );
if ( empty( $value ) ) {
$value = '';
}
} elseif ( 'wc_customer' === $source && method_exists( $user_or_customer, 'get_' . $field ) ) {
$value = $user_or_customer->{ 'get_' . $field }();
} elseif ( 'billing' === $source ) {
$value = $this->get_billing_data_field( $field, $args );
}

$address_fields[ $key ] = $value;
}

return wp_parse_args( $args, $defaults );
return $address_fields;
}

/**
Expand Down Expand Up @@ -343,7 +416,7 @@ function ( $field_data ) {
*
* @return string
*/
private function get_billing_data_field( $field, $args = [] ) {
protected function get_billing_data_field( $field, $args = [] ) {
$valid_fields = [
'billing_email',
'billing_first_name',
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,6 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
* Fix - Detect WooCommerce Subscriptions staging sites when checking if payments can be detached
* Fix - Fix saved ACH payment methods sending unsupported capture_method parameter causing checkout failures
* Dev - Add Stripe's masked API key to API request/response logs
* Update - Add `wc_stripe_customer_data_preferred_source` to make it possible to get customer details from WooCommerce customer object

[See changelog for full details across versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/trunk/changelog.txt).
Loading
Loading