PaymentButton 컴포넌트는 Solana 결제를 수락하기 위한 완전한 결제 인터페이스를
제공하는 React 컴포넌트입니다. 지갑 연결, 토큰 선택, 트랜잭션 처리 및 UI 상태
관리를 내부적으로 처리합니다. 기본적으로 커스터마이징 가능한 버튼과 모달이 함께
제공됩니다:
팁 버튼
Tip Button
결제 모달
Pay Modal
Solana Pay QR 코드 모달
Cart Modal
설치
pnpm add @solana-commerce/kit
컴포넌트 Props
PaymentButtonProps
PaymentButton 컴포넌트는 다음 props를 받습니다:
필수 Props
config(SolanaCommerceConfig) - 결제 컴포넌트의 주요 구성 객체입니다. 이것이 유일한 필수 prop입니다. 아래 SolanaCommerceConfig를 참조하세요.
선택적 Props
-
paymentConfig(PaymentConfig) - 제품, 가격 재정의 및 커스텀 가격 조회 함수를 포함한 결제별 구성입니다. 아래 PaymentConfig를 참조하세요. -
onPayment((amount: number, currency: string) => void) - 사용자가 금액과 통화를 확인한 후 결제가 시작될 때 호출됩니다. 결제 금액(lamports가 아닌 토큰 단위)과 통화 식별자를 받습니다. -
onPaymentStart(() => void) - 실제 트랜잭션이 제출되기 전에 결제 플로우가 시작될 때 호출됩니다. 로딩 상태를 표시하거나 분석 추적을 하는 데 사용하세요. -
onPaymentSuccess((signature: string) => void) - 트랜잭션이 온체인에서 확인될 때 호출됩니다. 트랜잭션 서명을 받습니다. 여기에서 주문 상태를 업데이트하고 확인 이메일을 보내는 등의 작업을 수행해야 합니다. -
onPaymentError((error: Error) => void) - 결제가 어느 단계에서든 실패할 때 호출됩니다(지갑 연결, 트랜잭션 제출 또는 확인). 오류 객체에는 무엇이 잘못되었는지에 대한 세부 정보가 포함됩니다. -
onCancel(() => void) - 사용자가 명시적으로 결제 플로우를 취소할 때(모달을 닫거나 취소 버튼을 클릭할 때) 호출됩니다. -
children(React.ReactNode) - 선택적 사용자 정의 트리거 요소입니다. 제공되는 경우 기본 결제 버튼을 대체합니다. 자식 요소는 클릭 가능해야 합니다(예: 버튼). -
className(string) - 트리거 버튼에 적용되는 CSS 클래스 이름입니다(사용자 정의 자식 요소가 제공되지 않은 경우에만 사용됨). -
style(React.CSSProperties) - 트리거 버튼에 적용되는 인라인 스타일입니다(사용자 정의 자식 요소가 제공되지 않은 경우에만 사용됨). -
variant('default' | 'icon-only') - 버튼 변형입니다. 기본값은 텍스트와 아이콘을 표시하며,'icon-only'는 결제 아이콘만 표시합니다.
구성 객체
SolanaCommerceConfig
config prop에 전달되는 주요 구성 객체입니다.
필수 필드
-
merchant(MerchantConfig) - 판매자 정보 및 결제 수령인 세부정보입니다. MerchantConfig를 참조하세요. -
mode('cart' | 'tip' | 'buyNow') - 버튼 표시 텍스트 및 UI 흐름을 결정하는 결제 모드입니다:'buyNow'- 고정 금액의 단일 제품 구매'cart'- 여러 제품이 포함된 장바구니'tip'- 사용자가 자신의 금액을 선택(기부/팁)
선택적 필드
-
position('inline' | 'overlay') - 결제 UI가 표시되는 방식입니다. 기본값은'overlay'입니다.'overlay'- 모달/드로어 오버레이로 열림'inline'- 페이지에 직접 임베드됨
-
theme(ThemeConfig) - 시각적 사용자 정의 옵션입니다. ThemeConfig를 참조하세요. -
network('mainnet' | 'devnet' | 'testnet') - 사용할 솔라나 네트워크입니다. 기본값은'mainnet'입니다. -
rpcUrl(string) - 사용자 정의 RPC 엔드포인트 URL입니다. 제공되지 않으면 선택한 네트워크의 기본 공개 엔드포인트를 사용합니다. -
allowedMints(string[]) - 결제 방법을 제한하기 위한 토큰 민트 주소 배열입니다. 제공되지 않으면 지원되는 모든 토큰(SOL, USDC, USDT)을 사용할 수 있습니다. -
showQR(boolean) - QR 코드 결제 옵션 표시 여부입니다. 모바일 및 Solana Pay 통합에 유용합니다. -
enableWalletConnect(boolean) - 지갑 연결 활성화 여부. 외부에서 지갑 연결을 처리하는 경우false로 설정하세요. -
showMerchantInfo(boolean) - 결제 UI에서 판매자 이름과 로고를 표시할지 여부. -
debug(boolean) - 디버깅을 위한 상세 콘솔 로깅을 활성화합니다.
MerchantConfig
결제 수령인 및 비즈니스 정보를 정의합니다.
필수 필드
-
name(string) - 결제 시 사용자에게 표시되는 비즈니스 또는 판매자 이름. -
wallet(string) - 결제를 받을 솔라나 지갑 주소. 유효한 base58 인코딩 솔라나 주소여야 합니다.
선택 필드
-
logo(string) - 판매자 로고 이미지 URL.showMerchantInfo가 활성화되면 결제 UI에 표시됩니다. -
description(string) - 사용자에게 표시되는 비즈니스 설명.
ThemeConfig
결제 UI의 시각적 커스터마이징.
모든 필드는 선택사항이며 합리적인 기본값을 가지고 있습니니다.
-
primaryColor(string) - 버튼과 강조 요소에 사용되는 주요 브랜드 색상. 기본값:'#9945FF'(솔라나 퍼플). -
secondaryColor(string) - 보조 강조 색상. 기본값:'#14F195'(솔라나 그린). -
backgroundColor(string) - 모달/컨테이너 배경 색상. 기본값:'#ffffff'. -
textColor(string) - 주요 텍스트 색상. 기본값:'#111827'. -
borderRadius('none' | 'sm' | 'md' | 'lg' | 'xl' | 'full') - UI 요소에 적용되는 테두리 반경. 기본값:'lg'.'none'= 0px'sm'= 12px'md'= 16px'lg'= 20px'xl'= 24px'full'= 완전히 둥글게 (상황에 따라 다름)
-
fontFamily(string) - 모든 텍스트의 글꼴 패밀리. 기본값:'system-ui, -apple-system, sans-serif'. -
buttonShadow('none' | 'sm' | 'md' | 'lg' | 'xl') - 버튼의 드롭 섀도우. 기본값:'md'. -
buttonBorder('none' | 'black-10') - 버튼의 테두리 스타일. 기본값:'black-10'(은은한 검은색 테두리).
PaymentConfig
가격, 소수점 및 제품에 대한 고급 결제 구성입니다.
모든 필드는 선택 사항입니다.
-
products(Product[]) -'cart'또는'buyNow'모드에 대한 제품 배열입니다. 이러한 모드를 사용할 때 필수입니다. 각 제품은 다음을 포함합니다:id(문자열, 필수) - 고유한 제품 식별자name(문자열, 필수) - 사용자에게 표시되는 제품명quantity(숫자, 필수) - 해당 제품의 수량price(숫자, 선택) - USD 단위당 가격unitAmount(숫자, 선택) -price필드의 대안description(문자열, 선택) - 제품 설명
-
solPriceUsd(number) - USD로 표시된 고정 SOL 가격입니다. 테스트용으로 사용하거나 SOL 가격을 고정하려는 경우 사용하세요. 제공되지 않으면 컴포넌트가 CoinGecko에서 현재 가격을 가져옵니다. -
getSolPrice(() => Promise<number>) - SOL 가격을 가져오기 위한 커스텀 함수입니다. 다음과 같은 경우에 사용하세요:- 비공개 가격 오라클
- 공개 API 속도 제한 회피
- 커스텀 가격 로직
- 엔터프라이즈 애플리케이션
제공되지 않으면 1분 캐싱이 적용된 CoinGecko 공개 API가 기본값으로 사용됩니다.
-
tokenDecimals({ [currency: string]: number }) - 토큰 소수점 정밀도를 재정의합니다. 커스텀 토큰에 유용합니다. 예시:tokenDecimals: {'CUSTOM': 8,'USDC': 6 // Can override defaults} -
fallbackSolPriceUsd(number) - 가격 API가 실패하고 사용 가능한 캐시가 없을 때의 대체 SOL 가격입니다. 이 값이 없으면 가격 가져오기가 실패할 경우 결제 UI에 오류가 표시됩니다.
내부 훅
PaymentButton 컴포넌트는 상태를 관리하고 값을 계산하기 위해 여러 내부 훅을
사용합니다:
useTheme(theme?: ThemeConfig)
사용자가 제공한 테마 구성을 기본 테마 값과 병합합니다. 모든 필드가 채워진 완전한
ThemeConfig 객체를 반환합니다.
기본 테마 값:
primaryColor: '#9945FF'secondaryColor: '#14F195'backgroundColor: '#ffffff'textColor: '#111827'borderRadius: 'lg'fontFamily: 'system-ui, -apple-system, sans-serif'buttonShadow: 'md'buttonBorder: 'black-10'
훅은 메모이제이션되어 테마 설정이 변경될 때만 재계산됩니다.
useTotalAmount(mode, paymentConfig?)
커머스 모드와 상품을 기반으로 총 결제 금액을 계산합니다.
모드별 동작:
'tip'모드 -0반환 (금액은 사용자가 결정)'cart'및'buyNow'모드 -paymentConfig.products의 모든 상품에 대해price * quantity합산
훅은 예외 사항을 처리합니다:
- 누락되거나 유효하지 않은 가격은 기본값
0로 설정 - 누락되거나 유효하지 않은 수량은 기본값
0로 설정 - 모든 값이 유한 숫자임을 보장
price및unitAmount상품 필드 모두 지원
총 금액을 숫자로 반환합니다(장바구니/즉시구매의 경우 USD, 팁의 경우 0).
usePaymentUrl(merchant, amount, mode)
결제를 위한 Solana Pay URL을 생성합니다. 이 URL은 모바일 지갑 스캔을 위해 QR 코드로 인코딩될 수 있습니다.
반환값: 다음 쿼리 매개변수가 포함된 solana: 프로토콜 URL:
recipient- 판매자 지갑 주소amount- 결제 금액reference- 고유 결제 참조값 (타임스탬프 + 무작위 문자열로 생성)label- 판매자 이름 (URL 안전성을 위해 정제됨)message- 모드에 기반한 컨텍스트 메시지
판매자 지갑이 유효하지 않거나 금액이 <= 0인 경우 빈 문자열을 반환합니다.
보안: 판매자 이름은 URL 주입을 통한 XSS 공격을 방지하기 위해
sanitizeString()를 사용하여 정제됩니다.
검증 및 오류 처리
컴포넌트는 렌더링 전에 검증을 수행합니다:
-
지갑 검증 -
gill의isAddress()를 사용하여 판매자 지갑 주소를 검증합니다. 유효하지 않은 경우 결제 UI 대신 오류 상태를 렌더링합니다. -
가격 검증 - 유효한 가격 설정을 보장합니다:
'tip'모드: 항상 유효 (사용자가 금액 선택)'cart'및'buyNow'모드:totalAmount > 0검증
-
SSR 안전성 - 클라이언트 측 감지를 사용하여 하이드레이션 불일치를 방지합니다.
isClient상태는 브라우저 전용 기능(예: 지갑 지속성을 위한localStorage)이 클라이언트에서만 실행되도록 보장합니다.
컴포넌트 아키텍처
PaymentButton는 모든 하위 요소를 두 개의 컨텍스트 프로바이더로 감쌉니다:
-
AppProvider- 지갑 연결 상태 및 커넥터 클라이언트 제공- 자동 연결: 기본적으로 비활성화
- 저장소: 사용 가능한 경우
localStorage사용 (클라이언트 측 전용) - 디버그 모드: 설정을 통해 구성 가능
-
ArcProvider- 솔라나 블록체인 클라이언트 및 RPC 연결 제공- 네트워크:
config.network에서 결정 - RPC URL: 공개 엔드포인트로의 폴백과 함께 서버 측 확인 사용
- 네트워크:
RPC URL 확인
컴포넌트는 정교한 RPC URL 확인 기능을 포함합니다:
config.rpcUrl가 제공되면 직접 사용됩니다- 그렇지 않으면 신뢰할 수 있는 엔드포인트를 선택하는 서버 측 확인자를 호출합니다
- 확인 실패 시
https://api.mainnet-beta.solana.com로 폴백합니다 - 마운트 시 비동기적으로 확인이 이루어지고 상태를 업데이트합니다
렌더링 모드
오버레이 모드 (position: 'overlay' 또는 기본값):
- 트리거 버튼(커스텀 또는 기본값) 렌더링
- 반응형 모달(데스크톱) 또는 드로어(모바일)에서 결제 UI 열기
- 적응형 레이아웃을 위해
ResponsiveShell컴포넌트 사용
인라인 모드 (position: 'inline'):
- 페이지에 결제 UI를 직접 임베드
- 트리거 버튼 불필요
- 전용 체크아웃 페이지에 유용
두 모드 모두 보안을 위해 샌드박스 처리된 iframe에서 결제 인터페이스를 렌더링하기
위해 내부적으로 SecureIframeShell를 사용합니다.
사용 예제
기본 결제
<PaymentButtonconfig={{merchant: {name: "Coffee Shop",wallet: "your-wallet-address"},mode: "buyNow"}}paymentConfig={{products: [{id: "coffee-001",name: "Espresso",price: 4.5,quantity: 1}]}}onPaymentSuccess={(sig) => {console.log("Payment confirmed:", sig);}}/>
커스텀 가격 가져오기를 사용한 팁 위젯
<PaymentButtonconfig={{merchant: {name: "Content Creator",wallet: "creator-wallet"},mode: "tip"}}paymentConfig={{// Use your own price API to avoid rate limitsgetSolPrice: async () => {const res = await fetch("/custom-api/solana-price");const data = await res.json();return data.price;},// Fallback if your API failsfallbackSolPriceUsd: 200}}/>
커스텀 테마를 사용한 장바구니
<PaymentButtonconfig={{merchant: {name: "My Store",wallet: "store-wallet",logo: "/logo.png"},mode: "cart",theme: {primaryColor: "#FF6B6B",backgroundColor: "#1a1a1a",textColor: "#ffffff",borderRadius: "xl",buttonShadow: "lg"},showMerchantInfo: true}}paymentConfig={{products: [{ id: "1", name: "T-Shirt", price: 25, quantity: 2 },{ id: "2", name: "Hoodie", price: 45, quantity: 1 }]}}onPaymentSuccess={(signature) => {// Verify transaction on your backendfetch("/api/verify-payment", {method: "POST",body: JSON.stringify({ signature })});}}/>
커스텀 트리거 버튼
<PaymentButtonconfig={{merchant: { name: "Shop", wallet: "address" },mode: "buyNow"}}paymentConfig={{products: [{ id: "1", name: "Product", price: 10, quantity: 1 }]}}><button className="custom-button">🚀 Pay with Solana</button></PaymentButton>
Is this page helpful?