0
votes

I am trying to do payment with saved card in react-native-stripe library, but getting the following error:

The payment_method parameter supplied pm_1J6uUAJe0mL5QUbWTxbO90MK belongs to the Customer cus_JkKJdvAXk19JMu. Please include the Customer in the customer parameter on the PaymentIntent.

Below is the code:

export default function CheckoutScreen({route}) {
  const {
    vehicleType,
    packages: pkg,
    // price,
    addon,
  } = route.params;
  const auth = useSelector((state) => state.auth);
  const {displayName} = auth?.profile || {};
  const styles = useStyleSheet(themedStyles);
  const [cardToken, setCardToken] = useState('');

  const {confirmPayment, loading} = useConfirmPayment();

  const fetchPaymentIntentClientSecret = async () => {
    const response = await fetch(`${API_URL}/app/createPaymentIntent`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        items: {package: pkg, addon, vehicleType},
        discountCost: 0,
      }),
    });
    const {clientSecret} = await response.json();
    return {clientSecret};
  };

  const handlePayPress = async () => {
    try {
      const {clientSecret} = await fetchPaymentIntentClientSecret();

      const updatedObj = cardToken
        ? {
            type: 'Card',
            cvc: 424,
            paymentMethodId: cardToken              }
        : {
            type: 'Card',
            billingDetails: {
              name: displayName,
            },
            setupFutureUsage: 'OffSession',
          };

      console.log(`udpatedObj`, updatedObj);

      const {error, paymentIntent} = await confirmPayment(
        clientSecret,
        updatedObj,
      );
      if (error) {
        console.log(`error.message`, error.message);
        Alert.alert(`Error code: ${error.code}`, error.message);
      } else if (paymentIntent) {
        Alert.alert('Success', `Payment successfull: ${paymentIntent.id}`);
        await firestore()
          .collection('stripe_customers')
          .doc(auth.profile.uid)
          .collection('payment_methods')
          .add({id: paymentIntent.id});
      }
    } catch (error) {
      console.log(`error`, error);
    }
  };

  const updateSelectedItem = (item, cardDetails) => {
    setCardToken(item);
  };

  return (
    <>
      <SafeAreaView style={styles.safeAreaTop} />
      <SafeAreaView style={styles.safeArea}>
        <StatusBar barStyle="light-content" />
        {/* <Button
          variant="primary"
          disabled={!loading}
          title="Checkout"
          onPress={openPaymentSheet}
        /> */}
        <CardField
          onCardChange={(cardDetails) =>
            console.log('cardDetails', cardDetails)
          }
          style={styles.cardField}
        />
        <SavedCards
          selectedItem={cardToken}
          setSelectedItem={updateSelectedItem}
        />
        <Button
          variant="primary"
          disabled={loading}
          title="Pay"
          onPress={handlePayPress}
        />
      </SafeAreaView>
    </>
  );
}

Error

I have already attached the payment to the customer

Payment Method

1

1 Answers

1
votes

You may have to pass customer_id key in your fetchPaymentIntentClientSecret function.

More details on: https://stripe.com/docs/api/payment_intents/create