-
Notifications
You must be signed in to change notification settings - Fork 214
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
feat(payment): PAYPAL-3520 Max capture amount failure #2485
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -28,6 +28,7 @@ import { | |||||||||||||||||||||
PaymentStrategy, | ||||||||||||||||||||||
PaypalInstrument, | ||||||||||||||||||||||
} from '@bigcommerce/checkout-sdk/payment-integration-api'; | ||||||||||||||||||||||
import { isPaypalCommerceProviderError } from '@bigcommerce/checkout-sdk/paypal-commerce-utils'; | ||||||||||||||||||||||
|
||||||||||||||||||||||
import isBraintreeError from '../is-braintree-error'; | ||||||||||||||||||||||
import mapToBraintreeShippingAddressOverride from '../map-to-braintree-shipping-address-override'; | ||||||||||||||||||||||
|
@@ -40,6 +41,7 @@ import { | |||||||||||||||||||||
export default class BraintreePaypalPaymentStrategy implements PaymentStrategy { | ||||||||||||||||||||||
private paymentMethod?: PaymentMethod; | ||||||||||||||||||||||
private braintreeHostWindow: BraintreeHostWindow = window; | ||||||||||||||||||||||
private braintree?: BraintreePaypalPaymentInitializeOptions; | ||||||||||||||||||||||
|
||||||||||||||||||||||
constructor( | ||||||||||||||||||||||
private paymentIntegrationService: PaymentIntegrationService, | ||||||||||||||||||||||
|
@@ -51,6 +53,8 @@ export default class BraintreePaypalPaymentStrategy implements PaymentStrategy { | |||||||||||||||||||||
) { | ||||||||||||||||||||||
const { braintree: braintreeOptions, methodId } = options; | ||||||||||||||||||||||
|
||||||||||||||||||||||
this.braintree = braintreeOptions; | ||||||||||||||||||||||
|
||||||||||||||||||||||
if (!this.paymentMethod || !this.paymentMethod.nonce) { | ||||||||||||||||||||||
this.paymentMethod = this.paymentIntegrationService | ||||||||||||||||||||||
.getState() | ||||||||||||||||||||||
|
@@ -85,6 +89,12 @@ export default class BraintreePaypalPaymentStrategy implements PaymentStrategy { | |||||||||||||||||||||
async execute(orderRequest: OrderRequestBody, options?: PaymentRequestOptions): Promise<void> { | ||||||||||||||||||||||
const { payment, ...order } = orderRequest; | ||||||||||||||||||||||
|
||||||||||||||||||||||
const { onError } = this.braintree || {}; | ||||||||||||||||||||||
const state = this.paymentIntegrationService.getState(); | ||||||||||||||||||||||
const features = state.getStoreConfigOrThrow().checkoutSettings.features; | ||||||||||||||||||||||
const shouldHandleInstrumentDeclinedError = | ||||||||||||||||||||||
features && features['PAYPAL-3521.handling_declined_error_braintree']; | ||||||||||||||||||||||
|
||||||||||||||||||||||
if (!payment) { | ||||||||||||||||||||||
throw new PaymentArgumentInvalidError(['payment']); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
@@ -95,6 +105,18 @@ export default class BraintreePaypalPaymentStrategy implements PaymentStrategy { | |||||||||||||||||||||
await this.paymentIntegrationService.submitOrder(order, options); | ||||||||||||||||||||||
await this.paymentIntegrationService.submitPayment(paymentData); | ||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||
if (this.isProviderError(error) && shouldHandleInstrumentDeclinedError) { | ||||||||||||||||||||||
await this.loadPaypal(); | ||||||||||||||||||||||
|
||||||||||||||||||||||
await new Promise((_resolve, reject) => { | ||||||||||||||||||||||
if (onError && typeof onError === 'function') { | ||||||||||||||||||||||
onError(new Error('INSTRUMENT_DECLINED')); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
reject(); | ||||||||||||||||||||||
}); | ||||||||||||||||||||||
Comment on lines
+125
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really see why do we need this promise.. To avoid code freeze we can simply remove the promise, since there is no reason to wait for something.
Suggested change
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
this.handleError(error); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
@@ -316,4 +338,14 @@ export default class BraintreePaypalPaymentStrategy implements PaymentStrategy { | |||||||||||||||||||||
|
||||||||||||||||||||||
throw new PaymentMethodFailedError(error.message); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
private isProviderError(error: unknown): boolean { | ||||||||||||||||||||||
if (isPaypalCommerceProviderError(error)) { | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should not use paypal commerce related code inside brainteree strategy. Please create another typeguard for that. |
||||||||||||||||||||||
const paypalProviderError = error?.errors?.filter((e: any) => e.provider_error) || []; | ||||||||||||||||||||||
|
||||||||||||||||||||||
return paypalProviderError[0].provider_error?.code === '2046'; | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it would be better to create a separate constant for '2046' error? How do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the late response. I think it is not necessary, we use this code only here and nowhere else |
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
return false; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to reject promise in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to do this to avoid the execution code freeze. Code will not execute correctly without reject calling