Toss payments 개발자 커뮤니티Tp개커Toss payments 개발자 커뮤니티
Powered by
cindyC
Toss payments 개발자 커뮤니티•12mo ago•
6 replies
cindy

결제 위젯 연동 시 결제 위젯을 띄우는 컴포넌트와 결제하기 버튼 로직 컴포넌트가 분리되어 있을 경우

기존에는 빌링 결제만 이용하다가 단건결제를 추가하기 위해서 결제 위젯 연동 테스트 중에 있습니다.
기존에 있는 코드에서 추가하다 보니 결제 위젯을 띄우는 컴포넌트와 실제 결제가 이뤄지는 컴포넌트가 분리되게 되었습니다. 그래서 둘의 상위 컴포넌트에서 아래와 같이 paymentWidget 상태를 만들어서 넘겨주고 있습니다.
const [paymentWidget, setPaymentWidget] = useState<PaymentWidgetInstance | null>(null);
const [paymentWidget, setPaymentWidget] = useState<PaymentWidgetInstance | null>(null);


그런데 결제 수단을 선택하고 결제하기 버튼을 클릭하면 첨부한 사진과 같은 오류들이 뜹니다. 어쩔 때는 결제 수단이 선택되지 않았다는 오류가 뜨고 어쩔 때는 지원하지 않는 결제 수단이라는 오류가 뜹니다... ㅠ
또 가끔은 네이버페이랑 카카오페이만 지원하지 않는 결제 수단이라고 안되고 나머지 수단들은 결제 테스트가 될 때도 있는데 어떻게 수정해야 할까요...?


현재 위젯이 렌더링되는 컴포넌트는 PaymentWidget 컴포넌트이고 결제가 이뤄지는 컴포넌트는 PaymentInfo 컴포넌트입니다.

아래는 PaymentWidget 코드입니다.
import { useEffect } from "react";
import { loadPaymentWidget, PaymentWidgetInstance } from "@tosspayments/payment-widget-sdk";
import styled from "styled-components";

interface PaymentWidgetProps {
  setPaymentWidget: (widget: PaymentWidgetInstance | null) => void;
}

export default function PaymentWidget({ setPaymentWidget }: PaymentWidgetProps) {
  const clientKey = 
import { useEffect } from "react";
import { loadPaymentWidget, PaymentWidgetInstance } from "@tosspayments/payment-widget-sdk";
import styled from "styled-components";

interface PaymentWidgetProps {
  setPaymentWidget: (widget: PaymentWidgetInstance | null) => void;
}

export default function PaymentWidget({ setPaymentWidget }: PaymentWidgetProps) {
  const clientKey = 
${import.meta.env.VITE_SINGLE_CLIENTKEY}
;
  const price = 500;
  const customerKey = "customer-unique-key";

  useEffect(() => {
    (async () => {
      const paymentWidget = await loadPaymentWidget(clientKey, customerKey);

      paymentWidget.renderPaymentMethods("#payment-widget", price);

      setPaymentWidget(paymentWidget);
    })();
  }, [setPaymentWidget]);

  return (
    <PaymentWidgetContainer>
      <PaymentWidgetBox id="payment-widget" />
    </PaymentWidgetContainer>
  );
}

const PaymentWidgetContainer = styled.div
;
  const price = 500;
  const customerKey = "customer-unique-key";

  useEffect(() => {
    (async () => {
      const paymentWidget = await loadPaymentWidget(clientKey, customerKey);

      paymentWidget.renderPaymentMethods("#payment-widget", price);

      setPaymentWidget(paymentWidget);
    })();
  }, [setPaymentWidget]);

  return (
    <PaymentWidgetContainer>
      <PaymentWidgetBox id="payment-widget" />
    </PaymentWidgetContainer>
  );
}

const PaymentWidgetContainer = styled.div

width: 100%;
;

const PaymentWidgetBox = styled.div
;

const PaymentWidgetBox = styled.div

width: 100%;
;
;

그리고 PaymentInfo에서 결제가 이뤄지는 코드는 다음과 같습니다.
<PaymentButton $isAgree={isAgree} disabled={!isAgree} type="button" onClick={() => handlePayment(id)}>결제하기</PaymentButton>
<PaymentButton $isAgree={isAgree} disabled={!isAgree} type="button" onClick={() => handlePayment(id)}>결제하기</PaymentButton>


async function handlePayment(id: number) {
    if (id === 4) {
      // 단건 결제 요청 (paymentWidget 사용)
      if (!paymentWidget) return;

      try {
        await paymentWidget.requestPayment({
          orderId: "FWZbnh9VMiNXnK9zBqn4f",
          orderName: "토스 티셔츠 외 2건",
          customerName: "김토스",
          customerEmail: "customer123@gmail.com",
          customerMobilePhone: "01012341234",
          successUrl: 
async function handlePayment(id: number) {
    if (id === 4) {
      // 단건 결제 요청 (paymentWidget 사용)
      if (!paymentWidget) return;

      try {
        await paymentWidget.requestPayment({
          orderId: "FWZbnh9VMiNXnK9zBqn4f",
          orderName: "토스 티셔츠 외 2건",
          customerName: "김토스",
          customerEmail: "customer123@gmail.com",
          customerMobilePhone: "01012341234",
          successUrl: 
${window.location.origin}/success
,
          failUrl: 
,
          failUrl: 
${window.location.origin}/fail
,
        });
      } catch (error) {
        console.error("Error requesting payment:", error);
      }
    } else {
      // 다른 결제 방식 처리 (단건 결제 외 로직)
      postMembership(
        {
          productId: selectedPlan,
          couponMemberId: activeCouponId,
        },
        {
          onSuccess: () => {
            if (activeCouponId) {
              sessionStorage.removeItem("couponTxt");
              sessionStorage.removeItem("dcInfo");
            }
          },
        },
      );
    }
  }
,
        });
      } catch (error) {
        console.error("Error requesting payment:", error);
      }
    } else {
      // 다른 결제 방식 처리 (단건 결제 외 로직)
      postMembership(
        {
          productId: selectedPlan,
          couponMemberId: activeCouponId,
        },
        {
          onSuccess: () => {
            if (activeCouponId) {
              sessionStorage.removeItem("couponTxt");
              sessionStorage.removeItem("dcInfo");
            }
          },
        },
      );
    }
  }
2025-02-25_8.49.02.png
2025-02-25_8.51.26.png
Toss payments 개발자 커뮤니티 banner
Toss payments 개발자 커뮤니티Join
Toss payments 개발자 커뮤니티입니다. 결제 연동하며 겪는 기술 문의부터, 결제 시장에 대한 다양한 정보까지 얻어가세요~
15,588Members
Resources
Recent Announcements

Similar Threads

Was this page helpful?

Similar Threads

결제하기 버튼 커스텀
1231123 / ❓┃연동개발-문의
3y ago
Android 결제 위젯 연동 시 TaxFreeAmount 설정
데브윤데데브윤 / ❓┃연동개발-문의
2y ago
결제 위젯 연동 문의
토스페이먼츠 BOT토토스페이먼츠 BOT / ❓┃연동개발-문의
7mo ago
결제 위젯 연동 질문
준섭준준섭 / ❓┃연동개발-문의
7mo ago