#kabachok_error

1 messages · Page 1 of 1 (latest)

olive juncoBOT
#

👋 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/1319631833608224853

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

unkempt spear
#

hi there!

#

are you using the Payment Element to accept payments?

autumn harness
#

Hi! Yes I do

unkempt spear
autumn harness
#

Yes, I followed this documentation.

#

Here you can see error example

unkempt spear
#

can you share a link where we can reproduce the issue?

autumn harness
#

You should first login and then go back to this url.

#

Here are the production keys. Should I change them to test ones?

#

This site should be opened from a mobile view.

olive juncoBOT
deft mortar
#

Yes, could you please change the keys to Test mode?

autumn harness
#

Switched to test keys.

deft mortar
#

Could you please share the full code related to the Express Checkout Element?

autumn harness
#

Server-side intent.client_secret generation (python-django)
intent: PaymentIntent = PaymentIntent.create(
api_key=settings.STRIPE_SECRET_KEY,
amount=int(price.amount * 100),
currency=price.currency.symbol_code.lower(),
automatic_payment_methods={"enabled": True},
metadata={"transaction_id": transaction.id},
)
return Response({"id": intent.client_secret}, status=status.HTTP_200_OK)

#

"Pay" button code

import { ModalPrimary } from "@/components/ModalPrimary/ModalPrimary";
import { FC, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
import { PaymentRequestForm } from "@/components/PaymentRequestForm/PaymentRequestForm";
import s from "./ReplenishModal.module.scss";

const appearance = {
theme: "night" as const,
labels: "floating" as const,
variables: {
spacingGridColumn: "0",
spacingGridRow: "0",
borderRadius: "0",
},
};

const stripePromise = loadStripe(${import.meta.env.VITE_STRIPE_TEST_PUBLIC_KEY});

interface IProps {
clientSecret: string | null;
isOpen: boolean;
onExit: () => void;
}

const ReplenishModal: FC<IProps> = ({ clientSecret, isOpen, onExit }) => {
const { t } = useTranslation();

return (
<ModalPrimary
title={t("Оплатить")}
closeIcon
onExit={onExit}
onOverlayClick={onExit}
isOpen={isOpen}
classNameWrapper={s.modal}>
{clientSecret && stripePromise && (
<Elements stripe={stripePromise} options={{ clientSecret, appearance }}>
<PaymentRequestForm clientSecret={clientSecret} />
</Elements>
)}
</ModalPrimary>
);
};

export default ReplenishModal;

#

Payment Form code:

import React, { useEffect, useState } from "react";
import { PaymentElement, useElements, useStripe, ExpressCheckoutElement} from "@stripe/react-stripe-js";
import { Button } from "../ui-kit";
import s from "./PaymentRequestForm.module.scss";
import BaseRoutes from "@/routes/BaseRoutes";
import { useAppSelector } from "@/redux/reducers/reducers";
import { StripeElementType } from "@stripe/stripe-js";
import { useTranslation } from "react-i18next";
import toast from "react-hot-toast";

interface PaymentRequestFormProps {
clientSecret: string;
}

export const PaymentRequestForm: React.FC<PaymentRequestFormProps> = ({ clientSecret }) => {
const { t } = useTranslation();
const isTelegramApp = useAppSelector(s => s.app.isTelegramApp)
const stripe = useStripe();
const elements = useElements();
const [message, setMessage] = useState<string | null>(null);
const [isProcessing, setIsProcessing] = useState(false);
const [keyboardVisible, setKeyboardVisible] = useState(false);

const handleSubmit = async (e: any) => {
e.preventDefault();

if (!stripe || !elements) {
  return;
}

setIsProcessing(true);
const { error: submitError } = await elements.submit();
if (submitError) {
  console.log(submitError);
  return;
}

const { error } = await stripe.confirmPayment({
  elements,
  clientSecret,
  confirmParams: {
    return_url: window.location.origin + BaseRoutes.wallet,
  },
});

if (error.type === "card_error" || error.type === "validation_error") {
  toast.error(error.message || t("An unexpected error occured."));
} else {
  toast.error(t("An unexpected error occured."));
}

setIsProcessing(false);

};

#

const handleElementFocus = (event: { elementType: StripeElementType }) => {
console.log(event);
if (!isTelegramApp) {
return
}

setKeyboardVisible(true);

};

const handleElementBlur = () => {
setKeyboardVisible(false)
};

return (
<form id="payment-form" className={s.form} onSubmit={handleSubmit} style={{ paddingBottom: ${keyboardVisible ? 100 : 0}%}}>
<ExpressCheckoutElement onConfirm={handleSubmit} />
<PaymentElement
id="payment-element"
onFocus={handleElementFocus}
onBlur={handleElementBlur}
/>
<Button className={s.btn} type="submit" disabled={isProcessing || !stripe || !elements} onClick={handleSubmit}>
{isProcessing ? t("Обработка...") : t("Оплатить")}
</Button>
{message && <div id="payment-message">{message}</div>}
</form>
);
}

deft mortar
#

I see you've updated the code to show Google Pay in Payment Element and now the payment seems to be going through.

autumn harness
#

I still getting REQUEST_TIMEOUT error

deft mortar
#

I cannot reproduce it anymore.
I suggest you to write in to us so my engineering team can investigate it in our own time:

olive juncoBOT
#

Hello @autumn harness, we have sent you a direct message, please check it at https://discord.com/channels/@me/1319648476908224533

  • 🔗The message has instructions on how to open a direct support case with our Developer Support team, in order to help you more effectively.