#Srujan-react-paymentrequestbutton
1 messages · Page 1 of 1 (latest)
Hello! We've had people hit this before, but usually they diagnose WHY canMakePayment is called multiple times and correct their code to get rid of the rerenders. Have you pinpointed why your component is being rendered multiple times?
It's because the event handling I am doing makes use of context values that get updated by other components =/.
Just confirming though, if I console log I do see multiple console logs within my useEffect that is making the call to canMakePayment (more than 2, I believe React.strictmode runs useEffects twice but this shouldn't affect the display, confirmed from an earlier branch of code where Google Pay was showing up)
From the docs: If the checkout flow needs to know whether PaymentRequest.canMakePayment() will return true even before all line items and their prices are known, you can instantiate PaymentRequest with dummy data and pre-query .canMakePayment(). If you call .canMakePayment() multiple times, keep in mind that the first parameter to the PaymentRequest constructor should contain the same method names and data.
So I'm wondering if Stripe behind the hood is using the same parameters when making the call?
But I think you're right, if I can remove the multiple renders I would be in better shape
Sorry I spoke too soon. It does look like my google pay button is only rendering once and the useEffect that makes the canMakePayment call only happens once (twice with strictmode, but again, shouldn't affect the code)
I can post my Button here if it helps
So I'm wondering if Stripe behind the hood is using the same parameters when making the call?
I'm not sure of this since I don't know the specifics of how we've implemented under the hood, but assuming you're creating the Payment Request in useEffect then I'd assume we'd pass the same thing
Would you mind looking at my Google Pay Button component and seeing if you see any reason why it wouldn't be showing? The result coming back from the Promise returned from paymentRequest.canMakePayment is null
import { useNavigate } from 'react-router-dom';
import {
PaymentRequestButtonElement,
useStripe
} from '@stripe/react-stripe-js';
import { PaymentRequest } from '@stripe/stripe-js';
import fetchClientSecret from '../../../utils/Stripe/fetchClientSecret';
import { getErrorDialogText } from '../../../utils/Functions/errors';
import { useCart } from '../../../hooks/useCart';
import { useOrder } from '../../../hooks/useOrder';
import { useRestaurant } from '../../../hooks/useRestaurant';
import { Order, OrderStatus } from '../../../types/order';
import { useTranslation } from 'react-i18next';
const GooglePayButton = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const stripe = useStripe();
const cart = useCart();
const { setOpenOrderModal, orderDispatch } = useOrder();
const { currentRestaurant } = useRestaurant();
const {
stripeAmount,
userInfo,
setErrorDialogText,
setOpenPaymentsDrawer,
setOpenSubmittingOrderDialog,
cartDispatch
} = cart;
const getTranslatedError = (error: string) => {
const errorResponse = getErrorDialogText(error);
setErrorDialogText({
title: t(errorResponse.title),
description: t(errorResponse.description)
});
};
const redirectToOrder = () => {
setOpenOrderModal(true);
navigate(`/r/${currentRestaurant.restaurantId}`);
};
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest>();
useEffect(() => {
if (stripe) {
const pr = stripe.paymentRequest({
country: 'US',
currency: 'usd',
total: {
label: 'Payment Amount',
amount: stripeAmount
}
});
// Check the availability of the Payment Request API.
console.log('how many times does this fucking run');
pr.canMakePayment()
.then((result) => {
if (result) {
setPaymentRequest(pr);
}
})
.catch((err) => console.error(err));
}
}, [stripe, stripeAmount]);
if (stripe && paymentRequest) {
paymentRequest.on('paymentmethod', async (ev) => {
setOpenPaymentsDrawer(false);
setOpenSubmittingOrderDialog(true);
const clientSecret = await fetchClientSecret(stripeAmount);
if (typeof clientSecret === 'string') {
const { paymentIntent, error } = await stripe.confirmCardPayment(
clientSecret,
{
payment_method: ev.paymentMethod.id,
receipt_email: userInfo.email
},
{ handleActions: false }
);
if (error && error.code) {
getTranslatedError(error.code);
ev.complete('fail');
}
ev.complete('success');
if (paymentIntent && paymentIntent.status === 'requires_action') {
// Let Stripe.js handle the rest of the payment flow.
stripe.confirmCardPayment(clientSecret, {
payment_method: ev.paymentMethod.id,
receipt_email: userInfo.email
});
} else {
// The payment has succeeded.
const newOrder: Order = {
restaurantId: currentRestaurant.restaurantUUID,
orderNum: 1,
orderItem: cart,
orderStatus: OrderStatus.PENDING
};
console.log('my new order', newOrder);
orderDispatch({ type: 'add_order', payload: newOrder });
window.sessionStorage.removeItem('cart');
cartDispatch({
type: 'clear_storage'
});
redirectToOrder();
}
}
});
}
if (paymentRequest) {
const options = {
paymentRequest,
style: {
paymentRequestButton: {
height: '48px',
borderRadius: '8px'
}
}
};
return <PaymentRequestButtonElement options={options} />;
}
return null;
};
export default GooglePayButton;
do you actually have a site I can look at instead to start?
Sure
The deceptive site ahead warning chrome gives isn't the issue since this is failing on my dev server as well
Add an item to the cart and a banner will popup on the bottom and click it, then follow to check out, enter name and phone, then hit continue to pay, and that's where you should see the Button displayed (there's a placeholder text for when it isn't showing)
Google pay is showing up fine for me - is there supposed to be an error/not show up?
Damn really? Okay...maybe it's just my browser then
Yeah, like I definitely see it working on my end - what do you see when you go to https://stripe.com/docs/stripe-js/elements/payment-request-button?
That one works for me
It shows. the error for 2 seconds then displays
This shows for a little before the Gpay button shows
So weird
Does it show for you here? https://mweb.dev.sparkd.com/r/naq01
yup, it shows for me there as well (but it does initially show as unavailable and takes one second before showing)
I tried running in incognito mode and signing into my google account but it doesn't show up on the stripe page. Do you know of a good way to test this or browser settings that may be disabling me from seeing it show?
incognito mode never works with google pay, so that's not an option
i'm glad it got all sorted out! I know testing the payment request button can be a pain
Well it's not stripe's fault. I believe the source of it is chrome and the payment request api
source of pain ***
How do you like working for Stripe? Are you technically a dev? Was considering put in an application
You probably can't answer truthfully here, that's okay.
Most of the stripe folks here are devs (including me) 🙂