React Native App Crashes Unexpectedly in Build Mode when Accessing Stripe Payment Screen

15 views Asked by At

I developed an app in React Native that performs a financial transaction with Stripe. The function below is responsible for accessing the endpoint of the Node.js server I developed. There is no complexity, it's something simple. In the emulator, I can access the elements (payment screen) and get success in the transaction, but in the build (preview mode), the application closes unexpectedly without warning and without any notification. Below is the code for the server and React Native.

 const buy = async () => {
try {
  const finalAmount = amount;
  const response = await fetch('https://app-production.up.railway.app/buy', {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      coin: `App - ${priceList[selectedId].time_session}`,
      quantity: quantity,
      amount: finalAmount,
    }),
  });
  const data = await response.json();
  if (!response.ok) {
    return Alert.alert(data.message);
  }
  const initSheet = await stripe.initPaymentSheet({
    paymentIntentClientSecret: data.clientSecret,
    merchantDisplayName: "App",
  });
  if (initSheet.error) {
    return Alert.alert(initSheet.error.message);
  }
 
  const presentSheet = await stripe.presentPaymentSheet();
  if (presentSheet.error) {
    return Alert.alert(presentSheet.error.message);
  }

  Alert.alert("Payment successful!");
  addIncomeTransaction()
  // Update user data in Firestore
  const userRef = doc(db, 'users', userID);
  await updateDoc(userRef, {
    'user_billing.balance': totalCoins + amount,
    'user_billing.plan_aquisition': PlanAquired,
  });

  setTotalCoins(totalCoins + amount);
  setQuantity(1);
} catch (err) {
  Alert.alert("Error", err.message);
}
};

App.tsx

return (
<StripeProvider publishableKey={process.env.EXPO_PUBLIC_STRIPE_KEY}>
<ReduxProvider store={Store}>
  <PaperProvider>
    <GestureHandlerRootView style={{ flex: 1 }} onLayout={onLayoutRootView}>
      <Router />
    </GestureHandlerRootView>
  </PaperProvider>
</ReduxProvider>
</StripeProvider>

);

Server below

require("dotenv").config();
const express = require("express");
const app = express();
const Stripe = require("stripe");
const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
const cors = require("cors");
const PORT = process.env.PORT || 4242;

app.use("/stripe", express.raw({ type: "*/*" }));
app.use(express.json());
app.use(cors({
origin: 'https://App-production.up.railway.app/'
}));


app.post("/buy", async (req, res) => {
 try {
 // Getting data from client
 let { coin, quantity, amount } = req.body;
 // Simple validation
 if (!coin || !quantity || !amount)
  return res.status(400).json({ message: "Invalid data, try again" });
  amount = parseInt(amount);

// Initiate payment
const paymentIntent = await stripe.paymentIntents.create({
amount: Math.round(amount * 100) / 10 * 10, // Amount in cents ex: 10.90 -> 1090  
currency: 'brl',
payment_method_types: ["card"],
metadata: { coin, quantity, amount },
 });
// Extracting the client secret
const clientSecret = paymentIntent.client_secret;
// Sending the client secret as response
res.json({ message: "Initializing payment", clientSecret });
 } catch (err) {
 // Catch any error and send error 500 to client
 console.error(err);
 res.status(500).json({ message: "Internal server error." });
 }
 });

  // Webhook endpoint
  app.post("/stripe", async (req, res) => {
 // Get the signature from the headers
 const sig = req.headers["stripe-signature"];

 let event;

  try {
   // Check if the event is sent from Stripe or a third party
   // And parse the event
   event = await stripe.webhooks.constructEvent(
    req.body,
    sig,
    process.env.STRIPE_WEBHOOK_SECRET
    );
    } catch (err) {
    // Handle what happens if the event is not from Stripe
    console.log(err);
   return res.status(400).json({ message: err.message });
   }
  // Event when a payment is initiated
 if (event.type === "payment_intent.created") {
  console.log(`${event.data.object.metadata.coin} payment initated!`);
 }
 // Event when a payment is succeeded
 if (event.type === "payment_intent.succeeded") {
  // fulfilment
  console.log(`${event.data.object.metadata.coin} payment successfuly!`);
 }
res.json({ ok: true });
 });

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
0

There are 0 answers