Merge branch 'master' into bdorfman-single-line-postalfield

This commit is contained in:
Brian Dorfman 2017-07-26 12:03:39 -07:00
commit 4023480ba7
279 changed files with 5539 additions and 1674 deletions

View File

@ -1,2 +1,2 @@
try: try:
project: 'Example/Stripe iOS Example (Simple).xcworkspace' project: 'Example/UI Examples.xcworkspace'

View File

@ -1,3 +1,14 @@
== X.X.X 2017-XX-XX
* Adds an option to allow users to delete payment methods from the `STPPaymentMethodsViewController`. Enabled by default but can disabled using the `canDeletePaymentMethods` property of `STPPaymentConfiguration`.
* Screenshots: https://user-images.githubusercontent.com/28276156/28131357-7a353474-66ee-11e7-846c-b38277d111fd.png
* `STPCustomer`'s `shippingAddress` property is now correctly annotated as nullable.
* Removed `STPCheckoutUnknownError`, `STPCheckoutTooManyAttemptsError`, and `STPCustomerContextMissingKeyProviderError`. These errors will no longer occur.
== 11.1.0 2017-07-12
* Adds stripeAccount property to `STPAPIClient`, set this to perform API requests on behalf of a connected account
* Fixes the `routingNumber` property of `STPBankAccount` so that it is populated when the information is available
* Adds iOS Objective-C Style Guide
== 11.0.0 2017-06-27 == 11.0.0 2017-06-27
* We've greatly simplified the integration for `STPPaymentContext`. See MIGRATING.md. * We've greatly simplified the integration for `STPPaymentContext`. See MIGRATING.md.
* As part of this new integration, we've added a new class, `STPCustomerContext`, which will automatically prefetch your customer and cache it for a brief interval. We recommend initializing your `STPCustomerContext` before your user enters your checkout flow so their payment methods are loaded in advance. If in addition to using `STPPaymentContext`, you create a separate `STPPaymentMethodsViewController` to let your customer manage their payment methods outside of your checkout flow, you can use the same instance of `STPCustomerContext` for both. * As part of this new integration, we've added a new class, `STPCustomerContext`, which will automatically prefetch your customer and cache it for a brief interval. We recommend initializing your `STPCustomerContext` before your user enters your checkout flow so their payment methods are loaded in advance. If in addition to using `STPPaymentContext`, you create a separate `STPPaymentMethodsViewController` to let your customer manage their payment methods outside of your checkout flow, you can use the same instance of `STPCustomerContext` for both.

View File

@ -38,7 +38,7 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
04533E871A687F5D00C7E52E /* Stripe iOS Example (Custom).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Stripe iOS Example (Custom).app"; sourceTree = BUILT_PRODUCTS_DIR; }; 04533E871A687F5D00C7E52E /* Custom Integration (ObjC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Custom Integration (ObjC).app"; sourceTree = BUILT_PRODUCTS_DIR; };
04533E8B1A687F5D00C7E52E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 04533E8B1A687F5D00C7E52E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
04533E8C1A687F5D00C7E52E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 04533E8C1A687F5D00C7E52E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
04533E8E1A687F5D00C7E52E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 04533E8E1A687F5D00C7E52E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@ -53,6 +53,7 @@
04533F181A688A0A00C7E52E /* Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = "<group>"; }; 04533F181A688A0A00C7E52E /* Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = "<group>"; };
C12C50DB1E57B3C800EC6D58 /* BrowseExamplesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BrowseExamplesViewController.h; sourceTree = "<group>"; }; C12C50DB1E57B3C800EC6D58 /* BrowseExamplesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BrowseExamplesViewController.h; sourceTree = "<group>"; };
C12C50DC1E57B3C800EC6D58 /* BrowseExamplesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BrowseExamplesViewController.m; sourceTree = "<group>"; }; C12C50DC1E57B3C800EC6D58 /* BrowseExamplesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BrowseExamplesViewController.m; sourceTree = "<group>"; };
C18A6EE31F1EB7A6005600CC /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = "Custom Integration (ObjC)/README.md"; sourceTree = "<group>"; };
C1CACE841E5DE6C3002D0821 /* CardExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CardExampleViewController.h; sourceTree = "<group>"; }; C1CACE841E5DE6C3002D0821 /* CardExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CardExampleViewController.h; sourceTree = "<group>"; };
C1CACE851E5DE6C3002D0821 /* CardExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CardExampleViewController.m; sourceTree = "<group>"; }; C1CACE851E5DE6C3002D0821 /* CardExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CardExampleViewController.m; sourceTree = "<group>"; };
C1CACE871E5DF7A9002D0821 /* ApplePayExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplePayExampleViewController.h; sourceTree = "<group>"; }; C1CACE871E5DF7A9002D0821 /* ApplePayExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplePayExampleViewController.h; sourceTree = "<group>"; };
@ -80,8 +81,9 @@
04533E7E1A687F5D00C7E52E = { 04533E7E1A687F5D00C7E52E = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C18A6EE31F1EB7A6005600CC /* README.md */,
04533E891A687F5D00C7E52E /* Custom Integration (ObjC) */,
04533F0E1A68813100C7E52E /* Frameworks */, 04533F0E1A68813100C7E52E /* Frameworks */,
04533E891A687F5D00C7E52E /* Stripe iOS Example (Custom) */,
04533E881A687F5D00C7E52E /* Products */, 04533E881A687F5D00C7E52E /* Products */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
@ -89,12 +91,12 @@
04533E881A687F5D00C7E52E /* Products */ = { 04533E881A687F5D00C7E52E /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04533E871A687F5D00C7E52E /* Stripe iOS Example (Custom).app */, 04533E871A687F5D00C7E52E /* Custom Integration (ObjC).app */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
04533E891A687F5D00C7E52E /* Stripe iOS Example (Custom) */ = { 04533E891A687F5D00C7E52E /* Custom Integration (ObjC) */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04533EB01A68802E00C7E52E /* ShippingManager.h */, 04533EB01A68802E00C7E52E /* ShippingManager.h */,
@ -116,7 +118,7 @@
04533E971A687F5D00C7E52E /* Images.xcassets */, 04533E971A687F5D00C7E52E /* Images.xcassets */,
04533E8A1A687F5D00C7E52E /* Supporting Files */, 04533E8A1A687F5D00C7E52E /* Supporting Files */,
); );
path = "Stripe iOS Example (Custom)"; path = "Custom Integration (ObjC)";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
04533E8A1A687F5D00C7E52E /* Supporting Files */ = { 04533E8A1A687F5D00C7E52E /* Supporting Files */ = {
@ -141,9 +143,9 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
04533E861A687F5D00C7E52E /* Stripe iOS Example (Custom) */ = { 04533E861A687F5D00C7E52E /* Custom Integration (ObjC) */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 04533EAA1A687F5E00C7E52E /* Build configuration list for PBXNativeTarget "Stripe iOS Example (Custom)" */; buildConfigurationList = 04533EAA1A687F5E00C7E52E /* Build configuration list for PBXNativeTarget "Custom Integration (ObjC)" */;
buildPhases = ( buildPhases = (
04533E831A687F5D00C7E52E /* Sources */, 04533E831A687F5D00C7E52E /* Sources */,
04533E841A687F5D00C7E52E /* Frameworks */, 04533E841A687F5D00C7E52E /* Frameworks */,
@ -154,9 +156,9 @@
); );
dependencies = ( dependencies = (
); );
name = "Stripe iOS Example (Custom)"; name = "Custom Integration (ObjC)";
productName = "Stripe iOS Example (Custom)"; productName = "Custom Integration (ObjC)";
productReference = 04533E871A687F5D00C7E52E /* Stripe iOS Example (Custom).app */; productReference = 04533E871A687F5D00C7E52E /* Custom Integration (ObjC).app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@ -174,7 +176,7 @@
}; };
}; };
}; };
buildConfigurationList = 04533E821A687F5D00C7E52E /* Build configuration list for PBXProject "Stripe iOS Example (Custom)" */; buildConfigurationList = 04533E821A687F5D00C7E52E /* Build configuration list for PBXProject "Custom Integration (ObjC)" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English; developmentRegion = English;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
@ -187,7 +189,7 @@
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
04533E861A687F5D00C7E52E /* Stripe iOS Example (Custom) */, 04533E861A687F5D00C7E52E /* Custom Integration (ObjC) */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
@ -338,9 +340,9 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/**", "$(PROJECT_DIR)/**",
); );
INFOPLIST_FILE = "Stripe iOS Example (Custom)/Info.plist"; INFOPLIST_FILE = "Custom Integration (ObjC)/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.stripe.CustomSDKExample; PRODUCT_BUNDLE_IDENTIFIER = com.stripe.customexample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
@ -362,9 +364,9 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/**", "$(PROJECT_DIR)/**",
); );
INFOPLIST_FILE = "Stripe iOS Example (Custom)/Info.plist"; INFOPLIST_FILE = "Custom Integration (ObjC)/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.stripe.CustomSDKExample; PRODUCT_BUNDLE_IDENTIFIER = com.stripe.customexample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
@ -373,7 +375,7 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
04533E821A687F5D00C7E52E /* Build configuration list for PBXProject "Stripe iOS Example (Custom)" */ = { 04533E821A687F5D00C7E52E /* Build configuration list for PBXProject "Custom Integration (ObjC)" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
04533EA81A687F5E00C7E52E /* Debug */, 04533EA81A687F5E00C7E52E /* Debug */,
@ -382,7 +384,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
04533EAA1A687F5E00C7E52E /* Build configuration list for PBXNativeTarget "Stripe iOS Example (Custom)" */ = { 04533EAA1A687F5E00C7E52E /* Build configuration list for PBXNativeTarget "Custom Integration (ObjC)" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
04533EAB1A687F5E00C7E52E /* Debug */, 04533EAB1A687F5E00C7E52E /* Debug */,

View File

@ -15,23 +15,9 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04533E861A687F5D00C7E52E" BlueprintIdentifier = "04533E861A687F5D00C7E52E"
BuildableName = "Stripe iOS Example (Custom).app" BuildableName = "Custom Integration (ObjC).app"
BlueprintName = "Stripe iOS Example (Custom)" BlueprintName = "Custom Integration (ObjC)"
ReferencedContainer = "container:Stripe iOS Example (Custom).xcodeproj"> ReferencedContainer = "container:Custom Integration (ObjC).xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "04533E9F1A687F5E00C7E52E"
BuildableName = "Stripe iOS Example (Custom)Tests.xctest"
BlueprintName = "Stripe iOS Example (Custom)Tests"
ReferencedContainer = "container:Stripe iOS Example (Custom).xcodeproj">
</BuildableReference> </BuildableReference>
</BuildActionEntry> </BuildActionEntry>
</BuildActionEntries> </BuildActionEntries>
@ -42,24 +28,14 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<Testables> <Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "04533E9F1A687F5E00C7E52E"
BuildableName = "Stripe iOS Example (Custom)Tests.xctest"
BlueprintName = "Stripe iOS Example (Custom)Tests"
ReferencedContainer = "container:Stripe iOS Example (Custom).xcodeproj">
</BuildableReference>
</TestableReference>
</Testables> </Testables>
<MacroExpansion> <MacroExpansion>
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04533E861A687F5D00C7E52E" BlueprintIdentifier = "04533E861A687F5D00C7E52E"
BuildableName = "Stripe iOS Example (Custom).app" BuildableName = "Custom Integration (ObjC).app"
BlueprintName = "Stripe iOS Example (Custom)" BlueprintName = "Custom Integration (ObjC)"
ReferencedContainer = "container:Stripe iOS Example (Custom).xcodeproj"> ReferencedContainer = "container:Custom Integration (ObjC).xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions> <AdditionalOptions>
@ -80,9 +56,9 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04533E861A687F5D00C7E52E" BlueprintIdentifier = "04533E861A687F5D00C7E52E"
BuildableName = "Stripe iOS Example (Custom).app" BuildableName = "Custom Integration (ObjC).app"
BlueprintName = "Stripe iOS Example (Custom)" BlueprintName = "Custom Integration (ObjC)"
ReferencedContainer = "container:Stripe iOS Example (Custom).xcodeproj"> ReferencedContainer = "container:Custom Integration (ObjC).xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions> <AdditionalOptions>
@ -99,9 +75,9 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04533E861A687F5D00C7E52E" BlueprintIdentifier = "04533E861A687F5D00C7E52E"
BuildableName = "Stripe iOS Example (Custom).app" BuildableName = "Custom Integration (ObjC).app"
BlueprintName = "Stripe iOS Example (Custom)" BlueprintName = "Custom Integration (ObjC)"
ReferencedContainer = "container:Stripe iOS Example (Custom).xcodeproj"> ReferencedContainer = "container:Custom Integration (ObjC).xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
</ProfileAction> </ProfileAction>

View File

@ -1,6 +1,6 @@
// //
// AppDelegate.h // AppDelegate.h
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Jack Flintermann on 1/15/15. // Created by Jack Flintermann on 1/15/15.
// Copyright (c) 2015 Stripe. All rights reserved. // Copyright (c) 2015 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// ApplePayExampleViewController.h // ApplePayExampleViewController.h
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// ApplePayExampleViewController.m // ApplePayExampleViewController.m
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// BrowseExamplesViewController.h // BrowseExamplesViewController.h
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/17/17. // Created by Ben Guo on 2/17/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// BrowseExamplesViewController.m // BrowseExamplesViewController.m
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/17/17. // Created by Ben Guo on 2/17/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// CardExampleViewController.h // CardExampleViewController.h
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// CardExampleViewController.m // CardExampleViewController.m
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -18,6 +18,17 @@
<string>1.0</string> <string>1.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>$(BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>payments-example</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1</string> <string>1</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
@ -34,16 +45,5 @@
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>$(BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>payments-example</string>
</array>
</dict>
</array>
</dict> </dict>
</plist> </plist>

View File

@ -0,0 +1,7 @@
# Custom Integration (ObjC)
This example app demonstrates how to to use `STPAPIClient` to accept various payment methods. These integrations may be a useful reference if you're building your own payment UI, and not using `STPPaymentContext`.
For a detailed guide on the various subcomponents of the SDK, see https://stripe.com/docs/mobile/ios/custom
For more details on using Sources with the iOS SDK, see https://stripe.com/docs/mobile/ios/sources

View File

@ -1,6 +1,6 @@
// //
// SofortExampleViewController.h // SofortExampleViewController.h
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// SofortExampleViewController.m // SofortExampleViewController.m
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// Card3DSExampleViewController.h // Card3DSExampleViewController.h
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// Card3DSExampleViewController.m // Card3DSExampleViewController.m
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Ben Guo on 2/22/17. // Created by Ben Guo on 2/22/17.
// Copyright © 2017 Stripe. All rights reserved. // Copyright © 2017 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// main.m // main.m
// Stripe iOS Example (Custom) // Custom Integration (ObjC)
// //
// Created by Jack Flintermann on 1/15/15. // Created by Jack Flintermann on 1/15/15.
// Copyright (c) 2015 Stripe. All rights reserved. // Copyright (c) 2015 Stripe. All rights reserved.

View File

@ -18,7 +18,6 @@
C186AC341ECD0DDD00497DE3 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C186AC331ECD0DDD00497DE3 /* Alamofire.framework */; }; C186AC341ECD0DDD00497DE3 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C186AC331ECD0DDD00497DE3 /* Alamofire.framework */; };
C188F2A61CC1A338003A524B /* MyAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = C188F2A51CC1A338003A524B /* MyAPIClient.swift */; }; C188F2A61CC1A338003A524B /* MyAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = C188F2A51CC1A338003A524B /* MyAPIClient.swift */; };
C1B83CBD1CCE6C0700F0790B /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B83CBC1CCE6C0700F0790B /* Buttons.swift */; }; C1B83CBD1CCE6C0700F0790B /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B83CBC1CCE6C0700F0790B /* Buttons.swift */; };
F10C9F6B1DC916BD00A91F7C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F10C9F691DC916BD00A91F7C /* Localizable.strings */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -39,24 +38,17 @@
042CA4141A685E8D00D778E7 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 042CA4141A685E8D00D778E7 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
042CA4191A685E8D00D778E7 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; 042CA4191A685E8D00D778E7 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
042CA41A1A685E8D00D778E7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 042CA41A1A685E8D00D778E7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
04823F781A6849200098400B /* Stripe iOS Example (Simple).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Stripe iOS Example (Simple).app"; sourceTree = BUILT_PRODUCTS_DIR; }; 04823F781A6849200098400B /* Standard Integration (Swift).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Standard Integration (Swift).app"; sourceTree = BUILT_PRODUCTS_DIR; };
04BC299F1CD81D3900318357 /* BrowseProductsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrowseProductsViewController.swift; sourceTree = "<group>"; }; 04BC299F1CD81D3900318357 /* BrowseProductsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrowseProductsViewController.swift; sourceTree = "<group>"; };
04D075D91A69B82B00094431 /* Stripe iOS Example (Simple).entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Stripe iOS Example (Simple).entitlements"; sourceTree = "<group>"; }; 04D075D91A69B82B00094431 /* Standard Integration (Swift).entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Standard Integration (Swift).entitlements"; sourceTree = "<group>"; };
04D076191A69C14700094431 /* Stripe.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Stripe.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 04D076191A69C14700094431 /* Stripe.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Stripe.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C124A18A1CCACAA1007D42EE /* CheckoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutViewController.swift; sourceTree = "<group>"; }; C124A18A1CCACAA1007D42EE /* CheckoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutViewController.swift; sourceTree = "<group>"; };
C124A18C1CCACC92007D42EE /* CheckoutRowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutRowView.swift; sourceTree = "<group>"; }; C124A18C1CCACC92007D42EE /* CheckoutRowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutRowView.swift; sourceTree = "<group>"; };
C13C24211D14438700F3765E /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; }; C13C24211D14438700F3765E /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
C186AC331ECD0DDD00497DE3 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/iOS/Alamofire.framework; sourceTree = "<group>"; }; C186AC331ECD0DDD00497DE3 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/iOS/Alamofire.framework; sourceTree = "<group>"; };
C188F2A51CC1A338003A524B /* MyAPIClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyAPIClient.swift; sourceTree = "<group>"; }; C188F2A51CC1A338003A524B /* MyAPIClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyAPIClient.swift; sourceTree = "<group>"; };
C18A6EE11F1EB78B005600CC /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = "Standard Integration (Swift)/README.md"; sourceTree = "<group>"; };
C1B83CBC1CCE6C0700F0790B /* Buttons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = "<group>"; }; C1B83CBC1CCE6C0700F0790B /* Buttons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = "<group>"; };
F10C9F6A1DC916BD00A91F7C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Localizations/de.lproj/Localizable.strings; sourceTree = "<group>"; };
F10C9F6C1DC916C200A91F7C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizations/en.lproj/Localizable.strings; sourceTree = "<group>"; };
F10C9F6D1DC916C800A91F7C /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = Localizations/nl.lproj/Localizable.strings; sourceTree = "<group>"; };
F10C9F6E1DC916CD00A91F7C /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "Localizations/zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
F1F3832B1DC917110006DA86 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Localizations/ja.lproj/Localizable.strings; sourceTree = "<group>"; };
F1F3832C1DC917170006DA86 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Localizations/it.lproj/Localizable.strings; sourceTree = "<group>"; };
F1F3832D1DC9171C0006DA86 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Localizations/fr.lproj/Localizable.strings; sourceTree = "<group>"; };
F1F3832E1DC917260006DA86 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Localizations/es.lproj/Localizable.strings; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -72,10 +64,9 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
042CA4131A685E8D00D778E7 /* Stripe iOS Example (Simple) */ = { 042CA4131A685E8D00D778E7 /* Standard Integration (Swift) */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F11726811DC913D30058F2A0 /* Localizations */,
042CA4141A685E8D00D778E7 /* AppDelegate.swift */, 042CA4141A685E8D00D778E7 /* AppDelegate.swift */,
C188F2A51CC1A338003A524B /* MyAPIClient.swift */, C188F2A51CC1A338003A524B /* MyAPIClient.swift */,
C13C24211D14438700F3765E /* SettingsViewController.swift */, C13C24211D14438700F3765E /* SettingsViewController.swift */,
@ -85,15 +76,16 @@
C1B83CBC1CCE6C0700F0790B /* Buttons.swift */, C1B83CBC1CCE6C0700F0790B /* Buttons.swift */,
042CA4191A685E8D00D778E7 /* Images.xcassets */, 042CA4191A685E8D00D778E7 /* Images.xcassets */,
042CA41A1A685E8D00D778E7 /* Info.plist */, 042CA41A1A685E8D00D778E7 /* Info.plist */,
04D075D91A69B82B00094431 /* Stripe iOS Example (Simple).entitlements */, 04D075D91A69B82B00094431 /* Standard Integration (Swift).entitlements */,
); );
path = "Stripe iOS Example (Simple)"; path = "Standard Integration (Swift)";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
04823F6F1A6849200098400B = { 04823F6F1A6849200098400B = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
042CA4131A685E8D00D778E7 /* Stripe iOS Example (Simple) */, C18A6EE11F1EB78B005600CC /* README.md */,
042CA4131A685E8D00D778E7 /* Standard Integration (Swift) */,
04823F9F1A6849850098400B /* Frameworks */, 04823F9F1A6849850098400B /* Frameworks */,
04823F791A6849200098400B /* Products */, 04823F791A6849200098400B /* Products */,
); );
@ -102,7 +94,7 @@
04823F791A6849200098400B /* Products */ = { 04823F791A6849200098400B /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04823F781A6849200098400B /* Stripe iOS Example (Simple).app */, 04823F781A6849200098400B /* Standard Integration (Swift).app */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -116,20 +108,12 @@
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
F11726811DC913D30058F2A0 /* Localizations */ = {
isa = PBXGroup;
children = (
F10C9F691DC916BD00A91F7C /* Localizable.strings */,
);
name = Localizations;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
04823F771A6849200098400B /* Stripe iOS Example (Simple) */ = { 04823F771A6849200098400B /* Standard Integration (Swift) */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 04823F971A6849200098400B /* Build configuration list for PBXNativeTarget "Stripe iOS Example (Simple)" */; buildConfigurationList = 04823F971A6849200098400B /* Build configuration list for PBXNativeTarget "Standard Integration (Swift)" */;
buildPhases = ( buildPhases = (
C186AC351ECD0E1C00497DE3 /* Check Dependencies */, C186AC351ECD0E1C00497DE3 /* Check Dependencies */,
04823F741A6849200098400B /* Sources */, 04823F741A6849200098400B /* Sources */,
@ -143,9 +127,9 @@
); );
dependencies = ( dependencies = (
); );
name = "Stripe iOS Example (Simple)"; name = "Standard Integration (Swift)";
productName = "Stripe iOS Exampe (Simple)"; productName = "Stripe iOS Exampe (Simple)";
productReference = 04823F781A6849200098400B /* Stripe iOS Example (Simple).app */; productReference = 04823F781A6849200098400B /* Standard Integration (Swift).app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@ -155,7 +139,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0800; LastSwiftUpdateCheck = 0800;
LastUpgradeCheck = 0800; LastUpgradeCheck = 0830;
ORGANIZATIONNAME = Stripe; ORGANIZATIONNAME = Stripe;
TargetAttributes = { TargetAttributes = {
04823F771A6849200098400B = { 04823F771A6849200098400B = {
@ -176,27 +160,20 @@
}; };
}; };
}; };
buildConfigurationList = 04823F731A6849200098400B /* Build configuration list for PBXProject "Stripe iOS Example (Simple)" */; buildConfigurationList = 04823F731A6849200098400B /* Build configuration list for PBXProject "Standard Integration (Swift)" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English; developmentRegion = English;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
en, en,
Base, Base,
de,
nl,
"zh-Hans",
ja,
it,
fr,
es,
); );
mainGroup = 04823F6F1A6849200098400B; mainGroup = 04823F6F1A6849200098400B;
productRefGroup = 04823F791A6849200098400B /* Products */; productRefGroup = 04823F791A6849200098400B /* Products */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
04823F771A6849200098400B /* Stripe iOS Example (Simple) */, 04823F771A6849200098400B /* Standard Integration (Swift) */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
@ -207,7 +184,6 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
042CA4201A685E8D00D778E7 /* Images.xcassets in Resources */, 042CA4201A685E8D00D778E7 /* Images.xcassets in Resources */,
F10C9F6B1DC916BD00A91F7C /* Localizable.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -276,24 +252,6 @@
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
F10C9F691DC916BD00A91F7C /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
F10C9F6A1DC916BD00A91F7C /* de */,
F10C9F6C1DC916C200A91F7C /* en */,
F10C9F6D1DC916C800A91F7C /* nl */,
F10C9F6E1DC916CD00A91F7C /* zh-Hans */,
F1F3832B1DC917110006DA86 /* ja */,
F1F3832C1DC917170006DA86 /* it */,
F1F3832D1DC9171C0006DA86 /* fr */,
F1F3832E1DC917260006DA86 /* es */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
04823F951A6849200098400B /* Debug */ = { 04823F951A6849200098400B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
@ -337,7 +295,7 @@
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "Stripe iOS Example (Simple)/Stripe iOS Example (Simple)-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Standard Integration (Swift)/Standard Integration (Swift)-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
}; };
name = Debug; name = Debug;
@ -376,7 +334,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.4; IPHONEOS_DEPLOYMENT_TARGET = 8.4;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "Stripe iOS Example (Simple)/Stripe iOS Example (Simple)-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Standard Integration (Swift)/Standard Integration (Swift)-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
@ -387,7 +345,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Stripe iOS Example (Simple)/Stripe iOS Example (Simple).entitlements"; CODE_SIGN_ENTITLEMENTS = "Standard Integration (Swift)/Standard Integration (Swift).entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
@ -398,11 +356,11 @@
"$(PROJECT_DIR)/Carthage/Build/iOS", "$(PROJECT_DIR)/Carthage/Build/iOS",
); );
GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = "Stripe iOS Example (Simple)/Info.plist"; INFOPLIST_FILE = "Standard Integration (Swift)/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.stripe.SimpleSDKExample; PRODUCT_BUNDLE_IDENTIFIER = com.stripe.standardexample;
PRODUCT_NAME = "Stripe iOS Example (Simple)"; PRODUCT_NAME = "Standard Integration (Swift)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OBJC_BRIDGING_HEADER = "";
@ -417,7 +375,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Stripe iOS Example (Simple)/Stripe iOS Example (Simple).entitlements"; CODE_SIGN_ENTITLEMENTS = "Standard Integration (Swift)/Standard Integration (Swift).entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
@ -428,11 +386,11 @@
"$(PROJECT_DIR)/Carthage/Build/iOS", "$(PROJECT_DIR)/Carthage/Build/iOS",
); );
GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = "Stripe iOS Example (Simple)/Info.plist"; INFOPLIST_FILE = "Standard Integration (Swift)/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.stripe.SimpleSDKExample; PRODUCT_BUNDLE_IDENTIFIER = com.stripe.standardexample;
PRODUCT_NAME = "Stripe iOS Example (Simple)"; PRODUCT_NAME = "Standard Integration (Swift)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 3.0; SWIFT_VERSION = 3.0;
@ -443,7 +401,7 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
04823F731A6849200098400B /* Build configuration list for PBXProject "Stripe iOS Example (Simple)" */ = { 04823F731A6849200098400B /* Build configuration list for PBXProject "Standard Integration (Swift)" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
04823F951A6849200098400B /* Debug */, 04823F951A6849200098400B /* Debug */,
@ -452,7 +410,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
04823F971A6849200098400B /* Build configuration list for PBXNativeTarget "Stripe iOS Example (Simple)" */ = { 04823F971A6849200098400B /* Build configuration list for PBXNativeTarget "Standard Integration (Swift)" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
04823F981A6849200098400B /* Debug */, 04823F981A6849200098400B /* Debug */,

View File

@ -15,9 +15,9 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04823F771A6849200098400B" BlueprintIdentifier = "04823F771A6849200098400B"
BuildableName = "Stripe iOS Example (Simple).app" BuildableName = "Standard Integration (Swift).app"
BlueprintName = "Stripe iOS Example (Simple)" BlueprintName = "Standard Integration (Swift)"
ReferencedContainer = "container:Stripe iOS Example (Simple).xcodeproj"> ReferencedContainer = "container:Standard Integration (Swift).xcodeproj">
</BuildableReference> </BuildableReference>
</BuildActionEntry> </BuildActionEntry>
</BuildActionEntries> </BuildActionEntries>
@ -28,24 +28,14 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<Testables> <Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C11745D21C456C730029936F"
BuildableName = "Stripe iOS Application Tests.xctest"
BlueprintName = "Stripe iOS Application Tests"
ReferencedContainer = "container:Stripe iOS Example (Simple).xcodeproj">
</BuildableReference>
</TestableReference>
</Testables> </Testables>
<MacroExpansion> <MacroExpansion>
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04823F771A6849200098400B" BlueprintIdentifier = "04823F771A6849200098400B"
BuildableName = "Stripe iOS Example (Simple).app" BuildableName = "Standard Integration (Swift).app"
BlueprintName = "Stripe iOS Example (Simple)" BlueprintName = "Standard Integration (Swift)"
ReferencedContainer = "container:Stripe iOS Example (Simple).xcodeproj"> ReferencedContainer = "container:Standard Integration (Swift).xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions> <AdditionalOptions>
@ -66,9 +56,9 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04823F771A6849200098400B" BlueprintIdentifier = "04823F771A6849200098400B"
BuildableName = "Stripe iOS Example (Simple).app" BuildableName = "Standard Integration (Swift).app"
BlueprintName = "Stripe iOS Example (Simple)" BlueprintName = "Standard Integration (Swift)"
ReferencedContainer = "container:Stripe iOS Example (Simple).xcodeproj"> ReferencedContainer = "container:Standard Integration (Swift).xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions> <AdditionalOptions>
@ -85,9 +75,9 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "04823F771A6849200098400B" BlueprintIdentifier = "04823F771A6849200098400B"
BuildableName = "Stripe iOS Example (Simple).app" BuildableName = "Standard Integration (Swift).app"
BlueprintName = "Stripe iOS Example (Simple)" BlueprintName = "Standard Integration (Swift)"
ReferencedContainer = "container:Stripe iOS Example (Simple).xcodeproj"> ReferencedContainer = "container:Standard Integration (Swift).xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
</ProfileAction> </ProfileAction>

View File

@ -1,6 +1,6 @@
// //
// AppDelegate.swift // AppDelegate.swift
// Stripe iOS Exampe (Simple) // Standard Integration (Swift)
// //
// Created by Jack Flintermann on 1/15/15. // Created by Jack Flintermann on 1/15/15.
// Copyright (c) 2015 Stripe. All rights reserved. // Copyright (c) 2015 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// BrowseProductsViewController.swift // BrowseProductsViewController.swift
// Stripe iOS Example (Simple) // Standard Integration (Swift)
// //
// Created by Jack Flintermann on 5/2/16. // Created by Jack Flintermann on 5/2/16.
// Copyright © 2016 Stripe. All rights reserved. // Copyright © 2016 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// Buttons.swift // Buttons.swift
// Stripe iOS Example (Simple) // Standard Integration (Swift)
// //
// Created by Ben Guo on 4/25/16. // Created by Ben Guo on 4/25/16.
// Copyright © 2016 Stripe. All rights reserved. // Copyright © 2016 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// CheckoutRowView.swift // CheckoutRowView.swift
// Stripe iOS Example (Simple) // Standard Integration (Swift)
// //
// Created by Ben Guo on 4/22/16. // Created by Ben Guo on 4/22/16.
// Copyright © 2016 Stripe. All rights reserved. // Copyright © 2016 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// CheckoutViewController.swift // CheckoutViewController.swift
// Stripe iOS Example (Simple) // Standard Integration (Swift)
// //
// Created by Ben Guo on 4/22/16. // Created by Ben Guo on 4/22/16.
// Copyright © 2016 Stripe. All rights reserved. // Copyright © 2016 Stripe. All rights reserved.

View File

@ -1,6 +1,6 @@
// //
// BackendAPIAdapter.swift // BackendAPIAdapter.swift
// Stripe iOS Example (Simple) // Standard Integration (Swift)
// //
// Created by Ben Guo on 4/15/16. // Created by Ben Guo on 4/15/16.
// Copyright © 2016 Stripe. All rights reserved. // Copyright © 2016 Stripe. All rights reserved.

View File

@ -0,0 +1,5 @@
# Standard Integration (Swift)
This example app demonstrates how to build a payment flow using our pre-built UI components (`STPPaymentContext`).
For a detailed guide, see https://stripe.com/docs/mobile/ios/standard

View File

@ -1,6 +1,6 @@
// //
// SettingsViewController.swift // SettingsViewController.swift
// Stripe iOS Example (Simple) // Standard Integration (Swift)
// //
// Created by Ben Guo on 6/17/16. // Created by Ben Guo on 6/17/16.
// Copyright © 2016 Stripe. All rights reserved. // Copyright © 2016 Stripe. All rights reserved.

View File

@ -0,0 +1,355 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
C1140CC11F1EC0FC002084AB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1140CC01F1EC0FC002084AB /* AppDelegate.swift */; };
C1140CC31F1EC0FC002084AB /* BrowseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1140CC21F1EC0FC002084AB /* BrowseViewController.swift */; };
C1140CC81F1EC0FC002084AB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C1140CC71F1EC0FC002084AB /* Assets.xcassets */; };
C1140CCB1F1EC0FC002084AB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C1140CC91F1EC0FC002084AB /* LaunchScreen.storyboard */; };
C13A00561F1FFA0D00825683 /* ThemeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13A00551F1FFA0D00825683 /* ThemeViewController.swift */; };
C13A00581F1FFEC200825683 /* CardFieldViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13A00571F1FFEC200825683 /* CardFieldViewController.swift */; };
C19A55B01F1EC1ED00C8AABE /* Stripe.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C19A55A81F1EC1B000C8AABE /* Stripe.framework */; };
C19A55B11F1EC1ED00C8AABE /* Stripe.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C19A55A81F1EC1B000C8AABE /* Stripe.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
C1A658E51F1EC7F500799757 /* MockCustomerContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A658E41F1EC7F500799757 /* MockCustomerContext.swift */; };
C1A658E71F1ED05500799757 /* MockAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A658E61F1ED05500799757 /* MockAPIClient.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
C19A55B21F1EC1ED00C8AABE /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
C19A55B11F1EC1ED00C8AABE /* Stripe.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
C1140CBD1F1EC0FC002084AB /* Stripe UI Examples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Stripe UI Examples.app"; sourceTree = BUILT_PRODUCTS_DIR; };
C1140CC01F1EC0FC002084AB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C1140CC21F1EC0FC002084AB /* BrowseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseViewController.swift; sourceTree = "<group>"; };
C1140CC71F1EC0FC002084AB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
C1140CCA1F1EC0FC002084AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
C1140CCC1F1EC0FC002084AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C13A00541F1FF7A800825683 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = "UI Examples/README.md"; sourceTree = "<group>"; };
C13A00551F1FFA0D00825683 /* ThemeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeViewController.swift; sourceTree = "<group>"; };
C13A00571F1FFEC200825683 /* CardFieldViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardFieldViewController.swift; sourceTree = "<group>"; };
C19A55A81F1EC1B000C8AABE /* Stripe.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Stripe.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C1A658E41F1EC7F500799757 /* MockCustomerContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockCustomerContext.swift; sourceTree = "<group>"; };
C1A658E61F1ED05500799757 /* MockAPIClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockAPIClient.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C1140CBA1F1EC0FC002084AB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C19A55B01F1EC1ED00C8AABE /* Stripe.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
C1140CB41F1EC0FC002084AB = {
isa = PBXGroup;
children = (
C13A00541F1FF7A800825683 /* README.md */,
C1140CBF1F1EC0FC002084AB /* UI Examples */,
C19A55A71F1EC18600C8AABE /* Frameworks */,
C1140CBE1F1EC0FC002084AB /* Products */,
);
sourceTree = "<group>";
};
C1140CBE1F1EC0FC002084AB /* Products */ = {
isa = PBXGroup;
children = (
C1140CBD1F1EC0FC002084AB /* Stripe UI Examples.app */,
);
name = Products;
sourceTree = "<group>";
};
C1140CBF1F1EC0FC002084AB /* UI Examples */ = {
isa = PBXGroup;
children = (
C1140CC01F1EC0FC002084AB /* AppDelegate.swift */,
C1140CC21F1EC0FC002084AB /* BrowseViewController.swift */,
C13A00571F1FFEC200825683 /* CardFieldViewController.swift */,
C13A00551F1FFA0D00825683 /* ThemeViewController.swift */,
C1A658E41F1EC7F500799757 /* MockCustomerContext.swift */,
C1A658E61F1ED05500799757 /* MockAPIClient.swift */,
C1140CC71F1EC0FC002084AB /* Assets.xcassets */,
C1140CC91F1EC0FC002084AB /* LaunchScreen.storyboard */,
C1140CCC1F1EC0FC002084AB /* Info.plist */,
);
path = "UI Examples";
sourceTree = "<group>";
};
C19A55A71F1EC18600C8AABE /* Frameworks */ = {
isa = PBXGroup;
children = (
C19A55A81F1EC1B000C8AABE /* Stripe.framework */,
);
name = Frameworks;
path = "UI Examples";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C1140CBC1F1EC0FC002084AB /* UI Examples */ = {
isa = PBXNativeTarget;
buildConfigurationList = C1140CCF1F1EC0FC002084AB /* Build configuration list for PBXNativeTarget "UI Examples" */;
buildPhases = (
C1140CB91F1EC0FC002084AB /* Sources */,
C1140CBA1F1EC0FC002084AB /* Frameworks */,
C1140CBB1F1EC0FC002084AB /* Resources */,
C19A55B21F1EC1ED00C8AABE /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "UI Examples";
productName = "UI Examples";
productReference = C1140CBD1F1EC0FC002084AB /* Stripe UI Examples.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C1140CB51F1EC0FC002084AB /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0900;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = Stripe;
TargetAttributes = {
C1140CBC1F1EC0FC002084AB = {
CreatedOnToolsVersion = 9.0;
};
};
};
buildConfigurationList = C1140CB81F1EC0FC002084AB /* Build configuration list for PBXProject "UI Examples" */;
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = C1140CB41F1EC0FC002084AB;
productRefGroup = C1140CBE1F1EC0FC002084AB /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C1140CBC1F1EC0FC002084AB /* UI Examples */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
C1140CBB1F1EC0FC002084AB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C1140CCB1F1EC0FC002084AB /* LaunchScreen.storyboard in Resources */,
C1140CC81F1EC0FC002084AB /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C1140CB91F1EC0FC002084AB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C1A658E51F1EC7F500799757 /* MockCustomerContext.swift in Sources */,
C1140CC31F1EC0FC002084AB /* BrowseViewController.swift in Sources */,
C1A658E71F1ED05500799757 /* MockAPIClient.swift in Sources */,
C13A00581F1FFEC200825683 /* CardFieldViewController.swift in Sources */,
C13A00561F1FFA0D00825683 /* ThemeViewController.swift in Sources */,
C1140CC11F1EC0FC002084AB /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
C1140CC91F1EC0FC002084AB /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
C1140CCA1F1EC0FC002084AB /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
C1140CCD1F1EC0FC002084AB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
C1140CCE1F1EC0FC002084AB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C1140CD01F1EC0FC002084AB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = "UI Examples/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.stripe.uiexamples;
PRODUCT_NAME = "Stripe UI Examples";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
C1140CD11F1EC0FC002084AB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = "UI Examples/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.stripe.uiexamples;
PRODUCT_NAME = "Stripe UI Examples";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C1140CB81F1EC0FC002084AB /* Build configuration list for PBXProject "UI Examples" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C1140CCD1F1EC0FC002084AB /* Debug */,
C1140CCE1F1EC0FC002084AB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C1140CCF1F1EC0FC002084AB /* Build configuration list for PBXNativeTarget "UI Examples" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C1140CD01F1EC0FC002084AB /* Debug */,
C1140CD11F1EC0FC002084AB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = C1140CB51F1EC0FC002084AB /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:UI Examples.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C1140CBC1F1EC0FC002084AB"
BuildableName = "Stripe UI Examples.app"
BlueprintName = "UI Examples"
ReferencedContainer = "container:UI Examples.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C1140CBC1F1EC0FC002084AB"
BuildableName = "Stripe UI Examples.app"
BlueprintName = "UI Examples"
ReferencedContainer = "container:UI Examples.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C1140CBC1F1EC0FC002084AB"
BuildableName = "Stripe UI Examples.app"
BlueprintName = "UI Examples"
ReferencedContainer = "container:UI Examples.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C1140CBC1F1EC0FC002084AB"
BuildableName = "Stripe UI Examples.app"
BlueprintName = "UI Examples"
ReferencedContainer = "container:UI Examples.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:../Stripe.xcodeproj">
</FileRef>
<FileRef
location = "group:UI Examples.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,28 @@
//
// AppDelegate.swift
// UI Examples
//
// Created by Ben Guo on 7/18/17.
// Copyright © 2017 Stripe. All rights reserved.
//
import UIKit
import Stripe
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let rootVC = BrowseViewController()
let navController = UINavigationController(rootViewController: rootVC)
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = navController
window.makeKeyAndVisible()
self.window = window
return true
}
}

View File

@ -0,0 +1,93 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,194 @@
//
// BrowseViewController.swift
// UI Examples
//
// Created by Ben Guo on 7/18/17.
// Copyright © 2017 Stripe. All rights reserved.
//
import UIKit
import Stripe
class BrowseViewController: UITableViewController, STPAddCardViewControllerDelegate, STPPaymentMethodsViewControllerDelegate, STPShippingAddressViewControllerDelegate {
enum Demo: Int {
static let count = 5
case STPPaymentCardTextField
case STPAddCardViewController
case STPPaymentMethodsViewController
case STPShippingInfoViewController
case ChangeTheme
var title: String {
switch self {
case .STPPaymentCardTextField: return "Card Field"
case .STPAddCardViewController: return "Card Form with Billing Address"
case .STPPaymentMethodsViewController: return "Payment Method Picker"
case .STPShippingInfoViewController: return "Shipping Info Form"
case .ChangeTheme: return "Change Theme"
}
}
var detail: String {
switch self {
case .STPPaymentCardTextField: return "STPPaymentCardTextField"
case .STPAddCardViewController: return "STPAddCardViewController"
case .STPPaymentMethodsViewController: return "STPPaymentMethodsViewController"
case .STPShippingInfoViewController: return "STPShippingInfoViewController"
case .ChangeTheme: return ""
}
}
}
let customerContext = MockCustomerContext()
let themeViewController = ThemeViewController()
override func viewDidLoad() {
super.viewDidLoad()
title = "Stripe UI Examples"
tableView.tableFooterView = UIView()
tableView.rowHeight = 60
navigationController?.navigationBar.isTranslucent = false
STPAddCardViewController.startMockingAPIClient()
}
// MARK: UITableViewDelegate
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Demo.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
if let example = Demo(rawValue: indexPath.row) {
cell.textLabel?.text = example.title
cell.detailTextLabel?.text = example.detail
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard let example = Demo(rawValue: indexPath.row) else { return }
let theme = themeViewController.theme.stpTheme
switch example {
case .STPPaymentCardTextField:
let viewController = CardFieldViewController()
viewController.theme = theme
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.navigationBar.stp_theme = theme
present(navigationController, animated: true, completion: nil)
case .STPAddCardViewController:
let config = STPPaymentConfiguration()
config.requiredBillingAddressFields = .full
let viewController = STPAddCardViewController(configuration: config, theme: theme)
viewController.delegate = self
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.navigationBar.stp_theme = theme
present(navigationController, animated: true, completion: nil)
case .STPPaymentMethodsViewController:
let config = STPPaymentConfiguration()
config.additionalPaymentMethods = .all
config.requiredBillingAddressFields = .none
config.appleMerchantIdentifier = "dummy-merchant-id"
let viewController = STPPaymentMethodsViewController(configuration: config,
theme: theme,
customerContext: self.customerContext,
delegate: self)
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.navigationBar.stp_theme = theme
present(navigationController, animated: true, completion: nil)
case .STPShippingInfoViewController:
let config = STPPaymentConfiguration()
config.requiredShippingAddressFields = [.postalAddress]
let viewController = STPShippingAddressViewController(configuration: config,
theme: theme,
currency: "usd",
shippingAddress: nil,
selectedShippingMethod: nil,
prefilledInformation: nil)
viewController.delegate = self
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.navigationBar.stp_theme = theme
present(navigationController, animated: true, completion: nil)
case .ChangeTheme:
let navigationController = UINavigationController(rootViewController: self.themeViewController)
present(navigationController, animated: true, completion: nil)
}
}
// MARK: STPAddCardViewControllerDelegate
func addCardViewControllerDidCancel(_ addCardViewController: STPAddCardViewController) {
dismiss(animated: true, completion: nil)
}
func addCardViewController(_ addCardViewController: STPAddCardViewController, didCreateToken token: STPToken, completion: @escaping STPErrorBlock) {
dismiss(animated: true, completion: nil)
}
// MARK: STPPaymentMethodsViewControllerDelegate
func paymentMethodsViewControllerDidCancel(_ paymentMethodsViewController: STPPaymentMethodsViewController) {
dismiss(animated: true, completion: nil)
}
func paymentMethodsViewControllerDidFinish(_ paymentMethodsViewController: STPPaymentMethodsViewController) {
paymentMethodsViewController.navigationController?.popViewController(animated: true)
}
func paymentMethodsViewController(_ paymentMethodsViewController: STPPaymentMethodsViewController, didFailToLoadWithError error: Error) {
dismiss(animated: true, completion: nil)
}
// MARK: STPShippingAddressViewControllerDelegate
func shippingAddressViewControllerDidCancel(_ addressViewController: STPShippingAddressViewController) {
dismiss(animated: true, completion: nil)
}
func shippingAddressViewController(_ addressViewController: STPShippingAddressViewController, didFinishWith address: STPAddress, shippingMethod method: PKShippingMethod?) {
self.customerContext.updateCustomer(withShippingAddress: address, completion: nil)
dismiss(animated: true, completion: nil)
}
func shippingAddressViewController(_ addressViewController: STPShippingAddressViewController, didEnter address: STPAddress, completion: @escaping STPShippingMethodsCompletionBlock) {
let upsGround = PKShippingMethod()
upsGround.amount = 0
upsGround.label = "UPS Ground"
upsGround.detail = "Arrives in 3-5 days"
upsGround.identifier = "ups_ground"
let upsWorldwide = PKShippingMethod()
upsWorldwide.amount = 10.99
upsWorldwide.label = "UPS Worldwide Express"
upsWorldwide.detail = "Arrives in 1-3 days"
upsWorldwide.identifier = "ups_worldwide"
let fedEx = PKShippingMethod()
fedEx.amount = 5.99
fedEx.label = "FedEx"
fedEx.detail = "Arrives tomorrow"
fedEx.identifier = "fedex"
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
if address.country == nil || address.country == "US" {
completion(.valid, nil, [upsGround, fedEx], fedEx)
}
else if address.country == "AQ" {
let error = NSError(domain: "ShippingError", code: 123, userInfo: [NSLocalizedDescriptionKey: "Invalid Shipping Address",
NSLocalizedFailureReasonErrorKey: "We can't ship to this country."])
completion(.invalid, error, nil, nil)
}
else {
fedEx.amount = 20.99
completion(.valid, nil, [upsWorldwide, fedEx], fedEx)
}
}
}
}

View File

@ -0,0 +1,52 @@
//
// CardFieldViewController.swift
// UI Examples
//
// Created by Ben Guo on 7/19/17.
// Copyright © 2017 Stripe. All rights reserved.
//
import UIKit
import Stripe
class CardFieldViewController: UIViewController {
let cardField = STPPaymentCardTextField()
var theme = STPTheme.default()
override func viewDidLoad() {
super.viewDidLoad()
title = "Card Field"
view.backgroundColor = UIColor.white
view.addSubview(cardField)
edgesForExtendedLayout = []
view.backgroundColor = theme.primaryBackgroundColor
cardField.backgroundColor = theme.secondaryBackgroundColor
cardField.textColor = theme.primaryForegroundColor
cardField.placeholderColor = theme.secondaryForegroundColor
cardField.borderColor = theme.accentColor
cardField.borderWidth = 1.0
cardField.textErrorColor = theme.errorColor
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(done))
navigationController?.navigationBar.stp_theme = theme
}
func done() {
dismiss(animated: true, completion: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
cardField.becomeFirstResponder()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let padding: CGFloat = 15
cardField.frame = CGRect(x: padding,
y: padding,
width: view.bounds.width - (padding * 2),
height: 50)
}
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,75 @@
//
// MockAPIClient.swift
// UI Examples
//
// Created by Ben Guo on 7/18/17.
// Copyright © 2017 Stripe. All rights reserved.
//
import Foundation
import Stripe
private let swizzle: (AnyClass, Selector, Selector) -> () = { forClass, originalSelector, swizzledSelector in
let originalMethod = class_getInstanceMethod(forClass, originalSelector)
let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
method_exchangeImplementations(originalMethod, swizzledMethod)
}
extension STPAddCardViewController {
// We can't swizzle in initialize because it's been deprecated in Swift 3.1.
// Instead, we have to call this method before STPAddCardViewController appears.
static func startMockingAPIClient() {
let originalSelector = #selector(apiClient)
let swizzledSelector = #selector(swizzled_apiClient)
swizzle(self, originalSelector, swizzledSelector)
}
// Expose the private `apiClient` property as a method
func apiClient() -> STPAPIClient? {
return nil
}
func swizzled_apiClient() -> STPAPIClient? {
return MockAPIClient()
}
}
class MockAPIClient: STPAPIClient {
override func createToken(withCard card: STPCardParams, completion: STPTokenCompletionBlock? = nil) {
guard let completion = completion else { return }
// Generate a mock card model using the given card params
var cardJSON: [String: Any] = [:]
cardJSON["id"] = "\(card.hashValue)"
cardJSON["exp_month"] = "\(card.expMonth)"
cardJSON["exp_year"] = "\(card.expYear)"
cardJSON["name"] = card.name
cardJSON["address_line1"] = card.addressLine1
cardJSON["address_line2"] = card.addressLine2
cardJSON["address_state"] = card.addressState
cardJSON["address_zip"] = card.addressZip
cardJSON["address_country"] = card.addressCountry
cardJSON["last4"] = card.last4()
if let number = card.number {
let brand = STPCardValidator.brand(forNumber: number)
cardJSON["brand"] = STPCard.string(from: brand)
}
cardJSON["fingerprint"] = "\(card.hashValue)"
cardJSON["country"] = "US"
let tokenJSON: [String: Any] = [
"id": "\(card.hashValue)",
"object": "token",
"livemode": false,
"created": NSDate().timeIntervalSince1970,
"used": false,
"card": cardJSON,
]
let token = STPToken.decodedObject(fromAPIResponse: tokenJSON)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
completion(token, nil)
}
}
}

View File

@ -0,0 +1,123 @@
//
// MockCustomerContext.swift
// UI Examples
//
// Created by Ben Guo on 7/18/17.
// Copyright © 2017 Stripe. All rights reserved.
//
import Foundation
import Stripe
class MockCustomer: STPCustomer {
var mockSources: [STPSourceProtocol] = []
var mockDefaultSource: STPSourceProtocol? = nil
var mockShippingAddress: STPAddress?
override init() {
/**
Preload the mock customer with saved cards.
last4 values are from test cards: https://stripe.com/docs/testing#cards
Not using the "4242" and "4444" numbers, since those are the easiest
to remember and fill.
*/
let visa = [
"id": "preloaded_visa",
"exp_month": "10",
"exp_year": "2020",
"last4": "1881",
"brand": "visa",
]
if let card = STPCard.decodedObject(fromAPIResponse: visa) {
mockSources.append(card)
}
let masterCard = [
"id": "preloaded_mastercard",
"exp_month": "10",
"exp_year": "2020",
"last4": "8210",
"brand": "mastercard",
]
if let card = STPCard.decodedObject(fromAPIResponse: masterCard) {
mockSources.append(card)
}
let amex = [
"id": "preloaded_amex",
"exp_month": "10",
"exp_year": "2020",
"last4": "0005",
"brand": "american express",
]
if let card = STPCard.decodedObject(fromAPIResponse: amex) {
mockSources.append(card)
}
}
override var sources: [STPSourceProtocol] {
get {
return mockSources
}
set {
mockSources = newValue
}
}
override var defaultSource: STPSourceProtocol? {
get {
return mockDefaultSource
}
set {
mockDefaultSource = newValue
}
}
override var shippingAddress: STPAddress? {
get {
return mockShippingAddress
}
set {
mockShippingAddress = newValue
}
}
}
class MockCustomerContext: STPCustomerContext {
let customer = MockCustomer()
override func retrieveCustomer(_ completion: STPCustomerCompletionBlock? = nil) {
if let completion = completion {
completion(customer, nil)
}
}
override func attachSource(toCustomer source: STPSourceProtocol, completion: @escaping STPErrorBlock) {
if let token = source as? STPToken, let card = token.card {
customer.sources.append(card)
}
completion(nil)
}
override func selectDefaultCustomerSource(_ source: STPSourceProtocol, completion: @escaping STPErrorBlock) {
if customer.sources.contains(where: { $0.stripeID == source.stripeID }) {
customer.defaultSource = source
}
completion(nil)
}
func updateCustomer(withShippingAddress shipping: STPAddress, completion: STPErrorBlock?) {
customer.shippingAddress = shipping
if let completion = completion {
completion(nil)
}
}
func detachSource(fromCustomer source: STPSourceProtocol, completion: STPErrorBlock?) {
if let index = customer.sources.index(where: { $0.stripeID == source.stripeID }) {
customer.sources.remove(at: index)
}
if let completion = completion {
completion(nil)
}
}
}

View File

@ -0,0 +1,5 @@
# UI Examples
This example app lets you try out the pre-built UI components we provide. You can run it without any initial setup, and it's a great place to start if you're evaluating whether you want to use our UI components in your app.
If you'd like to use our pre-built UI components, you can refer to our Standard Integration app for an example of how to use `STPPaymentContext` to present our UI components and drive your app's payment flow.

View File

@ -0,0 +1,95 @@
//
// ThemeViewController.swift
// UI Examples
//
// Created by Ben Guo on 7/19/17.
// Copyright © 2017 Stripe. All rights reserved.
//
import UIKit
import Stripe
class ThemeViewController: UITableViewController {
enum Theme: String {
static let count = 3
case Default = "Default"
case CustomDark = "Custom - Dark"
case CustomLight = "Custom - Light"
init?(row: Int) {
switch row {
case 0: self = .Default
case 1: self = .CustomDark
case 2: self = .CustomLight
default: return nil
}
}
var stpTheme: STPTheme {
switch self {
case .Default:
return STPTheme.default()
case .CustomDark:
let theme = STPTheme.default()
theme.primaryBackgroundColor = UIColor(red:66.0/255.0, green:69.0/255.0, blue:112.0/255.0, alpha:255.0/255.0)
theme.secondaryBackgroundColor = theme.primaryBackgroundColor
theme.primaryForegroundColor = UIColor.white
theme.secondaryForegroundColor = UIColor(red:130.0/255.0, green:147.0/255.0, blue:168.0/255.0, alpha:255.0/255.0)
theme.accentColor = UIColor(red:14.0/255.0, green:211.0/255.0, blue:140.0/255.0, alpha:255.0/255.0)
theme.errorColor = UIColor(red:237.0/255.0, green:83.0/255.0, blue:69.0/255.0, alpha:255.0/255.0)
return theme
case .CustomLight:
let theme = STPTheme.default()
theme.primaryBackgroundColor = UIColor(red:230.0/255.0, green:235.0/255.0, blue:241.0/255.0, alpha:255.0/255.0)
theme.secondaryBackgroundColor = UIColor.white
theme.primaryForegroundColor = UIColor(red:55.0/255.0, green:53.0/255.0, blue:100.0/255.0, alpha:255.0/255.0)
theme.secondaryForegroundColor = UIColor(red:148.0/255.0, green:163.0/255.0, blue:179.0/255.0, alpha:255.0/255.0)
theme.accentColor = UIColor(red:101.0/255.0, green:101.0/255.0, blue:232.0/255.0, alpha:255.0/255.0)
theme.errorColor = UIColor(red:240.0/255.0, green:2.0/255.0, blue:36.0/255.0, alpha:255.0/255.0)
return theme
}
}
}
var theme: Theme = .Default
override func viewDidLoad() {
super.viewDidLoad()
title = "Change Theme"
tableView.tableFooterView = UIView()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancel))
}
func cancel() {
dismiss(animated: true, completion: nil)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Theme.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
guard let theme = Theme(row: indexPath.row) else { return cell }
cell.textLabel?.text = theme.rawValue
cell.accessoryType = theme == self.theme ? .checkmark : .none
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard let theme = Theme(row: indexPath.row) else { return }
self.theme = theme
tableView.reloadSections(IndexSet(integer: (indexPath as NSIndexPath).section), with: .automatic)
dismiss(animated: true, completion: nil)
}
}

View File

@ -1,5 +1,8 @@
## Migration Guides ## Migration Guides
### Migrating from versions < X.X.X
* `STPCustomer`'s `shippingAddress` property is now correctly annotated as nullable. Its type is an optional (`STPAddress?`) in Swift.
### Migration from versions < 11.0.0 ### Migration from versions < 11.0.0
- We've greatly simplified the integration for `STPPaymentContext`. In order to migrate to the new `STPPaymentContext` integration using ephemeral keys, you'll need to: - We've greatly simplified the integration for `STPPaymentContext`. In order to migrate to the new `STPPaymentContext` integration using ephemeral keys, you'll need to:
1. On your backend, add a new endpoint that creates an ephemeral key for the Stripe customer associated with your user, and returns its raw JSON. Note that you should _not_ remove the 3 endpoints you added for your initial PaymentContext integration until you're ready to drop support for previous versions of your app. 1. On your backend, add a new endpoint that creates an ephemeral key for the Stripe customer associated with your user, and returns its raw JSON. Note that you should _not_ remove the 3 endpoints you added for your initial PaymentContext integration until you're ready to drop support for previous versions of your app.

View File

@ -15,7 +15,7 @@ We also offer [seamless integration](https://stripe.com/apple-pay) with [Apple P
We recommend you only use official versioned releases of the sdk (accessible from Github's [Releases](https://github.com/stripe/stripe-ios/releases) page) as the master branch is considered unstable. We recommend you only use official versioned releases of the sdk (accessible from Github's [Releases](https://github.com/stripe/stripe-ios/releases) page) as the master branch is considered unstable.
If you're reading this on github.com, make sure you are looking at the version that matches the release you have installed, otherwise the instructions and example code may be mismatched. You can read the latest released version of this readme and browse the associated code on Github via [this link](https://github.com/stripe/stripe-ios/tree/v11.0.0). If you're reading this on github.com, make sure you are looking at the version that matches the release you have installed, otherwise the instructions and example code may be mismatched. You can read the latest released version of this readme and browse the associated code on Github via [this link](https://github.com/stripe/stripe-ios/tree/v11.1.0).
## Requirements ## Requirements
Our SDK is compatible with iOS apps supporting iOS 8.0 and above. It requires Xcode 8.0+ to build the source. Our SDK is compatible with iOS apps supporting iOS 8.0 and above. It requires Xcode 8.0+ to build the source.
@ -31,8 +31,8 @@ For more fine-grained information on all of the classes and methods in our SDK,
## Example apps ## Example apps
There are 2 example apps included in the repository: There are 2 example apps included in the repository:
- Stripe iOS Example (Simple) shows an integration using our prebuilt UI components [Swift] - Standard Integration (Swift) shows an integration using our prebuilt UI components.
- Stripe iOS Example (Custom) shows how to use our low-level methods to accept payments using several different payment methods [Objective-C]. - Custom Integration (ObjC) shows how to use our low-level methods to accept payments using several different payment methods.
To build the example apps, you'll need to first run `./setup.sh`. Then, open `Stripe.xcworkspace` and choose the appropriate scheme. To build the example apps, you'll need to first run `./setup.sh`. Then, open `Stripe.xcworkspace` and choose the appropriate scheme.
@ -43,7 +43,7 @@ Note: all the example apps require Xcode 8.0 to build and run.
Before you can run the apps, you need to provide them with your Stripe publishable key. Before you can run the apps, you need to provide them with your Stripe publishable key.
1. If you haven't already, sign up for a [Stripe account](https://dashboard.stripe.com/register) (it takes seconds). Then go to https://dashboard.stripe.com/account/apikeys. 1. If you haven't already, sign up for a [Stripe account](https://dashboard.stripe.com/register) (it takes seconds). Then go to https://dashboard.stripe.com/account/apikeys.
2. Replace the `stripePublishableKey` constant in CheckoutViewController.swift (for the Simple app) or Constants.m (for the Custom app) with your Test Publishable Key. 2. Replace the `stripePublishableKey` constant in CheckoutViewController.swift (for the Standard Integration app) or Constants.m (for the Custom Integration app) with your Test Publishable Key.
3. Head to https://github.com/stripe/example-ios-backend/tree/v11.0.0 and click "Deploy to Heroku" (you may have to sign up for a Heroku account as part of this process). Provide your Stripe test secret key for the STRIPE_TEST_SECRET_KEY field under 'Env'. Click "Deploy for Free". 3. Head to https://github.com/stripe/example-ios-backend/tree/v11.0.0 and click "Deploy to Heroku" (you may have to sign up for a Heroku account as part of this process). Provide your Stripe test secret key for the STRIPE_TEST_SECRET_KEY field under 'Env'. Click "Deploy for Free".
4. Replace the `backendBaseURL` variable in the example iOS app with the app URL Heroku provides you with (e.g. "https://my-example-app.herokuapp.com") 4. Replace the `backendBaseURL` variable in the example iOS app with the app URL Heroku provides you with (e.g. "https://my-example-app.herokuapp.com")
@ -53,7 +53,7 @@ After this is done, you can make test payments through the app and see them in y
To add card scanning capabilities to our prebuilt UI components, you can simply [install card.io](https://github.com/card-io/card.io-iOS-SDK#setup) alongside our SDK. You'll also need to set `NSCameraUsageDescription` in your application's plist, and provide a reason for accessing the camera (e.g. "To scan cards"). To add card scanning capabilities to our prebuilt UI components, you can simply [install card.io](https://github.com/card-io/card.io-iOS-SDK#setup) alongside our SDK. You'll also need to set `NSCameraUsageDescription` in your application's plist, and provide a reason for accessing the camera (e.g. "To scan cards").
To try this out, you can run `./install_cardio.rb`, which will download and install card.io in Stripe iOS Example (Simple). Now, when you run the example app on a device, you'll see a "Scan Card" button when adding a new card. To try this out, you can run `./install_cardio.rb`, which will download and install card.io in Standard Integration (Swift). Now, when you run the example app on a device, you'll see a "Scan Card" button when adding a new card.
## Running the tests ## Running the tests

View File

@ -1,10 +1,10 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'Stripe' s.name = 'Stripe'
s.version = '11.0.0' s.version = '11.1.0'
s.summary = 'Stripe is a web-based API for accepting payments online.' s.summary = 'Stripe is a web-based API for accepting payments online.'
s.license = { :type => 'MIT', :file => 'LICENSE' } s.license = { :type => 'MIT', :file => 'LICENSE' }
s.homepage = 'https://stripe.com/docs/mobile/ios' s.homepage = 'https://stripe.com/docs/mobile/ios'
s.authors = { 'Jack Flintermann' => 'jack@stripe.com', 'Stripe' => 'support+github@stripe.com' } s.authors = { 'Stripe' => 'support+github@stripe.com' }
s.source = { :git => 'https://github.com/stripe/stripe-ios.git', :tag => "v#{s.version}" } s.source = { :git => 'https://github.com/stripe/stripe-ios.git', :tag => "v#{s.version}" }
s.frameworks = 'Foundation', 'Security', 'WebKit', 'PassKit', 'AddressBook', 'CoreLocation' s.frameworks = 'Foundation', 'Security', 'WebKit', 'PassKit', 'AddressBook', 'CoreLocation'
s.weak_frameworks = 'Contacts' s.weak_frameworks = 'Contacts'

View File

@ -332,13 +332,21 @@
04F94DD31D22A23F004FC826 /* NSBundle+Stripe_AppName.h in Headers */ = {isa = PBXBuildFile; fileRef = 049A3F971CC76A2400F57DE7 /* NSBundle+Stripe_AppName.h */; }; 04F94DD31D22A23F004FC826 /* NSBundle+Stripe_AppName.h in Headers */ = {isa = PBXBuildFile; fileRef = 049A3F971CC76A2400F57DE7 /* NSBundle+Stripe_AppName.h */; };
04F94DD41D22A242004FC826 /* NSBundle+Stripe_AppName.m in Sources */ = {isa = PBXBuildFile; fileRef = 049A3F981CC76A2400F57DE7 /* NSBundle+Stripe_AppName.m */; }; 04F94DD41D22A242004FC826 /* NSBundle+Stripe_AppName.m in Sources */ = {isa = PBXBuildFile; fileRef = 049A3F981CC76A2400F57DE7 /* NSBundle+Stripe_AppName.m */; };
04FCFA191BD59A8C00297732 /* STPCategoryLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 04FCFA171BD59A8C00297732 /* STPCategoryLoader.h */; }; 04FCFA191BD59A8C00297732 /* STPCategoryLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 04FCFA171BD59A8C00297732 /* STPCategoryLoader.h */; };
8B013C891F1E784A00DD831B /* STPPaymentConfigurationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B013C881F1E784A00DD831B /* STPPaymentConfigurationTest.m */; };
8B429AD81EF9D4B400F95F34 /* STPBankAccountParams+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429AD71EF9D4A300F95F34 /* STPBankAccountParams+Private.h */; }; 8B429AD81EF9D4B400F95F34 /* STPBankAccountParams+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429AD71EF9D4A300F95F34 /* STPBankAccountParams+Private.h */; };
8B429AD91EF9D4B500F95F34 /* STPBankAccountParams+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429AD71EF9D4A300F95F34 /* STPBankAccountParams+Private.h */; }; 8B429AD91EF9D4B500F95F34 /* STPBankAccountParams+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429AD71EF9D4A300F95F34 /* STPBankAccountParams+Private.h */; };
8B429ADB1EF9E18400F95F34 /* STPBankAccount+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */; }; 8B429ADB1EF9E18400F95F34 /* STPBankAccount+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */; };
8B429ADC1EF9E18400F95F34 /* STPBankAccount+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */; }; 8B429ADC1EF9E18400F95F34 /* STPBankAccount+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */; };
8B429ADE1EF9EFF900F95F34 /* STPFile+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */; }; 8B429ADE1EF9EFF900F95F34 /* STPFile+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */; };
8B429ADF1EF9EFFA00F95F34 /* STPFile+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */; }; 8B429ADF1EF9EFFA00F95F34 /* STPFile+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */; };
8B5B4B441EFDD925005CF475 /* STPSourceOwnerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B5B4B431EFDD925005CF475 /* STPSourceOwnerTest.m */; };
8B6DC9751F0171D20025E811 /* STPSourceReceiverTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B6DC9741F0171D20025E811 /* STPSourceReceiverTest.m */; };
8B6DC9771F0172640025E811 /* STPSourceSEPADebitDetailsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B6DC9761F0172640025E811 /* STPSourceSEPADebitDetailsTest.m */; };
8B8DDBB31EF887A4004B141F /* STPBankAccountParamsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */; }; 8B8DDBB31EF887A4004B141F /* STPBankAccountParamsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */; };
8BD213371F044B57007F6FD1 /* BankAccount.json in Resources */ = {isa = PBXBuildFile; fileRef = 8BD213361F044B57007F6FD1 /* BankAccount.json */; };
8BD213391F0457A1007F6FD1 /* FileUpload.json in Resources */ = {isa = PBXBuildFile; fileRef = 8BD213381F0457A1007F6FD1 /* FileUpload.json */; };
8BD2133C1F0458F5007F6FD1 /* BitcoinSource.json in Resources */ = {isa = PBXBuildFile; fileRef = 8BD2133B1F0458F5007F6FD1 /* BitcoinSource.json */; };
8BD2133E1F045D31007F6FD1 /* SEPADebitSource.json in Resources */ = {isa = PBXBuildFile; fileRef = 8BD2133D1F045D31007F6FD1 /* SEPADebitSource.json */; };
8BD87B881EFB131700269C2B /* STPSourceCardDetails+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */; }; 8BD87B881EFB131700269C2B /* STPSourceCardDetails+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */; };
8BD87B891EFB131800269C2B /* STPSourceCardDetails+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */; }; 8BD87B891EFB131800269C2B /* STPSourceCardDetails+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */; };
8BD87B8B1EFB136F00269C2B /* STPSourceCardDetailsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */; }; 8BD87B8B1EFB136F00269C2B /* STPSourceCardDetailsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */; };
@ -968,10 +976,18 @@
04FCFA171BD59A8C00297732 /* STPCategoryLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCategoryLoader.h; sourceTree = "<group>"; }; 04FCFA171BD59A8C00297732 /* STPCategoryLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCategoryLoader.h; sourceTree = "<group>"; };
11C74B9B164043050071C2CA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 11C74B9B164043050071C2CA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
4A0D74F918F6106100966D7B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 4A0D74F918F6106100966D7B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
8B013C881F1E784A00DD831B /* STPPaymentConfigurationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPPaymentConfigurationTest.m; sourceTree = "<group>"; };
8B429AD71EF9D4A300F95F34 /* STPBankAccountParams+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPBankAccountParams+Private.h"; sourceTree = "<group>"; }; 8B429AD71EF9D4A300F95F34 /* STPBankAccountParams+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPBankAccountParams+Private.h"; sourceTree = "<group>"; };
8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPBankAccount+Private.h"; sourceTree = "<group>"; }; 8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPBankAccount+Private.h"; sourceTree = "<group>"; };
8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPFile+Private.h"; sourceTree = "<group>"; }; 8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPFile+Private.h"; sourceTree = "<group>"; };
8B5B4B431EFDD925005CF475 /* STPSourceOwnerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceOwnerTest.m; sourceTree = "<group>"; };
8B6DC9741F0171D20025E811 /* STPSourceReceiverTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceReceiverTest.m; sourceTree = "<group>"; };
8B6DC9761F0172640025E811 /* STPSourceSEPADebitDetailsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceSEPADebitDetailsTest.m; sourceTree = "<group>"; };
8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPBankAccountParamsTest.m; sourceTree = "<group>"; }; 8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPBankAccountParamsTest.m; sourceTree = "<group>"; };
8BD213361F044B57007F6FD1 /* BankAccount.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = BankAccount.json; sourceTree = "<group>"; };
8BD213381F0457A1007F6FD1 /* FileUpload.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = FileUpload.json; sourceTree = "<group>"; };
8BD2133B1F0458F5007F6FD1 /* BitcoinSource.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = BitcoinSource.json; sourceTree = "<group>"; };
8BD2133D1F045D31007F6FD1 /* SEPADebitSource.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = SEPADebitSource.json; sourceTree = "<group>"; };
8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPSourceCardDetails+Private.h"; sourceTree = "<group>"; }; 8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPSourceCardDetails+Private.h"; sourceTree = "<group>"; };
8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceCardDetailsTest.m; sourceTree = "<group>"; }; 8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceCardDetailsTest.m; sourceTree = "<group>"; };
8BD87B8C1EFB152800269C2B /* STPSourceRedirect+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPSourceRedirect+Private.h"; sourceTree = "<group>"; }; 8BD87B8C1EFB152800269C2B /* STPSourceRedirect+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPSourceRedirect+Private.h"; sourceTree = "<group>"; };
@ -1442,6 +1458,18 @@
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
8BD2133A1F0458B7007F6FD1 /* Source */ = {
isa = PBXGroup;
children = (
F1BA241F1E57BEC600E4A1CF /* 3DSSource.json */,
8BD2133B1F0458F5007F6FD1 /* BitcoinSource.json */,
F1BA241C1E57BE5700E4A1CF /* CardSource.json */,
F152322E1EA9344000D65C67 /* iDEALSource.json */,
8BD2133D1F045D31007F6FD1 /* SEPADebitSource.json */,
);
name = Source;
sourceTree = "<group>";
};
C18867D61E8B069E00A77634 /* Snapshot */ = { C18867D61E8B069E00A77634 /* Snapshot */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1479,9 +1507,9 @@
C12711091DBA7E490087840D /* STPAddressViewModelTest.m */, C12711091DBA7E490087840D /* STPAddressViewModelTest.m */,
C124A1841CCAB750007D42EE /* STPAnalyticsClientTest.m */, C124A1841CCAB750007D42EE /* STPAnalyticsClientTest.m */,
04CDB51E1A5F3A9300B854EE /* STPAPIClientTest.m */, 04CDB51E1A5F3A9300B854EE /* STPAPIClientTest.m */,
C14C4DB01EC3B34500C2FDF6 /* STPAPIRequestTest.m */,
C1AED1551EE0C8C6008BEFBF /* STPApplePayTest.m */, C1AED1551EE0C8C6008BEFBF /* STPApplePayTest.m */,
8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */, 8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */,
C14C4DB01EC3B34500C2FDF6 /* STPAPIRequestTest.m */,
04CDB5231A5F3A9300B854EE /* STPBankAccountTest.m */, 04CDB5231A5F3A9300B854EE /* STPBankAccountTest.m */,
045D71301CF514BB00F6CD65 /* STPBinRangeTest.m */, 045D71301CF514BB00F6CD65 /* STPBinRangeTest.m */,
8BE5AE8A1EF8905B0081A33C /* STPCardParamsTest.m */, 8BE5AE8A1EF8905B0081A33C /* STPCardParamsTest.m */,
@ -1492,21 +1520,25 @@
C1D23FAC1D37F81F002FD83C /* STPCustomerTest.m */, C1D23FAC1D37F81F002FD83C /* STPCustomerTest.m */,
C1EEDCC51CA2126000A54582 /* STPDelegateProxyTest.m */, C1EEDCC51CA2126000A54582 /* STPDelegateProxyTest.m */,
04A488351CA34DC600506E53 /* STPEmailAddressValidatorTest.m */, 04A488351CA34DC600506E53 /* STPEmailAddressValidatorTest.m */,
C1CFCB701ED5E11500BE45DF /* STPFileTest.m */,
C1C02CCD1ECCE92900DF5643 /* STPEphemeralKeyTest.m */,
C184107D1EC2704700178149 /* STPEphemeralKeyManagerTest.m */, C184107D1EC2704700178149 /* STPEphemeralKeyManagerTest.m */,
C1C02CCD1ECCE92900DF5643 /* STPEphemeralKeyTest.m */,
C1CFCB701ED5E11500BE45DF /* STPFileTest.m */,
04CDB51F1A5F3A9300B854EE /* STPFormEncoderTest.m */, 04CDB51F1A5F3A9300B854EE /* STPFormEncoderTest.m */,
C16F66AA1CA21BAC006A21B5 /* STPFormTextFieldTest.m */, C16F66AA1CA21BAC006A21B5 /* STPFormTextFieldTest.m */,
04827D171D257A6C002DB3E8 /* STPImageLibraryTest.m */, 04827D171D257A6C002DB3E8 /* STPImageLibraryTest.m */,
045A62AA1B8E7259000165CE /* STPPaymentCardTextFieldTest.m */, 045A62AA1B8E7259000165CE /* STPPaymentCardTextFieldTest.m */,
0438EF4B1B741B0100D506CC /* STPPaymentCardTextFieldViewModelTest.m */, 0438EF4B1B741B0100D506CC /* STPPaymentCardTextFieldViewModelTest.m */,
8B013C881F1E784A00DD831B /* STPPaymentConfigurationTest.m */,
F14C872E1D4FCDBA00C7CC6A /* STPPaymentContextApplePayTest.m */, F14C872E1D4FCDBA00C7CC6A /* STPPaymentContextApplePayTest.m */,
C1EEDCC91CA2186300A54582 /* STPPhoneNumberValidatorTest.m */, C1EEDCC91CA2186300A54582 /* STPPhoneNumberValidatorTest.m */,
C1FEE5981CBFF24000A7632B /* STPPostalCodeValidatorTest.m */, C1FEE5981CBFF24000A7632B /* STPPostalCodeValidatorTest.m */,
F152321A1EA92F9D00D65C67 /* STPRedirectContextTest.m */, F152321A1EA92F9D00D65C67 /* STPRedirectContextTest.m */,
8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */, 8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */,
8B5B4B431EFDD925005CF475 /* STPSourceOwnerTest.m */,
C1BD9B1E1E390A2700CEE925 /* STPSourceParamsTest.m */, C1BD9B1E1E390A2700CEE925 /* STPSourceParamsTest.m */,
8B6DC9741F0171D20025E811 /* STPSourceReceiverTest.m */,
8BD87B8F1EFB17AA00269C2B /* STPSourceRedirectTest.m */, 8BD87B8F1EFB17AA00269C2B /* STPSourceRedirectTest.m */,
8B6DC9761F0172640025E811 /* STPSourceSEPADebitDetailsTest.m */,
C17D24ED1E37DBAC005CB188 /* STPSourceTest.m */, C17D24ED1E37DBAC005CB188 /* STPSourceTest.m */,
8BD87B941EFB1CB100269C2B /* STPSourceVerificationTest.m */, 8BD87B941EFB1CB100269C2B /* STPSourceVerificationTest.m */,
F1D777BF1D81DD520076FA19 /* STPStringUtilsTest.m */, F1D777BF1D81DD520076FA19 /* STPStringUtilsTest.m */,
@ -1531,12 +1563,12 @@
C1D23FB71D37FE0F002FD83C /* JSON */ = { C1D23FB71D37FE0F002FD83C /* JSON */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
8BD213361F044B57007F6FD1 /* BankAccount.json */,
C1D23FB31D37FE0B002FD83C /* Card.json */, C1D23FB31D37FE0B002FD83C /* Card.json */,
C1D23FB41D37FE0B002FD83C /* Customer.json */, C1D23FB41D37FE0B002FD83C /* Customer.json */,
F1BA241C1E57BE5700E4A1CF /* CardSource.json */,
C1C02CCA1ECCD0E500DF5643 /* EphemeralKey.json */, C1C02CCA1ECCD0E500DF5643 /* EphemeralKey.json */,
F1BA241F1E57BEC600E4A1CF /* 3DSSource.json */, 8BD213381F0457A1007F6FD1 /* FileUpload.json */,
F152322E1EA9344000D65C67 /* iDEALSource.json */, 8BD2133A1F0458B7007F6FD1 /* Source */,
); );
name = JSON; name = JSON;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2358,12 +2390,16 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
F1343BEA1D652CAD00F102D8 /* Customer.json in Resources */, F1343BEA1D652CAD00F102D8 /* Customer.json in Resources */,
8BD2133E1F045D31007F6FD1 /* SEPADebitSource.json in Resources */,
8BD213371F044B57007F6FD1 /* BankAccount.json in Resources */,
C1C02CCC1ECCD0ED00DF5643 /* EphemeralKey.json in Resources */, C1C02CCC1ECCD0ED00DF5643 /* EphemeralKey.json in Resources */,
F1BA24211E57BECA00E4A1CF /* 3DSSource.json in Resources */, F1BA24211E57BECA00E4A1CF /* 3DSSource.json in Resources */,
F1BA241E1E57BE5E00E4A1CF /* CardSource.json in Resources */, F1BA241E1E57BE5E00E4A1CF /* CardSource.json in Resources */,
F1343BE91D652CAB00F102D8 /* Card.json in Resources */, F1343BE91D652CAB00F102D8 /* Card.json in Resources */,
8BD213391F0457A1007F6FD1 /* FileUpload.json in Resources */,
C1CFCB7A1ED5F88D00BE45DF /* stp_test_upload_image.jpeg in Resources */, C1CFCB7A1ED5F88D00BE45DF /* stp_test_upload_image.jpeg in Resources */,
F152322F1EA9344600D65C67 /* iDEALSource.json in Resources */, F152322F1EA9344600D65C67 /* iDEALSource.json in Resources */,
8BD2133C1F0458F5007F6FD1 /* BitcoinSource.json in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -2621,12 +2657,16 @@
04415C681A6605B5001225ED /* STPFormEncoderTest.m in Sources */, 04415C681A6605B5001225ED /* STPFormEncoderTest.m in Sources */,
C1CFCB751ED5E12400BE45DF /* STPFileTest.m in Sources */, C1CFCB751ED5E12400BE45DF /* STPFileTest.m in Sources */,
C11810991CC6D46D0022FB55 /* NSDecimalNumber+StripeTest.m in Sources */, C11810991CC6D46D0022FB55 /* NSDecimalNumber+StripeTest.m in Sources */,
8B5B4B441EFDD925005CF475 /* STPSourceOwnerTest.m in Sources */,
8B013C891F1E784A00DD831B /* STPPaymentConfigurationTest.m in Sources */,
C1EEDCC81CA2172700A54582 /* NSString+StripeTest.m in Sources */, C1EEDCC81CA2172700A54582 /* NSString+StripeTest.m in Sources */,
8BD87B901EFB17AA00269C2B /* STPSourceRedirectTest.m in Sources */, 8BD87B901EFB17AA00269C2B /* STPSourceRedirectTest.m in Sources */,
04415C6A1A6605B5001225ED /* STPApplePayFunctionalTest.m in Sources */, 04415C6A1A6605B5001225ED /* STPApplePayFunctionalTest.m in Sources */,
8BE5AE8B1EF8905B0081A33C /* STPCardParamsTest.m in Sources */, 8BE5AE8B1EF8905B0081A33C /* STPCardParamsTest.m in Sources */,
F1D3A25F1EB015B30095BFA9 /* UIImage+StripeTests.m in Sources */, F1D3A25F1EB015B30095BFA9 /* UIImage+StripeTests.m in Sources */,
04415C6B1A6605B5001225ED /* STPBankAccountFunctionalTest.m in Sources */, 04415C6B1A6605B5001225ED /* STPBankAccountFunctionalTest.m in Sources */,
8B6DC9751F0171D20025E811 /* STPSourceReceiverTest.m in Sources */,
8B6DC9771F0172640025E811 /* STPSourceSEPADebitDetailsTest.m in Sources */,
04415C6C1A6605B5001225ED /* STPBankAccountTest.m in Sources */, 04415C6C1A6605B5001225ED /* STPBankAccountTest.m in Sources */,
C19D09931EAEAE5E00A4AB3E /* STPTelemetryClientTest.m in Sources */, C19D09931EAEAE5E00A4AB3E /* STPTelemetryClientTest.m in Sources */,
F152321B1EA92F9D00D65C67 /* STPRedirectContextTest.m in Sources */, F152321B1EA92F9D00D65C67 /* STPRedirectContextTest.m in Sources */,

View File

@ -5,9 +5,12 @@
location = "group:Stripe.xcodeproj"> location = "group:Stripe.xcodeproj">
</FileRef> </FileRef>
<FileRef <FileRef
location = "group:Example/Stripe iOS Example (Simple).xcodeproj"> location = "group:Example/UI Examples.xcodeproj">
</FileRef> </FileRef>
<FileRef <FileRef
location = "group:Example/Stripe iOS Example (Custom).xcodeproj"> location = "group:Example/Standard Integration (Swift).xcodeproj">
</FileRef>
<FileRef
location = "group:Example/Custom Integration (ObjC).xcodeproj">
</FileRef> </FileRef>
</Workspace> </Workspace>

View File

@ -13,11 +13,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>11.0.0</string> <string>11.1.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>11.0.0</string> <string>11.1.0</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string></string> <string></string>
</dict> </dict>

View File

@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
#define FAUXPAS_IGNORED_IN_FILE(...) #define FAUXPAS_IGNORED_IN_FILE(...)
FAUXPAS_IGNORED_IN_FILE(APIAvailability) FAUXPAS_IGNORED_IN_FILE(APIAvailability)
static NSString *const STPSDKVersion = @"11.0.0"; static NSString *const STPSDKVersion = @"11.1.0";
@class STPBankAccount, STPBankAccountParams, STPCard, STPCardParams, STPSourceParams, STPToken, STPPaymentConfiguration; @class STPBankAccount, STPBankAccountParams, STPCard, STPCardParams, STPSourceParams, STPToken, STPPaymentConfiguration;
@ -27,53 +27,83 @@ static NSString *const STPSDKVersion = @"11.0.0";
@interface Stripe : NSObject FAUXPAS_IGNORED_ON_LINE(UnprefixedClass); @interface Stripe : NSObject FAUXPAS_IGNORED_ON_LINE(UnprefixedClass);
/** /**
* Set your Stripe API key with this method. New instances of STPAPIClient will be initialized with this value. You should call this method as early as Set your Stripe API key with this method. New instances of STPAPIClient will be initialized with this value. You should call this method as early as
* possible in your application's lifecycle, preferably in your AppDelegate. possible in your application's lifecycle, preferably in your AppDelegate.
*
* @param publishableKey Your publishable key, obtained from https://stripe.com/account/apikeys @param publishableKey Your publishable key, obtained from https://stripe.com/account/apikeys
* @warning Make sure not to ship your test API keys to the App Store! This will log a warning if you use your test key in a release build. @warning Make sure not to ship your test API keys to the App Store! This will log a warning if you use your test key in a release build.
*/ */
+ (void)setDefaultPublishableKey:(NSString *)publishableKey; + (void)setDefaultPublishableKey:(NSString *)publishableKey;
/// The current default publishable key. /**
The current default publishable key.
*/
+ (nullable NSString *)defaultPublishableKey; + (nullable NSString *)defaultPublishableKey;
@end @end
/// A client for making connections to the Stripe API. /**
A client for making connections to the Stripe API.
*/
@interface STPAPIClient : NSObject @interface STPAPIClient : NSObject
/** /**
* A shared singleton API client. Its API key will be initially equal to [Stripe defaultPublishableKey]. A shared singleton API client. Its API key will be initially equal to [Stripe defaultPublishableKey].
*/ */
+ (instancetype)sharedClient; + (instancetype)sharedClient;
/**
Initializes an API client with the given configuration. Its API key will be
set to the configuration's publishable key.
@param configuration The configuration to use.
@return An instance of STPAPIClient.
*/
- (instancetype)initWithConfiguration:(STPPaymentConfiguration *)configuration NS_DESIGNATED_INITIALIZER; - (instancetype)initWithConfiguration:(STPPaymentConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
/**
Initializes an API client with the given publishable key.
@param publishableKey The publishable key to use.
@return An instance of STPAPIClient.
*/
- (instancetype)initWithPublishableKey:(NSString *)publishableKey; - (instancetype)initWithPublishableKey:(NSString *)publishableKey;
/** /**
* @see [Stripe setDefaultPublishableKey:] The client's publishable key.
*/ */
@property (nonatomic, copy, nullable) NSString *publishableKey; @property (nonatomic, copy, nullable) NSString *publishableKey;
/** /**
* @see -initWithConfiguration The client's configuration.
*/ */
@property (nonatomic, copy) STPPaymentConfiguration *configuration; @property (nonatomic, copy) STPPaymentConfiguration *configuration;
/**
In order to perform API requests on behalf of a connected account, e.g. to
create a source on a connected account, set this property to the ID of the
account for which this request is being made.
@see https://stripe.com/docs/connect/authentication#authentication-via-the-stripe-account-header
*/
@property (nonatomic, copy, nullable) NSString *stripeAccount;
@end @end
#pragma mark Bank Accounts #pragma mark Bank Accounts
/** /**
* STPAPIClient extensions to create Stripe tokens from bank accounts. STPAPIClient extensions to create Stripe tokens from bank accounts.
*/ */
@interface STPAPIClient (BankAccounts) @interface STPAPIClient (BankAccounts)
/** /**
* Converts an STPBankAccount object into a Stripe token using the Stripe API. Converts an STPBankAccount object into a Stripe token using the Stripe API.
*
* @param bankAccount The user's bank account details. Cannot be nil. @see https://stripe.com/docs/api#create_bank_account_token @param bankAccount The user's bank account details. Cannot be nil. @see https://stripe.com/docs/api#create_bank_account_token
* @param completion The callback to run with the returned Stripe token (and any errors that may have occurred). @param completion The callback to run with the returned Stripe token (and any errors that may have occurred).
*/ */
- (void)createTokenWithBankAccount:(STPBankAccountParams *)bankAccount completion:(__nullable STPTokenCompletionBlock)completion; - (void)createTokenWithBankAccount:(STPBankAccountParams *)bankAccount completion:(__nullable STPTokenCompletionBlock)completion;
@ -82,40 +112,40 @@ static NSString *const STPSDKVersion = @"11.0.0";
#pragma mark Personally Identifiable Information #pragma mark Personally Identifiable Information
/** /**
* STPAPIClient extensions to create Stripe tokens from a personal identification number. STPAPIClient extensions to create Stripe tokens from a personal identification number.
*/ */
@interface STPAPIClient (PII) @interface STPAPIClient (PII)
/** /**
* Converts a personal identification number into a Stripe token using the Stripe API. Converts a personal identification number into a Stripe token using the Stripe API.
*
* @param pii The user's personal identification number. Cannot be nil. @see https://stripe.com/docs/api#create_pii_token @param pii The user's personal identification number. Cannot be nil. @see https://stripe.com/docs/api#create_pii_token
* @param completion The callback to run with the returned Stripe token (and any errors that may have occurred). @param completion The callback to run with the returned Stripe token (and any errors that may have occurred).
*/ */
- (void)createTokenWithPersonalIDNumber:(NSString *)pii completion:(__nullable STPTokenCompletionBlock)completion; - (void)createTokenWithPersonalIDNumber:(NSString *)pii completion:(__nullable STPTokenCompletionBlock)completion;
@end @end
/** /**
* STPAPIClient extensions to upload files. STPAPIClient extensions to upload files.
*/ */
@interface STPAPIClient (Upload) @interface STPAPIClient (Upload)
/** /**
* Uses the Stripe file upload API to upload an image. This can be used for Uses the Stripe file upload API to upload an image. This can be used for
* identity veritfication and evidence disputes. identity veritfication and evidence disputes.
*
* @param image The image to be uploaded. The maximum allowed file size is 4MB @param image The image to be uploaded. The maximum allowed file size is 4MB
* for identity documents and 8MB for evidence disputes. Cannot be nil. for identity documents and 8MB for evidence disputes. Cannot be nil.
* Your image will be automatically resized down if you pass in one that Your image will be automatically resized down if you pass in one that
* is too large is too large
* @param purpose The purpose of this file. This can be either an identifing @param purpose The purpose of this file. This can be either an identifing
* document or an evidence dispute. document or an evidence dispute.
* @param completion The callback to run with the returned Stripe file @param completion The callback to run with the returned Stripe file
* (and any errors that may have occurred). (and any errors that may have occurred).
*
* @see https://stripe.com/docs/file-upload @see https://stripe.com/docs/file-upload
*/ */
- (void)uploadImage:(UIImage *)image - (void)uploadImage:(UIImage *)image
purpose:(STPFilePurpose)purpose purpose:(STPFilePurpose)purpose
@ -126,71 +156,73 @@ static NSString *const STPSDKVersion = @"11.0.0";
#pragma mark Credit Cards #pragma mark Credit Cards
/** /**
* STPAPIClient extensions to create Stripe tokens from credit or debit cards. STPAPIClient extensions to create Stripe tokens from credit or debit cards.
*/ */
@interface STPAPIClient (CreditCards) @interface STPAPIClient (CreditCards)
/** /**
* Converts an STPCardParams object into a Stripe token using the Stripe API. Converts an STPCardParams object into a Stripe token using the Stripe API.
*
* @param card The user's card details. Cannot be nil. @see https://stripe.com/docs/api#create_card_token @param card The user's card details. Cannot be nil. @see https://stripe.com/docs/api#create_card_token
* @param completion The callback to run with the returned Stripe token (and any errors that may have occurred). @param completion The callback to run with the returned Stripe token (and any errors that may have occurred).
*/ */
- (void)createTokenWithCard:(STPCardParams *)card completion:(nullable STPTokenCompletionBlock)completion; - (void)createTokenWithCard:(STPCardParams *)card completion:(nullable STPTokenCompletionBlock)completion;
@end @end
/** /**
* Convenience methods for working with Apple Pay. Convenience methods for working with Apple Pay.
*/ */
@interface Stripe(ApplePay) @interface Stripe(ApplePay)
/** /**
* Whether or not this device is capable of using Apple Pay. This checks both whether the user is running an iPhone 6/6+ or later, iPad Air 2 or later, or iPad Whether or not this device is capable of using Apple Pay. This checks both
*mini 3 or later, as well as whether or not they have stored any cards in Apple Pay on their device. whether the device supports Apple Pay, as well as whether or not they have
* stored Apple Pay cards on their device.
* @param paymentRequest The return value of this method depends on the `supportedNetworks` property of this payment request, which by default should be
*`@[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa, PKPaymentNetworkDiscover]`. @param paymentRequest The return value of this method depends on the
* `supportedNetworks` property of this payment request, which by default should be
* @return whether or not the user is currently able to pay with Apple Pay. `@[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa, PKPaymentNetworkDiscover]`.
*/
@return whether or not the user is currently able to pay with Apple Pay.
*/
+ (BOOL)canSubmitPaymentRequest:(PKPaymentRequest *)paymentRequest; + (BOOL)canSubmitPaymentRequest:(PKPaymentRequest *)paymentRequest;
+ (BOOL)deviceSupportsApplePay; + (BOOL)deviceSupportsApplePay;
/** /**
* A convenience method to build a `PKPaymentRequest` with sane default values. A convenience method to build a `PKPaymentRequest` with sane default values.
* You will still need to configure the `paymentSummaryItems` property to indicate You will still need to configure the `paymentSummaryItems` property to indicate
* what the user is purchasing, as well as the optional `requiredShippingAddressFields`, what the user is purchasing, as well as the optional `requiredShippingAddressFields`,
* `requiredBillingAddressFields`, and `shippingMethods` properties to indicate `requiredBillingAddressFields`, and `shippingMethods` properties to indicate
* what contact information your application requires. what contact information your application requires.
* Note that this method sets the payment request's countryCode to "US" and its Note that this method sets the payment request's countryCode to "US" and its
* currencyCode to "USD". currencyCode to "USD".
*
* @param merchantIdentifier Your Apple Merchant ID. @param merchantIdentifier Your Apple Merchant ID.
*
* @return a `PKPaymentRequest` with proper default values. Returns nil if running on < iOS8. @return a `PKPaymentRequest` with proper default values. Returns nil if running on < iOS8.
* @deprecated Use `paymentRequestWithMerchantIdentifier:country:currency:` instead. @deprecated Use `paymentRequestWithMerchantIdentifier:country:currency:` instead.
* Apple Pay is available in many countries and currencies, and you should use Apple Pay is available in many countries and currencies, and you should use
* the appropriate values for your business. the appropriate values for your business.
*/ */
+ (PKPaymentRequest *)paymentRequestWithMerchantIdentifier:(NSString *)merchantIdentifier __attribute__((deprecated)); + (PKPaymentRequest *)paymentRequestWithMerchantIdentifier:(NSString *)merchantIdentifier __attribute__((deprecated));
/** /**
* A convenience method to build a `PKPaymentRequest` with sane default values. A convenience method to build a `PKPaymentRequest` with sane default values.
* You will still need to configure the `paymentSummaryItems` property to indicate You will still need to configure the `paymentSummaryItems` property to indicate
* what the user is purchasing, as well as the optional `requiredShippingAddressFields`, what the user is purchasing, as well as the optional `requiredShippingAddressFields`,
* `requiredBillingAddressFields`, and `shippingMethods` properties to indicate `requiredBillingAddressFields`, and `shippingMethods` properties to indicate
* what contact information your application requires. what contact information your application requires.
*
* @param merchantIdentifier Your Apple Merchant ID. @param merchantIdentifier Your Apple Merchant ID.
* @param countryCode The two-letter code for the country where the payment @param countryCode The two-letter code for the country where the payment
* will be processed. This should be the country of your Stripe account. will be processed. This should be the country of your Stripe account.
* @param currencyCode The three-letter code for the currency used by this @param currencyCode The three-letter code for the currency used by this
* payment request. Apple Pay interprets the amounts provided by the summary items payment request. Apple Pay interprets the amounts provided by the summary items
* attached to this request as amounts in this currency. attached to this request as amounts in this currency.
*
* @return a `PKPaymentRequest` with proper default values. Returns nil if running on < iOS8. @return a `PKPaymentRequest` with proper default values. Returns nil if running on < iOS8.
*/ */
+ (PKPaymentRequest *)paymentRequestWithMerchantIdentifier:(NSString *)merchantIdentifier + (PKPaymentRequest *)paymentRequestWithMerchantIdentifier:(NSString *)merchantIdentifier
country:(NSString *)countryCode country:(NSString *)countryCode
@ -201,51 +233,54 @@ static NSString *const STPSDKVersion = @"11.0.0";
#pragma mark Sources #pragma mark Sources
/** /**
* STPAPIClient extensions for working with Source objects STPAPIClient extensions for working with Source objects
*/ */
@interface STPAPIClient (Sources) @interface STPAPIClient (Sources)
/** /**
* Creates a Source object using the provided details. Creates a Source object using the provided details.
* Note: in order to create a source on a connected account, you can set your
* @param params The details of the source to create. Cannot be nil. @see https://stripe.com/docs/api#create_source API client's `stripeAccount` property to the ID of the account.
* @param completion The callback to run with the returned Source object, or an error. @see https://stripe.com/docs/sources/connect#creating-direct-charges
@param params The details of the source to create. Cannot be nil. @see https://stripe.com/docs/api#create_source
@param completion The callback to run with the returned Source object, or an error.
*/ */
- (void)createSourceWithParams:(STPSourceParams *)params completion:(STPSourceCompletionBlock)completion; - (void)createSourceWithParams:(STPSourceParams *)params completion:(STPSourceCompletionBlock)completion;
/** /**
* Retrieves the Source object with the given ID. @see https://stripe.com/docs/api#retrieve_source Retrieves the Source object with the given ID. @see https://stripe.com/docs/api#retrieve_source
*
* @param identifier The identifier of the source to be retrieved. Cannot be nil. @param identifier The identifier of the source to be retrieved. Cannot be nil.
* @param secret The client secret of the source. Cannot be nil. @param secret The client secret of the source. Cannot be nil.
* @param completion The callback to run with the returned Source object, or an error. @param completion The callback to run with the returned Source object, or an error.
*/ */
- (void)retrieveSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret completion:(STPSourceCompletionBlock)completion; - (void)retrieveSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret completion:(STPSourceCompletionBlock)completion;
/** /**
* Starts polling the Source object with the given ID. For payment methods that require Starts polling the Source object with the given ID. For payment methods that require
* additional customer action (e.g. authorizing a payment with their bank), polling additional customer action (e.g. authorizing a payment with their bank), polling
* allows you to determine if the action was successful. Polling will stop and the allows you to determine if the action was successful. Polling will stop and the
* provided callback will be called once the source's status is no longer `pending`, provided callback will be called once the source's status is no longer `pending`,
* or if the given timeout is reached and the source is still `pending`. If polling or if the given timeout is reached and the source is still `pending`. If polling
* stops due to an error, the callback will be fired with the latest retrieved stops due to an error, the callback will be fired with the latest retrieved
* source and the error. source and the error.
*
* Note that if a poll is already running for a source, subsequent calls to `startPolling` Note that if a poll is already running for a source, subsequent calls to `startPolling`
* with the same source ID will do nothing. with the same source ID will do nothing.
*
* @param identifier The identifier of the source to be retrieved. Cannot be nil. @param identifier The identifier of the source to be retrieved. Cannot be nil.
* @param secret The client secret of the source. Cannot be nil. @param secret The client secret of the source. Cannot be nil.
* @param timeout The timeout for the polling operation, in seconds. Timeouts are capped at 5 minutes. @param timeout The timeout for the polling operation, in seconds. Timeouts are capped at 5 minutes.
* @param completion The callback to run with the returned Source object, or an error. @param completion The callback to run with the returned Source object, or an error.
*/ */
- (void)startPollingSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret timeout:(NSTimeInterval)timeout completion:(STPSourceCompletionBlock)completion NS_EXTENSION_UNAVAILABLE("Source polling is not available in extensions") DEPRECATED_MSG_ATTRIBUTE("You should poll your own backend to update based on source status change webhook events it may receive."); - (void)startPollingSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret timeout:(NSTimeInterval)timeout completion:(STPSourceCompletionBlock)completion NS_EXTENSION_UNAVAILABLE("Source polling is not available in extensions") DEPRECATED_MSG_ATTRIBUTE("You should poll your own backend to update based on source status change webhook events it may receive.");
/** /**
* Stops polling the Source object with the given ID. Note that the completion block passed to Stops polling the Source object with the given ID. Note that the completion block passed to
* `startPolling` will not be fired when `stopPolling` is called. `startPolling` will not be fired when `stopPolling` is called.
*
* @param identifier The identifier of the source to be retrieved. Cannot be nil. @param identifier The identifier of the source to be retrieved. Cannot be nil.
*/ */
- (void)stopPollingSourceWithId:(NSString *)identifier NS_EXTENSION_UNAVAILABLE("Source polling is not available in extensions") DEPRECATED_ATTRIBUTE; - (void)stopPollingSourceWithId:(NSString *)identifier NS_EXTENSION_UNAVAILABLE("Source polling is not available in extensions") DEPRECATED_ATTRIBUTE;
@ -256,23 +291,23 @@ static NSString *const STPSDKVersion = @"11.0.0";
@interface Stripe (STPURLCallbackHandlerAdditions) @interface Stripe (STPURLCallbackHandlerAdditions)
/** /**
* Call this method in your app delegate whenever you receive an URL in your Call this method in your app delegate whenever you receive an URL in your
* app delegate for a Stripe callback. app delegate for a Stripe callback.
*
* For convenience, you can pass all URL's you receive in your app delegate For convenience, you can pass all URL's you receive in your app delegate
* to this method first, and check the return value to this method first, and check the return value
* to easily determine whether it is a callback URL that Stripe will handle to easily determine whether it is a callback URL that Stripe will handle
* or if your app should process it normally. or if your app should process it normally.
*
* If you are using a universal link URL, you will receive the callback in `application:continueUserActivity:restorationHandler:` If you are using a universal link URL, you will receive the callback in `application:continueUserActivity:restorationHandler:`
* To learn more about universal links, see https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html To learn more about universal links, see https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html
*
* If you are using a native scheme URL, you will receive the callback in `application:openURL:options:` If you are using a native scheme URL, you will receive the callback in `application:openURL:options:`
* To learn more about native url schemes, see https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW10 To learn more about native url schemes, see https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW10
*
* @param url The URL that you received in your app delegate @param url The URL that you received in your app delegate
*
* @return YES if the URL is expected and will be handled by Stripe. NO otherwise. @return YES if the URL is expected and will be handled by Stripe. NO otherwise.
*/ */
+ (BOOL)handleStripeURLCallbackWithURL:(NSURL *)url; + (BOOL)handleStripeURLCallbackWithURL:(NSURL *)url;

View File

@ -8,8 +8,8 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "STPAPIResponseDecodable.h"
#import "STPBankAccountParams.h" #import "STPBankAccountParams.h"
#import "STPAPIResponseDecodable.h"
typedef NS_ENUM(NSInteger, STPBankAccountStatus) { typedef NS_ENUM(NSInteger, STPBankAccountStatus) {
STPBankAccountStatusNew, STPBankAccountStatusNew,
@ -19,7 +19,9 @@ typedef NS_ENUM(NSInteger, STPBankAccountStatus) {
}; };
/** /**
* Representation of a user's bank account details that have been tokenized with the Stripe API. @see https://stripe.com/docs/api#cards * Representation of a user's bank account details that have been tokenized with the Stripe API
*
* @see https://stripe.com/docs/api#bank_accounts
*/ */
@interface STPBankAccount : STPBankAccountParams<STPAPIResponseDecodable> @interface STPBankAccount : STPBankAccountParams<STPAPIResponseDecodable>

View File

@ -7,6 +7,7 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "STPFormEncodable.h" #import "STPFormEncodable.h"
typedef NS_ENUM(NSInteger, STPBankAccountHolderType) { typedef NS_ENUM(NSInteger, STPBankAccountHolderType) {
@ -16,7 +17,9 @@ typedef NS_ENUM(NSInteger, STPBankAccountHolderType) {
/** /**
* Representation of a user's bank account details. You can assemble these with information that your user enters and * Representation of a user's bank account details. You can assemble these with information that your user enters and
* then create Stripe tokens with them using an STPAPIClient. @see https://stripe.com/docs/api#create_bank_account_token * then create Stripe tokens with them using an STPAPIClient.
*
* @see https://stripe.com/docs/api#create_bank_account_token
*/ */
@interface STPBankAccountParams : NSObject<STPFormEncodable> @interface STPBankAccountParams : NSObject<STPFormEncodable>

View File

@ -27,7 +27,9 @@ typedef NS_ENUM(NSInteger, STPCardFundingType) {
}; };
/** /**
* Representation of a user's credit card details that have been tokenized with the Stripe API. @see https://stripe.com/docs/api#cards * Representation of a user's credit card details that have been tokenized with the Stripe API
*
* @see https://stripe.com/docs/api#cards
*/ */
@interface STPCard : STPCardParams<STPAPIResponseDecodable, STPPaymentMethod, STPSourceProtocol> @interface STPCard : STPCardParams<STPAPIResponseDecodable, STPPaymentMethod, STPSourceProtocol>

View File

@ -7,6 +7,7 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "STPFormEncodable.h" #import "STPFormEncodable.h"
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
#import "STPAddress.h" #import "STPAddress.h"
@ -14,7 +15,9 @@
/** /**
* Representation of a user's credit card details. You can assemble these with information that your user enters and * Representation of a user's credit card details. You can assemble these with information that your user enters and
* then create Stripe tokens with them using an STPAPIClient. @see https://stripe.com/docs/api#cards * then create Stripe tokens with them using an STPAPIClient.
*
* @see https://stripe.com/docs/api#cards
*/ */
@interface STPCardParams : NSObject<STPFormEncodable> @interface STPCardParams : NSObject<STPFormEncodable>

View File

@ -55,7 +55,7 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
* The customer's shipping address. * The customer's shipping address.
*/ */
@property(nonatomic, readonly) STPAddress *shippingAddress; @property(nonatomic, readonly, nullable) STPAddress *shippingAddress;
@end @end

View File

@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
@protocol STPEphemeralKeyProvider; @protocol STPEphemeralKeyProvider;
@class STPEphemeralKey, STPEphemeralKeyManager; @class STPEphemeralKey, STPEphemeralKeyManager;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
/** /**
An `STPCustomerContext` retrieves and updates a Stripe customer using An `STPCustomerContext` retrieves and updates a Stripe customer using
an ephemeral key, a short-lived API key scoped to a specific customer object. an ephemeral key, a short-lived API key scoped to a specific customer object.
@ -23,8 +25,6 @@ NS_ASSUME_NONNULL_BEGIN
instance's cached customer. On your backend, be sure to create and return a instance's cached customer. On your backend, be sure to create and return a
new ephemeral key for the Customer object associated with the new user. new ephemeral key for the Customer object associated with the new user.
*/ */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
@interface STPCustomerContext : NSObject <STPBackendAPIAdapter> @interface STPCustomerContext : NSObject <STPBackendAPIAdapter>
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -7,6 +7,7 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
/** /**
@ -34,4 +35,5 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readwrite, copy)NSDictionary *additionalAPIParameters; @property(nonatomic, readwrite, copy)NSDictionary *additionalAPIParameters;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -123,6 +123,11 @@ IB_DESIGNABLE
*/ */
@property(nonatomic, assign) UIKeyboardAppearance keyboardAppearance UI_APPEARANCE_SELECTOR; @property(nonatomic, assign) UIKeyboardAppearance keyboardAppearance UI_APPEARANCE_SELECTOR;
/**
This behaves identically to setting the inputView for each child text field.
*/
@property(nonatomic, strong, nullable) UIView *inputView;
/** /**
This behaves identically to setting the inputAccessoryView for each child text field. This behaves identically to setting the inputAccessoryView for each child text field.
*/ */

View File

@ -25,51 +25,88 @@ NS_ASSUME_NONNULL_BEGIN
@interface STPPaymentConfiguration : NSObject<NSCopying> @interface STPPaymentConfiguration : NSObject<NSCopying>
/** /**
This is a convenience singleton configuration that uses the default values This is a convenience singleton configuration that uses the default values for
for every property every property
*/ */
+ (instancetype)sharedConfiguration; + (instancetype)sharedConfiguration;
/** /**
* Your Stripe publishable key. You can get this from https://dashboard.stripe.com/account/apikeys . Your Stripe publishable key
@see https://dashboard.stripe.com/account/apikeys
*/ */
@property(nonatomic, copy)NSString *publishableKey; @property (nonatomic, copy, readwrite) NSString *publishableKey;
/** /**
* An enum value representing which payment methods you will accept from your user in addition to credit cards. Unless you have a very specific reason not to, you should leave this at the default, `STPPaymentMethodTypeAll`. An enum value representing which payment methods you will accept from your user
in addition to credit cards. Unless you have a very specific reason not to, you
should leave this at the default, `STPPaymentMethodTypeAll`.
*/ */
@property(nonatomic)STPPaymentMethodType additionalPaymentMethods; @property (nonatomic, assign, readwrite) STPPaymentMethodType additionalPaymentMethods;
/** /**
* The billing address fields the user must fill out when prompted for their payment details. These fields will all be present on the returned token from Stripe. See https://stripe.com/docs/api#create_card_token for more information. The billing address fields the user must fill out when prompted for their
payment details. These fields will all be present on the returned token from
Stripe.
@see https://stripe.com/docs/api#create_card_token
*/ */
@property(nonatomic)STPBillingAddressFields requiredBillingAddressFields; @property (nonatomic, assign, readwrite) STPBillingAddressFields requiredBillingAddressFields;
/** /**
* The shipping address fields the user must fill out when prompted for their shipping info. The shipping address fields the user must fill out when prompted for their
shipping info.
*/ */
@property(nonatomic)PKAddressField requiredShippingAddressFields; @property (nonatomic, assign, readwrite) PKAddressField requiredShippingAddressFields;
/** /**
* Whether the user should be prompted to verify prefilled shipping information. Whether the user should be prompted to verify prefilled shipping information.
* The default value is YES.
The default value is YES.
*/ */
@property(nonatomic)BOOL verifyPrefilledShippingAddress; @property (nonatomic, assign, readwrite) BOOL verifyPrefilledShippingAddress;
/** /**
* The type of shipping for this purchase. This property sets the labels displayed when the user is prompted for shipping info, and whether they should also be asked to select a shipping method. The default value is STPShippingTypeShipping. The type of shipping for this purchase. This property sets the labels displayed
when the user is prompted for shipping info, and whether they should also be
asked to select a shipping method.
The default value is STPShippingTypeShipping.
*/ */
@property(nonatomic)STPShippingType shippingType; @property (nonatomic, assign, readwrite) STPShippingType shippingType;
/** /**
* The name of your company, for displaying to the user during payment flows. For example, when using Apple Pay, the payment sheet's final line item will read "PAY {companyName}". This defaults to the name of your iOS application. The name of your company, for displaying to the user during payment flows. For
example, when using Apple Pay, the payment sheet's final line item will read
"PAY {companyName}".
The default value is the name of your iOS application which is derived from the
`kCFBundleNameKey` of `[NSBundle mainBundle]`.
*/ */
@property(nonatomic, copy)NSString *companyName; @property (nonatomic, copy, readwrite) NSString *companyName;
/** /**
* The Apple Merchant Identifier to use during Apple Pay transactions. To create one of these, see our guide at https://stripe.com/docs/mobile/apple-pay . You must set this to a valid identifier in order to automatically enable Apple Pay. The Apple Merchant Identifier to use during Apple Pay transactions. To create
one of these, see our guide at https://stripe.com/docs/mobile/apple-pay . You
must set this to a valid identifier in order to automatically enable Apple Pay.
*/ */
@property(nonatomic, nullable, copy)NSString *appleMerchantIdentifier; @property (nonatomic, copy, nullable, readwrite) NSString *appleMerchantIdentifier;
/**
Determines whether or not the user is able to delete payment methods
This is only relevant to the `STPPaymentMethodsViewController` which, if
enabled, will allow the user to delete payment methods by tapping the "Edit"
button in the navigation bar or by swiping left on a payment method and tapping
"Delete". Currently, the user is not allowed to delete the selected payment
method but this may change in the future.
Default value is YES but will only work if `STPPaymentMethodsViewController` is
initialized with a `STPCustomerContext` either through the `STPPaymentContext`
or directly as an init parameter.
*/
@property (nonatomic, assign, readwrite) BOOL canDeletePaymentMethods;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -7,6 +7,7 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "STPAPIResponseDecodable.h" #import "STPAPIResponseDecodable.h"
@class STPAddress; @class STPAddress;

View File

@ -22,14 +22,22 @@ STP_ERROR_ENUM(NSInteger, STPErrorCode, StripeDomain) {
#else #else
typedef NS_ENUM(NSInteger, STPErrorCode) { typedef NS_ENUM(NSInteger, STPErrorCode) {
#endif #endif
STPConnectionError = 40, // Trouble connecting to Stripe. // Trouble connecting to Stripe.
STPInvalidRequestError = 50, // Your request had invalid parameters. STPConnectionError = 40,
STPAPIError = 60, // General-purpose API error. // Your request had invalid parameters.
STPCardError = 70, // Something was wrong with the given card details. STPInvalidRequestError = 50,
STPCancellationError = 80, // The operation was cancelled. // General-purpose API error.
STPCheckoutUnknownError = 5000, // Checkout failed STPAPIError = 60,
STPCheckoutTooManyAttemptsError = 5001, // Too many incorrect code attempts // Something was wrong with the given card details.
STPCustomerContextMissingKeyProviderError = 30000, // STPCustomerContext is missing a key provider. STPCardError = 70,
// The operation was cancelled.
STPCancellationError = 80,
/**
The ephemeral key could not be decoded. Make sure your backend is sending
the unmodified JSON of the ephemeral key to your app.
https://stripe.com/docs/mobile/ios/standard#prepare-your-api
*/
STPEphemeralKeyDecodingError = 1000,
}; };
#pragma mark userInfo keys #pragma mark userInfo keys
@ -80,8 +88,6 @@ FOUNDATION_EXPORT STPCardErrorCode __nonnull const STPIncorrectCVC;
+ (nullable NSError *)stp_errorFromStripeResponse:(nullable NSDictionary *)jsonDictionary; + (nullable NSError *)stp_errorFromStripeResponse:(nullable NSDictionary *)jsonDictionary;
+ (nonnull NSError *)stp_genericConnectionError; + (nonnull NSError *)stp_genericConnectionError;
+ (nonnull NSError *)stp_genericFailedToParseResponseError; + (nonnull NSError *)stp_genericFailedToParseResponseError;
- (BOOL)stp_isUnknownCheckoutError;
- (BOOL)stp_isURLSessionCancellationError;
#pragma mark Strings #pragma mark Strings

View File

@ -11,49 +11,68 @@
#import "STPAPIClient.h" #import "STPAPIClient.h"
#import "STPAPIRequest.h" #import "STPAPIRequest.h"
NS_ASSUME_NONNULL_BEGIN
@class STPEphemeralKey; @class STPEphemeralKey;
@interface STPAPIClient() NS_ASSUME_NONNULL_BEGIN
@interface STPAPIClient ()
+ (NSString *)apiVersion; + (NSString *)apiVersion;
- (instancetype)initWithPublishableKey:(NSString *)publishableKey
baseURL:(NSString *)baseURL;
- (void)createTokenWithParameters:(NSDictionary *)parameters - (void)createTokenWithParameters:(NSDictionary *)parameters
completion:(STPTokenCompletionBlock)completion; completion:(STPTokenCompletionBlock)completion;
- (NSURLSessionDataTask *)retrieveSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret responseCompletion:(STPAPIResponseBlock)completion;
@property (nonatomic, readwrite) NSURL *apiURL; @property (nonatomic, strong, readwrite) NSURL *apiURL;
@property (nonatomic, readwrite) NSURLSession *urlSession; @property (nonatomic, strong, readwrite) NSURLSession *urlSession;
@end
@interface STPAPIClient (SourcesPrivate)
- (NSURLSessionDataTask *)retrieveSourceWithId:(NSString *)identifier
clientSecret:(NSString *)secret
responseCompletion:(STPAPIResponseBlock)completion;
@end @end
@interface STPAPIClient (Customers) @interface STPAPIClient (Customers)
/** /**
https://stripe.com/docs/api#retrieve_customer Retrieve a customer
@see https://stripe.com/docs/api#retrieve_customer
*/ */
+ (void)retrieveCustomerUsingKey:(STPEphemeralKey *)ephemeralKey + (void)retrieveCustomerUsingKey:(STPEphemeralKey *)ephemeralKey
completion:(STPCustomerCompletionBlock)completion; completion:(STPCustomerCompletionBlock)completion;
/** /**
https://stripe.com/docs/api#create_card Add a source to a customer
@see https://stripe.com/docs/api#create_card
*/ */
+ (void)addSource:(NSString *)sourceID + (void)addSource:(NSString *)sourceID
toCustomerUsingKey:(STPEphemeralKey *)ephemeralKey toCustomerUsingKey:(STPEphemeralKey *)ephemeralKey
completion:(STPSourceProtocolCompletionBlock)completion; completion:(STPSourceProtocolCompletionBlock)completion;
/** /**
https://stripe.com/docs/api#update_customer Update a customer with parameters
@see https://stripe.com/docs/api#update_customer
*/ */
+ (void)updateCustomerWithParameters:(NSDictionary *)parameters + (void)updateCustomerWithParameters:(NSDictionary *)parameters
usingKey:(STPEphemeralKey *)ephemeralKey usingKey:(STPEphemeralKey *)ephemeralKey
completion:(STPCustomerCompletionBlock)completion; completion:(STPCustomerCompletionBlock)completion;
/**
Delete a source from a customer
@see https://stripe.com/docs/api#delete_card
*/
+ (void)deleteSource:(NSString *)sourceID
fromCustomerUsingKey:(STPEphemeralKey *)ephemeralKey
completion:(STPSourceProtocolCompletionBlock)completion;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -9,9 +9,11 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <sys/utsname.h> #import <sys/utsname.h>
#import "NSBundle+Stripe_AppName.h"
#import "STPAPIClient+ApplePay.h"
#import "STPAPIClient.h" #import "STPAPIClient.h"
#import "STPAPIClient+ApplePay.h"
#import "STPAPIClient+Private.h"
#import "NSBundle+Stripe_AppName.h"
#import "STPAPIRequest.h" #import "STPAPIRequest.h"
#import "STPAnalyticsClient.h" #import "STPAnalyticsClient.h"
#import "STPBankAccount.h" #import "STPBankAccount.h"
@ -44,13 +46,14 @@
#define FAUXPAS_IGNORED_IN_METHOD(...) #define FAUXPAS_IGNORED_IN_METHOD(...)
FAUXPAS_IGNORED_IN_FILE(APIAvailability) FAUXPAS_IGNORED_IN_FILE(APIAvailability)
static NSString *const apiURLBase = @"api.stripe.com/v1"; static NSString * const APIVersion = @"2015-10-12";
static NSString *const tokenEndpoint = @"tokens"; static NSString * const APIBaseURL = @"https://api.stripe.com/v1";
static NSString *const sourcesEndpoint = @"sources"; static NSString * const APIEndpointToken = @"tokens";
static NSString *const customersEndpoint = @"customers"; static NSString * const APIEndpointSources = @"sources";
static NSString *const fileUploadPath = @"https://uploads.stripe.com/v1/files"; static NSString * const APIEndpointCustomers = @"customers";
static NSString *const stripeAPIVersion = @"2015-10-12"; static NSString * const FileUploadURL = @"https://uploads.stripe.com/v1/files";
#pragma mark - Stripe
@implementation Stripe @implementation Stripe
@ -64,21 +67,26 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
@end @end
#pragma mark - STPAPIClient
#if __has_include("Fabric.h") #if __has_include("Fabric.h")
@interface STPAPIClient ()<FABKit> @interface STPAPIClient ()<FABKit>
#else #else
@interface STPAPIClient() @interface STPAPIClient()
#endif #endif
@property (nonatomic, readwrite) NSURL *apiURL;
@property (nonatomic, readwrite) NSURLSession *urlSession; @property (nonatomic, strong, readwrite) NSMutableDictionary<NSString *,NSObject *> *sourcePollers;
@property (nonatomic, readwrite) NSMutableDictionary<NSString *,NSObject *>*sourcePollers; @property (nonatomic, strong, readwrite) dispatch_queue_t sourcePollersQueue;
@property (nonatomic, readwrite) dispatch_queue_t sourcePollersQueue; @property (nonatomic, strong, readwrite) NSString *apiKey;
// See STPAPIClient+Private.h
@end @end
@implementation STPAPIClient @implementation STPAPIClient
+ (NSString *)apiVersion { + (NSString *)apiVersion {
return stripeAPIVersion; return APIVersion;
} }
+ (void)initialize { + (void)initialize {
@ -113,33 +121,32 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
} }
self = [super init]; self = [super init];
if (self) { if (self) {
_apiURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", apiURLBase]]; _apiKey = publishableKey;
_apiURL = [NSURL URLWithString:APIBaseURL];
_urlSession = [NSURLSession sessionWithConfiguration:[self sessionConfiguration]];
_configuration = configuration; _configuration = configuration;
_sourcePollers = [NSMutableDictionary dictionary]; _sourcePollers = [NSMutableDictionary dictionary];
_sourcePollersQueue = dispatch_queue_create("com.stripe.sourcepollers", DISPATCH_QUEUE_SERIAL); _sourcePollersQueue = dispatch_queue_create("com.stripe.sourcepollers", DISPATCH_QUEUE_SERIAL);
self.apiKey = publishableKey;
} }
return self; return self;
} }
- (instancetype)initWithPublishableKey:(NSString *)publishableKey - (NSURLSessionConfiguration *)sessionConfiguration {
baseURL:(NSString *)baseURL { NSMutableDictionary *additionalHeaders = [NSMutableDictionary new];
self = [self initWithPublishableKey:publishableKey]; additionalHeaders[@"X-Stripe-User-Agent"] = [self.class stripeUserAgentDetails];
if (self) { additionalHeaders[@"Stripe-Version"] = APIVersion;
_apiURL = [NSURL URLWithString:baseURL]; additionalHeaders[@"Authorization"] = [@"Bearer " stringByAppendingString:self.apiKey ?: @""];
} additionalHeaders[@"Stripe-Account"] = self.stripeAccount;
return self; NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = additionalHeaders;
return sessionConfiguration;
} }
- (void)setApiKey:(NSString *)apiKey { - (void)setApiKey:(NSString *)apiKey {
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; _apiKey = apiKey;
NSString *auth = [@"Bearer " stringByAppendingString:apiKey ?: @""];
sessionConfiguration.HTTPAdditionalHeaders = @{ // Regenerate url session configuration
@"X-Stripe-User-Agent": [self.class stripeUserAgentDetails], self.urlSession = [NSURLSession sessionWithConfiguration:[self sessionConfiguration]];
@"Stripe-Version": stripeAPIVersion,
@"Authorization": auth,
};
self.urlSession = [NSURLSession sessionWithConfiguration:sessionConfiguration];
} }
- (void)setPublishableKey:(NSString *)publishableKey { - (void)setPublishableKey:(NSString *)publishableKey {
@ -151,26 +158,30 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
return self.configuration.publishableKey; return self.configuration.publishableKey;
} }
- (void)setStripeAccount:(NSString *)stripeAccount {
_stripeAccount = stripeAccount;
// Regenerate url session configuration
self.urlSession = [NSURLSession sessionWithConfiguration:[self sessionConfiguration]];
}
- (void)createTokenWithParameters:(NSDictionary *)parameters - (void)createTokenWithParameters:(NSDictionary *)parameters
completion:(STPTokenCompletionBlock)completion { completion:(STPTokenCompletionBlock)completion {
NSCAssert(parameters != nil, @"'parameters' is required to create a token"); NSCAssert(parameters != nil, @"'parameters' is required to create a token");
NSCAssert(completion != nil, @"'completion' is required to use the token that is created"); NSCAssert(completion != nil, @"'completion' is required to use the token that is created");
NSDate *start = [NSDate date];
NSString *tokenType = [STPAnalyticsClient tokenTypeFromParameters:parameters]; NSString *tokenType = [STPAnalyticsClient tokenTypeFromParameters:parameters];
[[STPAnalyticsClient sharedClient] logTokenCreationAttemptWithConfiguration:self.configuration [[STPAnalyticsClient sharedClient] logTokenCreationAttemptWithConfiguration:self.configuration
tokenType:tokenType]; tokenType:tokenType];
[STPAPIRequest<STPToken *> postWithAPIClient:self [STPAPIRequest<STPToken *> postWithAPIClient:self
endpoint:tokenEndpoint endpoint:APIEndpointToken
parameters:parameters parameters:parameters
deserializer:[STPToken new] deserializer:[STPToken new]
completion:^(STPToken *object, NSHTTPURLResponse *response, NSError *error) { completion:^(STPToken *object, __unused NSHTTPURLResponse *response, NSError *error) {
NSDate *end = [NSDate date];
[[STPAnalyticsClient sharedClient] logRUMWithToken:object configuration:self.configuration response:response start:start end:end];
completion(object, error); completion(object, error);
}]; }];
} }
#pragma mark - private helpers #pragma mark Helpers
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunused-variable"
@ -192,8 +203,6 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop
#pragma mark Utility methods -
+ (NSString *)stripeUserAgentDetails { + (NSString *)stripeUserAgentDetails {
NSMutableDictionary *details = [@{ NSMutableDictionary *details = [@{
@"lang": @"objective-c", @"lang": @"objective-c",
@ -223,6 +232,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
} }
#pragma mark Fabric #pragma mark Fabric
#if __has_include("Fabric.h") #if __has_include("Fabric.h")
+ (NSString *)bundleIdentifier { + (NSString *)bundleIdentifier {
@ -255,6 +265,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
@end @end
#pragma mark - Bank Accounts #pragma mark - Bank Accounts
@implementation STPAPIClient (BankAccounts) @implementation STPAPIClient (BankAccounts)
- (void)createTokenWithBankAccount:(STPBankAccountParams *)bankAccount - (void)createTokenWithBankAccount:(STPBankAccountParams *)bankAccount
@ -268,6 +279,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
@end @end
#pragma mark - Personally Identifiable Information #pragma mark - Personally Identifiable Information
@implementation STPAPIClient (PII) @implementation STPAPIClient (PII)
- (void)createTokenWithPersonalIDNumber:(NSString *)pii completion:(__nullable STPTokenCompletionBlock)completion { - (void)createTokenWithPersonalIDNumber:(NSString *)pii completion:(__nullable STPTokenCompletionBlock)completion {
@ -279,6 +291,8 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
@end @end
#pragma mark - Upload
@implementation STPAPIClient (Upload) @implementation STPAPIClient (Upload)
- (NSData *)dataForUploadedImage:(UIImage *)image - (NSData *)dataForUploadedImage:(UIImage *)image
@ -318,7 +332,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
NSString *boundary = [STPMultipartFormDataEncoder generateBoundary]; NSString *boundary = [STPMultipartFormDataEncoder generateBoundary];
NSData *data = [STPMultipartFormDataEncoder multipartFormDataForParts:@[purposePart, imagePart] boundary:boundary]; NSData *data = [STPMultipartFormDataEncoder multipartFormDataForParts:@[purposePart, imagePart] boundary:boundary];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:fileUploadPath]]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:FileUploadURL]];
[request setHTTPMethod:@"POST"]; [request setHTTPMethod:@"POST"];
[request stp_setMultipartFormData:data boundary:boundary]; [request stp_setMultipartFormData:data boundary:boundary];
@ -348,6 +362,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
@end @end
#pragma mark - Credit Cards #pragma mark - Credit Cards
@implementation STPAPIClient (CreditCards) @implementation STPAPIClient (CreditCards)
- (void)createTokenWithCard:(STPCard *)card completion:(STPTokenCompletionBlock)completion { - (void)createTokenWithCard:(STPCard *)card completion:(STPTokenCompletionBlock)completion {
@ -359,6 +374,8 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
@end @end
#pragma mark - Apple Pay
@implementation Stripe (ApplePay) @implementation Stripe (ApplePay)
+ (BOOL)canSubmitPaymentRequest:(PKPaymentRequest *)paymentRequest { + (BOOL)canSubmitPaymentRequest:(PKPaymentRequest *)paymentRequest {
@ -418,7 +435,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
NSMutableDictionary *params = [[STPFormEncoder dictionaryForObject:sourceParams] mutableCopy]; NSMutableDictionary *params = [[STPFormEncoder dictionaryForObject:sourceParams] mutableCopy];
[[STPTelemetryClient sharedInstance] addTelemetryFieldsToParams:params]; [[STPTelemetryClient sharedInstance] addTelemetryFieldsToParams:params];
[STPAPIRequest<STPSource *> postWithAPIClient:self [STPAPIRequest<STPSource *> postWithAPIClient:self
endpoint:sourcesEndpoint endpoint:APIEndpointSources
parameters:params parameters:params
deserializer:[STPSource new] deserializer:[STPSource new]
completion:^(STPSource *object, __unused NSHTTPURLResponse *response, NSError *error) { completion:^(STPSource *object, __unused NSHTTPURLResponse *response, NSError *error) {
@ -437,7 +454,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
} }
- (NSURLSessionDataTask *)retrieveSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret responseCompletion:(STPAPIResponseBlock)completion { - (NSURLSessionDataTask *)retrieveSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret responseCompletion:(STPAPIResponseBlock)completion {
NSString *endpoint = [NSString stringWithFormat:@"%@/%@", sourcesEndpoint, identifier]; NSString *endpoint = [NSString stringWithFormat:@"%@/%@", APIEndpointSources, identifier];
NSDictionary *parameters = @{@"client_secret": secret}; NSDictionary *parameters = @{@"client_secret": secret};
return [STPAPIRequest<STPSource *> getWithAPIClient:self return [STPAPIRequest<STPSource *> getWithAPIClient:self
endpoint:endpoint endpoint:endpoint
@ -482,7 +499,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
+ (void)retrieveCustomerUsingKey:(STPEphemeralKey *)ephemeralKey completion:(STPCustomerCompletionBlock)completion { + (void)retrieveCustomerUsingKey:(STPEphemeralKey *)ephemeralKey completion:(STPCustomerCompletionBlock)completion {
STPAPIClient *client = [self apiClientWithEphemeralKey:ephemeralKey]; STPAPIClient *client = [self apiClientWithEphemeralKey:ephemeralKey];
NSString *endpoint = [NSString stringWithFormat:@"%@/%@", customersEndpoint, ephemeralKey.customerID]; NSString *endpoint = [NSString stringWithFormat:@"%@/%@", APIEndpointCustomers, ephemeralKey.customerID];
[STPAPIRequest<STPCustomer *> getWithAPIClient:client [STPAPIRequest<STPCustomer *> getWithAPIClient:client
endpoint:endpoint endpoint:endpoint
parameters:nil parameters:nil
@ -496,7 +513,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
usingKey:(STPEphemeralKey *)ephemeralKey usingKey:(STPEphemeralKey *)ephemeralKey
completion:(STPCustomerCompletionBlock)completion { completion:(STPCustomerCompletionBlock)completion {
STPAPIClient *client = [self apiClientWithEphemeralKey:ephemeralKey]; STPAPIClient *client = [self apiClientWithEphemeralKey:ephemeralKey];
NSString *endpoint = [NSString stringWithFormat:@"%@/%@", customersEndpoint, ephemeralKey.customerID]; NSString *endpoint = [NSString stringWithFormat:@"%@/%@", APIEndpointCustomers, ephemeralKey.customerID];
[STPAPIRequest<STPCustomer *> postWithAPIClient:client [STPAPIRequest<STPCustomer *> postWithAPIClient:client
endpoint:endpoint endpoint:endpoint
parameters:parameters parameters:parameters
@ -510,7 +527,7 @@ static NSString *const stripeAPIVersion = @"2015-10-12";
toCustomerUsingKey:(STPEphemeralKey *)ephemeralKey toCustomerUsingKey:(STPEphemeralKey *)ephemeralKey
completion:(STPSourceProtocolCompletionBlock)completion { completion:(STPSourceProtocolCompletionBlock)completion {
STPAPIClient *client = [self apiClientWithEphemeralKey:ephemeralKey]; STPAPIClient *client = [self apiClientWithEphemeralKey:ephemeralKey];
NSString *endpoint = [NSString stringWithFormat:@"%@/%@/%@", customersEndpoint, ephemeralKey.customerID, sourcesEndpoint]; NSString *endpoint = [NSString stringWithFormat:@"%@/%@/%@", APIEndpointCustomers, ephemeralKey.customerID, APIEndpointSources];
[STPAPIRequest<STPSourceProtocol> postWithAPIClient:client [STPAPIRequest<STPSourceProtocol> postWithAPIClient:client
endpoint:endpoint endpoint:endpoint
parameters:@{@"source": sourceID} parameters:@{@"source": sourceID}
@ -520,4 +537,16 @@ toCustomerUsingKey:(STPEphemeralKey *)ephemeralKey
}]; }];
} }
+ (void)deleteSource:(NSString *)sourceID fromCustomerUsingKey:(STPEphemeralKey *)ephemeralKey completion:(STPSourceProtocolCompletionBlock)completion {
STPAPIClient *client = [self apiClientWithEphemeralKey:ephemeralKey];
NSString *endpoint = [NSString stringWithFormat:@"%@/%@/%@/%@", APIEndpointCustomers, ephemeralKey.customerID, APIEndpointSources, sourceID];
[STPAPIRequest<STPSourceProtocol> deleteWithAPIClient:client
endpoint:endpoint
parameters:nil
deserializers:@[[STPCard new], [STPSource new]]
completion:^(id object, __unused NSHTTPURLResponse *response, NSError *error) {
completion(object, error);
}];
}
@end @end

View File

@ -8,6 +8,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "STPAPIResponseDecodable.h" #import "STPAPIResponseDecodable.h"
@class STPAPIClient; @class STPAPIClient;
@interface STPAPIRequest<__covariant ResponseType:id<STPAPIResponseDecodable>> : NSObject @interface STPAPIRequest<__covariant ResponseType:id<STPAPIResponseDecodable>> : NSObject
@ -23,19 +24,25 @@ typedef void(^STPAPIResponseBlock)(ResponseType object, NSHTTPURLResponse *respo
+ (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient + (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint endpoint:(NSString *)endpoint
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
deserializers:(NSArray<ResponseType>*)deserializers deserializers:(NSArray<ResponseType> *)deserializers
completion:(STPAPIResponseBlock)completion; completion:(STPAPIResponseBlock)completion;
+ (NSURLSessionDataTask *)getWithAPIClient:(STPAPIClient *)apiClient + (NSURLSessionDataTask *)getWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint endpoint:(NSString *)endpoint
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
deserializer:(id<STPAPIResponseDecodable>)deserializer deserializer:(ResponseType)deserializer
completion:(STPAPIResponseBlock)completion; completion:(STPAPIResponseBlock)completion;
+ (void)parseResponse:(NSURLResponse *)response + (NSURLSessionDataTask *)deleteWithAPIClient:(STPAPIClient *)apiClient
body:(NSData *)body endpoint:(NSString *)endpoint
error:(NSError *)error parameters:(NSDictionary *)parameters
deserializers:(NSArray<id<STPAPIResponseDecodable>>*)deserializers deserializer:(ResponseType)deserializer
completion:(STPAPIResponseBlock)completion; completion:(STPAPIResponseBlock)completion;
+ (NSURLSessionDataTask *)deleteWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint
parameters:(NSDictionary *)parameters
deserializers:(NSArray<ResponseType> *)deserializer
completion:(STPAPIResponseBlock)completion;
@end @end

View File

@ -9,27 +9,28 @@
#import "STPAPIRequest.h" #import "STPAPIRequest.h"
#import "NSMutableURLRequest+Stripe.h" #import "NSMutableURLRequest+Stripe.h"
#import "STPInternalAPIResponseDecodable.h"
#import "STPAPIClient+Private.h"
#import "STPAPIClient.h" #import "STPAPIClient.h"
#import "STPCard+Private.h" #import "STPAPIClient+Private.h"
#import "STPDispatchFunctions.h" #import "STPDispatchFunctions.h"
#import "STPFormEncoder.h" #import "STPInternalAPIResponseDecodable.h"
#import "STPSource+Private.h"
#import "StripeError.h" #import "StripeError.h"
@implementation STPAPIRequest @implementation STPAPIRequest
static NSString * const HTTPMethodPOST = @"POST";
static NSString * const HTTPMethodGET = @"GET";
static NSString * const HTTPMethodDELETE = @"DELETE";
static NSString * const JSONKeyObject = @"object";
#pragma mark - POST
+ (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient + (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint endpoint:(NSString *)endpoint
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
deserializer:(id<STPAPIResponseDecodable>)deserializer deserializer:(id<STPAPIResponseDecodable>)deserializer
completion:(STPAPIResponseBlock)completion { completion:(STPAPIResponseBlock)completion {
return [self postWithAPIClient:apiClient return [self postWithAPIClient:apiClient endpoint:endpoint parameters:parameters deserializers:@[deserializer] completion:completion];
endpoint:endpoint
parameters:parameters
deserializers:@[deserializer]
completion:completion];
} }
+ (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient + (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient
@ -37,92 +38,154 @@
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
deserializers:(NSArray<id<STPAPIResponseDecodable>>*)deserializers deserializers:(NSArray<id<STPAPIResponseDecodable>>*)deserializers
completion:(STPAPIResponseBlock)completion { completion:(STPAPIResponseBlock)completion {
// Build url
NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint]; NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = @"POST";
NSString *query = [STPFormEncoder queryStringFromParameters:parameters];
request.HTTPBody = [query dataUsingEncoding:NSUTF8StringEncoding];
NSURLSessionDataTask *task = [apiClient.urlSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable body, NSURLResponse * _Nullable response, NSError * _Nullable error) { // Setup request
[[self class] parseResponse:response NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
body:body request.HTTPMethod = HTTPMethodPOST;
error:error [request stp_setFormPayload:parameters];
deserializers:deserializers
completion:completion]; // Perform request
NSURLSessionDataTask *task = [apiClient.urlSession dataTaskWithRequest:request completionHandler:^(NSData *body, NSURLResponse *response, NSError *error) {
[[self class] parseResponse:response body:body error:error deserializers:deserializers completion:completion];
}]; }];
[task resume]; [task resume];
return task; return task;
} }
#pragma mark - GET
+ (NSURLSessionDataTask *)getWithAPIClient:(STPAPIClient *)apiClient + (NSURLSessionDataTask *)getWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint endpoint:(NSString *)endpoint
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
deserializer:(id<STPAPIResponseDecodable>)deserializer deserializer:(id<STPAPIResponseDecodable>)deserializer
completion:(STPAPIResponseBlock)completion { completion:(STPAPIResponseBlock)completion {
// Build url
NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint]; NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint];
// Setup request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request stp_addParametersToURL:parameters]; [request stp_addParametersToURL:parameters];
request.HTTPMethod = @"GET"; request.HTTPMethod = HTTPMethodGET;
NSURLSessionDataTask *task = [apiClient.urlSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable body, NSURLResponse * _Nullable response, NSError * _Nullable error) { // Perform request
[[self class] parseResponse:response NSURLSessionDataTask *task = [apiClient.urlSession dataTaskWithRequest:request completionHandler:^(NSData *body, NSURLResponse *response, NSError *error) {
body:body [[self class] parseResponse:response body:body error:error deserializers:@[deserializer] completion:completion];
error:error
deserializers:@[deserializer]
completion:completion];
}]; }];
[task resume]; [task resume];
return task; return task;
} }
#pragma mark - DELETE
+ (NSURLSessionDataTask *)deleteWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint
parameters:(NSDictionary *)parameters
deserializer:(id<STPAPIResponseDecodable>)deserializer
completion:(STPAPIResponseBlock)completion {
return [self deleteWithAPIClient:apiClient endpoint:endpoint parameters:parameters deserializers:@[deserializer] completion:completion];
}
+ (NSURLSessionDataTask *)deleteWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint
parameters:(NSDictionary *)parameters
deserializers:(NSArray<id<STPAPIResponseDecodable>> *)deserializers
completion:(STPAPIResponseBlock)completion {
// Build url
NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint];
// Setup request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request stp_addParametersToURL:parameters];
request.HTTPMethod = HTTPMethodDELETE;
// Perform request
NSURLSessionDataTask *task = [apiClient.urlSession dataTaskWithRequest:request completionHandler:^(NSData *body, NSURLResponse *response, NSError *error) {
[[self class] parseResponse:response body:body error:error deserializers:deserializers completion:completion];
}];
[task resume];
return task;
}
#pragma mark -
+ (void)parseResponse:(NSURLResponse *)response + (void)parseResponse:(NSURLResponse *)response
body:(NSData *)body body:(NSData *)body
error:(NSError *)error error:(NSError *)error
deserializers:(NSArray<id<STPAPIResponseDecodable>>*)deserializers deserializers:(NSArray<id<STPAPIResponseDecodable>>*)deserializers
completion:(STPAPIResponseBlock)completion { completion:(STPAPIResponseBlock)completion {
id<STPAPIResponseDecodable> responseObject; // Derive HTTP URL response
NSError *returnedError; NSHTTPURLResponse *httpResponse = nil;
NSHTTPURLResponse *httpResponse;
if ([response isKindOfClass:[NSHTTPURLResponse class]]) { if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
httpResponse = (NSHTTPURLResponse *)response; httpResponse = (NSHTTPURLResponse *)response;
} }
if (deserializers.count == 0) { // Wrap completion block with main thread dispatch
returnedError = [NSError stp_genericFailedToParseResponseError]; void (^safeCompletion)(id<STPAPIResponseDecodable>, NSError *) = ^(id<STPAPIResponseDecodable> responseObject, NSError *responseError) {
} else { stpDispatchToMainThreadIfNecessary(^{
NSDictionary *jsonDictionary = body ? [NSJSONSerialization JSONObjectWithData:body options:(NSJSONReadingOptions)kNilOptions error:NULL] : nil; completion(responseObject, httpResponse, responseError);
NSString *object = jsonDictionary[@"object"]; });
Class deserializerClass; };
if (deserializers.count == 1) {
deserializerClass = [deserializers.firstObject class]; if (error) {
} else { // Forward NSURLSession error
for (id<STPAPIResponseDecodable> deserializer in deserializers) { return safeCompletion(nil, error);
if ([deserializer respondsToSelector:@selector(stripeObject)]
&& [[(id<STPInternalAPIResponseDecodable>)deserializer stripeObject] isEqualToString:object]) {
deserializerClass = [deserializer class];
}
}
}
if (!deserializerClass) {
returnedError = [NSError stp_genericFailedToParseResponseError];
} else {
responseObject = [deserializerClass decodedObjectFromAPIResponse:jsonDictionary];
returnedError = [NSError stp_errorFromStripeResponse:jsonDictionary] ?: error;
}
if ((!responseObject || ![response isKindOfClass:[NSHTTPURLResponse class]]) && !returnedError) {
returnedError = [NSError stp_genericFailedToParseResponseError];
}
} }
stpDispatchToMainThreadIfNecessary(^{ if (deserializers.count == 0) {
if (returnedError) { // Missing deserializers
completion(nil, httpResponse, returnedError); return safeCompletion(nil, [NSError stp_genericFailedToParseResponseError]);
} else { }
completion(responseObject, httpResponse, nil);
}
});
// Parse JSON response body
NSDictionary *jsonDictionary = nil;
if (body) {
jsonDictionary = [NSJSONSerialization JSONObjectWithData:body options:(NSJSONReadingOptions)kNilOptions error:NULL];
}
// Determine appropriate deserializer
NSString *objectString = jsonDictionary[JSONKeyObject];
Class deserializerClass = nil;
if (deserializers.count == 1) {
// Some deserializers don't conform to STPInternalAPIResponseDecodable
deserializerClass = [deserializers.firstObject class];
}
else {
for (id<STPAPIResponseDecodable> deserializer in deserializers) {
if ([deserializer respondsToSelector:@selector(stripeObject)]
&& [[(id<STPInternalAPIResponseDecodable>)deserializer stripeObject] isEqualToString:objectString]) {
// Found matching deserializer
deserializerClass = [deserializer class];
}
}
}
if (!deserializerClass) {
// No deserializer for response body
return safeCompletion(nil, [NSError stp_genericFailedToParseResponseError]);
}
// Generate response object
id<STPAPIResponseDecodable> responseObject = [deserializerClass decodedObjectFromAPIResponse:jsonDictionary];
if (!responseObject) {
// Failed to parse response
NSError *parsedError = [NSError stp_errorFromStripeResponse:jsonDictionary];
if (parsedError) {
// Use response body error
return safeCompletion(nil, parsedError);
}
// Use generic error
return safeCompletion(nil, [NSError stp_genericFailedToParseResponseError]);
}
return safeCompletion(responseObject, nil);
} }
@end @end

View File

@ -29,10 +29,4 @@
- (void)logSourceCreationAttemptWithConfiguration:(STPPaymentConfiguration *)configuration - (void)logSourceCreationAttemptWithConfiguration:(STPPaymentConfiguration *)configuration
sourceType:(NSString *)sourceType; sourceType:(NSString *)sourceType;
- (void)logRUMWithToken:(STPToken *)token
configuration:(STPPaymentConfiguration *)config
response:(NSHTTPURLResponse *)response
start:(NSDate *)startTime
end:(NSDate *)endTime;
@end @end

View File

@ -115,10 +115,6 @@
#endif #endif
} }
+ (NSNumber *)timestampWithDate:(NSDate *)date {
return @((NSInteger)([date timeIntervalSince1970]*1000));
}
+ (NSString *)tokenTypeFromParameters:(NSDictionary *)parameters { + (NSString *)tokenTypeFromParameters:(NSDictionary *)parameters {
if ([parameters.allKeys count] == 1) { if ([parameters.allKeys count] == 1) {
NSArray *validTypes = @[@"bank_account", @"card", @"pii"]; NSArray *validTypes = @[@"bank_account", @"card", @"pii"];
@ -215,36 +211,6 @@
[self logPayload:payload]; [self logPayload:payload];
} }
- (void)logRUMWithToken:(STPToken *)token
configuration:(STPPaymentConfiguration *)configuration
response:(NSHTTPURLResponse *)response
start:(NSDate *)startTime
end:(NSDate *)endTime {
NSString *tokenTypeString = @"unknown";
if (token.bankAccount) {
tokenTypeString = @"bank_account";
} else if (token.card) {
if (token.card.isApplePayCard) {
tokenTypeString = @"apple_pay";
} else {
tokenTypeString = @"card";
}
}
NSNumber *start = [[self class] timestampWithDate:startTime];
NSNumber *end = [[self class] timestampWithDate:endTime];
NSMutableDictionary *payload = [self.class commonPayload];
[payload addEntriesFromDictionary:@{
@"event": @"rum.stripeios",
@"tokenType": tokenTypeString,
@"url": response.URL.absoluteString ?: @"unknown",
@"status": @(response.statusCode),
@"publishable_key": configuration.publishableKey ?: @"unknown",
@"start": start,
@"end": end,
}];
[self logPayload:payload];
}
+ (NSMutableDictionary *)commonPayload { + (NSMutableDictionary *)commonPayload {
NSMutableDictionary *payload = [NSMutableDictionary dictionary]; NSMutableDictionary *payload = [NSMutableDictionary dictionary];
payload[@"bindings_version"] = STPSDKVersion; payload[@"bindings_version"] = STPSDKVersion;

View File

@ -12,8 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface STPBankAccount () @interface STPBankAccount ()
+ (STPBankAccountStatus)statusFromString:(NSString *)string; //
+ (NSString *)stringFromStatus:(STPBankAccountStatus)status;
@end @end

View File

@ -21,6 +21,8 @@
@property (nonatomic) STPBankAccountStatus status; @property (nonatomic) STPBankAccountStatus status;
@property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields; @property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields;
// See STPBankAccount+Private.h
@end @end
@implementation STPBankAccount @implementation STPBankAccount
@ -134,15 +136,25 @@
} }
STPBankAccount *bankAccount = [self new]; STPBankAccount *bankAccount = [self new];
// Identifier
bankAccount.bankAccountId = dict[@"id"]; bankAccount.bankAccountId = dict[@"id"];
// Basic account details
bankAccount.routingNumber = dict[@"routing_number"];
bankAccount.last4 = dict[@"last4"]; bankAccount.last4 = dict[@"last4"];
// Additional account details (alphabetical)
bankAccount.bankName = dict[@"bank_name"]; bankAccount.bankName = dict[@"bank_name"];
bankAccount.country = dict[@"country"]; bankAccount.country = dict[@"country"];
bankAccount.fingerprint = dict[@"fingerprint"];
bankAccount.currency = dict[@"currency"]; bankAccount.currency = dict[@"currency"];
bankAccount.fingerprint = dict[@"fingerprint"];
bankAccount.status = [self statusFromString:dict[@"status"]];
// Owner details
bankAccount.accountHolderName = dict[@"account_holder_name"]; bankAccount.accountHolderName = dict[@"account_holder_name"];
bankAccount.accountHolderType = [self accountHolderTypeFromString:dict[@"account_holder_type"]]; bankAccount.accountHolderType = [self accountHolderTypeFromString:dict[@"account_holder_type"]];
bankAccount.status = [self statusFromString:dict[@"status"]];
bankAccount.allResponseFields = dict; bankAccount.allResponseFields = dict;
return bankAccount; return bankAccount;

View File

@ -15,8 +15,6 @@ NS_ASSUME_NONNULL_BEGIN
+ (STPBankAccountHolderType)accountHolderTypeFromString:(NSString *)string; + (STPBankAccountHolderType)accountHolderTypeFromString:(NSString *)string;
+ (NSString *)stringFromAccountHolderType:(STPBankAccountHolderType)accountHolderType; + (NSString *)stringFromAccountHolderType:(STPBankAccountHolderType)accountHolderType;
- (NSString *)accountHolderTypeString;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -13,7 +13,7 @@
@interface STPBankAccountParams () @interface STPBankAccountParams ()
@property (nonatomic, readonly) NSString *accountHolderTypeString; // See STPBankAccountParams+Private.h
@end @end
@ -93,12 +93,12 @@
+ (NSDictionary *)propertyNamesToFormFieldNamesMapping { + (NSDictionary *)propertyNamesToFormFieldNamesMapping {
return @{ return @{
@"accountNumber": @"account_number", NSStringFromSelector(@selector(accountNumber)): @"account_number",
@"routingNumber": @"routing_number", NSStringFromSelector(@selector(routingNumber)): @"routing_number",
@"country": @"country", NSStringFromSelector(@selector(country)): @"country",
@"currency": @"currency", NSStringFromSelector(@selector(currency)): @"currency",
@"accountHolderName": @"account_holder_name", NSStringFromSelector(@selector(accountHolderName)): @"account_holder_name",
@"accountHolderTypeString": @"account_holder_type", NSStringFromSelector(@selector(accountHolderTypeString)): @"account_holder_type",
}; };
} }

View File

@ -13,9 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface STPCard () <STPInternalAPIResponseDecodable> @interface STPCard () <STPInternalAPIResponseDecodable>
+ (STPCardFundingType)fundingFromString:(NSString *)string;
+ (nullable NSString *)stringFromFunding:(STPCardFundingType)funding; + (nullable NSString *)stringFromFunding:(STPCardFundingType)funding;
- (nullable STPAddress *)address;
@end @end

View File

@ -23,6 +23,8 @@
@property (nonatomic, readwrite) NSString *country; @property (nonatomic, readwrite) NSString *country;
@property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields; @property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields;
// See STPCard+Private.h
@end @end
@implementation STPCard @implementation STPCard

View File

@ -85,18 +85,18 @@
+ (NSDictionary *)propertyNamesToFormFieldNamesMapping { + (NSDictionary *)propertyNamesToFormFieldNamesMapping {
return @{ return @{
@"number": @"number", NSStringFromSelector(@selector(number)): @"number",
@"cvc": @"cvc", NSStringFromSelector(@selector(cvc)): @"cvc",
@"name": @"name", NSStringFromSelector(@selector(name)): @"name",
@"addressLine1": @"address_line1", NSStringFromSelector(@selector(addressLine1)): @"address_line1",
@"addressLine2": @"address_line2", NSStringFromSelector(@selector(addressLine2)): @"address_line2",
@"addressCity": @"address_city", NSStringFromSelector(@selector(addressCity)): @"address_city",
@"addressState": @"address_state", NSStringFromSelector(@selector(addressState)): @"address_state",
@"addressZip": @"address_zip", NSStringFromSelector(@selector(addressZip)): @"address_zip",
@"addressCountry": @"address_country", NSStringFromSelector(@selector(addressCountry)): @"address_country",
@"expMonth": @"exp_month", NSStringFromSelector(@selector(expMonth)): @"exp_month",
@"expYear": @"exp_year", NSStringFromSelector(@selector(expYear)): @"exp_year",
@"currency": @"currency", NSStringFromSelector(@selector(currency)): @"currency",
}; };
} }

View File

@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface STPCustomerContext (Private) @interface STPCustomerContext (Private)
- (void)updateCustomerWithShippingAddress:(STPAddress *)shipping completion:(nullable STPErrorBlock)completion; - (void)updateCustomerWithShippingAddress:(STPAddress *)shipping completion:(nullable STPErrorBlock)completion;
- (void)detachSourceFromCustomer:(id<STPSourceProtocol>)source completion:(nullable STPErrorBlock)completion;
@end @end

View File

@ -104,7 +104,8 @@ static NSTimeInterval const CachedCustomerMaxAge = 60;
[STPAPIClient addSource:source.stripeID [STPAPIClient addSource:source.stripeID
toCustomerUsingKey:ephemeralKey toCustomerUsingKey:ephemeralKey
completion:^(__unused id<STPSourceProtocol> object, NSError *error) { completion:^(__unused id<STPSourceProtocol> object, NSError *error) {
self.customer = nil; [self clearCachedCustomer];
if (completion) { if (completion) {
stpDispatchToMainThreadIfNecessary(^{ stpDispatchToMainThreadIfNecessary(^{
completion(error); completion(error);
@ -167,4 +168,29 @@ static NSTimeInterval const CachedCustomerMaxAge = 60;
}]; }];
} }
- (void)detachSourceFromCustomer:(id<STPSourceProtocol>)source completion:(STPErrorBlock)completion {
[self.keyManager getCustomerKey:^(STPEphemeralKey *ephemeralKey, NSError *retrieveKeyError) {
if (retrieveKeyError) {
if (completion) {
stpDispatchToMainThreadIfNecessary(^{
completion(retrieveKeyError);
});
}
return;
}
[STPAPIClient deleteSource:source.stripeID
fromCustomerUsingKey:ephemeralKey
completion:^(__unused id<STPSourceProtocol> obj, NSError *error) {
[self clearCachedCustomer];
if (completion) {
stpDispatchToMainThreadIfNecessary(^{
completion(error);
});
}
}];
}];
}
@end @end

Some files were not shown because too many files have changed in this diff Show More