From bdbe4f4b04eb82c770682770e84802fc64d8bc61 Mon Sep 17 00:00:00 2001 From: dzfelix Date: Sun, 14 Jul 2024 11:36:23 +0300 Subject: [PATCH] Revert "stripe payment" This reverts commit 3a6c7bd88c358f050c0edbbf2ec290714644f4c9. --- src/actions/experts.ts | 34 +-- src/actions/stripe.ts | 78 ----- src/app/[locale]/(main)/layout.tsx | 5 +- src/app/[locale]/experts/[expertId]/page.tsx | 3 +- src/app/[locale]/layout.tsx | 2 +- src/app/[locale]/payment/@payment/page.tsx | 20 -- src/app/[locale]/payment/page.tsx | 28 -- src/app/[locale]/payment/result/layout.tsx | 19 -- src/app/[locale]/payment/result/page.tsx | 27 -- src/app/api/webhooks/route.ts | 66 ----- src/components/Experts/ExpertDetails.tsx | 33 +-- src/components/Modals/SchedulerModal.tsx | 290 ------------------- src/components/stripe/ElementsForm.tsx | 195 ------------- src/components/stripe/PrintObject.tsx | 10 - src/components/stripe/StripeTestCards.tsx | 19 -- src/lib/stripe.ts | 11 - src/types/experts.ts | 26 -- src/types/payment.ts | 3 - src/utils/get-stripe.ts | 15 - src/utils/stripe-helpers.ts | 30 -- 20 files changed, 9 insertions(+), 905 deletions(-) delete mode 100644 src/actions/stripe.ts delete mode 100644 src/app/[locale]/payment/@payment/page.tsx delete mode 100644 src/app/[locale]/payment/page.tsx delete mode 100644 src/app/[locale]/payment/result/layout.tsx delete mode 100644 src/app/[locale]/payment/result/page.tsx delete mode 100644 src/app/api/webhooks/route.ts delete mode 100644 src/components/Modals/SchedulerModal.tsx delete mode 100644 src/components/stripe/ElementsForm.tsx delete mode 100644 src/components/stripe/PrintObject.tsx delete mode 100644 src/components/stripe/StripeTestCards.tsx delete mode 100644 src/lib/stripe.ts delete mode 100644 src/types/payment.ts delete mode 100644 src/utils/get-stripe.ts delete mode 100644 src/utils/stripe-helpers.ts diff --git a/src/actions/experts.ts b/src/actions/experts.ts index 5ddb524..91e0d73 100644 --- a/src/actions/experts.ts +++ b/src/actions/experts.ts @@ -1,7 +1,5 @@ import { apiClient } from '../lib/apiClient'; -import {GeneralFilter, ExpertsData, ExpertDetails, ExpertScheduler, ExpertSchedulerSession} from '../types/experts'; -import {useLocalStorage} from "../hooks/useLocalStorage"; -import {AUTH_TOKEN_KEY} from "../constants/common"; +import { GeneralFilter, ExpertsData, ExpertDetails } from '../types/experts'; export const getExpertsList = async (locale: string, filter?: GeneralFilter) => { const response = await apiClient.post( @@ -30,33 +28,3 @@ export const getExpertById = async (id: string, locale: string) => { return response.data as ExpertDetails || null; }; - -export const getSchedulerByExpertId = async (expertId: string, locale: string, jwt: string) => { - const response = await apiClient.post( - '/home/sessionsignupdata', - { id: expertId }, - { - headers: { - 'X-User-Language': locale, - Authorization: `Bearer ${jwt}` - } - } - ); - - return response.data as ExpertScheduler || null; -}; - -export const getSchedulerSession = async (data: { coachId: number, tagId: number, startAtUtc: string, clientComment: string }, locale: string, jwt: string) => { - const response = await apiClient.post( - '/home/sessionsignupsubmit', - data, - { - headers: { - 'X-User-Language': locale, - Authorization: `Bearer ${jwt}` - } - } - ); - - return response.data as ExpertSchedulerSession || null; -}; \ No newline at end of file diff --git a/src/actions/stripe.ts b/src/actions/stripe.ts deleted file mode 100644 index c0d2254..0000000 --- a/src/actions/stripe.ts +++ /dev/null @@ -1,78 +0,0 @@ -"use server"; - -import {PaymentIntentCreateParams, Stripe} from "stripe"; - -import { headers } from "next/headers"; - -import { formatAmountForStripe } from "../utils/stripe-helpers"; -import { stripe } from "../lib/stripe"; - -export async function createCheckoutSession( - data: FormData, -): Promise<{ client_secret: string | null; url: string | null }> { - const ui_mode = data.get( - "uiMode", - ) as Stripe.Checkout.SessionCreateParams.UiMode; - console.log('DATA', data) - const origin: string = headers().get("origin") as string; - - const checkoutSession: Stripe.Checkout.Session = - await stripe.checkout.sessions.create({ - mode: "payment", - submit_type: "donate", - line_items: [ - { - quantity: 1, - price_data: { - currency: 'eur', - product_data: { - name: "Custom amount donation", - }, - unit_amount: formatAmountForStripe( - Number(data.get("customDonation") as string), - 'eur', - ), - }, - }, - ], - ...(ui_mode === "hosted" && { - success_url: `${origin}/payment/with-checkout/result?session_id={CHECKOUT_SESSION_ID}`, - cancel_url: `${origin}/with-checkout`, - }), - ...(ui_mode === "embedded" && { - return_url: `${origin}/payment/with-embedded-checkout/result?session_id={CHECKOUT_SESSION_ID}`, - }), - ui_mode, - }); - - return { - client_secret: checkoutSession.client_secret, - url: checkoutSession.url, - }; -} - -export async function createPaymentIntent( - data: any, -): Promise<{ client_secret: string }> { - - const params = { - amount: formatAmountForStripe( - Number(data['amount'] as string), - 'eur', - ), - automatic_payment_methods: { enabled: true }, - currency: 'eur', - } as PaymentIntentCreateParams; - - // additional params - if (data.sessionId){ - params.metadata = { - sessionId : data.sessionId - } - } - - const paymentIntent: Stripe.PaymentIntent = - await stripe.paymentIntents.create(params); - - return { client_secret: paymentIntent.client_secret as string }; -} \ No newline at end of file diff --git a/src/app/[locale]/(main)/layout.tsx b/src/app/[locale]/(main)/layout.tsx index 7558955..daa1e7d 100644 --- a/src/app/[locale]/(main)/layout.tsx +++ b/src/app/[locale]/(main)/layout.tsx @@ -16,8 +16,7 @@ export default function MainLayout({ children, news, directions, experts }: { children: ReactNode, news: ReactNode, directions: ReactNode, - experts: ReactNode, - payment: ReactNode + experts: ReactNode }) { return ( <> @@ -27,4 +26,4 @@ export default function MainLayout({ children, news, directions, experts }: { {experts} ); -} +}; diff --git a/src/app/[locale]/experts/[expertId]/page.tsx b/src/app/[locale]/experts/[expertId]/page.tsx index 23dd24e..6d1a701 100644 --- a/src/app/[locale]/experts/[expertId]/page.tsx +++ b/src/app/[locale]/experts/[expertId]/page.tsx @@ -11,7 +11,6 @@ import { } from '../../../../components/Experts/ExpertDetails'; import { Details } from '../../../../types/experts'; import { BackButton } from '../../../../components/view/BackButton'; -import {SchedulerModal} from "../../../../components/Modals/SchedulerModal"; export const metadata: Metadata = { title: 'Bbuddy - Experts item', @@ -82,7 +81,7 @@ export default async function ExpertItem({ params: { expertId = '', locale} }: { - +

Expert Background

diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 8eee097..520e6ae 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -39,4 +39,4 @@ export default function LocaleLayout({ children, params: { locale } }: LayoutPro ); -} +}; diff --git a/src/app/[locale]/payment/@payment/page.tsx b/src/app/[locale]/payment/@payment/page.tsx deleted file mode 100644 index c93d91d..0000000 --- a/src/app/[locale]/payment/@payment/page.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import type { Metadata } from "next"; - -import {ElementsForm} from "../../../../components/stripe/ElementsForm"; - -export const metadata: Metadata = { - title: "Payment", -}; - -export default function PaymentElementPage({ - searchParams, - }: { - searchParams?: { payment_intent_client_secret?: string }; -}) { - return ( -
-

Pay

- -
- ); -} \ No newline at end of file diff --git a/src/app/[locale]/payment/page.tsx b/src/app/[locale]/payment/page.tsx deleted file mode 100644 index 55064d7..0000000 --- a/src/app/[locale]/payment/page.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import type { Metadata } from 'next'; -import { unstable_setRequestLocale } from 'next-intl/server'; -import { useTranslations } from 'next-intl'; -import { GeneralTopSection } from '../../../components/Page'; -import PaymentElementPage from "./@payment/page"; - -export const metadata: Metadata = { - title: 'Bbuddy - Take the lead with BB', - description: 'Bbuddy desc Take the lead with BB' -}; - -export default function BbClientPage({ params: { locale } }: { params: { locale: string } }) { - unstable_setRequestLocale(locale); - const t = useTranslations('BbClient'); - - return ( - <> - -
- -
- - ); -}; diff --git a/src/app/[locale]/payment/result/layout.tsx b/src/app/[locale]/payment/result/layout.tsx deleted file mode 100644 index bea1996..0000000 --- a/src/app/[locale]/payment/result/layout.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import type { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Payment Intent Result", -}; - -export default function ResultLayout({ - children, - }: { - children: React.ReactNode; -}) { - return ( -
-

Payment Intent Result

- {children} -
- ); -} \ No newline at end of file diff --git a/src/app/[locale]/payment/result/page.tsx b/src/app/[locale]/payment/result/page.tsx deleted file mode 100644 index dad26cd..0000000 --- a/src/app/[locale]/payment/result/page.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import type { Stripe } from "stripe"; - -import { stripe} from "../../../../lib/stripe"; -import PrintObject from "../../../../components/stripe/PrintObject"; - -export default async function ResultPage({ - searchParams, - }: { - searchParams: { payment_intent: string }; -}) { - if (!searchParams.payment_intent) - throw new Error("Please provide a valid payment_intent (`pi_...`)"); - - const paymentIntent: Stripe.PaymentIntent = - await stripe.paymentIntents.retrieve(searchParams.payment_intent); - - // Тут под идее тыкнуться в бек на тему того - прошла ли оплата. в зависимости от этого показать что все ок или нет - // также стоит расшить ссылкой КУДА переходить после того как показали что все ок. - - return ( - <> -

Status: {paymentIntent.status}

-

Payment Intent response:

- - - ); -} \ No newline at end of file diff --git a/src/app/api/webhooks/route.ts b/src/app/api/webhooks/route.ts deleted file mode 100644 index 6fa9a39..0000000 --- a/src/app/api/webhooks/route.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { Stripe } from "stripe"; - -import { NextResponse } from "next/server"; - -import { stripe } from "../../../lib/stripe"; - -export async function POST(req: Request) { - let event: Stripe.Event; - - try { - event = stripe.webhooks.constructEvent( - await (await req.blob()).text(), - req.headers.get("stripe-signature") as string, - process.env.STRIPE_WEBHOOK_SECRET as string, - ); - } catch (err) { - const errorMessage = err instanceof Error ? err.message : "Unknown error"; - // On error, log and return the error message. - if (err! instanceof Error) console.log(err); - console.log(`❌ Error message: ${errorMessage}`); - return NextResponse.json( - { message: `Webhook Error: ${errorMessage}` }, - { status: 400 }, - ); - } - - // Successfully constructed event. - console.log("✅ Success:", event.id); - - const permittedEvents: string[] = [ - "checkout.session.completed", - "payment_intent.succeeded", - "payment_intent.payment_failed", - ]; - - if (permittedEvents.includes(event.type)) { - let data; - - try { - switch (event.type) { - case "checkout.session.completed": - data = event.data.object as Stripe.Checkout.Session; - console.log(`💰 CheckoutSession status: ${data.payment_status}`); - break; - case "payment_intent.payment_failed": - data = event.data.object as Stripe.PaymentIntent; - console.log(`❌ Payment failed: ${data.last_payment_error?.message}`); - break; - case "payment_intent.succeeded": - data = event.data.object as Stripe.PaymentIntent; - console.log(`💰 PaymentIntent status: ${data.status}`); - break; - default: - throw new Error(`Unhandled event: ${event.type}`); - } - } catch (error) { - console.log(error); - return NextResponse.json( - { message: "Webhook handler failed" }, - { status: 500 }, - ); - } - } - // Return a response to acknowledge receipt of the event. - return NextResponse.json({ message: "Received" }, { status: 200 }); -} \ No newline at end of file diff --git a/src/components/Experts/ExpertDetails.tsx b/src/components/Experts/ExpertDetails.tsx index 773a73a..0c06c74 100644 --- a/src/components/Experts/ExpertDetails.tsx +++ b/src/components/Experts/ExpertDetails.tsx @@ -1,36 +1,20 @@ 'use client'; -import React, {FC, useEffect, useState} from 'react'; +import React, { FC } from 'react'; import Image from 'next/image'; import { Tag, Image as AntdImage, Space } from 'antd'; import { ZoomInOutlined, ZoomOutOutlined, StarFilled } from '@ant-design/icons'; -import {ExpertDetails, ExpertDocument, ExpertScheduler} from '../../types/experts'; +import { ExpertDetails, ExpertDocument } from '../../types/experts'; import { Locale } from '../../types/locale'; import { CustomRate } from '../view/CustomRate'; -import {getSchedulerByExpertId} from "../../actions/experts"; -import {useLocalStorage} from "../../hooks/useLocalStorage"; -import {AUTH_TOKEN_KEY} from "../../constants/common"; -import dayjs from "dayjs"; -import {SchedulerModal} from "../Modals/SchedulerModal"; type ExpertDetailsProps = { expert: ExpertDetails; locale?: string; - expertId?: string; }; -export const ExpertCard: FC = ({ expert, locale, expertId }) => { +export const ExpertCard: FC = ({ expert }) => { const { publicCoachDetails } = expert || {}; - const [showSchedulerModal, setShowSchedulerModal] = useState(false); - const [mode, setMode] = useState<'data' | 'time' | 'pay' | 'finish'>('data'); - const { publicCoachDetails: { tags = [], sessionCost = 0, sessionDuration = 0 } } = expert || {}; - - const onSchedulerHandle = async () => { - console.log('sessionCost', sessionCost); - setMode('data'); - setShowSchedulerModal(true) - // отмаппим. - } return (
@@ -52,7 +36,7 @@ export const ExpertCard: FC = ({ expert, locale, expertId })
- + Schedule @@ -61,15 +45,6 @@ export const ExpertCard: FC = ({ expert, locale, expertId }) Video
- setShowSchedulerModal(false)} - updateMode={setMode} - mode={mode} - expertId={expertId as string} - locale={locale as string} - sessionCost={sessionCost} - /> ); }; diff --git a/src/components/Modals/SchedulerModal.tsx b/src/components/Modals/SchedulerModal.tsx deleted file mode 100644 index 77d6c82..0000000 --- a/src/components/Modals/SchedulerModal.tsx +++ /dev/null @@ -1,290 +0,0 @@ -'use client'; - -import React, {Dispatch, FC, SetStateAction, useEffect, useState} from 'react'; -import { usePathname } from 'next/navigation'; -import classNames from 'classnames'; -import Link from 'next/link'; -import {Modal, Form, Calendar, Radio } from 'antd'; -import type { CalendarProps, RadioChangeEvent } from 'antd'; -import { CloseOutlined } from '@ant-design/icons'; -import { RegisterContent, ResetContent, FinishContent, EnterContent } from './authModalContent'; -import dayjs, { Dayjs } from 'dayjs'; -import {ExpertDetails, ExpertScheduler, Tags} from "../../types/experts"; -import { createStyles } from 'antd-style'; -import {useLocalStorage} from "../../hooks/useLocalStorage"; -import {AUTH_TOKEN_KEY} from "../../constants/common"; -import {getSchedulerByExpertId, getSchedulerSession} from "../../actions/experts"; -import {ElementsForm} from "../stripe/ElementsForm"; - -type SchedulerModalProps = { - open: boolean; - handleCancel: () => void; - mode: 'data' | 'time' | 'pay' | 'finish'; - updateMode: (mode: 'data' | 'time' | 'pay' | 'finish') => void; - sessionCost: number; - expertId: string; - locale: string; -}; - -const useStyle = createStyles(({ token, css, cx }) => { - const lunar = css` - color: ${token.colorTextTertiary}; - font-size: ${token.fontSizeSM}px; - `; - return { - wrapper: css` - width: 450px; - border: 1px solid ${token.colorBorderSecondary}; - border-radius: ${token.borderRadiusOuter}; - padding: 5px; - `, - dateCell: css` - position: relative; - &:before { - content: ''; - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - margin: auto; - max-width: 40px; - max-height: 40px; - background: transparent; - transition: background 300ms; - border-radius: ${token.borderRadiusOuter}px; - border: 1px solid transparent; - box-sizing: border-box; - } - &:hover:before { - background: rgba(0, 0, 0, 0.04); - } - `, - today: css` - &:before { - border: 1px solid ${token.colorPrimary}; - } - `, - text: css` - position: relative; - z-index: 1; - `, - lunar, - current: css` - color: ${token.colorTextLightSolid}; - &:before { - background: ${token.colorPrimary}; - } - &:hover:before { - background: ${token.colorPrimary}; - opacity: 0.8; - } - .${cx(lunar)} { - color: ${token.colorTextLightSolid}; - opacity: 0.9; - } - `, - monthCell: css` - width: 120px; - color: ${token.colorTextBase}; - border-radius: ${token.borderRadiusOuter}px; - padding: 5px 0; - &:hover { - background: rgba(0, 0, 0, 0.04); - } - `, - monthCellCurrent: css` - color: ${token.colorTextLightSolid}; - background: ${token.colorPrimary}; - &:hover { - background: ${token.colorPrimary}; - opacity: 0.8; - } - `, - weekend: css` - color: ${token.colorError}; - &.gray { - opacity: 0.4; - } - `, - }; -}); - -export const SchedulerModal: FC = ({ - open, - handleCancel, - mode, - updateMode, - sessionCost, - locale, - expertId, -}) => { - const { styles } = useStyle({ test: true }); - const [selectDate, setSelectDate] = React.useState(dayjs()); - const [dates, setDates] = React.useState(); - const [tags, setTags] = React.useState([]); - const [tag, setTag] = React.useState(-1); - const [slot, setSlot] = React.useState(''); - const [sessionId, setSessionId] = React.useState(-1); - const [rawScheduler, setRawScheduler] = useState(null); - const [jwt] = useLocalStorage(AUTH_TOKEN_KEY, ''); - - useEffect( ()=> { - async function loadScheduler(){ - const rawScheduler = await getSchedulerByExpertId(expertId as string, locale as string, jwt) - setRawScheduler(rawScheduler) - } - if (open) { - loadScheduler() - } - }, [open]) - - useEffect(() => { - const map = {} as any - rawScheduler?.availableSlots.forEach((el)=>{ - const key = dayjs(el.startTime).format('YYYY-MM-DD'); - if (!map[key]){ - map[key] = [] - } - map[key].push(el) - - }) - console.log(rawScheduler, map) - setDates(map) - setTags(rawScheduler?.tags) - }, [rawScheduler]); - - const onPanelChange = (value: Dayjs, mode: CalendarProps['mode']) => { - console.log(value.format('YYYY-MM-DD'), mode); - }; - - const onDateChange: CalendarProps['onSelect'] = (value, selectInfo) => { - if (selectInfo.source === 'date') { - setSelectDate(value); - updateMode('time') - } - }; - - const disabledDate = (currentDate: Dayjs) => { - return !dates || !dates[currentDate.format('YYYY-MM-DD')] - } - - const handleTimeslot = (e: RadioChangeEvent) => { - setSlot(e.target.value.startTime) - console.log('radio checked', e.target.value); - }; - - const handleTag = (e: RadioChangeEvent) => { - setTag(e.target.value) - console.log('tag radio checked', e.target.value); - }; - - const handleSingupSession = async () => { - const data = {coachId: expertId, tagId: tag, startAtUtc: slot, clientComment:''} - console.log(data) - const session = await getSchedulerSession({coachId: expertId, tagId: tag, startAtUtc: slot, clientComment:''}, locale, jwt) - console.log(session); - // тут должна быть проверка все ли с регистрацией сессии - setSessionId(session?.sessionId) - updateMode('pay') - } - - const currentDay = dayjs() - - const cellRender: CalendarProps['fullCellRender'] = (date, info) => { - const isWeekend = date.day() === 6 || date.day() === 0; - return React.cloneElement(info.originNode, { - ...info.originNode.props, - className: classNames(styles.dateCell, { - [styles.current]: selectDate.isSame(date, 'date'), - [styles.today]: date.isSame(dayjs(), 'date'), - }), - children: ( -
- - {date.get('date')} - -
- ), - }); - } - - - return ( - } - > -
- {tags && ( - - {tags?.map((tag)=>( - {tag.name} - ) - )} - - ) - } -
- {mode === 'data' && ( - { - const start = 0; - const end = 12; - const monthOptions = []; - - let current = currentDay.clone(); - const localeData = value.locale(); - const months = []; - - for(let i=0; i<6; i++){ - const m = current.clone() - months.push(m); - current = current.add(1,'month') - } - return (<> - {months.map((m, i)=>( - - ))} - ) - }} - - /> - )} - {mode === 'time' && ( - <> -
- -
- - - {dates[selectDate.format('YYYY-MM-DD')].map( (el) => { - return ({dayjs(el.startTime).format('hh-mm')} - {dayjs(el.endTime).format('hh-mm')}) - })} - - - - )} - {mode === 'pay' && ( - - )} -
- ); -}; diff --git a/src/components/stripe/ElementsForm.tsx b/src/components/stripe/ElementsForm.tsx deleted file mode 100644 index 0e3da2f..0000000 --- a/src/components/stripe/ElementsForm.tsx +++ /dev/null @@ -1,195 +0,0 @@ -"use client"; - -import type { StripeError } from "@stripe/stripe-js"; - -import * as React from "react"; -import { - useStripe, - useElements, - PaymentElement, - Elements, -} from "@stripe/react-stripe-js"; - -import StripeTestCards from "./StripeTestCards"; - -import getStripe from "../../utils/get-stripe"; -import { createPaymentIntent} from "../../actions/stripe"; -import {Form} from "antd"; -import {Payment} from "../../types/payment"; -import {CustomInput} from "../view/CustomInput"; -import {i18nText} from "../../i18nKeys"; -import {FC, useEffect} from "react"; -import {getPersonalData} from "../../actions/profile"; - -type PaymentFormProps = { - amount: number, - sessionId?: string -} - - -export const CheckoutForm: FC = ({amount, sessionId}) => { - const [input, setInput] = React.useState<{ - paySumm: number; - cardholderName: string; - }>({ - paySumm: 1, - cardholderName: "", - }); - const [form, ] = Form.useForm(); - const formAmount = Form.useWatch('amount', form); - const [paymentType, setPaymentType] = React.useState(""); - const [payment, setPayment] = React.useState<{ - status: "initial" | "processing" | "error"; - }>({ status: "initial" }); - const [errorMessage, setErrorMessage] = React.useState(""); - - const stripe = useStripe(); - const elements = useElements(); - - const PaymentStatus = ({ status }: { status: string }) => { - switch (status) { - case "processing": - case "requires_payment_method": - case "requires_confirmation": - return

Processing...

; - - case "requires_action": - return

Authenticating...

; - - case "succeeded": - return

Payment Succeeded 🥳

; - - case "error": - return ( - <> -

Error 😭

-

{errorMessage}

- - ); - - default: - return null; - } - }; - - useEffect(() => { - elements?.update({ amount: formAmount * 100 }); - }, [formAmount]); - - const handleInputChange: React.ChangeEventHandler = (e) => { - setInput({ - ...input, - [e.currentTarget.name]: e.currentTarget.value, - }); - }; - - const onSubmit = async (data) => { - try { - if (!elements || !stripe) return; - - setPayment({ status: "processing" }); - - const { error: submitError } = await elements.submit(); - - if (submitError) { - setPayment({ status: "error" }); - setErrorMessage(submitError.message ?? "An unknown error occurred"); - - return; - } - - // Create a PaymentIntent with the specified amount. - console.log('DATA', data); - const { client_secret: clientSecret } = await createPaymentIntent( - {amount: amount}, - ); - - // Use your card Element with other Stripe.js APIs - const { error: confirmError } = await stripe!.confirmPayment({ - elements, - clientSecret, - confirmParams: { - return_url: `${window.location.origin}/ru/payment/result`, - payment_method_data: { - allow_redisplay: 'limited', - billing_details: { - name: input.cardholderName, - }, - }, - }, - }); - - if (confirmError) { - setPayment({ status: "error" }); - setErrorMessage(confirmError.message ?? "An unknown error occurred"); - } - } catch (err) { - const { message } = err as StripeError; - - setPayment({ status: "error" }); - setErrorMessage(message ?? "An unknown error occurred"); - } - }; - - - - return ( - <> -
-
- - Your payment details: - {paymentType === "card" ? ( - - ) : null} -
- { - setPaymentType(e.value.type); - }} - /> -
-
- -
- - - ); -} - -export const ElementsForm: FC = ({amount, sessionId}) => { - return ( - - - - ) -} \ No newline at end of file diff --git a/src/components/stripe/PrintObject.tsx b/src/components/stripe/PrintObject.tsx deleted file mode 100644 index b7cd424..0000000 --- a/src/components/stripe/PrintObject.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import type { Stripe } from "stripe"; - -export default function PrintObject({ - content, - }: { - content: Stripe.PaymentIntent | Stripe.Checkout.Session; -}): JSX.Element { - const formattedContent: string = JSON.stringify(content, null, 2); - return
{formattedContent}
; -} \ No newline at end of file diff --git a/src/components/stripe/StripeTestCards.tsx b/src/components/stripe/StripeTestCards.tsx deleted file mode 100644 index cf40281..0000000 --- a/src/components/stripe/StripeTestCards.tsx +++ /dev/null @@ -1,19 +0,0 @@ -export default function StripeTestCards(): JSX.Element { - return ( -
- Use any of the{" "} - - Stripe test cards - {" "} - for demo, e.g.{" "} -
- 4242424242424242 -
- . -
- ); -} \ No newline at end of file diff --git a/src/lib/stripe.ts b/src/lib/stripe.ts deleted file mode 100644 index 08773a7..0000000 --- a/src/lib/stripe.ts +++ /dev/null @@ -1,11 +0,0 @@ -import "server-only"; - -import Stripe from "stripe"; - -export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, { - apiVersion: "2024-06-20", - appInfo: { - name: "bbuddy-ui", - url: "", - }, -}); \ No newline at end of file diff --git a/src/types/experts.ts b/src/types/experts.ts index 3df393d..160db87 100644 --- a/src/types/experts.ts +++ b/src/types/experts.ts @@ -112,29 +112,3 @@ export type ExpertDetails = { associations?: Association[]; associationLevels?: AssociationLevel[]; }; - -export type Tags = { - id: number, - groupId: number, - name: string, - couchCount: number, - group: { - id: number, - name: string, - tags: string[]; - } -} - -export type Slot = { - startTime: string; - endTime: string; -} - -export type ExpertScheduler = { - tags: Tags[], - availableSlots: Slot[]; -} - -export type ExpertSchedulerSession = { - sessionId: string -} \ No newline at end of file diff --git a/src/types/payment.ts b/src/types/payment.ts deleted file mode 100644 index cdadd42..0000000 --- a/src/types/payment.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type Payment = { - amount: number; -} \ No newline at end of file diff --git a/src/utils/get-stripe.ts b/src/utils/get-stripe.ts deleted file mode 100644 index 6930d5b..0000000 --- a/src/utils/get-stripe.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * This is a singleton to ensure we only instantiate Stripe once. - */ -import { Stripe, loadStripe } from "@stripe/stripe-js"; - -let stripePromise: Promise; - -export default function getStripe(): Promise { - if (!stripePromise) - stripePromise = loadStripe( - process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY as string, - ); - - return stripePromise; -} \ No newline at end of file diff --git a/src/utils/stripe-helpers.ts b/src/utils/stripe-helpers.ts deleted file mode 100644 index 09144bd..0000000 --- a/src/utils/stripe-helpers.ts +++ /dev/null @@ -1,30 +0,0 @@ -export function formatAmountForDisplay( - amount: number, - currency: string, -): string { - let numberFormat = new Intl.NumberFormat(["en-US"], { - style: "currency", - currency: currency, - currencyDisplay: "symbol", - }); - return numberFormat.format(amount); -} - -export function formatAmountForStripe( - amount: number, - currency: string, -): number { - let numberFormat = new Intl.NumberFormat(["en-US"], { - style: "currency", - currency: currency, - currencyDisplay: "symbol", - }); - const parts = numberFormat.formatToParts(amount); - let zeroDecimalCurrency: boolean = true; - for (let part of parts) { - if (part.type === "decimal") { - zeroDecimalCurrency = false; - } - } - return zeroDecimalCurrency ? amount : Math.round(amount * 100); -} \ No newline at end of file