#crisscrosschris

1 messages · Page 1 of 1 (latest)

dawn dirgeBOT
rose venture
#

Hi 👋

Are you saving multiple Payment Methods of the same type? If you already have a saved payment method, what is the purpose behind saving a new one?

cedar cloak
#

the pre-built Stripe React Native UI allows you to save multiple cards and then select the one you want to be charged (as indicated by the check to the bottom right of the chosen card). When you call list payment methods it gives me an array of those payment methods, but I don't know which one to charge

rose venture
#

But with the RN UI, the customer is the one who selects the PM to use. What is it you are trying to do here?

#

Like, it's up to you to decide which PM to use, isn't it?

cedar cloak
#

Right, I'm trying to get the PM id of the card they selected

#

Yeah

#

the documentation says "When you have the Customer and PaymentMethod IDs [...]," so now I have an array of PM IDs. The next API call requires the PM id of their card

the problem is i have an array of PM IDs so I don't know which one to use

rose venture
#

So when the customer is selecting the PM, are you setting it as their default?

cedar cloak
#

afaik Stripe handles all that with their pre-built payment sheet, so I'm not able to get the default when they set it

rose venture
#

Hi sorry for the delay. Can you share an example Customer in test mode where you have gone through this flow?

dawn dirgeBOT
cedar cloak
#

This user has 2 PMs

  "id": "cus_ORFsXyE09aqu6l",
  "object": "customer",
  "address": null,
  "balance": 0,
  "created": 1691868030,
  "currency": null,
  "default_source": null,
  "delinquent": false,
  "description": null,
  "discount": null,
  "email": "chrischencmp@gmail.com"
  "invoice_prefix": "FCEC071C",
  "invoice_settings": {
    "custom_fields": null,
    "default_payment_method": null,
    "footer": null,
    "rendering_options": null
  },
  "livemode": false,
  "metadata": {},
  "name": "Chris Cehn",
  "next_invoice_sequence": 1,
  "phone": null,
  "preferred_locales": [],
  "shipping": null,
  "tax_exempt": "none",
  "test_clock": null
}```
rose venture
#

Yes I think this is something you would need to detect and update from the client side, since neither of these PMs is set as the default source. The data that defines which PM has the check mark is only stored on the client device.

cedar cloak
#

I'm logging undefined for paymentOption

 const openPaymentSheet = async () => {
   setTimeout(() => {}, 300);
   const { paymentOption, error } = await presentPaymentSheet();

   // Result: Error
   if (error) {
     if (error.code !== "Canceled") {
       Alert.alert(`Error code: ${error.code}`, error.message);
     }

     // User may have removed credit card and dismissed/canceled the sheet
     checkIfPaymentInitialized();
   }

   // Result: Success - payment has been setup
   else {
     console.log("paymentOption");
     console.log(paymentOption);
     setLoading(true);
     checkIfPaymentInitialized();
     loadPaymentSheet();
   }
 };```
#

There doesn't appear to be anything there

rose venture
#

Drat, I didn't have too much hope based on this description in our docs

After the customer completes setting up their payment method for future use, the sheet is dismissed and the promise resolves with an optional StripeError<PaymentSheetError>.
but I saw it in the RN SDK docs and thought it might work

rose venture
#

I think your server would need to respond to the setup_intent.succeeded event by setting the attached Payment Method to be the default for that customer.

cedar cloak
#

So I would need to add a webhook?

#

Are there no other possible solutions or workarounds?

#

seems a bit convoluted

rose venture
#

The way the PaymentSheet is designed, the user's preferred PM is stored locally and not exposed to you. What is occurring when you are calling checkIfPaymentInitialized()?

cedar cloak
#

Since I couldn't find a way to keep track of the PMs, I'm actually fetching the PM list every time and comparing the new PM count with a prev PM count to know if there was a change

  const checkIfPaymentInitialized = async () => {
    const userRef = doc(db, "users", currentUserID);

    const paymentMethods = await fetchPaymentMethods(
      stripeCustomerId,
      currentUserID
    );

    const cardCount = paymentMethods.data.length;
    if (cardCount === 0) {
      setIsPaymentInitialized(false);
      await updateDoc(userRef, {
        isPaymentSetup: false,
      });
    } else if (cardCount > 0) {
      setIsPaymentInitialized(true);
      if (isPaymentSetup == false) {
        await updateDoc(userRef, {
          isPaymentSetup: true,
        });
      }
    }

    // Check if card count has decreased
    if (prevCardCountRef.current > cardCount) {
      setLoading(true);

      setTimeout(() => {
        setLoading(false);
      }, 300);
    }

    // Update the previous card count after the check
    prevCardCountRef.current = cardCount;
  };```
#

Maybe I'm missing something, but there doesn't seem to be much support when it comes to this specific API

rose venture
cedar cloak
rose venture
#

You're right and that data is only stored locally on the phone

#

SInce that functionality is only designed for interfacing with the Payment Sheet

#

And is not used to specify a default PM for non-Payment Sheet charges