Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,28 @@ final class SavedPaymentMethodManager {

let configuration: PaymentElementConfiguration
let elementsSession: STPElementsSession
let customerProvider: CustomerProvider

private lazy var ephemeralKey: String? = {
guard let ephemeralKey = configuration.customer?.ephemeralKeySecret(basedOn: elementsSession) else {
guard let ephemeralKey = customerProvider.ephemeralKeySecret(basedOn: elementsSession) else {
stpAssert(true, "Failed to read ephemeral key.")
let errorAnalytic = ErrorAnalytic(event: .unexpectedPaymentSheetError,
error: Error.missingEphemeralKey,
additionalNonPIIParams: ["customer_access_provider": configuration.customer?.customerAccessProvider.analyticValue ?? "unknown"])
additionalNonPIIParams: ["customer_access_provider": customerProvider.analyticsValue ?? "unknown"])
STPAnalyticsClient.sharedClient.log(analytic: errorAnalytic)
return nil
}
return ephemeralKey
}()

init(configuration: PaymentElementConfiguration, elementsSession: STPElementsSession) {
init(
configuration: PaymentElementConfiguration,
elementsSession: STPElementsSession,
customerProvider: CustomerProvider? = nil
) {
self.configuration = configuration
self.elementsSession = elementsSession
self.customerProvider = customerProvider ?? CustomerProvider.make(configuration: configuration)
}

func update(paymentMethod: STPPaymentMethod,
Expand All @@ -52,9 +58,8 @@ final class SavedPaymentMethodManager {
return
}

if let customerAccessProvider = configuration.customer?.customerAccessProvider,
case .customerSession(let customerSessionClientSecret) = customerAccessProvider,
let customerId = configuration.customer?.id {
if let customerSessionClientSecret = customerProvider.customerSessionClientSecretIfAvailable,
let customerId = customerProvider.customerID {
if paymentMethod.type == .card {
configuration.apiClient.detachPaymentMethodRemoveDuplicates(
paymentMethod.stripeId,
Expand Down Expand Up @@ -86,7 +91,7 @@ final class SavedPaymentMethodManager {
guard let ephemeralKey else {
throw PaymentSheetError.unknown(debugDescription: "Failed to read ephemeral key while setting a payment method as default.")
}
guard let customerId = configuration.customer?.id else {
guard let customerId = customerProvider.customerID else {
throw PaymentSheetError.unknown(debugDescription: "Failed to read customerId while setting a payment method as default.")
}
return try await configuration.apiClient.setAsDefaultPaymentMethod(defaultPaymentMethodId, for: customerId, using: ephemeralKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ extension STPAPIClient {
customerAccessProvider: PaymentSheet.CustomerAccessProvider?,
linkDisallowFundingSourceCreation: Set<String>,
userOverrideCountry: String? = nil
) -> [String: Any] {
makeElementsSessionsParams(
mode: mode,
epmConfiguration: epmConfiguration,
cpmConfiguration: cpmConfiguration,
clientDefaultPaymentMethod: clientDefaultPaymentMethod,
customerProvider: CustomerProvider.make(customerAccessProvider: customerAccessProvider),
linkDisallowFundingSourceCreation: linkDisallowFundingSourceCreation,
userOverrideCountry: userOverrideCountry
)
}

func makeElementsSessionsParams(
mode: PaymentSheet.InitializationMode,
epmConfiguration: PaymentSheet.ExternalPaymentMethodConfiguration?,
cpmConfiguration: PaymentSheet.CustomPaymentMethodConfiguration?,
clientDefaultPaymentMethod: String?,
customerProvider: CustomerProvider,
linkDisallowFundingSourceCreation: Set<String>,
userOverrideCountry: String? = nil
) -> [String: Any] {
var parameters: [String: Any] = [
"locale": Locale.current.toLanguageTag(),
Expand All @@ -41,11 +61,7 @@ extension STPAPIClient {
if let appId = Bundle.main.bundleIdentifier {
parameters["mobile_app_id"] = appId
}
if case .customerSession(let clientSecret) = customerAccessProvider {
parameters["customer_session_client_secret"] = clientSecret
} else if case .legacyCustomerEphemeralKey(let ephemeralKey) = customerAccessProvider {
parameters["legacy_customer_ephemeral_key"] = ephemeralKey
}
customerProvider.addingElementsSessionCustomerParams(to: &parameters)
if let clientDefaultPaymentMethod {
parameters["client_default_payment_method"] = clientDefaultPaymentMethod
}
Expand Down Expand Up @@ -108,6 +124,20 @@ extension STPAPIClient {
paymentIntentClientSecret: String,
clientDefaultPaymentMethod: String?,
configuration: PaymentElementConfiguration
) async throws -> (STPPaymentIntent, STPElementsSession) {
try await retrieveElementsSession(
paymentIntentClientSecret: paymentIntentClientSecret,
clientDefaultPaymentMethod: clientDefaultPaymentMethod,
configuration: configuration,
customerProvider: CustomerProvider.make(configuration: configuration)
)
}

func retrieveElementsSession(
paymentIntentClientSecret: String,
clientDefaultPaymentMethod: String?,
configuration: PaymentElementConfiguration,
customerProvider: CustomerProvider
) async throws -> (STPPaymentIntent, STPElementsSession) {
let elementsSession = try await APIRequest<STPElementsSession>.getWith(
self,
Expand All @@ -117,7 +147,7 @@ extension STPAPIClient {
epmConfiguration: configuration.externalPaymentMethodConfiguration,
cpmConfiguration: configuration.customPaymentMethodConfiguration,
clientDefaultPaymentMethod: clientDefaultPaymentMethod,
customerAccessProvider: configuration.customer?.customerAccessProvider,
customerProvider: customerProvider,
linkDisallowFundingSourceCreation: configuration.link.disallowFundingSourceCreation,
userOverrideCountry: configuration.userOverrideCountry
)
Expand All @@ -129,14 +159,28 @@ extension STPAPIClient {
else {
throw PaymentSheetError.unknown(debugDescription: "PaymentIntent missing from v1/elements/sessions response")
}
try verifyCustomerSessionForPaymentSheet(configuration: configuration, elementsSession: elementsSession)
try verifyCustomerSessionForPaymentSheet(customerProvider: customerProvider, elementsSession: elementsSession)
return (paymentIntent, elementsSession)
}

func retrieveElementsSession(
setupIntentClientSecret: String,
clientDefaultPaymentMethod: String?,
configuration: PaymentElementConfiguration
) async throws -> (STPSetupIntent, STPElementsSession) {
try await retrieveElementsSession(
setupIntentClientSecret: setupIntentClientSecret,
clientDefaultPaymentMethod: clientDefaultPaymentMethod,
configuration: configuration,
customerProvider: CustomerProvider.make(configuration: configuration)
)
}

func retrieveElementsSession(
setupIntentClientSecret: String,
clientDefaultPaymentMethod: String?,
configuration: PaymentElementConfiguration,
customerProvider: CustomerProvider
) async throws -> (STPSetupIntent, STPElementsSession) {
let elementsSession = try await APIRequest<STPElementsSession>.getWith(
self,
Expand All @@ -146,7 +190,7 @@ extension STPAPIClient {
epmConfiguration: configuration.externalPaymentMethodConfiguration,
cpmConfiguration: configuration.customPaymentMethodConfiguration,
clientDefaultPaymentMethod: clientDefaultPaymentMethod,
customerAccessProvider: configuration.customer?.customerAccessProvider,
customerProvider: customerProvider,
linkDisallowFundingSourceCreation: configuration.link.disallowFundingSourceCreation,
userOverrideCountry: configuration.userOverrideCountry
)
Expand All @@ -158,21 +202,35 @@ extension STPAPIClient {
else {
throw PaymentSheetError.unknown(debugDescription: "SetupIntent missing from v1/elements/sessions response")
}
try verifyCustomerSessionForPaymentSheet(configuration: configuration, elementsSession: elementsSession)
try verifyCustomerSessionForPaymentSheet(customerProvider: customerProvider, elementsSession: elementsSession)
return (setupIntent, elementsSession)
}

func retrieveDeferredElementsSession(
withIntentConfig intentConfig: PaymentSheet.IntentConfiguration,
clientDefaultPaymentMethod: String?,
configuration: PaymentElementConfiguration
) async throws -> STPElementsSession {
try await retrieveDeferredElementsSession(
withIntentConfig: intentConfig,
clientDefaultPaymentMethod: clientDefaultPaymentMethod,
configuration: configuration,
customerProvider: CustomerProvider.make(configuration: configuration)
)
}

func retrieveDeferredElementsSession(
withIntentConfig intentConfig: PaymentSheet.IntentConfiguration,
clientDefaultPaymentMethod: String?,
configuration: PaymentElementConfiguration,
customerProvider: CustomerProvider
) async throws -> STPElementsSession {
let parameters = makeElementsSessionsParams(
mode: .deferredIntent(intentConfig),
epmConfiguration: configuration.externalPaymentMethodConfiguration,
cpmConfiguration: configuration.customPaymentMethodConfiguration,
clientDefaultPaymentMethod: clientDefaultPaymentMethod,
customerAccessProvider: configuration.customer?.customerAccessProvider,
customerProvider: customerProvider,
linkDisallowFundingSourceCreation: configuration.link.disallowFundingSourceCreation,
userOverrideCountry: configuration.userOverrideCountry
)
Expand All @@ -181,12 +239,12 @@ extension STPAPIClient {
endpoint: APIEndpointElementsSessions,
parameters: parameters
)
try verifyCustomerSessionForPaymentSheet(configuration: configuration, elementsSession: elementsSession)
try verifyCustomerSessionForPaymentSheet(customerProvider: customerProvider, elementsSession: elementsSession)
return elementsSession
}

func verifyCustomerSessionForPaymentSheet(configuration: PaymentElementConfiguration, elementsSession: STPElementsSession) throws {
if case .customerSession = configuration.customer?.customerAccessProvider {
func verifyCustomerSessionForPaymentSheet(customerProvider: CustomerProvider, elementsSession: STPElementsSession) throws {
if customerProvider.usesCustomerSession {
// User passed in a customerSessionClient secret
if let customer = elementsSession.customer {
// If claimed, customer will be not nil.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ShopPayECEPresenter: NSObject, UIAdaptivePresentationControllerDelegate {
func present(from viewController: UIViewController,
confirmHandler: @escaping (PaymentSheetResult) -> Void) {
// ShopPay support is experimental and currently not supported outside of CustomerSessions. Barring GA, there are no plans to support it with legacy EK or CheckoutSessions.
guard case .customerSession(let customerSessionClientSecret) = flowController.configuration.customer?.customerAccessProvider else {
guard let customerSessionClientSecret = flowController.customerProvider.customerSessionClientSecretIfAvailable else {
stpAssertionFailure("Integration Error: CustomerSessions is required")
return
}
Expand Down
Loading
Loading