Using iOS Custom UI Components

    Learn about the individual UI components of the Stripe iOS SDK.

    The iOS SDK provides customizable UIViews and UIViewControllers to collect payment information in your app. For example, you can build your own credit card form or collect card details with the STPPaymentCardTextField class and have on-the-fly validation and formatting handled for you.

    Our recommended UI components help you design your desired checkout flow. You can also design UI components yourself for greater flexibility.

    We also publish a full SDK reference that documents every single method and property of the classes described here.



    STPPaymentCardTextField


    The STPPaymentCardTextField class is a single-line text field that can be used to collect a credit card number, expiration, CVC, and postal code. The field also performs on-the-fly validation and formatting so that it can provide the user instant feedback. In fact, the STPAddCardViewController class uses it under the hood.

    let paymentCardTextField = STPPaymentCardTextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Setup payment card text field
        paymentCardTextField.delegate = self
    
        // Add payment card text field to view
        view.addSubview(paymentCardTextField)
    }
    
    // MARK: STPPaymentCardTextFieldDelegate
    
    func paymentCardTextFieldDidChange(_ textField: STPPaymentCardTextField) {
        // Toggle buy button state
        buyButton.enabled = textField.isValid
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // Setup payment card text field
        self.paymentCardTextField = [[STPPaymentCardTextField alloc] init];
        self.paymentCardTextField.delegate = self;
    
        // Add payment card text field to view
        [self.view addSubview:self.paymentCardTextField];
    }
    
    #pragma mark STPPaymentCardTextFieldDelegate
    
    - (void)paymentCardTextFieldDidChange:(STPPaymentCardTextField *)textField {
      // Toggle buy button state
      self.buyButton.enabled = textField.isValid;
    }

    STPAddCardViewController


    STPAddCardViewController

    The STPAddCardViewController class automatically handles both collecting and tokenizing your user's payment information. You can present it modally or push it onto a UINavigationController stack. You can also fully customize its appearance via the theme property.

    func handleAddPaymentOptionButtonTapped() {
        // Setup add card view controller
        let addCardViewController = STPAddCardViewController()
        addCardViewController.delegate = self
    
        // Present add card view controller
        let navigationController = UINavigationController(rootViewController: addCardViewController)
        present(navigationController, animated: true)
    }
    
    // MARK: STPAddCardViewControllerDelegate
    
    func addCardViewControllerDidCancel(_ addCardViewController: STPAddCardViewController) {
        // Dismiss add card view controller
        dismiss(animated: true)
    }
    
    func addCardViewController(_ addCardViewController: STPAddCardViewController, didCreatePaymentMethod paymentMethod: STPPaymentMethod, completion: @escaping STPErrorBlock) {
        submitPaymentMethodToBackend(paymentMethod, completion: { (error: Error?) in
            if let error = error {
                // Show error in add card view controller
                completion(error)
            }
            else {
                // Notify add card view controller that PaymentMethod creation was handled successfully
                completion(nil)
    
                // Dismiss add card view controller
                dismiss(animated: true)
            }
        })
    }
    - (void)handleAddPaymentOptionButtonTapped {
        // Setup add card view controller
        STPAddCardViewController *addCardViewController = [[STPAddCardViewController alloc] init];
        addCardViewController.delegate = self;
    
        // Present add card view controller
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addCardViewController];
        [self presentViewController:navigationController animated:YES completion:nil];
    }
    
    #pragma mark STPAddCardViewControllerDelegate
    
    - (void)addCardViewControllerDidCancel:(STPAddCardViewController *)addCardViewController {
        // Dismiss add card view controller
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (void)addCardViewController:(STPAddCardViewController *)addCardViewController didCreatePaymentMethod:(STPPaymentMethod *)paymentMethod completion:(STPErrorBlock)completion {
        [self submitPaymentMethodToBackend:paymentMethod completion:^(NSError *error) {
            if (error) {
                // Show error in add card view controller
                completion(error);
            }
            else {
                // Notify add card view controller that token creation was handled successfully
                completion(nil);
    
                // Dismiss add card view controller
                [self dismissViewControllerAnimated:YES completion:nil];
            }
        }];
    }

    STPPaymentOptionsViewController


    STPAddCardViewController

    The STPPaymentOptionsViewController class makes it easy to let your customers manage their payment methods. To initialize it, you'll need to first set up an STPCustomerContext instance. You can present it modally or push it onto a UINavigationController stack. You can also fully customize its appearance via the theme property.

    func handlePaymentOptionsButtonTapped() {
        // Setup customer context
        let customerContext = STPCustomerContext(keyProvider: MyKeyProvider().shared())
    
        // Setup payment options view controller
        let paymentOptionsViewController = STPPaymentOptionsViewController(configuration: STPPaymentConfiguration.shared(), theme: STPTheme.default(), customerContext: customerContext, delegate: self)
    
        // Present payment options view controller
        let navigationController = UINavigationController(rootViewController: paymentOptionsViewController)
        present(navigationController, animated: true)
    }
    
    // MARK: STPPaymentOptionsViewControllerDelegate
    
    func paymentOptionsViewController(_ paymentOptionsViewController: STPPaymentOptionsViewController, didFailToLoadWithError error: Error) {
        // Dismiss payment options view controller
        dismiss(animated: true)
    
        // Present error to user...
    }
    
    func paymentOptionsViewControllerDidCancel(_ paymentOptionsViewController: STPPaymentOptionsViewController) {
        // Dismiss payment options view controller
        dismiss(animated: true)
    }
    
    func paymentOptionsViewControllerDidFinish(_ paymentOptionsViewController: STPPaymentOptionsViewController) {
        // Dismiss payment options view controller
        dismiss(animated: true)
    }
    
    func paymentOptionsViewController(_ paymentOptionsViewController: STPPaymentOptionsViewController, didSelect paymentOption: STPPaymentOption) {
        // Save selected payment option
        selectedPaymentOption = paymentOption
    }
    - (void)handlePaymentOptionsButtonTapped {
        // Setup customer context
        STPCustomerContext *customerContext = [[STPCustomerContext alloc] initWithKeyProvider:[MyKeyProvider shared]];
    
        // Setup payment options view controller
        STPPaymentOptionsViewController *paymentOptionsViewController = [[STPPaymentOptionsViewController alloc] initWithConfiguration:[STPPaymentConfiguration sharedConfiguration] theme:[STPTheme defaultTheme] customerContext:customerContext delegate:self];
    
        // Present payment options view controller
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:paymentOptionsViewController];
        [self presentViewController:navigationController animated:YES completion:nil];
    }
    
    #pragma mark STPPaymentOptionsViewControllerDelegate
    
    - (void)paymentOptionsViewController:(STPPaymentOptionsViewController *)paymentOptionsViewController didFailToLoadWithError:(NSError *)error {
        // Dismiss payment options view controller
        [self dismissViewControllerAnimated:YES completion:nil];
    
        // Present error to user...
    }
    
    - (void)paymentOptionsViewControllerDidCancel:(STPPaymentOptionsViewController *)paymentOptionsViewController {
        // Dismiss payment options view controller
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (void)paymentOptionsViewControllerDidFinish:(STPPaymentOptionsViewController *)paymentOptionsViewController {
        // Dismiss payment options view controller
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (void)paymentOptionsViewController:(STPPaymentOptionsViewController *)paymentOptionsViewController didSelectPaymentOption:(id<STPPaymentOption>)paymentOption {
        // Save selected payment option
        self.selectedPaymentOption = paymentOption;
    }

    Note that if you're pushing an STPPaymentOptionsViewController instance onto a UINavigationController stack, you should pop it using its dismissWithCompletion: method rather than the standard popViewControllerAnimated:, as it may have pushed an additional add card view controller onto the navigation controller's stack.

    STPShippingAddressViewController


    The STPShippingAddressViewController class automatically handles collecting your user's shipping address and shipping method. You can present it modally or push it onto a UINavigationController stack. You can also fully customize its appearance via the theme property.

    func handleShippingButtonTapped() {
        // Setup shipping address view controller
        let shippingAddressViewController = STPShippingAddressViewController()
        shippingAddressViewController.delegate = self
    
        // Present shipping address view controller
        let navigationController = UINavigationController(rootViewController: shippingAddressViewController)
        present(navigationController, animated: true)
    }
    
    // MARK: STPShippingAddressViewControllerDelegate
    
    func shippingAddressViewControllerDidCancel(_ addressViewController: STPShippingAddressViewController) {
        // Dismiss shipping address view controller
        dismiss(animated: true)
    }
    
    func shippingAddressViewController(_ addressViewController: STPShippingAddressViewController, didEnter address: STPAddress, completion: @escaping STPShippingMethodsCompletionBlock) {
        let upsGroundShippingMethod = PKShippingMethod()
        upsGroundShippingMethod.amount = 0.00
        upsGroundShippingMethod.label = "UPS Ground"
        upsGroundShippingMethod.detail = "Arrives in 3-5 days"
        upsGroundShippingMethod.identifier = "ups_ground"
    
        let fedExShippingMethod = PKShippingMethod()
        fedExShippingMethod.amount = 5.99
        fedExShippingMethod.label = "FedEx"
        fedExShippingMethod.detail = "Arrives tomorrow"
        fedExShippingMethod.identifier = "fedex"
    
        if address.country == "US" {
            let availableShippingMethods = [upsGroundShippingMethod, fedExShippingMethod]
            let selectedShippingMethod = upsGroundShippingMethod
    
            completion(.valid, nil, availableShippingMethods, selectedShippingMethod)
        }
        else {
            completion(.invalid, nil, nil, nil)
        }
    }
    
    func shippingAddressViewController(_ addressViewController: STPShippingAddressViewController, didFinishWith address: STPAddress, shippingMethod method: PKShippingMethod?) {
        // Save selected address and shipping method
        selectedAddress = address
        selectedShippingMethod = method
    
        // Dismiss shipping address view controller
        dismiss(animated: true)
    }
    - (void)handleShippingButtonTapped {
        // Setup shipping address view controller
        STPShippingAddressViewController *shippingAddressViewController = [[STPShippingAddressViewController alloc] init];
        shippingAddressViewController.delegate = self;
    
        // Present shipping address view controller
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:shippingAddressViewController];
        [self presentViewController:navigationController animated:YES completion:nil];
    }
    
    #pragma mark STPShippingAddressViewControllerDelegate
    
    - (void)shippingAddressViewControllerDidCancel:(STPShippingAddressViewController *)addressViewController {
        // Dismiss shipping address view controller
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (void)shippingAddressViewController:(STPShippingAddressViewController *)addressViewController didEnterAddress:(STPAddress *)address completion:(STPShippingMethodsCompletionBlock)completion {
        PKShippingMethod *upsGroundShippingMethod = [PKShippingMethod new];
        upsGroundShippingMethod.amount = [NSDecimalNumber decimalNumberWithString:@"0.00"];
        upsGroundShippingMethod.label = @"UPS Ground";
        upsGroundShippingMethod.detail = @"Arrives in 3-5 days";
        upsGroundShippingMethod.identifier = @"ups_ground";
    
        PKShippingMethod *fedExShippingMethod = [PKShippingMethod new];
        fedExShippingMethod.amount = [NSDecimalNumber decimalNumberWithString:@"5.99"];
        fedExShippingMethod.label = @"FedEx";
        fedExShippingMethod.detail = @"Arrives tomorrow";
        fedExShippingMethod.identifier = @"fedex";
    
        if ([address.country isEqualToString:@"US"]) {
            NSArray *availableShippingMethods = @[upsGroundShippingMethod, fedExShippingMethod];
            PKShippingMethod *selectedShippingMethod = upsGroundShippingMethod;
    
            completion(STPShippingStatusValid, nil, availableShippingMethods, selectedShippingMethod);
        }
        else {
            completion(STPShippingStatusInvalid, nil, nil, nil);
        }
    }
    
    - (void)shippingAddressViewController:(STPShippingAddressViewController *)addressViewController didFinishWithAddress:(STPAddress *)address shippingMethod:(PKShippingMethod *)method {
        // Save selected address and shipping method
        self.selectedAddress = address;
        self.selectedShippingMethod = method;
    
        // Dismiss shipping address view controller
        [self dismissViewControllerAnimated:YES completion:nil];
    }

    Note that if you're pushing an STPShippingAddressViewController instance onto a UINavigationController stack, you should pop it using its dismissWithCompletion: method rather than the standard popViewControllerAnimated:, as it may have pushed an additional shipping method view controller onto the navigation controller's stack.

    Next steps

    Was this page helpful?

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    Questions?

    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    On this page