I'm encountering an error while integrating Stripe payment into my React Native app with an Express.js backend. When attempting to process payments, I'm receiving the following error message: "As per Indian regulations, only registered Indian businesses can accept international payments." This error is preventing the payment from being processed.
I am using "stripe": "^14.18.0", at back end.
And Front end. "@stripe/stripe-react-native": "~0.35.1",
Backend: Express.js
const stripe = require("stripe")(process.env.STRIPEKEY, {
apiVersion: "2023-10-16",
});
const createIntent = asyncHandler(async (req, res) => {
try {
const paymentIntent = await stripe.paymentIntents.create({
amount: req.body.amount * 100,
currency: "inr",
description: "Software development services",
payment_method_types: ["card"],
});
res.status(200).json({ clientSecret: paymentIntent.client_secret });
} catch (e) {
console.error("Error creating PaymentIntent:", error);
res.status(500).json({ error: "Failed to create PaymentIntent" });
}
});
Frontend: React Native
import {
Text,
FlatList,
View,
StyleSheet,
Pressable,
ActivityIndicator,
Alert,
} from "react-native";
import { useDispatch, useSelector } from "react-redux";
import React, { useState, useEffect } from "react";
import { useStripe } from "@stripe/stripe-react-native";
import Constants from "expo-constants";
import axios from "axios"; // Import Axios
const PaymentScreen = () => {
const FreshSabzi_API_URL = Constants?.expoConfig?.extra?.FreshSabzi_API_URL;
const { initPaymentSheet, presentPaymentSheet } = useStripe();
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
fetchPaymentIntentClientSecret();
}, []);
const fetchPaymentIntentClientSecret = async () => {
try {
const response = await axios.post(`${FreshSabzi_API_URL}payment/intent`, {
amount: 55,
});
setClientSecret(response.data.clientSecret);
} catch (error) {
console.error("Error fetching PaymentIntent client secret:", error);
// Handle the error (e.g., display an error message)
}
};
const onCheckout = async () => {
// 1. Create a payment intent
// const response = await createPaymentIntent({
// amount: Math.floor(10 * 100),
// });
// if (response.error) {
// Alert.alert("Something went wrong");
// return;
// }
console.log("clientSecret: " + clientSecret);
// 2. Initialize the Payment sheet
const initResponse = await initPaymentSheet({
merchantDisplayName: "notJust.dev",
paymentIntentClientSecret: clientSecret,
defaultBillingDetails: {
name: "Jane Doe",
},
});
if (initResponse.error) {
console.log(initResponse.error);
Alert.alert("Something went wrong");
return;
}
console.log("presentPaymentSheet started: ");
// 3. Present the Payment Sheet from Stripe
const paymentResponse = await presentPaymentSheet();
console.log("paymentResponse :" + JSON.stringify(paymentResponse));
if (paymentResponse.error) {
Alert.alert(
`Error code: ${paymentResponse.error.code}`,
paymentResponse.error.message
);
return;
}
// 4. If payment ok -> create the order
onCreateOrder();
};
const onCreateOrder = async () => {
Alert.alert("Order has been submitted");
};
return (
<>
<Pressable onPress={onCheckout} style={styles.button}>
<Text style={styles.buttonText}>Checkout</Text>
</Pressable>
</>
);
};
const styles = StyleSheet.create({
totalsContainer: {
margin: 20,
paddingTop: 10,
borderColor: "gainsboro",
borderTopWidth: 1,
},
row: {
flexDirection: "row",
justifyContent: "space-between",
marginVertical: 2,
},
text: {
fontSize: 16,
color: "gray",
},
textBold: {
fontSize: 16,
fontWeight: "500",
},
button: {
position: "absolute",
backgroundColor: "black",
bottom: 30,
width: "90%",
alignSelf: "center",
padding: 20,
borderRadius: 100,
alignItems: "center",
},
buttonText: {
color: "white",
fontWeight: "500",
fontSize: 16,
},
});
export default PaymentScreen;
Error message on Stripe in "last_payment_error":
"message": "As per Indian regulations, only registered Indian businesses (i.e. sole proprietorships, limited liability partnerships and companies, but not individuals) can accept international payments. More info here: https://stripe.com/docs/india-exports
In timeline getting below message:
3D Secure attempt acknowledged 3D Secure was completed, but the customer hasn't been verified because the bank does not support 3D Secure, has not set up 3D Secure for the card, or is experiencing an outage. The card network has provided proof of the attempt.
Please help me to know where I am missing something. I am trying with Stripe Developer account in test mode.
Note: I want to understand what exactly I need to do next to remove this error. Can anyone suggest what should be the next step?
Solution Found: Using Indian Test Card
After further investigation, I realized that there was no issue with the code provided in the question. The main problem was with the card used for testing purposes.
I was using a US test card for transactions in INR, which led to the error mentioned in the question. The correct approach is to use an Indian test card specifically designed for transactions in INR.
For testing purposes in INR, it's recommended to use the following Indian Test Visa Card:
Indian Test Visa Card: 4000 0035 6000 0008