#incaelum-reactnative-deferredintent

1 messages · Page 1 of 1 (latest)

lost deltaBOT
#

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.

modest venture
#

Hi 👋

Can you share the details of how you attempting to call initPaymentSheet()?

dusk obsidian
#

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??

modest venture
#

How is your code calling the initializePaymentSheet function?

dusk obsidian
#

here:
useEffect(() => {
initializePaymentSheet()

}, []);

modest venture
#

And do you se the empty log statement. being returned in your console?

dusk obsidian
#

yes no error no paymentOptions nothing printed in console

modest venture
#

Can you do me a favor and just log "TEST"? See if that returned to the console?

dusk obsidian
#

useEffect(() => {
initializePaymentSheet();
}, []);
console.log("TEST");

this prints TEST in console

#

1 question it is mandatory to pass confirmHandler to initPaymentSheet when customFlow is true?

lost deltaBOT
void ruin
#

Good question, looking in to this.

dusk obsidian
#

okkk pompey no hurry i just trying to understand how it works to add to my app

void ruin
dusk obsidian
#

ok i will, can i dm u later to keep this conversation, or need to start new one in dev-help?

void ruin
#

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

dusk obsidian
#

no worry ill start a new one i will take longer than 20 min thaks for the help

void ruin
#

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

dusk obsidian
#

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?

void ruin
#

As in it is not longer printing out the test string even?

dusk obsidian
#

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

void ruin
#

And the initPaymentSheet promis is not returning at all?

dusk obsidian
#

no nothing i can only see my console.log('TEST')

#

let me restar the sever and android emulator to see what happens

void ruin
#

Interesting. So customFlow is the differentiator.

#

Can you try passing a dummy confirmHandler? Not sure if that may be the differentiator here

dusk obsidian
#

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

void ruin
#

Gotcha, I will confer with my colleagues on why you are not seeing anything and will get back to you

dusk obsidian
#

okk thanks for the help!

void ruin
#

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?

dusk obsidian
#

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

outer cobalt
#

hey there, just helping out here a minute

dusk obsidian
#

okk thanks a lot all you for helping

outer cobalt
#

Is the payment sheet still not rendering rendering? Are there any other logs from the device for errors?

dusk obsidian
#

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?

outer cobalt
dusk obsidian
#

ok ill try ypur code

outer cobalt
#

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

dusk obsidian
#

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

outer cobalt
#

Do you have payment methods configured in your dashboard?

dusk obsidian
#

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

outer cobalt
#

Yea but thats with an intent client secret provided

dusk obsidian
#

i will try with yout github code

outer cobalt
#

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?

dusk obsidian
#

let my try

outer cobalt
#

or any object ID from your account

dusk obsidian
#

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

outer cobalt
#

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

dusk obsidian
#

i will, the most strange for me is that my code dont output anything

#

thanks for the help this is step will take me longer i will come tomorrow with updates, thanks so much for the help!