v1 API 상세: 회원
프로젝트 서버의 Basic 인증과 고객의 아이디/비밀번호로 로그인해요. 비밀번호 로그인은 외부 인증을 대신하는 로그인 토큰 발급과 다른 API예요.
로그인
POST https://api.bootapi.com/v1/users/login
{
"login_id": "user001",
"password": "customer-password"
}json본문은 최상위 필드이며 user로 감싸지 않아요. login_id 대신 id도 허용해요. 가입에서는 login_pw, 로그인에서는 password를 사용해요. corporate_type을 보내도 현재 로그인 서비스는 읽지 않아요.
const result = await commerce.user.userLogin({
login_id: 'user001',
password: 'customer-password'
})
// 실제 result: { token: '...', user_id: '...' }javascriptNode.js SDK 2.13.1의 user.login(loginId, loginPw)는 login_pw를 전송하므로 이 v1 컨트롤러와 맞지 않아요. user.userLogin({ login_id, password }) 또는 commerce.post('users/login', {...})를 사용해요.
성공 응답은 {"token":"CUSTOMER_JWT","user_id":"CUSTOMER_ID"}예요. expired_at이나 고객 객체를 함께 반환하지 않아요. BFF는 토큰을 HttpOnly·SameSite 쿠키에 저장하고 고객 표시 정보가 필요하면 세션을 조회해요.
세션 조회
GET https://api.bootapi.com/v1/users/session
Basic 인증과 user:user_session_detail scope가 필요해요. Bootpay-User-JWT 헤더가 없거나 유효하지 않으면 응답 본문은 null이에요. user_id 계열 파라미터로 회원을 지정할 수 없어요.
const session = await commerce.user.userSession(customerJwt)javascript로그인한 경우의 주요 필드는 user_id, name, phone, email, identification, user_groups, membership_type, is_ex, pending_corporate_approval, current_user_group이에요. 이름·전화·이메일은 마스킹될 수 있어요. 이 수동 응답의 membership_type은 모델 값을 그대로 사용하므로 모든 API의 enum 응답이 문자열이라고 가정하지 않아요.
고객이 없거나 유효하지 않은 JWT가 무시된 경우 성공 본문이 null일 수 있어요. 200이라는 이유만으로 로그인 상태라고 판정하지 말고 user_id의 존재를 확인해요.
Bootpay 주문서로 로그인 이어가기
이 로그인에서 받은 JWT를 BFF 세션에 보관했다면, 주문할 때마다 로그인 토큰을 새로 발급할 필요는 없어요. 같은 JWT를 확인한 뒤 서버 주문 준비에 요청별 Bootpay-User-JWT 헤더로 보내고 본문에 response_type: 'url', use_auto_login: true를 지정해요.
자사 쿠키는 shop.bootpay.co.kr로 이동할 때 전달되지 않아요. URL 모드에서 자동 로그인을 요청하면 API가 검증한 고객 JWT로 기존 /b/{client_key} 세션 경유 URL을 구성해요. 브라우저가 응답 url로 이동하면 호스팅 쿠키를 설정한 뒤 주문서로 진입해요. 가맹점은 JWT를 URL에 덧붙이거나 __s를 암호화·재조합하지 않아요. JWT 없이 true를 보내면 API는 주문 생성 전에 인증 오류로 거부해요. API 반환 경로·배포·세션 진단도 확인해요.
자사 인증 시스템으로만 로그인되어 Commerce JWT가 없는 경우에는 서버가 로그인 사용자를 검증하고 Bootpay 고객으로 매핑한 뒤 로그인 토큰을 발급해요. 두 경로 모두 동일한 주문 준비 헤더·본문 계약으로 이어져요.
로그인 토큰 재발급은 주문 유효시간을 연장하지 않아요. 화면 제목이 "세션 만료"여도 실제 코드가 ORDER_NOT_PAYMENT_READY이거나 주문 상태가 order_expired이면 주문 상태와 재시도를 확인해요. 일반 주문의 범용 /b 경유는 API가 처리하며, 청구서 전용 /i/{clientKey}/{invoiceId}/session에 일반 주문번호를 넣지 않아요.
로그아웃
DELETE https://api.bootapi.com/v1/users/session
await commerce.user.userLogout(customerJwt)javascriptBFF는 서버 로그아웃 처리와 함께 자체 세션 쿠키를 지워요. 이 요청에는 user:user_session_delete scope와 유효한 Bootpay-User-JWT가 필요해요. 응답 본문은 boolean이며, user_id 계열 파라미터는 거절해요. POST /v1/users/session은 라우트가 생성되어 있어도 create 액션이 구현되지 않아 로그인에 사용할 수 없어요.
고객 식별자 경계
POST /v1/users/login/token은 비밀번호 없이 지정한 고객의 세션을 발급하는 서버 권한 API예요. 브라우저가 임의 user_id를 보낼 수 있는 공개 엔드포인트로 그대로 연결하지 않아요. 서버에서 이미 검증한 로그인 고객과 Bootpay 고객의 매핑을 사용해요.
확인 근거: V1::Users::LoginController, LoginService, SessionsController, SessionShowService, User::DataFormat#session_data, 공식 SDK user 모듈.