skip to Main Content

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?

2

Answers


  1. Chosen as BEST ANSWER

    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


  2. I had similar problem and am using django. USE credit card number=4000 0035 6000 0008. (DO NOT USE credit card number= 4242 4242 4242 4242). I did not use any webhook.
    The view.py:

    from django.shortcuts import render, redirect  
    from django.conf import settings  
    from django.urls import reverse  
    
    import stripe  
    
    def home(request):
        stripe.api_key = settings.STRIPE_SECRET_KEY
        if request.method == "POST":
            checkout_session = stripe.checkout.Session.create(
                line_items=[
                    {
                        "price": "<API_PRODUCT_KEY>",  # enter yours here!!!
                        "quantity": 1,
                    }
                ],
                mode="payment",
                success_url=request.build_absolute_uri(reverse("success")),
                cancel_url=request.build_absolute_uri(reverse("cancel")),
            )
            return redirect(checkout_session.url, code=303)
        return render(request, "home.html")
    
    def success(request):
        return render(request, "success.html")
    
    def cancel(request):
        return render(request, "cancel.html")
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search