#incaelum-reactnative-deferredintent
1 messages · Page 1 of 1 (latest)
Hello! We'll be with you shortly. Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- incaelum-typo-docs, 3 hours ago, 9 messages
- incaelum, 7 hours ago, 15 messages
Hi 👋
Can you share the details of how you attempting to call initPaymentSheet()?
hi glad someone to help me!
i just made a very simple checkout screen to try to understand how initPaymentSheet works.
this is the simple code:
import { View } from "react-native";
import React, { useEffect, useState } from "react";
import { Colors, Fonts, Default } from "../constants/styles";
import { useStripe } from "@stripe/stripe-react-native";
import { StripeProvider } from "@stripe/stripe-react-native";
import { STRIPE_PUBLISH_KEY } from "../data/STRIPE_PUBIC";
const CheckOutScreen = () => {
const { initPaymentSheet, presentPaymentSheet } = useStripe();
const initializePaymentSheet = async () => {
try {
const { error, paymentOption } = await initPaymentSheet({
returnURL: "https://google.com",
merchantDisplayName: "Example, Inc.",
customFlow: true,
intentConfiguration: {
mode: {
amount: 1099,
currencyCode: "EUR",
},
},
});
if (error) {
console.error("Error initializing PaymentSheet:", error);
} else {
console.log("Payment Option:", paymentOption);
}
} catch (error) {
console.error("Exception during initialization:", error);
}
};
useEffect(() => {
initializePaymentSheet().then((response) => console.log(response));
}, []);
return (
<StripeProvider publishableKey={STRIPE_PUBLISH_KEY}>
<View
style={{
margin: Default.fixPadding * 2,
marginTop: 40,
}}
></View>
</StripeProvider>
);
};
export default CheckOutScreen;
but when I enter the sceen nothing happen, should I see the console.log sowing me the paymentOptions??
How is your code calling the initializePaymentSheet function?
here:
useEffect(() => {
initializePaymentSheet()
}, []);
And do you se the empty log statement. being returned in your console?
yes no error no paymentOptions nothing printed in console
Can you do me a favor and just log "TEST"? See if that returned to the console?
useEffect(() => {
initializePaymentSheet();
}, []);
console.log("TEST");
this prints TEST in console
1 question it is mandatory to pass confirmHandler to initPaymentSheet when customFlow is true?
Good question, looking in to this.
okkk pompey no hurry i just trying to understand how it works to add to my app
It looks like it is an important part of handling your server's response so it looks like you should define it/pass it in https://stripe.com/docs/payments/accept-a-payment-deferred?platform=react-native&type=payment&integration=paymentsheet-flowcontroller#confirm-the-payment
ok i will, can i dm u later to keep this conversation, or need to start new one in dev-help?
We typically like to start a new conversation in devhelp if the old one closed. We typically keep threads open for ~20 mins but if you are tinkering and think it might take longer I can keep this one open for a bit longer
no worry ill start a new one i will take longer than 20 min thaks for the help
Sounds good, also apologies I misread the section when I was going fast. For the deferred intents flow, the confirmHandler is how you reach out to your server to create a PaymentIntent and get a client secret back. So definitely required for this flow but for a different thing than I said
yes i think so, but for me is very strange my code is not printing any log no error no success nothing
dont you think my code should return anything?
As in it is not longer printing out the test string even?
my test code :
import { View } from "react-native";
import React, { useEffect, useState } from "react";
import { Colors, Fonts, Default } from "../constants/styles";
import { useStripe } from "@stripe/stripe-react-native";
import { StripeProvider } from "@stripe/stripe-react-native";
import { STRIPE_PUBLISH_KEY } from "../data/STRIPE_PUBIC";
const CheckOutScreen = () => {
const { initPaymentSheet, presentPaymentSheet } = useStripe();
const initializePaymentSheet = async () => {
try {
const { error, paymentOption } = await initPaymentSheet({
returnURL: "https://google.com",
merchantDisplayName: "Example, Inc.",
customFlow: true,
intentConfiguration: {
mode: {
amount: 1099,
currencyCode: "EUR",
},
},
});
if (error) {
console.error("Error initializing PaymentSheet:", error);
} else {
console.log("Payment Option:", paymentOption);
}
} catch (error) {
console.error("Exception during initialization:", error);
}
};
useEffect(() => {
initializePaymentSheet();
}, []);
console.log("TEST");
return (
<StripeProvider publishableKey={STRIPE_PUBLISH_KEY}>
<View
style={{
margin: Default.fixPadding * 2,
marginTop: 40,
}}
></View>
</StripeProvider>
);
};
export default CheckOutScreen;
is not printing anything in console. I made it that simple at least to see the errors, but not even errors are printed
And the initPaymentSheet promis is not returning at all?
no nothing i can only see my console.log('TEST')
let me restar the sever and android emulator to see what happens
no return in andoird studio emulator
no return in my cell phone
in fact i can tell you that this implementation:
https://stripe.com/docs/connect/collect-then-transfer-guide?platform=react-native&ui=payment-sheet#google-pay
is working for me perfectly fine, but i need to customFlow true to check if product is avaliable or not after user inputs card data
Interesting. So customFlow is the differentiator.
Can you try passing a dummy confirmHandler? Not sure if that may be the differentiator here
yes lets do it 2 min
i made this:
a dummy endpoint in my server that returns a 400:
class CreateIntent(APIView):
def post(self,request):
print (request)
return Response({},status.HTTP_400_BAD_REQUEST)
ckecked with postman and it works.
and now added to my code handleConfirmation and passing it to initPaymentSheet as this:
const initializePaymentSheet = async () => {
try {
const { error, paymentOption } = await initPaymentSheet({
returnURL: "https://google.com",
confirmHandler: handleConfirmation,
merchantDisplayName: "Example, Inc.",
customFlow: true,
intentConfiguration: {
mode: {
amount: 1099,
currencyCode: "EUR",
},
},
});
if (error) {
console.error("Error initializing PaymentSheet:", error);
} else {
console.log("Payment Option:", paymentOption);
}
} catch (error) {
console.error("Exception during initialization:", error);
}
};
const handleConfirmation = async (
paymentMethod,
shouldSavePaymentMethod,
intentCreationCallback
) => {
// Make a request to your own server, passing paymentMethod.id and shouldSavePaymentMethod.
// Your server creates a PaymentIntent and returns its client secret or an error message
const myServerResponse = await fetch(${HOST_URL}/api/create-intent/, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
paymentMethodId: paymentMethod.id,
shouldSavePaymentMethod: shouldSavePaymentMethod,
}),
});
// Call the intentCreationCallback with the client secret or error
const { clientSecret, error } = await myServerResponse.json();
if (clientSecret) {
intentCreationCallback({ clientSecret });
} else {
intentCreationCallback({ error });
}
};
RESULT:
1.- NO RESPOSE IN MY FRONTEND
2.- NO REQUEST IN MY BACKEND
Gotcha, I will confer with my colleagues on why you are not seeing anything and will get back to you
okk thanks for the help!
My colleague noticed that you have confirmHandler: handleConfirmation, at the top level of initialize rather than in intentConfiguration which is where it belongs
Can you try relocating it and running again?
srry my bad fixed:
const initializePaymentSheet = async () => {
const { error, paymentOption } = await initPaymentSheet({
returnURL: "https://google.com",
merchantDisplayName: "Example, Inc.",
customFlow: true,
intentConfiguration: {
mode: {
amount: 1099,
currencyCode: "USD",
},
confirmHandler: handleConfirmation,
},
});
if (error) {
console.error("Error initializing PaymentSheet:", error);
} else {
console.log("Payment Option:", paymentOption);
}
};
BUT STILL NO OUTPUT IN CONSOLE
hey there, just helping out here a minute
okk thanks a lot all you for helping
Is the payment sheet still not rendering rendering? Are there any other logs from the device for errors?
no logs are desplayed and no request to my backend
i am not trying to render the paymentOption i just console.log it but i have no resposne
do you have any basics code than i can copy paste in my app to ckeck if it works?
I would suggest taking a look at our example app payment sheet screen using the deferred intent flow here: https://github.com/stripe/stripe-react-native/blob/master/example/src/screens/PaymentSheetDeferredIntentScreen.tsx
in fact i folowed this instructions bedore:
https://stripe.com/docs/connect/collect-then-transfer-guide?platform=react-native&ui=payment-sheet#google-pay
and works for me perfect, buy i need to use customflow to check if product still avaliable after user input card data
ok ill try ypur code
So it works if you remove/disable custom flow?
The main difference between that guide and the deferred intent flow is the client secret coming into play later
this is workink perfect:
const initializePaymentSheet = async () => {
const { paymentIntent, ephemeralKey, customer, publishableKey } =
await fetchPaymentSheetParams();
const { error } = await initPaymentSheet({
merchantDisplayName: "parqueCar",
customerId: customer,
customerEphemeralKeySecret: ephemeralKey,
paymentIntentClientSecret: paymentIntent,
// Set `allowsDelayedPaymentMethods` to true if your business can handle payment
//methods that complete payment after a delay, like SEPA Debit and Sofort.
allowsDelayedPaymentMethods: true,
defaultBillingDetails: {
name: userData.nickname,
},
customFlow: false,
});
if (!error) {
setLoading(true);
}
console.log("done");
};
if i remove:
customerId: customer,
customerEphemeralKeySecret: ephemeralKey,
paymentIntentClientSecret: paymentIntent,
it stops working
Do you have payment methods configured in your dashboard?
You can try adding, eg, paymentMethodTypes: ['card'],
https://github.com/stripe/stripe-react-native/blob/master/example/src/screens/PaymentSheetDeferredIntentScreen.tsx#L136C9-L137C1
i did :
const initializePaymentSheet = async () => {
const { paymentIntent, ephemeralKey, customer, publishableKey } =
await fetchPaymentSheetParams();
const { error } = await initPaymentSheet({
merchantDisplayName: "parqueCar",
customerId: customer,
customerEphemeralKeySecret: ephemeralKey,
paymentIntentClientSecret: paymentIntent,
// Set `allowsDelayedPaymentMethods` to true if your business can handle payment
//methods that complete payment after a delay, like SEPA Debit and Sofort.
defaultBillingDetails: {
name: userData.nickname,
},
customFlow: false,
});
if (!error) {
setLoading(true);
}
console.log("done");
};
works fine and display my payment options
Yea but thats with an intent client secret provided
i will try with yout github code
when you remove that you need to get PM types from somewhere else, either from a dashboard configuration for dynamic PMs or by you specifying them
Can you share your account ID so we can see your request logs etc?
let my try
or any object ID from your account
one sec
this is not working:
const initializePaymentSheet = async () => {
const { error, paymentOption } = await initPaymentSheet({
returnURL: "https://google.com",
merchantDisplayName: "Example, Inc.",
customFlow: true,
paymentMethodTypes: ["card"],
intentConfiguration: {
mode: {
amount: 1099,
currencyCode: "USD",
},
confirmHandler: handleConfirmation,
},
});
and i think my id is acct_1OO4kzAvjvXhzemX ???
the code you give to me in github has customFlow: false,
i need to confirm if product is avaliable after user inputs card data
i am looking:
https://github.com/stripe/stripe-react-native/blob/master/example/src/screens/PaymentSheetDeferredIntentMultiStepScreen.tsx
from the same repo and seems is waht i need
Right, but honestly the issue you're having is before that decision matters (after payment sheet interaction)
You should get the payment sheet ui when you call presentPaymentSheet() after init
the difference between default & customer is what happens after that
I'd suggest comparing your code to the example carefully