#syedhussain_code
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1310590516123013163
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
^0.39.0
const initializePaymentSheet = async () => {
const {error} = await initPaymentSheet({
merchantDisplayName: 'Sarookh, Inc.',
intentConfiguration: {
mode: {
currencyCode: 'AED',
setupFutureUsage: 'OffSession',
},
confirmHandler: confirmHandler,
},
});
if (error) {
console.log({errorip: error});
// handle error
}
};
useEffect(() => {
initializePaymentSheet();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const confirmHandler = async (
paymentMethod: any,
shouldSavePaymentMethod: any,
intentCreationCallback: any,
) => {
try {
console.log({
paymentMethod,
shouldSavePaymentMethod,
intentCreationCallback,
});
// Fetching client secret from server
const res = await proceedSetupIntent(paymentMethod?.id);
console.log('client secret', res?.clientSecret);
if (res?.clientSecret) {
const intentResponse = intentCreationCallback({
clientSecret: res?.clientSecret,
});
console.log({intentResponse});
navigation.navigate('AdSummary');
} else {
console.log('error in ICC');
showToast('error', 'Error Occurred in saving Payment Method');
}
} catch (error) {
console.log({error});
}
};
const didTapCheckoutButton = async () => {
console.log('check');
const {error} = await presentPaymentSheet({timeout: 5000});
console.log({error});
if (error) {
if (
error.code === PaymentSheetError.Canceled ||
PaymentSheetError.Timeout ||
PaymentSheetError.Failed
) {
// Customer canceled - you should probably do nothing.
console.log('presentPaymentSheet errorrr');
} else {
showToast('error', error.message);
}
} else {
// Setup completed - show a confirmation screen.
}
};
This is my complete code
would you mind sharing a recording of what's happening or some screenshots? It would also help to see if you have any error logs
I have find a little workaround, that
const res = await proceedSetupIntent(paymentMethod?.id);
it gives undefined in res when error occurs, so can you tell me how to close payment sheet programatically, or maybe stop processing if gets undefined in response of createSetupIntent api?
hi! I'm taking over this thread.
ok sure, waiting for response of above mentioned query
it gives undefined in res when error occurs
can you clarify what exactly is the error?
how to close payment sheet programatically
not sure, having a look...
when we give the card which have insufficient balance, the error will occur
when that error occurs I need to close the payment sheet so that the user can input another card details
so the PaymentSheet opens, the user enter their payment information, and there you get an error and the user is "stuck"? again, can you share a screenshot and also the exact error message you see in your logs?
That would imply that your backend code to create the intent is failing:
const res = await proceedSetupIntent(paymentMethod?.id);
Are there any logs in your server code that proceedSetupIntent calls?
Or is not returning a clientSecret key in the response
it is not returning client secret because I am using a test card which is supposed to give insufficient balance error
now I need that what would I do if such error occurs because Payment sheet gets stuck on processing when this error occurs
I need something to close the sheet if error occurs or in other words need a method to stop processing or close payment sheet, if I do not receive client_secret
Not sure how you expect the callback to progress if your own if block expects a client_secret?
There's now way to programatically close the Payment Sheet, no
I don't understand why you wouldn't return a client_secret in the backend? What exactly does the proceedSetupIntent call do?
The confirmation should happen client side in the Payment Sheet, and there you'd see the 'insufficient funds' error and the sheet wouldn't be stuck
Yeah, confirmation is happening at client side
const initializePaymentSheet = async () => {
const {error} = await initPaymentSheet({
merchantDisplayName: 'Sarookh, Inc.',
intentConfiguration: {
mode: {
currencyCode: 'AED',
setupFutureUsage: 'OffSession',
},
confirmHandler: confirmHandler,
},
});
if (error) {
console.log({errorip: error});
// handle error
}
};
with confirmHandler
const confirmHandler = async (
paymentMethod: any,
shouldSavePaymentMethod: any,
intentCreationCallback: any,
) => {
try {
console.log({
paymentMethod,
shouldSavePaymentMethod,
intentCreationCallback,
});
const res = await proceedSetupIntent(paymentMethod?.id);
console.log('client secret', {res});
if (res?.clientSecret) {
const intentResponse = intentCreationCallback({
clientSecret: res?.clientSecret,
});
console.log({intentResponse});
navigation.navigate('AdSummary');
} else {
console.log('error in ICC');
showToast('error', 'Error Occurred in saving Payment Method');
}
} catch (error) {
console.log({error});
}
In confirmHandler, I send payment?.id to my server, which return me client secret if successful and error if unsuccessful, if it gets unsuccessful I need to close the bottomSheet so that user caninput details again
OK, but then what is proceedSetupIntent actually doing and why isn't it returning a client_secret?
In confirmHandler, I send payment?.id to my server, which return me client secret if successful and error if unsuccessful, if it gets unsuccessful I need to close the bottomSheet so that user caninput details again
Successful and unsuccessful what? Can you please just share the code in your server and/or a request it makes to our API
Overall I think you're confused. You seem to try to confirm an intent server-side, and also client-side?
const proceedSetupIntent = async (paymentId: string) => {
try {
const res = await setupIntent({
customerId: customerId,
paymentMethod: paymentId,
adId: adId,
AdCreationStep: 6,
});
if (res?.data) {
return res?.data;
}
} catch (error) {
console.log({error});
}
};
Because I am using a test card which is supposed to give an error of insufficient funds, thats why it does not return client secret
async createSetupIntent(
customerId: string,
email: string,
paymentMethod: string,
adId: number,
adCreationStep: number,
): Promise<{ clientSecret: string }> {
const setupIntent = await this.stripe.setupIntents.create({
customer: customerId,
metadata: {
email,
adId,
adCreationStep,
},
confirm: true,
payment_method: paymentMethod,
usage: 'off_session',
payment_method_types: ['card'],
});
if (setupIntent.client_secret) {
return { clientSecret: setupIntent?.client_secret };
}
}
async getAllPaymentMethods(customerId: string, limit: number): Promise<any> {
const paymentMethods = await this.stripe.customers.listPaymentMethods(
customerId,
{
limit,
},
);
if (paymentMethods.data.length === 0) {
throw new HttpException(
'No payment methods exist',
HttpStatus.BAD_REQUEST,
);
}
return paymentMethods;
}
This is my server side code
unsuccessfu setupIntentCreation
I don't understand. You're creating a Setup Intent, passing confirm: true meaning we will immediately attempt confirmation โ this is why it declines (with that test card) and you don't have a client_secret
If you're confirming server-side when why do you need the Payment Sheet?
IMO, you need to remove the confirm and payment_method parameters from your stripe.setupIntents.create and then you'll have a client_secret in the response than you can confirm client side in the Payment Sheet with whatever test details you input (simulating an actual customer flow)
Right now you've trying to create and confirm a Setup Intent with a pre-existing pm_xxx (paymentMethod) which is probably a test card that declines. Doesn't make any sense in a flow where your customer is inputting card details
https://docs.stripe.com/payments/accept-a-payment-deferred?platform=react-native&type=setup
I am using this documentation