Skip to content

Commit

Permalink
Fix mandate creation for subscriptions and saved payment methods (#3438)
Browse files Browse the repository at this point in the history
* Fix mandate creation for subscriptions and saved payment methods

When creating the payment intent and the order has a subscription,
we want to set `setup_future_usage` to `off_session`. We are already
doing this when the user is not using a saved card. We want
this same behavior even when using saved cards.

* Add changelog and readme entries

* Add unit test
  • Loading branch information
annemirasol authored Sep 19, 2024
1 parent 7f20b58 commit a592a76
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*** Changelog ***

= 8.8.0 - xxxx-xx-xx =
* Fix - Fix mandate creation for subscriptions and saved payment methods.
* Fix - Fix Google Pay address fields mapping for UAE addresses.
* Tweak - Render the Klarna payment page in the store locale.
* Tweak - Update the Apple Pay domain registration flow to use the new Stripe API endpoint.
Expand Down
2 changes: 1 addition & 1 deletion includes/class-wc-stripe-intent-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ private function build_base_payment_intent_request_params( $payment_information
$request['return_url'] = $payment_information['return_url'];
}

if ( $payment_information['save_payment_method_to_store'] ) {
if ( $payment_information['save_payment_method_to_store'] || ! empty( $payment_information['has_subscription'] ) ) {
$request['setup_future_usage'] = 'off_session';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2046,6 +2046,7 @@ private function prepare_payment_information_from_request( WC_Order $order ) {
'token' => $token,
'return_url' => $this->get_return_url_for_redirect( $order, $save_payment_method_to_store ),
'use_stripe_sdk' => 'true', // We want to use the SDK to handle next actions via the client payment elements. See https://docs.stripe.com/api/setup_intents/create#create_setup_intent-use_stripe_sdk
'has_subscription' => $this->has_subscription( $order->get_id() ),
];

// Use the dynamic + short statement descriptor if enabled and it's a card payment.
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ If you get stuck, you can ask for help in the Plugin Forum.
== Changelog ==

= 8.8.0 - xxxx-xx-xx =
* Fix - Fix mandate creation for subscriptions and saved payment methods.
* Fix - Fix Google Pay address fields mapping for UAE addresses.
* Tweak - Render the Klarna payment page in the store locale.
* Tweak - Update the Apple Pay domain registration flow to use the new Stripe API endpoint.
Expand Down
57 changes: 57 additions & 0 deletions tests/phpunit/test-wc-stripe-intent-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,61 @@ public function provide_test_update_and_confirm_payment_intent() {
],
];
}

/**
* Test for setting the `setup_future_usage` parameter in the
* create_and_confirm_payment_intent intent creation request.
*/
public function test_intent_creation_request_setup_future_usage() {
$payment_information = [
'amount' => 100,
'capture_method' => 'automattic',
'currency' => 'USD',
'customer' => 'cus_mock',
'level3' => [
'line_items' => [
[
'product_code' => 'ABC123',
'product_description' => 'Test Product',
'unit_cost' => 100,
'quantity' => 1,
],
],
],
'metadata' => [ '_stripe_metadata' => '123' ],
'order' => $this->order,
'payment_method' => 'pm_mock',
'shipping' => [],
'selected_payment_type' => 'card',
'payment_method_types' => [ 'card' ],
'is_using_saved_payment_method' => false,
];

$payment_information['save_payment_method_to_store'] = true;
$payment_information['has_subscription'] = false;
$this->check_setup_future_usage_off_session( $payment_information );

// If order has subscription, setup_future_usage should be off_session,
// regardless of save_payment_method_to_store, which may be false
// if using an already saved payment method.
$payment_information['save_payment_method_to_store'] = false;
$payment_information['has_subscription'] = true;
$this->check_setup_future_usage_off_session( $payment_information );
}

private function check_setup_future_usage_off_session( $payment_information ) {
$test_request = function ( $preempt, $parsed_args, $url ) {
$this->assertEquals( 'off_session', $parsed_args['body']['setup_future_usage'] );

return [
'response' => 200,
'headers' => [ 'Content-Type' => 'application/json' ],
'body' => json_encode( [] ),
];
};

add_filter( 'pre_http_request', $test_request, 10, 3 );

$this->mock_controller->create_and_confirm_payment_intent( $payment_information );
}
}

0 comments on commit a592a76

Please sign in to comment.