Skip to Content
SDKJavaScript / 브라우저

JavaScript / 브라우저 SDK

@lartech/infraio-checkout-js는 현재 공개된 유일한 SDK입니다. 브라우저에서 실행되며 호스팅 체크아웃을 엽니다. 백엔드 SDK(Node, Go, Python)는 로드맵에 있습니다. 그때까지는 게이트웨이와 직접 통신하세요 — HMAC 서명 헬퍼는 빠른 시작을 참조하세요.

  • 현재 버전: 0.1.1-beta.17 (pre-1.0; 마이너 변경 예상)
  • 포맷: ESM (index.js), CJS (index.cjs), IIFE (index.global.js)
  • 타입 번들됨 (index.d.ts)
  • 런타임 피어 없음 — React, jQuery 또는 기타 종속성 없음

서버 측 엔트리는 없습니다. 웹훅 서명 검증 헬퍼는 번들되지 않습니다 — crypto로 직접 구현하세요(서명 검증 페이지에 4개 언어로 복사하여 붙여넣을 수 있는 코드가 있습니다).

설치

npm install @lartech/infraio-checkout-js

loadInfraIo(publicKey, options?)

Promise<InfraIoInstance>를 반환합니다.

import { loadInfraIo } from "@lartech/infraio-checkout-js"; const sdk = await loadInfraIo("pk_live_yourkeyhere", { // 선택. 비프로덕션 환경을 가리킬 때만 오버라이드하세요. checkoutUrl: "https://checkout-dev.infraio.xyz", });
매개변수타입필수비고
publicKeystringpk_(live|test)_…와 일치해야 함
options.checkoutUrlstring기본 체크아웃 URL을 오버라이드합니다. 기본값: https://checkout.infraio.xyz. 일치하는 게이트웨이 URL은 체크아웃 페이지가 런타임에 결정합니다 — 각 checkout(-dev).infraio.xyz 배포는 컴파일 타임 NEXT_PUBLIC_API_URL을 가지므로 여기서 올바른 호스트명을 선택하면 올바른 백엔드가 자동으로 선택됩니다. 별도의 gatewayUrl 옵션은 없습니다.

sdk.checkout({ … })

호스팅 체크아웃을 엽니다. void를 반환합니다(상태는 콜백 사용).

필드타입필수비고
sessionIdstringPOST /b2b/v1/checkout-sessions/quick이 반환한 session_key
checkoutUrlstring동일한 엔드포인트가 반환한 전체 URL. 생략 시 SDK가 loadInfraIo()checkoutUrl(또는 기본값) + sessionId로 구성합니다
mode"popup" | "redirect" | "embed"기본값 "popup"
containerstring | HTMLElement임베드만iframe이 마운트될 CSS 선택자 또는 DOM 요소
widthnumber팝업 전용. 기본값 560. [320, 1280] 범위로 클램프
heightnumber팝업 전용. 기본값 780. [400, 1000] 범위로 클램프
timeoutMsnumber팝업 전용. iframe 로드 타임아웃. 기본값 30000. 0을 전달하면 비활성화
localestring체크아웃 페이지에 ?locale=로 전달되는 BCP-47 태그(en, ja, zh-CN, zh-TW)
hideSummaryboolean주문 요약 컬럼 숨기기. 기본값 false
hideHeaderbooleanInfraIO 헤더 및 내장 지갑 연결 버튼 숨기기. 기본값 false. 완전한 화이트 라벨을 위해 walletAddress와 함께 사용
walletAddressstring구매자 지갑 사전 연결. onSignRequest가 필요함
walletChainIdnumber사전 연결된 지갑의 EVM 체인 ID
onReady() => voidiframe이 상호작용 가능해질 때 발생. 팝업/임베드 전용
onSignRequest(req: { method: string; params: unknown[] }) => Promise<string>walletAddress 설정 시SDK가 지갑 RPC를 가맹점 핸들러로 프록시 — 서명된 hex를 반환
onSuccess({ sessionId }) => void성공적인 결제 시 발생. 권위 있는 신호가 아님 — 웹훅이 권위 있음
onCancel() => void구매자가 결제하지 않고 팝업/임베드를 닫을 때 발생
onError(err: InfraIoError) => voidiframe 로드 실패 시 발생(팝업 + 임베드 모드). 잘못된 인수는 동기적으로 throw되며 여기서 전달되지 않습니다. 리디렉션 모드는 런타임 오류 표면이 없음 — 실패는 리디렉션된 페이지에서 관찰됨.

onSuccess는 권위 있는 신호가 아닙니다. 웹훅이 나중에 결제 실패를 결정하더라도 발생할 수 있습니다(테스트넷 reorg, 구매자 측 타이밍). UX에만 사용하세요(예: “감사합니다!” 표시, 리디렉션). 이행 처리 전에 항상 웹훅으로 확인하세요.

sdk.close()

열려 있는 팝업이나 임베드를 프로그래밍 방식으로 해제합니다. 리디렉션 모드에서는 no-op입니다.

sdk.checkout({ sessionId, mode: "popup", /* … */ }); // 나중에, 예를 들어 사용자가 페이지를 떠날 때 sdk.close();

sdk.openRefundRequest({ … })

백엔드가 POST /b2b/v1/merchants/{merchant_id}/refund-requests로 발급한 일회성 토큰에 대해 호스팅 환불 요청 양식을 엽니다. 구매자는 저희 페이지에서 환불 목적지 주소 + 사유 + (선택) 메타데이터를 입력합니다. 가맹점 페이지는 열기/닫기 라이프사이클만 처리합니다. close() 함수를 반환합니다 — 호출하여 팝업을 프로그래밍 방식으로 해제하거나 임베드 iframe을 분리합니다. 리디렉션 모드에서 반환된 함수는 no-op입니다.

양식은 https://checkout.infraio.xyz/refund-request/:token에 있습니다. 이 메서드는 해당 URL을 팝업/리디렉션/임베드로 감싸서 구매자가 가맹점 도메인을 벗어나지 않거나(팝업/임베드) 자동으로 돌아오도록(리디렉션) 합니다. 백엔드가 토큰을 발급하기 위해 호출하는 엔드포인트는 POST /b2b/v1/merchants/{merchant_id}/refund-requests입니다 — 시크릿 키로 HMAC 서명하며, 나머지 B2B 표면과 동일한 인증입니다. 개념 → 환불을 참조하세요.

import { loadInfraIo } from "@lartech/infraio-checkout-js"; const sdk = await loadInfraIo("pk_live_yourkeyhere"); // 서버 측에서 토큰을 발급한 다음, 브라우저의 SDK에 전달합니다. const { token } = await fetch("/api/mint-refund-token", { method: "POST" }).then(r => r.json()); const close = sdk.openRefundRequest({ token, mode: "popup", onSuccess: ({ linkToken, refundId }) => { // 구매자가 양식을 제출했습니다. // linkToken → /r/:linkToken 상태 페이지(구매자와 공유). // refundId → 승인/거부에 B2B API와 함께 사용. window.location.href = `/r/${linkToken}`; }, onCancel: () => { /* 구매자가 제출 없이 닫음 */ }, }); // 나중에 필요하면 프로그래밍 방식으로 팝업 해제: // close();
필드타입필수비고
tokenstringPOST /b2b/v1/merchants/{merchant_id}/refund-requests가 반환한 rfqt_… 토큰
mode"popup" | "redirect" | "embed"기본값 "popup". sdk.checkout()과 동일한 표면 시맨틱 — 모드 비고 참조
containerstring | HTMLElement임베드만iframe이 마운트될 CSS 선택자 또는 DOM 요소
localestring?locale=로 전달되는 BCP-47 태그(en, ja, zh-CN, zh-TW)
hideHeaderbooleaniframe 내부의 InfraIO 헤더 숨기기. 팝업/임베드에서 SDK가 자체 모달 크롬을 그리므로 페이지 헤더는 일반적으로 노이즈입니다. 기본값 false
hideSummaryboolean주문 요약 컬럼을 숨기고 환불 양식만 표시. 기본값 false
walletAddressstring목적지 지갑 필드(?wallet_address=)를 사전 채움. 구매자의 지갑을 이미 알고 있는 가맹점이 수동 재입력을 건너뛸 수 있게 함
onSuccess(data: { linkToken: string; refundId: string }) => void구매자가 양식을 제출한 후 발생. linkToken → 구매자와 공유할 /r/:linkToken 상태 페이지. refundId → 승인/거부에 B2B API와 함께 사용
onCancel() => void구매자가 제출 없이 팝업/임베드를 닫을 때 발생
onError(err: InfraIoError) => voidiframe 로드 실패 또는 잘못된 인수에 발생. 토큰 만료/취소는 호스팅 페이지에서 처리되며 onError로 처리되지 않습니다

onError를 통해 노출되는 토큰 상태

구매자가 만료된 토큰을 열면 페이지 자체가 표시를 처리하며(“만료됨 — 새 링크 요청” 안내 등을 렌더링), SDK는 이러한 경우 onError발생시키지 않습니다 — 구매자는 양식 흐름 내에 있고 가맹점 코드는 반응할 필요가 없습니다. onError는 가맹점 코드가 조치할 수 있는 경우(잘못된 인수, iframe 로드 시 네트워크 실패) 에만 발생합니다.

openRefundRequest는 환불 인텐트를 기록할 뿐 자금을 이동시키지 않습니다. onSuccess 이후 환불 행은 PENDING(또는 가맹점 구성이 고객 환불을 자동 승인하는 경우 APPROVED)입니다. 가맹점 지갑에서 온체인 송금을 서명하고 브로드캐스트한 다음, tx 해시를 POST /b2b/v1/refunds/:id/submit-tx로 게시해야 합니다. 전체 라이프사이클은 개념 → 환불을 참조하세요.

오류 클래스

import { InfraIoError } from "@lartech/infraio-checkout-js"; sdk.checkout({ sessionId, onError: (err: InfraIoError) => { switch (err.code) { case "invalid_request_error": /* 잘못된 sessionId / 인수 */ break; case "iframe_load_error": /* iframe 로드 실패 */ break; case "iframe_timeout_error": /* timeoutMs 초과 */ break; case "already_open_error": /* 다른 체크아웃이 이미 열려 있음 */ break; case "network_error": /* 체크아웃 오리진과 통신 중 일시적인 네트워크 문제 */ break; case "api_error": /* SDK 발급 호출에 대해 백엔드가 non-2xx 반환 */ break; } }, });

sdk.openRefundRequest()invalid_request_error(누락 또는 잘못된 토큰/인수)만 동기적으로 throw합니다. iframe_load_error(환불 요청 iframe 로드 실패)는 throw되지 않고 onError를 통해 비동기적으로 전달됩니다. iframe_timeout_error 또는 already_open_error는 발생시키지 않습니다 — 환불 요청 팝업에는 로드 타임아웃이 없으며 여러 동시 팝업을 허용합니다.

모드 비고

팝업

  • 어두운 반투명 배경의 중앙 정렬 오버레이
  • z-index: 2147483647 (max int32) — 다른 모든 것 위에 위치
  • 열려 있는 동안 본문 스크롤 잠금. 닫히면 복원
  • 닫기 버튼이 초기 포커스를 받음. Tab은 팝업 내에 트랩됨
  • 닫기 방법: 닫기 버튼, Escape, 외부 클릭, sdk.close(). 이들 모두 onCancel을 호출
  • 체크아웃 페이지는 postMessage로 리사이즈를 요청할 수 있음 — SDK가 width/height 제한 내로 클램프

리디렉션

  • window.location.href를 통한 하드 내비게이션
  • ?return_url=<current-page>를 자동으로 추가하여 구매자가 출발점으로 돌아오게 함. 세션의 success_url / cancel_url이 이미 이를 처리하면 왕복은 return_url을 무시

임베드

  • allow="payment; clipboard-write"가 있는 iframe (HTML5 Feature Policy 지시문 — sandbox 속성이 아님). iframe은 체크아웃 오리진에서 제공되므로 구매자 측 지갑 팝업과 클립보드 쓰기는 추가 옵트인 없이 동작
  • 컨테이너 너비는 100%. 높이는 INFRAIO_RESIZE postMessage를 통해 자동 조정, [200, 2000]px 범위로 클램프
  • iframe 경계 외에 CSS 격리 없음 — 부모 페이지 스타일은 누출되지 않음
  • 체크아웃이 상호작용 가능해질 때 자체 로딩 상태를 숨길 수 있도록 항상 onReady를 연결

TypeScript

모든 타입이 번들됩니다. 가장 유용한 익스포트:

import type { CheckoutOptions, RefundRequestOptions, LoadOptions, InfraIoInstance, InfraIoErrorCode, } from "@lartech/infraio-checkout-js"; import { loadInfraIo, InfraIoError, VERSION } from "@lartech/infraio-checkout-js";

VERSION은 SDK 자체의 버전 문자열입니다 — 버그 리포트에 유용합니다.

다음 단계

  • React / Vue 프레임워크 래퍼 — 파일럿 가맹점 전반에서 vanilla JS 표면이 안정화된 후 출시 이후 반복을 위해 계획되었습니다. 현재 vanilla SDK는 React 내부에서 잘 동작합니다 — 래퍼는 수동 useRef + 라이프사이클 플러밍을 제거할 것입니다.
  • 크로스 탭 세션 재개 — 탭 A에서 체크아웃을 열고 탭 B에서 완료. 구매자가 흐름 중간에 매직 링크를 따라갈 때 유용합니다. 다음 마이너 릴리스에서 추적됩니다.
  • CSS 변수를 통한 테마 — iframe에 작은 디자인 토큰 세트(radius, accent color)를 노출하여 가맹점이 페이지를 포크하지 않고 브랜드에 맞출 수 있게 합니다.
  • 서버 측 헬퍼 — 백엔드 코드가 HMAC 의식을 복사하지 않도록 verifyWebhook() + signedRequest()를 노출하는 작은 @lartech/infraio-server 패키지. 출시 전까지 서명 검증 페이지에 TypeScript, Go, Python, Ruby의 드롭인 구현이 나와 있습니다.