Stripe 与 React Native 集成

问题描述 投票:0回答:2

我必须将 Stripe 与我的 React Native 应用程序集成,这个手机应用程序是桌面应用程序的手机版本,其中 stripe 已经集成并且工作正常,因此后端已经实现。我想使用我在react js应用程序中使用的上下文,但是useElement在stripe/stripe-react-native中不可用,但是经过一番研究后,我发现如果我使用@stripe/stripe-js库我的问题并不重要现在我不断收到错误:

Could not find Elements context; You need to wrap the part of your app that calls useElements() in an <Elements> provider.
但是我已经将表单包装在提供程序中,这是我的checkoutForm.js

从'@react-navigation/native'导入{useNavigation};

import 
  React, 
  { useState, 
  useEffect, useRef } 
from 'react'

import { 
    View, 
    Text, 
    SafeAreaView, 
    StatusBar, 
    StyleSheet, 
    TouchableOpacity, 
    ScrollView, 
    Image,
    Pressable , 
    TextInput, 
    Alert} 
from 'react-native';

import Icon from '../components'
import { COLORS } from '../constants';
import { useStateContext } from '../context/StateContext';
import { ProductCarousel } from '../../components';
import { useElements, Elements} from "@stripe/react-stripe-js"
import { CardField, useConfirmPayment, useStripe,  } from '@stripe/stripe-react-native';
import { Button } from 'react-native-elements';


const CheckoutForm = () => {

  const navigation = useNavigation();
  const [isDeliveryAddressOpen, setIsDeliveryAddressOpen] = useState(false);
  const [isContactNumberOpen, setIsContactNumberOpen] = useState(false);
  const [isDeliveryInstructionsOpen, setIsDeliveryInstructionsOpen] = useState(false);
  const [isCartItemsOpen, setIsCartItemsOpen] = useState(false);  
  const [isPaymentInfoOpen, setIsPaymentInfoOpen] = useState(false);
  //const { confirmPayment, loading } = useConfirmPayment();

  const [success, setSuccess ] = useState(false)
  const stripe = useStripe()
  const elements = useElements()
  const cardElement = useRef(null);

  const {  totalPrice,  cartItems } = useStateContext();

  const [fullName, setFullName] = useState('');
  const [email, setEmail] = useState('');
  const [address, setAddress] = useState('');
  const [address2, setAddress2] = useState('');  
  const [state, setState] = useState('');
  const [city, setCity] = useState('');
  const [zipCode, setZipCode] = useState('');
  const [primaryNumber, setPrimaryNumber] = useState('');
  const [SecondaryNumber, setSecondaryNumber] = useState('');
  const [DeliveryInstructions, setDeliveryInstructions] = useState('');   

  const [isProcessing, setIsProcessing] = useState(false);
  const [isError, setIsError] = useState(false);
  //const [cardDetails, setCardDetails] = useState('')


  

  const toggleDeliveryAddress = () => {
    setIsDeliveryAddressOpen(!isDeliveryAddressOpen);
  };

  const toggleContactNumber = () => {
    setIsContactNumberOpen(!isContactNumberOpen);
  };

  const toggleDeliveryInstructions = () => {
    setIsDeliveryInstructionsOpen(!isDeliveryInstructionsOpen);
  };

  const toggleCartItems = () => {
    setIsCartItemsOpen(!isCartItemsOpen);
  };

  const togglePaymentInfo = () => {
    setIsPaymentInfoOpen(!isPaymentInfoOpen);
  };


 //const navigate = useNavigate();
  const carts = { 
    status: 'pending', 
    items: (cartItems), 
    address, 
    fullName, 
    zipCode, 
    state,
    city,
    DeliveryInstructions, 
    primaryNumber, 
    SecondaryNumber, 
    totalPrice
  }

  const handleCheckout = async () => {
    
    const response = await fetch('/create_cart', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(carts),
    });

    if(response.statusCode === 500) return;
    // eslint-disable-next-line
    const data = await response.json();
    console.log('presseddddd', data)
  }  

 /*========================================================*/

 const handleSubmit = async () => {
       
    const {error, paymentMethod} = await stripe.createPaymentMethod({
        type: "card",
        card: elements.getElement(CardField),
        billing_details: {
            name: fullName,
            phone: primaryNumber,
            email: email,
            address: {
              city: city,
              line1: address,
              state: state,
              postal_code: zipCode
            }
          },
    })

    if(!error) {
        try {
            const {id} = paymentMethod
            
            const carts = { 
              id, 
              amount: totalPrice, 
              confirm: true, 
              currency: 'CAD'
            }

            setIsProcessing(true);
            
            const response = await fetch('/create-payment-intent', {
                method: 'POST',
                headers: {
                'Content-Type': 'application/json',
                },
                body: JSON.stringify(carts),
            });


            if(response.status === 200) {
                console.log(response.status)
                console.log("Successful payment")
                setSuccess(true)
            }

            const data = await response.json();

            if(response.status >= 400) {
              console.log(response.status)
              console.log(data.error.split(':').pop())
              setIsError(data.error)
          }

        } catch (error) {
            console.log("Error", error)
        }
    } else {
        console.log(error.message)

    }

    setIsProcessing(false)

    
    //navigate('/');
  }



  return (
    <View style={styles.container}>
        <View style={styles.insideContainer}>         
        <TouchableOpacity style={styles.titleContainer} onPress={togglePaymentInfo}>
            <Text style={styles.title}>Payment Info</Text>
            {!isPaymentInfoOpen ? 
            <Icon icon ='add-outline' color='#000' size={20}/>
            : <Icon icon ='remove-outline' color='#000' size={20}/> 
            }
        </TouchableOpacity>
        {isPaymentInfoOpen && (
            <View style={styles.containercollapsed}>
                <View style={{width: '98%'}}>
                <CardField
                    ref={cardElement}
                    postalCodeEnabled={false}
                    placeholders={{
                    number: '4242 4242 4242 4242',
                    }}
                    cardStyle={{
                    backgroundColor: '#FFFFFF',
                    textColor: '#000000',
                    borderColor: COLORS.lightGray2,
                    borderWidth: 1,
                    borderRadius: 4
                    }}
                    style={{
                    width: '100%',
                    height: 50,
                            
                    }}
                    onCardChange={(cardDetails) => {
                    }}
                    onFocus={(focusedField) => {
                    }}
                />
                </View>                
            </View>
        )}
        </View>   

        <View style={styles.PaybuttonView}>
        <Button
          title="Pay"
          onPress={ () => handleSubmit()}
          /*disabled={loading}
          loading={loading}*/
          />
          {/*<Pressable style={styles.Paybutton} onPress={() => {handleCheckout(); handlePayPress()} }>
            <Text style={{textAlign: 'center', fontSize: 20, color: '#FFFF', textTransform: 'uppercase'}}>Checkout</Text>
              </Pressable>*/}
        </View>           

  </View>
  )
}

export default CheckoutForm

这是我的StripeForm.js

import React from 'react'
import {Elements} from "@stripe/react-stripe-js"
import CheckoutForm from './CheckoutForm';
import { loadStripe } from "@stripe/stripe-js"

const stripePromise = loadStripe(i removed the key but this is the key's place);

export const StipeForm = () => {
    return (
        <Elements stripe={stripePromise}>
            <CheckoutForm />
        </Elements>
    ) 
}
react-native stripe-payments
2个回答
1
投票

要初始化 Stripe 以与 Stripe React Native SDK 一起使用,您需要使用

StripeProvider
initStripe
。请参阅此处的文档。您不能使用 React Stripe.JS 库为 React Native SDK 初始化 Stripe。


0
投票

这个问题我已经有经验了。

import {Elements} from "@stripe/react-stripe-js"

这仅适用于 React 版本。 React Native 不支持这个。

© www.soinside.com 2019 - 2024. All rights reserved.