'Infinite loading after secure checkout in react-native stripe application
I am using react-native and stripe in my application. Everything works fine till payment and I am getting success message in stripe and funds are transferred properly. But, while showing success message after 3D secure, it is infinitely loading not showing any error message or without proceeding further.
My backend code:
const checkout = (req,res,next)=>{
console.log("Entered checkout");
const amount = req.body.orderAmount;
console.log("IN checkout name,phone number and address are:"+req.body.user,req.body.phoneNumber,req.body.address);
stripe.customers.create({
name:req.body.user,
phone:req.body.phoneNumber,
metadata:{'Address':req.body.address}
}).then(customer=>{
console.log("Customer created successfully:"+customer.id);
stripe.ephemeralKeys.create(
{customer: customer.id},
{apiVersion: '2020-08-27'}
);
stripe.paymentIntents.create({
amount: amount,
currency: "inr",
customer : customer.id,
automatic_payment_methods: {
enabled: true,
},
}).then(paymentIntent=>{
console.log("Entered Payment intent creation:",paymentIntent.client_secret);
res.send({
publishableKey: publishable_key,
paymentIntent: paymentIntent.client_secret,
customer: customer.id,
// ephemeralKey: ephemeralKey.secret
});
}).catch(error=>{
console.log("Entered paymentIntent creation failed:",error);
res.send({status:error});
})
});
}
const payment=(req,res,next)=>{
try {
let intent;
console.log("Entered server payment");
if (req.body.payment_method_id) {
// Create the PaymentIntent
stripe.paymentIntents.create({
payment_method: req.body.payment_method_id,
amount: req.body.amount,
currency: 'inr',
confirmation_method: 'manual',
confirm: true
}).then(paymentIntent=>
{
intent=paymentIntent;
console.log("Entered first time payment_method:payment_intent:");
res.send(generateResponse(intent));
})
} else if (req.body.payment_intent_id) {
stripe.paymentIntents.confirm(
req.body.payment_intent_id
).then(payment_Intent=>{
intent=payment_Intent
console.log("Entered second time payment_method:payment_intent for otp code:",intent);
res.send(generateResponse(intent));
})
}
} catch (e) {
// Display error on client
console.log("Entered error statement:",e.message);
return res.send({ error: e.message });
}
}
const generateResponse = (intent) => {
// Note that if your API version is before 2019-02-11, 'requires_action'
// appears as 'requires_source_action'.
console.log("Entered generateResponsestatus and next action type:");
if (
intent.status === 'requires_action' &&
intent.next_action.type === 'use_stripe_sdk'
) {
// Tell the client to handle the action
console.log("Entered requires_action:");
return {
requires_action: true,
payment_intent_client_secret: intent.client_secret
};
} else if (intent.status === 'succeeded') {
// The payment didn’t need any additional actions and completed!
// Handle post-payment fulfillment
console.log("Entered successfull Payment:");
return {
success: true
};
} else {
// Invalid status
console.log("Entered invalidStatus");
return {
error: 'Invalid PaymentIntent status'
}
}
};
Frontend code:
const initializePaymentSheet = async () => {
const {
publishable_key,
paymentIntent,
customer,
} = fetchPaymentSheetParams();
};
const openPaymentSheet = async (e) => {
e.preventDefault();
console.log("Entered openPaymentSheet");
AsyncStorage.removeItem('paymentAmount');
setLoading(false);
createPaymentMethod({
type: 'card',
billing_details: {
// Include any additional collected billing details.
name: user,
},
}).then(stripePaymentMethodHandler)
.catch(error=>{console.log("Entered openpaymentSheet error block:",error)})
}
function stripePaymentMethodHandler(result) {
console.log("Entered stripePaymentHandler");
if (result.error) {
console.log("Payment not happened:",result.error);
alert("Payment not happened--",result.error);
} else {
// Otherwise send paymentMethod.id to your server (see Step 4)
fetch(API_URL+'/v1/payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payment_method_id: result.paymentMethod.id,
amount:orderAmount,
})
}).then(function(result) {
result.json().then(response=> {
console.log("Result in stripePaymentMethodHandler:",response);
handleServerResponse(response);
})
})
.catch(error=>{console.log("Entered fetch in stripePaymentHandler catch block:",error)})
}
}
function handleServerResponse(response) {
if (response.error) {
// Show error from server on payment form
//alert("Payment cannot be proceeded:",response.error);
Alert.alert("Payment cannot be proceeded--",
"",
[
{
text:"OK",
onPress:()=>{
navigation.navigate('DrawerNavigationRoutes',{screen:'profileScreenStack'})
}
},
]
);
} else if (response.requires_action) {
// Use Stripe.js to handle required card action
handleCardAction(
response.payment_intent_client_secret
).then(handleStripeJsResult);
} else {
console.log("Entered handleServerREsponse else block");
navigation.navigate(PaymentSuccessForm);
}
}
function handleStripeJsResult(result) {
if (result.error) {
// Show error in payment form
Alert.alert("Payment cannot be proceeded.",
"",
[
{
text:"OK",
onPress:()=>{
navigation.navigate('DrawerNavigationRoutes',{screen:'profileScreenStack'})
}
},
]
);
} else {
// The card action has been handled
// The PaymentIntent can be confirmed again on the server
console.log("Entered HandleJSReturn reconfirmation and order amount:",result,orderAmount);
fetch(API_URL+'/v1/payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ payment_intent_id: result.paymentIntent.id ,amount:orderAmount})
})
/*.then(function(confirmResult) {
return confirmResult.json();
})*/
.then(function(result) {
// Handle server response (see Step 4)
result.json().then(response=> {
console.log("Entered reconfirmation then block:",response);
handleServerResponse(response);
})
})
.catch(e=>{
console.log("Entered in HandleStripeJsResult catch block:",e);
Alert.alert("Payment cannot be proceeded.",
"",
[
{
text:"OK",
onPress:()=>{
navigation.navigate('DrawerNavigationRoutes',{screen:'profileScreenStack'})
}
},
]
);
})
}
}
useFocusEffect(React.useCallback(() => {
initializePaymentSheet();
//initStripe({publishableKey:publishable_Key});
return()=>{
AsyncStorage.removeItem('paymentAmount');
console.log("Leaving Payment screen");
}
}, [])
);
android/build.gradle
import org.apache.tools.ant.taskdefs.condition.Os
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "31.0.0"
minSdkVersion = 21
compileSdkVersion = 31
targetSdkVersion = 31
if (System.properties['os.arch'] == "aarch64") {
// For M1 Users we need to use the NDK 24 which added support for aarch64
ndkVersion = "24.0.8215888"
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// For Android Users, we need to use NDK 23, otherwise the build will
// fail due to paths longer than the OS limit
ndkVersion = "23.1.7779620"
} else {
// Otherwise we default to the side-by-side NDK version from AGP.
ndkVersion = "21.4.7075529"
}
}
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:4.1.0")
classpath("de.undercouch:gradle-download-task:4.1.2")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
mavenCentral {
// We don't want to fetch react-native from Maven Central as there are
// older versions over there.
}
google()
jcenter()
maven { url 'https://www.jitpack.io' }
}
}
Can you help me if there is anything blocking in my code. Thanks in advance
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
