'Add Stripe Credit Card without Payment in SwiftUI

I am struggling to find a solution that isn't UIKit, or one that requires you make a purchase.

My project is trying to integrate Stripe in SwiftUI, using node.js Firebase Functions for backend handling.

I built a STPPaymentCardTextField in UIViewRepresentable. Which allows me to obtain credit card details for the customer via State.

@State var params: STPPaymentMethodCardParams = STPPaymentMethodCardParams()

SwiftUI TextField

StripePaymentCardTextField(cardParams: $params, isValid: $isValid)

Then we can build paymentMethodParms like..

 let paymentMethodParams = STPPaymentMethodParams(card: params, billingDetails: billingDetails, metadata: nil)

Now I could easily pass the credit card details to my backend and add the card manually using

Function for adding payment method

const createPaymentMethods = functions.https.onCall(async (data, context) => {
    const paymentMethod = await stripe.paymentMethods.create({
        customer: '{{CUSTOMER_ID}}',
        payment_method: '{{PAYMENT_METHOD_ID}}',
        }, {
            stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
        });
    
}

but I am understanding this is bad practice. I found this post which might be a "duplicate", but is the closest relevant answer. Adding customer's Credit card info in stripe. That user however is using reactjs and wanted to store credit card details in a database, where I only want to pass it to Stripe.

Is there not a way I can send the credit card data to Stripe, get a paymentMethod ID back, and pass that to my backend or something? I have already solved subscriptions, and purchase charging, I just can't get a credit card setup without going through the payment setup process. I want the user to add a credit card manually on creating a new account and/or in settings.



Solution 1:[1]

Can you call stripe-ios's createPaymentMethod() function [0]? That is a client-side function your SwiftUI app would call to tokenize the card details from paymentMethodParams into a PaymentMethod object. You can then pass that ID server-side to attach to a Customer.

[0] https://stripe.dev/stripe-ios/docs/Classes/STPAPIClient.html#/c:@CM@Stripe@objc(cs)STPAPIClient(im)createPaymentMethodWithPayment:completion:

Solution 2:[2]

To expand on @hmunoz's answer and the way I got this to work is as follows.

  1. Create your user a Stripe account. https://stripe.com/docs/api/customers/create
  2. Log the customers stripe id in your user's Firestore database for easy reference.
  3. Create an "Add card" view to your frontend and call to the add payment method function. https://stripe.com/docs/api/cards/create
  4. Upon checkout as long as the customer's stripe ID is passed in the payment intent it should populate with their saved payment methods.

In summary it is best to keep track of your user that is signed in so that you can do any CRUD needed throughout.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hmunoz
Solution 2 Jarren Campos