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

fix: Native code audit, mostly Android #832

Merged
merged 17 commits into from
Mar 23, 2022

Conversation

charliecruzan-stripe
Copy link
Collaborator

@charliecruzan-stripe charliecruzan-stripe commented Mar 4, 2022

Summary / Motivation

Get rid of warnings, fix some code styling, better null checks, remove usage of deprecated Android features, better file naming, use PaymentLauncher instead of stripe.onPaymentResult

For reviewing- it's probably most efficient to review this PR commit by commit

Testing

  • I tested this manually
  • Existing automated tests should pass

Documentation

Select one:

  • I have added relevant documentation for my changes.
  • This PR does not result in any developer-facing changes.

@charliecruzan-stripe
Copy link
Collaborator Author

charliecruzan-stripe commented Mar 7, 2022

@michelleb-stripe requesting your review since you did the Android audit (here). Really the only commit that I think could use your attention is this one

when (paymentResult) {
is PaymentResult.Completed -> {
clientSecret?.let {
retrievePaymentIntent(it, stripeAccountId)
Copy link
Contributor

@michelleb-stripe michelleb-stripe Mar 9, 2022

Choose a reason for hiding this comment

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

How is the result of of retrievePaymentIntent being used? I don't think it should be needed because the PaymentFlowFailureMessageFactory contains similar logic. It is called from the PaymentFlowResultProcessor in the PaymentLauncherViewModel.

We have an example of how to use the PaymentLauncher here.

It would also be good to have @ccen-stripe take a final look at it too

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

retrievePaymentIntent allows us to get the relevant paymentIntent (or the error) and pass it back to the React Native app via promise.resolve. Went with stripe.retrievePaymentIntent based on this comment

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure I am understanding. It looks like the retrievePaymentIntent is only be retrieved in the "Complete" case and isn't being returned.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's correct- retrievePaymentIntent is only called in the complete case. In the case of cancellation or failure, we send an error object back to the user (L46 and L50)

In the case of a completed payment result, we retrieve the payment intent, and resolve the promise that was passed in via Javascript. We aren't explicitly calling return here with the payment intent object, but the promise.resolve call is passing the data back over the React Native bridge into "Javascript land".

The previous code functioned the same way, see here. But, if there's a better way to fetch the payment intent associated with the result then let me know!

Copy link
Contributor

Choose a reason for hiding this comment

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

I gotchya, that is ok to preserve behavior. The PaymentSheet on Android and iOS do not return the payment intent though, so it is a difference of behavior there.

I don't think an immediate action is needed.

Copy link
Contributor

@ccen-stripe ccen-stripe Mar 14, 2022

Choose a reason for hiding this comment

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

PaymentLauncher actually processes the status of the Intent internally and returns Completed/Failed/Cancelled according to the processed Outcomes.

Compared the logic with retrievePaymentIntent a bit, it seems we can just avoid the retrievePaymentIntent call and do the following mapping:

PaymentResult.Completed-> {
  val paymentIntent = createResult("paymentIntent", mapFromPaymentIntentResult(result))
  promise.resolve(paymentIntent)}
PaymentResult.Failed-> {
  val error = result.lastPaymentError
  promise.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), error))
}
PaymentResult.Cancelled-> {
if (isPaymentIntentNextActionVoucherBased(result.nextActionType)) {
    val paymentIntent = createResult("paymentIntent", mapFromPaymentIntentResult(result))
    promise.resolve(paymentIntent)
  } else {
    (result.lastPaymentError)?.let {
      promise.resolve(createError(ConfirmPaymentErrorType.Canceled.toString(), it))
    } ?: run {
      promise.resolve(createError(ConfirmPaymentErrorType.Canceled.toString(), "The payment has been canceled"))
    }
  }
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure I understand- mapFromPaymentIntentResult accepts a PaymentIntent, but the result we're getting here from PaymentLauncher is a PaymentResult. I thought in order to retrieve the full PaymentIntent object, we pretty much needed to use Stripe.retrievePaymentIntent

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, @ccen-stripe I think this api is a little different in that it returns the full payment intent to clients.

CHANGELOG.md Outdated Show resolved Hide resolved
@@ -271,6 +215,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
}

@ReactMethod
@SuppressWarnings("unused")
fun initialise(params: ReadableMap, promise: Promise) {
val publishableKey = getValOr(params, "publishableKey", null) as String
val appInfo = getMapOrNull(params, "appInfo") as ReadableMap
Copy link
Contributor

Choose a reason for hiding this comment

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

On line 278: setUrlSchemeOnAndroid, it appears this is the returnUrl on Android. I wonder if we can deprecate setUrlSchemeOnAndroid and move to setReturnUrlSchemeOnAndroid?

Let's check with @ccen-stripe, but I think we recommend that user's don't set this, but not sure where we indicate that to users. (Stripe.kt has some commentary on the effect of the returnUrl, but doesn't say anything about recommending it is not set.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

renamed to setReturnUrlSchemeOnAndroid and deprecated setUrlSchemeOnAndroid.

Copy link
Contributor

@michelleb-stripe michelleb-stripe left a comment

Choose a reason for hiding this comment

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

Lots of great changes and cleanup in here! Very excited to see this all implemented.

@michelleb-stripe michelleb-stripe removed their assignment Mar 9, 2022
@michelleb-stripe
Copy link
Contributor

I just sent @ccen-stripe a message this morning to get some feedback on one remaining comment: https://github.com/stripe/stripe-react-native/pull/832/files#r822856777

@charliecruzan-stripe charliecruzan-stripe changed the title [WIP] BREAKING CHANGE: Native code audit, mostly Android [WIP] fix: Native code audit, mostly Android Mar 21, 2022
@charliecruzan-stripe charliecruzan-stripe changed the title [WIP] fix: Native code audit, mostly Android fix: Native code audit, mostly Android Mar 21, 2022
@charliecruzan-stripe charliecruzan-stripe merged commit 422078d into master Mar 23, 2022
@charliecruzan-stripe charliecruzan-stripe deleted the charliecruzan-audit branch March 23, 2022 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants