我必须将 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>
)
}
要初始化 Stripe 以与 Stripe React Native SDK 一起使用,您需要使用
StripeProvider
或 initStripe
。请参阅此处的文档。您不能使用 React Stripe.JS 库为 React Native SDK 初始化 Stripe。
这个问题我已经有经验了。
import {Elements} from "@stripe/react-stripe-js"
这仅适用于 React 版本。 React Native 不支持这个。