-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
MBL-1123: Implement CreatePaymentIntent #1994
MBL-1123: Implement CreatePaymentIntent #1994
Conversation
clientSecretSignal = AppEnvironment.current.apiService | ||
.createPaymentIntentInput(input: CreatePaymentIntentInput( | ||
projectId: project.graphID, | ||
amountDollars: "10.00", |
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.
This is the important // TODO
here - we need the actual pledge amount in this view model.
a494263
to
daa6386
Compare
…mentMethodCellViewModel
10b8daa
to
921c2a7
Compare
Generated by 🚫 Danger |
921c2a7
to
3c48918
Compare
case let .success(paymentSheetFlowController): | ||
let topViewController = strongSelf.navigationController?.topViewController | ||
|
||
assert( |
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.
Note that I got rid of the if paymentSheetShownWithinPledgeContext
and changed it to an assert, instead. AFAIK this view controller is already only ever used from a pledge context.
@@ -195,7 +212,7 @@ final class PledgePaymentMethodsViewController: UIViewController { | |||
label: existingPaymentOption.label | |||
) | |||
strongSelf.viewModel.inputs | |||
.paymentSheetDidAdd(newCard: paymentDisplayData, setupIntent: clientSecret) | |||
.paymentSheetDidAdd(newCard: paymentDisplayData, clientSecret: clientSecret) |
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.
I've been trying to rename setupIntent
to clientSecret
or stripeIntent
wherever I can, but definitely have missed some spots.
@@ -50,7 +50,9 @@ final class PledgePaymentMethodsViewControllerTests: TestCase { | |||
project: project, | |||
reward: reward, | |||
context: .pledge, | |||
refTag: nil | |||
refTag: nil, | |||
pledgeTotal: Double.nan, |
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.
self.viewModel.outputs.configureStripeIntegration | ||
.observeForUI() | ||
.observeValues { merchantIdentifier, publishableKey in | ||
STPAPIClient.shared.publishableKey = publishableKey |
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.
Thanks @scottkicks! Just copied this directly over from PledgeViewModel/PledgeViewController
.
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.
It's not clear to me why we only set the Stripe keys if the payment view isn't hidden - does Stripe charge us for setup? Seems odd, but I'm not willing to plumb those depths right now.
@@ -155,7 +155,8 @@ public final class PaymentMethodsViewModel: PaymentMethodsViewModelType, | |||
configuration.allowsDelayedPaymentMethods = true | |||
let data = PaymentSheetSetupData( | |||
clientSecret: envelope.clientSecret, | |||
configuration: configuration | |||
configuration: configuration, | |||
paymentSheetType: .setupIntent |
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.
PaymentMethodsViewModel
is used by PaymentMethodSettingsViewControllerDelegate
, which is in the settings. That page only ever needs to use a SetupIntent
.
@@ -16,12 +16,20 @@ public typealias PledgePaymentMethodsValue = ( | |||
project: Project, | |||
reward: Reward, | |||
context: PledgeViewContext, | |||
refTag: RefTag? | |||
refTag: RefTag?, | |||
pledgeTotal: Double, |
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.
Passing the pledgeTotal
in this way is a bit ugly, since it means I'm setting it to an empty value for non-late-pledge usages of this screen. I tried to document it in the code with assert
s.
@@ -198,22 +207,26 @@ public final class PledgePaymentMethodsViewModel: PledgePaymentMethodsViewModelT | |||
|
|||
if indexPath.row < paymentSheetPaymentMethodCount { | |||
// we are selecting a new payment sheet card | |||
let setupIntent = data.paymentSheetPaymentMethodsCellData[indexPath.row].setupIntent | |||
let clientSecret = data.paymentSheetPaymentMethodsCellData[indexPath.row].clientSecret |
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.
At the level of each individual payment row, it just tracks a clientSecret
as a string. The PledgePaymentMethodsViewModel
, one level up, keeps track of whether that string is a PaymentIntent
or a SetupIntent
.
configuration.allowsDelayedPaymentMethods = true | ||
case .paymentIntent: | ||
assert( | ||
!pledgeTotal.isNaN, |
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.
This is my protection for the slightly ugly plumbing, here. I can't think of a good way around passing in the pledgeTotal
in the overall configuration of this page - there's nowhere else we can get it from, correct?
// This second to last value - pledgeTotal - is only needed when the payment methods controller | ||
// is used in late campaign pledges. There is an assert in PledgePaymentMethodsViewModel to ensure | ||
// we don't accidentally propagate this nan downstream. | ||
return (user, project, reward, context, refTag, Double.nan, .setupIntent) |
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.
@scottkicks @ifosli Can someone confirm that PledgeViewModel
is never used for late pledges?
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.
I can confirm! We're only using PostCampaignCheckoutViewModel
in this new flow. PledgeViewModel
should never get initialized.
@@ -67,7 +67,7 @@ public class PostCampaignCheckoutViewModel: PostCampaignCheckoutViewModelType, | |||
guard let user = AppEnvironment.current.currentUser else { return nil } | |||
guard let reward = data.rewards.first else { return nil } | |||
|
|||
return (user, data.project, reward, data.context, data.refTag) | |||
return (user, data.project, reward, data.context, data.refTag, data.total, .paymentIntent) |
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.
@scottkicks @ifosli Can someone confirm that data.total
is the correct value for the pledge total?
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.
Correct 👍
3c48918
to
5e9baef
Compare
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.
LGTM 👍
Great Job!
📲 What
For late pledges, create an
PaymentIntent
instead of aSetupIntent
, and use the associated Stripe payment sheet.This PR includes quite a bit of refactoring, which is to make the intent type significantly more explicit in
PledgePaymentsViewController/ViewModel
.🤔 Why
Swapping late pledges to use
PaymentIntent
is a requirement of the broader project.👀 See