简体   繁体   English

Stripe 与 React Native 的集成

[英]Stripe Integration with React Native

I have to integrate Stripe with my React Native Application this phone application is a phone version of a desktop application where stripe is already being integrated and works fine so the backend is already been implemented.我必须将 Stripe 与我的 React Native 应用程序集成,这个电话应用程序是桌面应用程序的电话版本,其中 stripe 已经集成并且工作正常,因此后端已经实现。 I wanted to use the context i used i nthe react js application however the useElementwas not available in stripe/stripe-react-native however after some reasearch i figured it didn't matter if i used the @stripe/stripe-js library my problem now is i keep getting the error: Could not find Elements context; You need to wrap the part of your app that calls useElements() in an <Elements> provider.我想使用我在 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. Could not find Elements context; You need to wrap the part of your app that calls useElements() in an <Elements> provider. However i already wrapped the form in an provider this is my checkoutForm.js :但是我已经将表单包装在提供者中,这是我的checkoutForm.js

import { useNavigation } from '@react-navigation/native';从'@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

this is my StripeForm.js :这是我的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>
    ) 
}

To initialize Stripe to be used with the Stripe React Native SDK you need to use either StripeProvider or initStripe .要初始化 Stripe 以与 Stripe React Native SDK 一起使用,您需要使用StripeProviderinitStripe See the docs here .请参阅此处的文档 You can't use the React Stripe.JS library initialize Stripe for the React Native SDK.您不能使用 React Stripe.JS 库为 React Native SDK 初始化 Stripe。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM