I integrated stripe payment in react native with laravel. My goal is to setup future payment and just collecting card details and charge them later.
Here's my react native code:
// Start App.js
import React, {useEffect, useState} from 'react';
import { AuthProvider } from './context/AuthProvider';
import Screens from "./navigation/Screens";
import { StripeProvider } from '@stripe/stripe-react-native';
import { fetchPublishableKey } from "./helper";
export default function App() {
const [publishableKey, setPublishableKey] = useState('');
const fetchKey = async () => {
const key = await fetchPublishableKey()
if (key) {
setPublishableKey(key)
}
};
useEffect(() => {
fetchKey();
}, []);
return (
<StripeProvider publishableKey={publishableKey}>
<AuthProvider>
<Screens />
</AuthProvider>
</StripeProvider>
);}
// End App.js
// Start AccountNoBilling.js
import {CardField,useConfirmSetupIntent} from '@stripe/stripe-react-native';
import axiosConfig from "../../helpers/axiosConfig";
import {API_URL} from "../../Config";
export default function AccountNoBilling ({ route, navigation}) {
const fetchPaymentIntentClientSecret = async () => {
axiosConfig.defaults.headers.common['Authorization'] = `Bearer ${user.token}`;
const response = await axiosConfig.post(`${API_URL}/payment-sheet`)
.catch(error => {
console.log('Error: ', error.response.data)
alert('Error: '+ error.response.data)
});
if (typeof (response.data) === undefined) {
alert('Hello')
} else {
return response.data;
}
};
const handlePayPress = async () => {
// Gather the customer's billing information (for example, email)
const billingDetails: BillingDetails = {
email: '[email protected]',
};
// Create a setup intent on the backend
const clientSecret = await fetchPaymentIntentClientSecret();
const { setupIntent, error } = await confirmSetupIntent(clientSecret, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails,
}
});
if (error) {
Alert.alert(`Error code: ${error.code}`, error.message);
} else {
Alert.alert('Success',setupIntent + ' Your payment method is successfully set up for future payments!');
}
}
function renderCreditCard() {
return (
<Block>
<CardField
postalCodeEnabled={true}
placeholder={{
number: '4242 4242 4242 4242',
}}
cardStyle={{
backgroundColor: '#edeff2',
textColor: '#000000',
borderWidth: 1,
borderColor: '#000000',
borderRadius: 8
}}
style={styles.cardInput}
onCardChange={(cardDetails) => {
console.log('cardDetails', cardDetails);
}}
onFocus={(focusedField) => {
// console.log('focusField', focusedField);
}}
/>
</Block>
);
}
function renderSaveButton() {
return (
<Block style={{ flex: 12 }} center>
<Button
color="success"
style={loading ? styles.buttonDisabled : styles.buttonEnabled}
variant="primary"
disabled={loading}
onPress={handlePayPress}
>
Save my billing details
</Button>
<Text color={argonTheme.COLORS.SUCCESS}>You do not pay now – cancel anytime</Text>
</Block>
)
return (
<Block flex style={{ backgroundColor: argonTheme.COLORS.BACKGROUND}}>
<ScrollView showsVerticalScrollIndicator={false}>
{ renderDescription() }
{ renderBillingAddress() }
{ renderCreditCard() }
{ renderSaveButton() }
</ScrollView>
</Block>
)}
// End AccountNoBilling.js
Here's my backend laravel api code:
public function createSetupIntent()
{
try {
Stripe::setApiKey(env('STRIPE_SECRET'));
$customer = User::find($request->userId ?? auth()->id());
$customer->createAsStripeCustomer();
$setupIntent = SetupIntent::create([
'customer' => $customer->stripe_id,
]);
return response()->json($setupIntent->client_secret, 200);
} catch (Exception $e) {
return response()->json($e->getMessage(), 422);
}
}
I was wondering why it says "You must provide paymentMethodType" which I already provided as you can see in handlePayPress function.

Really matters on version of react native SDK. before version 0.8.0 that field used to be named type which has change to paymentMethodType, so the naming difference may be part of why seeing this behavior.
stripe react native SDK version changes here
Adding to the latest answer, the migration guide from stripe 0.7.x to 0.8.0 helped me fix my issue. You seem to have correctly renamed the field indeed and its not clear for me, so I decided the link to the migration guide might help you, or somebody else with the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With