Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send bank statement descriptors to payment intents #3643

Closed
wants to merge 25 commits into from

Conversation

cesarcosta99
Copy link
Contributor

@cesarcosta99 cesarcosta99 commented Jan 16, 2022

Fixed #4329

Changes proposed in this Pull Request

The usage of the statement descriptor in transactions is being addressed in this PR. This is the final part of the #3625's work.

For some portion of the transactions, the regular statement descriptor is being added to the payment intents already. Here we're making sure the descriptor is passed to the payment intent and the shortened descriptor is being included to take place on card payments, if enabled.

It also includes a small fix for the Blocks checkout when using UPE, where the wcpay_selected_upe_payment_type was not being sent.

Testing instructions

Test the descriptors set are sent to the payment intent.

image

There's a vast amount of combinations for this test, please try to test as much as you can:

  • UPE enabled and disabled.
  • Classic checkout and Blocks checkout.
  • Card, non-card payment method and express checkout.
  • Add customer order number to the bank statement enabled and disabled.

Also consider the following:

  1. When no Full bank statement and Shortened customer bank statement are provided, the payment intent should either contain no statement descriptor or have the Full bank statement descriptor set.
  2. When Full bank statement is provided and Add customer order number to the bank statement is disabled, the payment intent should contain the Full bank statement's value in the statement descriptor regardless the payment method chosen.
  3. In card transactions (express checkout included), when Add customer order number to the bank statement is enabled and Shortened customer bank statement is provided, the payment intent should contain the Shortened customer bank statement's value concatenated with the order number in the statement descriptor.

The test:

  1. Set values for both Full bank statement and Shortened customer bank statement.
  2. Go to the shop page and add a product to the cart.
  3. Go to checkout and complete the order using the scenarios described above.
  4. Go to Payments in the Stripe dashboard, find the payment you've just made and click on it.
  5. Check whether the statement descriptor value (under Payment details section) match the expected value according to the scenario being tested.

  • Added changelog entries to both readme.txt and changelog.txt (or does not apply)
  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Post merge

  • Link to testing instructions from release testing doc : Add link here / 'QA Testing Not Applicable'

@cesarcosta99 cesarcosta99 added status: blocked The issue is blocked from progressing, waiting for another piece of work to be done. component: checkout Issues related to Checkout component: upe labels Jan 16, 2022
@cesarcosta99 cesarcosta99 self-assigned this Jan 16, 2022
@cesarcosta99
Copy link
Contributor Author

Waiting for #3625 getting merged before requesting review for this, since the work here depends and it's based on it.

@deepakpathania deepakpathania added category: core WC Payments core related issues, where it’s obvious. type: enhancement The issue is a request for an enhancement. category: projects For any issues which are part of any project, including bugs, enhancements, etc. and removed category: core WC Payments core related issues, where it’s obvious. labels Feb 23, 2022
@cesarcosta99 cesarcosta99 force-pushed the update/send-statement-descriptors-on-pi branch from 2bfa68f to ca779b6 Compare March 11, 2022 20:56
@cesarcosta99 cesarcosta99 changed the base branch from develop to update/statement-descriptors March 11, 2022 20:56
@cesarcosta99
Copy link
Contributor Author

Rebased develop to resolve conflicts.

Copy link
Member

@ricardo ricardo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't finish testing, will do on Monday, but so far tests well.

Advancing code review. 👍

includes/class-wc-payment-gateway-wcpay.php Outdated Show resolved Hide resolved
includes/payment-methods/class-upe-payment-gateway.php Outdated Show resolved Hide resolved
includes/class-wc-payments-utils.php Outdated Show resolved Hide resolved
includes/class-wc-payments-utils.php Outdated Show resolved Hide resolved
includes/wc-payment-api/class-wc-payments-api-client.php Outdated Show resolved Hide resolved
Base automatically changed from update/statement-descriptors to develop March 14, 2022 01:43
@cesarcosta99 cesarcosta99 force-pushed the update/send-statement-descriptors-on-pi branch 2 times, most recently from 84ffc42 to 86b05a7 Compare March 16, 2022 21:11
@cesarcosta99 cesarcosta99 removed the status: blocked The issue is blocked from progressing, waiting for another piece of work to be done. label Mar 16, 2022
@cesarcosta99
Copy link
Contributor Author

Rebased develop since #3625 got merged and there were conflicts.

Copy link
Member

@ricardo ricardo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I understand better how the full statement descriptor works, I believe we should make the short statement descriptor work the same way, and not try to save it under the plugin settings, but use the Stripe account for that, or at least explore this possibility, otherwise it can be hard to update this later and make it backwards compatible.

If we end up not having time to merge this with the statement descriptor prefix coming from the Stripe account, we could probably hide #3625 and merge this in the next WCPay version IMO (please check with others as well).

With the current implementation this tests well, despite one test detailed below. This is what I tested:

  • Short statement descriptor:
    • non-UPE:
      • ✅ Blocks checkout.
      • ✅ Classic checkout.
      • ✅ Pay for order page.
    • UPE:
      • ✅ Blocks checkout.
      • ✅ Classic checkout.
      • ❌ Pay for order page.
    • ✅ Payment Request Button checkout.
    • ✅ Checkout with saved payment method.
  • Full statement descriptor:
    • non-UPE:
      • ✅ Blocks checkout.
      • ✅ Classic checkout.
      • ✅ Pay for order page.
    • UPE:
      • ✅ Blocks checkout.
      • ✅ Classic checkout.
      • ✅ Pay for order page.
    • ✅ Payment Request Button checkout.
    • ✅ Checkout with saved payment method.

Reproduction steps for ❌ Pay for order page:

  • Make sure UPE is enabled and short statement descriptor is enabled.
  • Go to WooCommerce > Orders > Add order.
  • Add an item to the order, e.g Album.
  • Click Create.
  • Click "Customer payment page →".
  • Checkout with a new credit card.
  • Notice the full statement descriptor is used, instead of the short one.

Comment on lines 286 to 306
public function get_statement_descriptor() {
return $this->statement_descriptor;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we plan to use this in the future? I didn't find it being used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, removed it in 81e755a.

@@ -1111,6 +1111,8 @@ public function process_payment_for_order( $cart, $payment_information, $additio
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$platform_checkout_intent_id = sanitize_user( wp_unslash( $_POST['platform-checkout-intent'] ?? '' ), true );

$statement_descriptor = $this->get_statement_descriptor( $order->get_payment_method(), $order );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you confirmed that the full statement descriptor comes directly from Stripe, perhaps we don't want to pass it to the payment intent, unless it needs to be changed.

The full statement descriptor should always be the same from the Stripe dashboard, correct?https://dashboard.stripe.com/test/connect/accounts/{acct_id}/identity

I suppose what differs from the Stripe plugin now is that we don't (or can't), set the full statement descriptor for the standard Stripe account directly, so that's why we allow a custom statement descriptor from the plugin settings (I didn't check this assumption).

Since we can set the express account statement descriptor in WCPay, we may not want to pass it along with the request, since it will always default to its full form anyway. We also may not want to do that to not risk providing an invalid statement descriptor somehow.

Now that I look at the Stripe docs more carefully, we may actually want to save the short statement descriptor in the account instead: https://stripe.com/docs/api/accounts/object#account_object-settings-card_payments-statement_descriptor_prefix

And then pass a suffix.

So in the end, this could be refactored like so:

$statement_descriptor_suffix = $this->maybe_use_statement_descriptor_suffix( $order->get_payment_method(), $order );
public function maybe_use_statement_descriptor_suffix( $payment_method, $order ) {
    $statement_descriptor_prefix           = $this->get_account_statement_descriptor_prefix();
    $is_short_statement_descriptor_enabled = 'yes' === $this->get_option( 'is_short_statement_descriptor_enabled' );

    if ( in_array( $payment_method, [ 'card', 'woocommerce_payments' ], true ) && $is_short_statement_descriptor_enabled && ! empty( $statement_descriptor_prefix ) ) {
        // TODO: Refactor this:
        return WC_Payments_Utils::get_dynamic_statement_descriptor( $order );
    }

    return null;
}

get_account_statement_descriptor_prefix would grab the statement descriptor prefix from the account, similar to get_account_statement_descriptor, but probably without logging errors.

Then this function should only return the * #123 part, which is the suffix.

And then we need to rename the additional parameter statement_descriptor to statement_descriptor_suffix.

Note: I didn't test the code above.

Copy link
Contributor Author

@cesarcosta99 cesarcosta99 Mar 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps we don't want to pass it to the payment intent, unless it needs to be changed.

Agreed. I tweaked the logic here to only return it when payment method is not a card, which doesn't set a statement descriptor even if it's set on Stripe – that's why I also recommended testing a non-card payment method, such as SEPA.

we may actually want to save the short statement descriptor in the account instead

I've tried that approach and it didn't play well with the regular and suffix statement descriptors, not sure why. I've tried to follow Stripe docs and sent different combinations as well as setting all of them together and the payment intent always ended up having the full statement descriptor set in it.

Copy link
Member

@ricardo ricardo Jul 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cesarcosta99 I did some testing and was able to set the short statement descriptor (aka statement_descriptor_prefix) in the Stripe account level and create a PaymentIntent using that.

  1. Changed the server to also accept a "statement_descriptor_suffix" as an argument here and here.
  2. Manually updated my account using curl to have a card statement descriptor prefix:
curl https://api.stripe.com/v1/accounts/{WCPay_Dev_CONNECTED_ACCOUNT_ID} \
  -u "{WCPay_Dev_SECRET_KEY}:" \ # Remember the ":" at the end of the secret key
  -d "settings[card_payments][statement_descriptor_prefix]"="WOO.COM"
  1. Add the statement_descriptor_suffix to the WCPay client intentions request to something like "ID: 1234". (Like what you did with $request->set_statement_descriptor().

The only issue I encountered was that I needed to put a Latin character on the statement descriptor suffix, otherwise Stripe would throw an error:

invalid_request_error - statement_descriptor_suffix
The statement descriptor must contain at least one Latin character.

@cesarcosta99
Copy link
Contributor Author

Just commenting to say I've got back to this and it's in progress.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 10, 2023

Size Change: +2.56 kB (0%)

Total Size: 1.26 MB

Filename Size Change
release/woocommerce-payments/dist/blocks-checkout.js 39.8 kB +113 B (0%)
release/woocommerce-payments/dist/checkout.js 28.5 kB +128 B (0%)
release/woocommerce-payments/dist/index.js 283 kB +68 B (0%)
release/woocommerce-payments/dist/multi-currency-switcher-block.js 60.5 kB +61 B (0%)
release/woocommerce-payments/dist/multi-currency.js 55.4 kB +67 B (0%)
release/woocommerce-payments/dist/order.js 40.4 kB +62 B (0%)
release/woocommerce-payments/dist/payment-gateways.js 38.8 kB +58 B (0%)
release/woocommerce-payments/dist/payment-request.js 11.7 kB +117 B (+1%)
release/woocommerce-payments/dist/settings.css 8.68 kB -50 B (-1%)
release/woocommerce-payments/dist/settings.js 199 kB +1.18 kB (+1%)
release/woocommerce-payments/dist/upe_checkout.js 34.1 kB +150 B (0%)
release/woocommerce-payments/dist/upe_split_checkout.js 34.7 kB +154 B (0%)
release/woocommerce-payments/dist/upe_with_deferred_intent_creation_checkout.js 35.6 kB +109 B (0%)
release/woocommerce-payments/dist/upe-blocks-checkout.js 39.5 kB +111 B (0%)
release/woocommerce-payments/dist/upe-split-blocks-checkout.js 40.9 kB +116 B (0%)
release/woocommerce-payments/dist/woopay-express-button.js 16.8 kB +119 B (+1%)
ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 1.03 kB
release/woocommerce-payments/assets/css/success.css 158 B
release/woocommerce-payments/dist/blocks-checkout.css 1.4 kB
release/woocommerce-payments/dist/checkout.css 444 B
release/woocommerce-payments/dist/index.css 38.2 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 1.05 kB
release/woocommerce-payments/dist/multi-currency.css 2.91 kB
release/woocommerce-payments/dist/order.css 730 B
release/woocommerce-payments/dist/payment-gateways.css 704 B
release/woocommerce-payments/dist/product-details.js 787 B
release/woocommerce-payments/dist/subscription-edit-page.js 669 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 527 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 20.2 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 693 B
release/woocommerce-payments/dist/subscriptions-empty-state.css 298 B
release/woocommerce-payments/dist/subscriptions-empty-state.js 19.4 kB
release/woocommerce-payments/dist/tos.css 236 B
release/woocommerce-payments/dist/tos.js 21.7 kB
release/woocommerce-payments/dist/upe_checkout.css 444 B
release/woocommerce-payments/dist/upe_split_checkout.css 444 B
release/woocommerce-payments/dist/upe-blocks-checkout.css 1.4 kB
release/woocommerce-payments/dist/upe-split-blocks-checkout.css 1.41 kB
release/woocommerce-payments/dist/woopay.css 4.06 kB
release/woocommerce-payments/dist/woopay.js 70.4 kB
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 633 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 720 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js 2.43 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js 1.01 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js 522 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js 581 B
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/babel.config.js 160 B
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.css 2.32 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.js 13.8 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.rtl.css 2.32 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.2 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css 403 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css 3.56 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css 299 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css 742 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css 572 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css 411 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js 544 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js 9.55 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.js 6.8 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js 3.83 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js 544 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-subscription.js 2.38 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.js 22.1 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js 11.6 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/payment-method-restrictions.js 1.29 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/wcs-meta-boxes-order.js 502 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js 355 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js 429 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/view-subscription.js 1.38 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/wcs-cart.js 781 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js 1.1 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js 1.27 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css 392 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js 3.06 kB

compressed-size-action

@cesarcosta99 cesarcosta99 force-pushed the update/send-statement-descriptors-on-pi branch from 3b00e98 to 0168ec5 Compare July 25, 2023 19:17
@cesarcosta99
Copy link
Contributor Author

Rebased develop to resolve conflicts.

@ricardo, I'm requesting another review from you since you've got context from previous reviews. Please consider my last comment as well as my last replies from previous reviews. You might want to go through the testing instructions from #3625 too, since those changes got introduced in this PR.

@ricardo
Copy link
Member

ricardo commented Jul 26, 2023

@cesarcosta99 I didn't fully review the code yet, but considering it's possible to set the statement descriptor prefix at the account level, I guess that would be the best way to do it, given the full statement descriptor being already stored at the account level.

I think this would also simplify the implementation a little bit. We wouldn't need to store the statement descriptor prefix in the plugin settings nor handle the logic on whether to use the full statement or the short statement. We'd pass a statement_descriptor_suffix to the request in case the account has a statement_descriptor_prefix in cache and has a setting such as is_statement_descriptor_suffix_enabled – I didn't test this with other payment methods, but Stripe might handle the logic of which statement descriptor to use depending on the payment method.

Of course, this would require a server change as well, where we enable saving the statement_descriptor_prefix (ref) and allow it to be retrieved by the client along with the existing statement_descriptor in the account cache.

Another reason I came to not do this, is that even though we set it in the Stripe account, it's not visible in the account information in the Stripe Connect dashboard

I personally don't see this as a problem, since the statement descriptor prefix can be seen from the WCPay dashboard and account cache, but others might disagree.

Maybe we should ask the architects team on their thoughts about saving it under the plugin settings, or the Stripe account.

invalid_request_error - statement_descriptor_suffix
The statement descriptor must contain at least one Latin character.

Regarding this error. It might be worth asking Stripe about what's the "ideal" suffix there, if not an order ID, and how to prefix the order ID with a Latin character so that this requirement can be fulfilled.

@ricardo
Copy link
Member

ricardo commented Jul 26, 2023

Not sure if the input width used to be smaller at the time this PR was created, but maybe we should double-check this with design now, in order to avoid regression.

Also checking if the labels are accurate now.

Before After
Statement descriptor – Before Statement descriptor – After

@cesarcosta99 cesarcosta99 added pr: in progress status: on hold The issue is currently not prioritized. and removed pr: needs review labels Jul 26, 2023
@cesarcosta99
Copy link
Contributor Author

Thanks for reviewing, @ricardo. I'm putting the PR on hold since I can't prioritize these changes at the moment. I'll address your questions and concerns once I get back to this PR.

Copy link
Member

@ricardo ricardo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just to prevent future Slack alerts.

@cesarcosta99
Copy link
Contributor Author

Closing this pull request due to changes in Fractal priorities. More details in the original issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: projects For any issues which are part of any project, including bugs, enhancements, etc. component: checkout Issues related to Checkout component: upe type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invoice number on the bank statement
4 participants