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

Updates hideCvv flag for edit payment methods and new payment methods. #1109

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

wjames111
Copy link

OKR: Implement real-time CVV validation on all transactions for Give App

@wjames111 wjames111 self-assigned this Oct 28, 2024
@wjames111 wjames111 added the On Staging Will be merged to the staging branch by Github Actions label Oct 28, 2024
@wjames111
Copy link
Author

@wrandall22 I'm having some difficulty with this one. I need to validate that the CVV is correct when paying with a saved card. I added a save payment method that is essentially just ripped from creditCardForm.component.js. I haven’t been able to get it working though which isn't surprising seeing as I'm not entirely sure what all is going on in that code block. Do you have any pointers for me/is this the right way of going about it?

@wrandall22
Copy link
Contributor

So, there are a few things.

  1. You should probably make the changes in existingPaymentMethods instead of in paymentMethodDisplay since the first is only used in checkout and the latter is used in several places we don't want to capture cvv.
  2. The validation is happening, but is not preventing the user from moving forward, which means we need to hook into the continue button on checkout step 2 and ensure that the validation passes there before moving forward.
  3. The Angular way of re-using the cvv template/controller code is to create a directive and put it in both places. We have several directives in the codebase already which you can reference (even creditCardNumber has one). This would be a way to not copy/paste code and maintain it in two places.

@wjames111
Copy link
Author

@wrandall22 thank you this is really helpful. One question, do we only need the validators on the CVV? I would assume we need to ensure the CVV is also correct for the given credit card before allowing them to move forward. That was what I was trying to accomplish with the savePayment method, although it didn't appear to be working.

@wrandall22
Copy link
Contributor

The CVV is the only thing being entered, so is the only thing being validated in this situation. That validation can live in the directive.

@wjames111
Copy link
Author

Ahh okay that makes things a bit easier.

@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

Great work on this PR!

Just a note: before merging with staging, can you run yarn lint:write? This will ensure the lint issues are fixed or bring attention to code that needs to be changed. This way, your changes on staging will be deployed to the staging site.

@dr-bizz dr-bizz removed the On Staging Will be merged to the staging branch by Github Actions label Nov 8, 2024
@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

Removing the on staging label for now. Once everything is working on this branch, feel free to add it back

@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

It seems like it wasn't just you, there were some other changes from other PRs that caused staging to fail being deployed.

@wjames111
Copy link
Author

@dr-bizz thanks that make me feel better. Sorry about that, I didn't realize it was causing issues. It's not quite ready for staging either.

@wrandall22
Copy link
Contributor

You can turn it into a draft PR until it's ready if you want.

@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

It's all good. This is where amplify previews would come in handy

@wjames111 wjames111 marked this pull request as draft November 8, 2024 16:05
@wjames111
Copy link
Author

@wrandall22 is this more what you had in mind? Do you know where else the directive needs to be used apart from existingPaymentMethods?

@wrandall22
Copy link
Contributor

Hey Will, thanks for working on this. I was more thinking of putting this part of the HTML in the directive:

<div class="form-group" ng-class="{'has-error': ($ctrl.creditCardPaymentForm.securityCode | showErrors), 'is-required': !$ctrl.paymentMethod}">
          <label translate>{{'SEC_CODE'}}</label>
          <input type="text"
                 name="securityCode"
                 autocomplete="cc-csc"
                 class="form-control form-control-subtle"
                 ng-model="$ctrl.creditCardPayment.securityCode"
                 ng-required="!$ctrl.paymentMethod || $ctrl.creditCardPayment.cardNumber"
                 ng-attr-placeholder="{{$ctrl.paymentMethod && !$ctrl.creditCardPayment.cardNumber ? '***' : ''}}">
          <div role="alert" ng-messages="$ctrl.creditCardPaymentForm.securityCode.$error" ng-if="($ctrl.creditCardPaymentForm.securityCode | showErrors)">
            <div class="help-block" ng-message="required" translate>{{'CARD_SEC_CODE_ERROR'}}</div>
            <div class="help-block" ng-message="minLength" translate>{{'MIN_LENGTH_CARD_SEC_CODE'}}</div>
            <div class="help-block" ng-message="maxLength" translate>{{'MAX_LENGTH_CARD_SEC_CODE'}}</div>
            <div class="help-block" ng-message="cardTypeLength" ng-init="isAmex = $ctrl.cardInfo.type($ctrl.creditCardPayment.cardNumber) === 'American Express'">
              <translate ng-if="!isAmex">{{'LOCATION_OF_CODE_OTHER'}}</translate>
              <translate ng-if="isAmex">{{'LOCATION_OF_CODE_AMEX'}}</translate>
            </div>
          </div>
        </div>

Then using it in both creditCardForm and existingPaymentMethods

@wjames111
Copy link
Author

@wrandall22 is this a little more what you had in mind? I was initially trying to validate within the directive itself, but it ended up being easier to just use the directive for the template and use the validators that were already in place.

@wrandall22
Copy link
Contributor

Yep, this is the direction I was thinking.

@wjames111
Copy link
Author

@wrandall22 okay great! I'll fix it up.

@wjames111 wjames111 added the On Staging Will be merged to the staging branch by Github Actions label Nov 19, 2024
@wjames111 wjames111 marked this pull request as ready for review November 19, 2024 20:42
@wjames111 wjames111 requested a review from wrandall22 November 19, 2024 20:42
@wjames111 wjames111 removed the On Staging Will be merged to the staging branch by Github Actions label Nov 20, 2024
@wjames111 wjames111 requested a review from wrandall22 November 20, 2024 19:26
Copy link
Contributor

@wrandall22 wrandall22 left a comment

Choose a reason for hiding this comment

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

I got part way through the review, this is a good start. I'm going to play around a little bit with the directive locally as well.

src/app/checkout/step-2/step-2.component.js Outdated Show resolved Hide resolved
src/app/checkout/step-2/step-2.component.js Show resolved Hide resolved
src/app/checkout/step-2/step-2.component.spec.js Outdated Show resolved Hide resolved
src/common/directives/creditCardCvv.directive.js Outdated Show resolved Hide resolved
src/common/directives/creditCardCvv.directive.js Outdated Show resolved Hide resolved
@wjames111
Copy link
Author

Thanks @wrandall22! I'll get started on these changes.

Copy link
Contributor

@dr-bizz dr-bizz left a comment

Choose a reason for hiding this comment

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

I am getting this error message when trying to continue to step 3.

TypeError: Cannot read properties of undefined (reading 'cvv')
at Step2Controller.onPaymentFormStateChange (step-2.component.js:114:74)
at Step2Controller.submit (step-2.component.js:75:10)

I also get an error message when trying to submit the checkout.

{"error":"Invalid Data"}

In my incognito window, I get an error that prevents me from moving from Step 2 to Step 3. But this could just be my local.

Error tokenizing credit card 

@@ -117,7 +120,7 @@ class Step2Controller {
}

isContinueDisabled () {
if (this.selectedPaymentMethod?.['card-type'] && typeof this.isCvvValid !== 'undefined' && !this.isCvvValid) {
if (this.selectedPaymentMethod?.['card-type'] && !this.isCvvValid) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it no longer returning as undefined

Copy link
Author

Choose a reason for hiding this comment

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

It doesn't appear to be, so I just removed the condition.

@@ -109,14 +110,19 @@ class Step2Controller {
this.changeStep({ newStep: 'review' })
this.onStateChange({ state: 'submitted' })
this.paymentFormState = 'success'
} else if ($event.state === 'submitted') {
this.orderService.storeCardSecurityCode(this.selectedPaymentMethod.cvv, this.selectedPaymentMethod.self.uri)
Copy link
Contributor

Choose a reason for hiding this comment

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

Change the test to be like the below. Adding the line self.controller.selectedPaymentMethod = { cvv: '123', self: { uri: 'uri'} }

it('should update paymentFormState if transitioning to a different state', () => {
        self.controller.paymentFormState = 'unsubmitted'
        self.controller.selectedPaymentMethod = { cvv: '123', self: { uri: 'uri'} }
        self.controller.onPaymentFormStateChange({ state: 'submitted' })

        expect(self.controller.paymentFormState).toEqual('submitted')
})

@wrandall22
Copy link
Contributor

Error tokenizing credit card is due to you not using the Referer Control extension properly.

{"error":"Invalid Data"} is due to the work being done in staging for recaptcha enterprise.

@dr-bizz
Copy link
Contributor

dr-bizz commented Dec 6, 2024

Error tokenizing credit card is due to you not using the Referer Control extension properly.

{"error":"Invalid Data"} is due to the work being done in staging for recaptcha enterprise.

This makes sense. Ignore that comment.

'{"/paymentmethods/crugive/giydsnjqgi=":"456","/paymentmethods/crugive/giydsnjqgy=":"321"}'
'{"/paymentinstruments/orders/crugive/hfsdoylfhbswk…4tmljug5qtqllcg44wcljvhezgcntcmvtdeojwgy=":"456"}'
Copy link
Contributor

Choose a reason for hiding this comment

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

Note that both of these show possibilities of reality.

@wrandall22
Copy link
Contributor

Something seems to have regressed on the display of adding a new payment method and the optional cover fees area.

Prod:
Screenshot 2024-12-12 at 1 22 45 PM

This branch:
Screenshot 2024-12-12 at 1 21 10 PM

@wrandall22
Copy link
Contributor

@rguinee I'd be curious to hear your design perspective on a good way of showing the security code here as well. I'm thinking inline label/input instead of stacked and not quite so tall.

@rguinee
Copy link

rguinee commented Dec 12, 2024

@rguinee I'd be curious to hear your design perspective on a good way of showing the security code here as well. I'm thinking inline label/input instead of stacked and not quite so tall.

Are we requiring they enter it again on a saved card for security purposes?

@wrandall22
Copy link
Contributor

Correct

const storage = JSON.parse(this.sessionStorage.getItem('cvv')) || ''
this.creditCardPaymentForm.securityCode.$setViewValue(storage)
this.creditCardPaymentForm.securityCode.$render()
this.sessionStorage.removeItem('cvv')
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't want to clear this from session storage here, as this is what is sent to the server.

Copy link
Author

Choose a reason for hiding this comment

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

So here was my thinking; this only gets removed on switchPayment, which only happens previously to cvv getting added to storage. So if we remove it here it just gets added again once you proceed to the next step. From testing session storage appears to always hold the correct cvv key/value at the final step which I believe is where it gets sent to the server. The primary reason for deleting the session storage here is to only set it once, which will keep it from adding the stored cvv to the cvv field every time switchPayment is called. I could be missing something though, I could always try to come up with a different way to keep cvv getting set everytime.

Copy link
Contributor

Choose a reason for hiding this comment

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

In my testing, it cleared right after I edited the existing payment method and entering the CVV there. It got copied to the text box but then removed from session storage.

Copy link
Author

Choose a reason for hiding this comment

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

hmm okay I must have missed something.

Copy link
Author

Choose a reason for hiding this comment

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

So when you get to the final step. The stored cvv isn't present?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I see what you're saying. It does get added back after hitting continue. We need to test that on the single step BCO branch as well to see how that behaves.

Copy link
Author

Choose a reason for hiding this comment

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

Good call, I did not to think to check branded that could be problematic.

Copy link
Contributor

Choose a reason for hiding this comment

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

So, it looks like switchPayment is called when hitting Continue on 2 step branded checkout and when hitting Submit on single step branded checkout. So this will definitely need to change in some way.

@rguinee
Copy link

rguinee commented Dec 12, 2024

Screenshot 2024-12-12 at 1 57 57 PM

Agree on your instinct @wrandall22. There are several other recommendations I'd have for this like moving "Add a payment method" into the list of Your Payment Methods.

@wrandall22
Copy link
Contributor

Do you envision that being below the selected payment method or the full list? I think the former.

@rguinee
Copy link

rguinee commented Dec 12, 2024

Exactly @wrandall22. They could have multiple card payment methods, so we would show below the selected option the sec code verification input. There are other considerations to make here. Is it validated when 3 or 4 digits are entered and can show success or error response? Does it have it be submitted and if incorrect the errors appear after page reloads?

@wrandall22
Copy link
Contributor

The validation is there and it shows in real time, not after submit (unless the back-end finds issues with the card verification with TSYS)

@wjames111 wjames111 force-pushed the hideCvv-flag branch 2 times, most recently from b9a9e63 to 7988984 Compare December 12, 2024 23:46
@wjames111
Copy link
Author

@rguinee @wrandall22 Ryan is the image you shared what we want to go with? I can get started styling it, but I don't want to jump the gun if you guys are still deciding on what works/looks best.

.give-modal-content, .branded-checkout {
.credit-card-cvv-label {
text-transform: uppercase;
font-weight: 500;
Copy link
Contributor

Choose a reason for hiding this comment

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

On my local, this is being overwritten by the bold above.

display: block;
margin-bottom: 4px;
&::after {
content: '*';
Copy link
Contributor

Choose a reason for hiding this comment

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

On my local, this is being overwritten by the : above.

@wjames111 wjames111 added On Staging Will be merged to the staging branch by Github Actions and removed On Staging Will be merged to the staging branch by Github Actions labels Dec 17, 2024
@wjames111
Copy link
Author

Seems like the styling is working locally now, for some reason the changes aren't reflected on staging. Not sure if there's a cacheing issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
On Staging Will be merged to the staging branch by Github Actions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants