Stripe 통합 추가
Stripe는 인터넷 비즈니스를 위한 온라인 결제 처리 플랫폼입니다. Stripe를 통합하면 애플리케이션에서 거래, 구독 및 금융 데이터를 안전하게 처리할 수 있습니다.
구성 단계
섹션 제목: “구성 단계”통합 목록에서 Stripe를 선택하면 구성 모달이 나타납니다. 연결을 설정하려면 Stripe 대시보드에서 다음 자격 증명을 제공해야 합니다.
1. 비밀 키 (Secret Key)
섹션 제목: “1. 비밀 키 (Secret Key)”- 입력: Secret Key 필드에 개인 Stripe 비밀 키 (일반적으로
sk_로 시작)를 입력하십시오. 이 키를 통해 백엔드가 보안 요청을 인증할 수 있습니다.
2. 게시 가능 키 (Publishable Key)
섹션 제목: “2. 게시 가능 키 (Publishable Key)”- 입력: Publishable Key 필드에 공용 Stripe 게시 가능 키 (일반적으로
pk_로 시작)를 입력하십시오. 이 키는 프런트엔드 구현에 사용됩니다.
3. 환경
섹션 제목: “3. 환경”- 입력: 드롭다운 메뉴에서 적절한 환경 컨텍스트를 선택하십시오 (예: 개발/샌드박스 모드의 경우 Test, 실시간 처리의 경우 Production).
연결 완료
섹션 제목: “연결 완료”키와 환경이 구성되면:
- 상태 표시줄을 확인하십시오 (현재 Not Connected로 표시됨).
- 오른쪽 하단의 검은색 Add 버튼을 클릭하여 자격 증명을 저장하고 결제 통합을 활성화하십시오.


Stripe 통합 API 참조
섹션 제목: “Stripe 통합 API 참조”구성 관리
섹션 제목: “구성 관리”configureStripe
섹션 제목: “configureStripe”프로젝트 및 환경에 대한 새 Stripe 구성을 생성합니다.
Mutation:
mutation ConfigureStripe ( $input: ConfigureStripeInput!) { configureStripe ( input: $input ) { id publishableKey webhookUrl }}Input:
input ConfigureStripeInput { secretKey: String! # Stripe secret key (sk_test_... or sk_live_...) publishableKey: String! # Stripe publishable key (pk_test_... or pk_live_...) environment: StripeEnvironment! # TEST or LIVE webhookSecret: String # Webhook signing secret (optional)}Response:
type ConfigureStripePayload { id: ID! # Configuration ID publishableKey: String! # Publishable key webhookUrl: String! # Generated webhook URL}Example:
{ "input": { "secretKey": "sk_test_...", "publishableKey": "pk_test_...", "environment": "TEST", "webhookSecret": "whsec_..." }}참고:
- 비밀 키는 저장 전에 AES-256-GCM으로 암호화됩니다.
- 프로젝트/환경 조합당 하나의 구성만 가능
- 구성이 이미 존재하는 경우 오류 반환
updateStripeConfig
섹션 제목: “updateStripeConfig”기존 Stripe 구성을 업데이트합니다.
Mutation:
mutation UpdateStripeConfig ( $input: UpdateStripeConfigInput!) { updateStripeConfig ( input: $input ) { id publishableKey webhookUrl }}Input:
input UpdateStripeConfigInput { secretKey: String # Optional publishableKey: String # Optional environment: StripeEnvironment # Optional webhookSecret: String # Optional}Response:
type UpdateStripeConfigPayload { id: ID! publishableKey: String! webhookUrl: String!}참고:
- 모든 필드는 선택 사항입니다.
- 제공된 필드만 업데이트됩니다.
- 비밀 키가 제공되면 암호화됩니다.
고객 관리
섹션 제목: “고객 관리”stripe_customer
섹션 제목: “stripe_customer”ID로 단일 고객을 검색합니다.
Query:
query stripe_customer{ stripe_customer( id: "cus_Ts..." ) { id name email phone description metadata object createdAt }}stripe_customers
섹션 제목: “stripe_customers”페이지네이션 및 선택적 필터링을 사용하여 고객을 나열합니다.
Query:
query stripe_customers ( $first: Int, $after: String, $customerId: String) { stripe_customers ( first: $first, after: $after, customerId: $customerId ) { edges { node { id name email phone description createdAt } cursor } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } }}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서customerId: 고객 ID로 필터링 (선택 사항)
stripe_createCustomer
섹션 제목: “stripe_createCustomer”새 고객을 생성합니다.
Mutation:
mutation stripe_createCustomer { stripe_createCustomer ( input: { name: "Customer", email: "example@archie.com", phone: "+573001230001", description: "Description Example" metadata: { data1: "Example data1", data2: "Example data2" } } ) { id name email phone description metadata object createdAt }}stripe_updateCustomer
섹션 제목: “stripe_updateCustomer”기존 고객을 업데이트합니다.
Mutation:
mutation stripe_updateCustomer { stripe_updateCustomer( id: "cus_Ts...", input: { name: "Customer", email: "example@archie.com", phone: "+573001230001", description:"Description Example", metadata: { data1: "Example data1 updated", data2: "Example data2 updated" } } ) { id name email phone description metadata object createdAt }}참고:
- 모든 필드는 선택 사항입니다.
- 제공된 필드만 업데이트됩니다.
stripe_deleteCustomer
섹션 제목: “stripe_deleteCustomer”고객을 삭제합니다.
Mutation:
mutation stripe_deleteCustomer { stripe_deleteCustomer ( id: "cus_Ts...")}Response:
- 성공 시
true반환 - 고객을 찾을 수 없는 경우 오류 반환
결제 의도 (Payment Intents)
섹션 제목: “결제 의도 (Payment Intents)”stripe_paymentIntent
섹션 제목: “stripe_paymentIntent”ID로 단일 결제 의도를 검색합니다.
Query:
query stripe_paymentIntent { stripe_paymentIntent ( id: "pi_3Su..." ) { id customerId paymentMethodId currency amount status metadata object clientSecret createdAt }}stripe_paymentIntents
섹션 제목: “stripe_paymentIntents”페이지네이션 및 선택적 필터링을 사용하여 결제 의도를 나열합니다.
Query:
query stripe_paymentIntents ( $first: Int, $after: String, $customerId: String) { stripe_paymentIntents ( first: $first, after: $after, customerId: $customerId ) { edges { node { id customerId paymentMethodId currency amount status metadata object clientSecret createdAt } cursor } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } }}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서customerId: 고객 ID로 필터링 (선택 사항)
stripe_createPaymentIntent
섹션 제목: “stripe_createPaymentIntent”새 결제 의도를 생성합니다.
Mutation:
mutation stripe_createPaymentIntent { stripe_createPaymentIntent ( input: { amount: 12.35, currency: "usd", customerId: "cus_Ts...", paymentMethodId: "pm_1Su...", automaticPaymentMethods: true } ) { id customerId paymentMethodId currency amount status metadata object clientSecret createdAt }}참고:
clientSecret은 프런트엔드 확인을 위해 반환됩니다.- Stripe.js와의 통합을 위해
automaticPaymentMethods: true를 사용하십시오.
stripe_updatePaymentIntent
섹션 제목: “stripe_updatePaymentIntent”확인 전에 결제 의도를 업데이트합니다.
Mutation:
mutation stripe_updatePaymentIntent{ stripe_updatePaymentIntent( id: "pi_3S...", input: { amount: 36.92, currency: "usd", paymentMethodId: "pm_1Su..." metadata:{ data1: "Example data1" } } ) { id customerId paymentMethodId currency amount status metadata object clientSecret createdAt }}참고:
- 확인 전에만 업데이트할 수 있습니다.
- 모든 필드는 선택 사항입니다.
stripe_confirmPaymentIntent
섹션 제목: “stripe_confirmPaymentIntent”결제 의도를 확인합니다.
Mutation:
mutation stripe_confirmPaymentIntent{ stripe_confirmPaymentIntent( id: "pi_3Su..." input: { paymentMethodId: "pm_1Su...", returnUrl: "http://localhost:3000/successful-payment" } ) { id customerId paymentMethodId currency amount status metadata object clientSecret createdAt }}참고:
- 결제를 완료하려면 필수입니다.
- 3D Secure 인증이 필요할 수 있습니다.
- 업데이트된 상태 (succeeded, requires_action 등)를 반환합니다.
stripe_cancelPaymentIntent
섹션 제목: “stripe_cancelPaymentIntent”결제 의도를 취소합니다.
Mutation:
mutation stripe_cancelPaymentIntent { stripe_cancelPaymentIntent( id: "pi_3Su..." ) { id customerId paymentMethodId currency amount status metadata object clientSecret createdAt }}참고:
- 성공하지 않았거나 취소되지 않은 결제 의도만 취소할 수 있습니다.
- 상태가 “canceled”로 변경됩니다.
stripe_subscription
섹션 제목: “stripe_subscription”ID로 단일 구독을 검색합니다.
Query:
query stripe_subscription { stripe_subscription(id: "sub_1Su...") { id customerId status currentPeriodStart currentPeriodEnd createdAt cancelAtPeriodEnd metadata object items { data { id priceId quantity } } }}stripe_subscriptions
섹션 제목: “stripe_subscriptions”페이지네이션 및 선택적 필터링을 사용하여 구독을 나열합니다.
Query:
query stripe_subscriptions ( $first: Int, $after: String, $customerId: String) { stripe_subscriptions ( first: $first, after: $after, customerId: $customerId ) { edges { node { id customerId status currentPeriodStart currentPeriodEnd createdAt cancelAtPeriodEnd metadata object items { data { id priceId quantity } } } cursor } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } }}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서customerId: 고객 ID로 필터링 (선택 사항)status: 상태로 필터링 (선택 사항)
stripe_createSubscription
섹션 제목: “stripe_createSubscription”새 구독을 생성합니다.
Mutation:
mutation stripe_createSubscription { stripe_createSubscription ( input: { customerId: "cus_TsQ...", items: { priceId: "price_1Su...", quantity: 1 }, metadata: { data1: "Example data1" }, trialPeriodDays: 0 } ) { id customerId status currentPeriodStart currentPeriodEnd createdAt cancelAtPeriodEnd metadata object items { data { id priceId quantity } } }}참고:
paymentBehavior는 결제 방법이 필요한 구독에 대해 “default_incomplete”일 수 있습니다.- 평가 기간은 일 단위로 지정됩니다.
- 최신 인보이스 및 결제 의도가 자동으로 확장됩니다.
stripe_updateSubscription
섹션 제목: “stripe_updateSubscription”기존 구독을 업데이트합니다.
Mutation:
mutation stripe_updateSubscription { stripe_updateSubscription( id: "sub_1Sv..." input: { cancelAtPeriodEnd: false metadata: { data2: "Example data2" } } ) { id customerId status currentPeriodStart currentPeriodEnd createdAt cancelAtPeriodEnd metadata object items { data { id priceId quantity } } }}stripe_cancelSubscription
섹션 제목: “stripe_cancelSubscription”구독을 취소합니다.
Mutation:
mutation stripe_cancelSubscription { stripe_cancelSubscription ( cancelAtPeriodEnd: true, id: "sub_1Sv..." ) { id customerId status currentPeriodStart currentPeriodEnd createdAt cancelAtPeriodEnd metadata object items { data { id priceId quantity } } }}Parameters:
id: 구독 ID (필수)cancelAtPeriodEnd: true인 경우 기간 종료 시 취소, false인 경우 즉시 취소 (기본값: false)
참고:
- 즉시 취소: 구독이 지금 종료됩니다.
- 기간 종료 시 취소: 구독이 현재 기간이 끝날 때까지 계속됩니다.
제품 및 가격
섹션 제목: “제품 및 가격”stripe_products
섹션 제목: “stripe_products”페이지네이션을 사용하여 제품을 나열합니다.
Query:
query stripe_products ( $first: Int, $after: String) { stripe_products ( first: $first, after: $after ) { edges { node { id name description active metadata object createdAt } cursor } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } }}stripe_createProduct
섹션 제목: “stripe_createProduct”새 제품을 생성합니다.
Mutation:
mutation stripe_createProduct { stripe_createProduct ( input: { name: "Product 01", description: "Description product 01", metadata: { data1: "Example data1" } } ) { id name description active metadata object createdAt }}stripe_prices
섹션 제목: “stripe_prices”페이지네이션 및 선택적 필터링을 사용하여 가격을 나열합니다.
Query:
query stripe_prices ( $first: Int, $after: String, $productId: String) { stripe_prices ( first: $first, after: $after, productId: $productId ) { edges { node { id productId active currency unitAmount object metadata createdAt recurring { interval intervalCount } } cursor } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } }}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서productId: 제품 ID로 필터링 (선택 사항)
stripe_createPrice
섹션 제목: “stripe_createPrice”새 가격을 생성합니다.
Mutation:
mutation stripe_createPrice { stripe_createPrice ( input: { productId: "prod_Tst...", unitAmount: 25.85, currency: "usd", recurring: { interval: "month", intervalCount: 1 }, metadata: { data1: "Example data1" } } ) { id productId currency unitAmount active object createdAt metadata recurring { interval intervalCount } }}참고:
- 일회성 가격의 경우
recurring을 생략하십시오. interval은 “day”, “week”, “month”, “year” 중 하나여야 합니다.
인보이스 (Invoices)
섹션 제목: “인보이스 (Invoices)”stripe_invoice
섹션 제목: “stripe_invoice”ID로 단일 인보이스를 검색합니다.
Query:
query stripe_invoice { stripe_invoice ( id: "in_1Su..." ) { id customerId subscriptionId currency amountPaid amountDue status object metadata createdAt lineItems { data { id description currency amount quantity } } }}참고:
- 구독 ID는 가능한 경우 API 확장을 통해 채워집니다.
stripe_invoices
섹션 제목: “stripe_invoices”페이지네이션 및 선택적 필터링을 사용하여 인보이스를 나열합니다.
Query:
query stripe_invoices ( $first: Int, $after: String, $customerId: String, $status: String) { stripe_invoices ( first: $first, after: $after, customerId: $customerId, status: $status ) { edges { node { id customerId subscriptionId currency amountPaid amountDue status object metadata createdAt lineItems { data { id description currency amount quantity } } } cursor } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } }}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서customerId: 고객 ID로 필터링 (선택 사항)status: 상태로 필터링 (선택 사항)
stripe_payInvoice
섹션 제목: “stripe_payInvoice”프로그래밍 방식으로 인보이스를 결제합니다.
Mutation:
mutation stripe_payInvoice { stripe_payInvoice ( id: "in_1Sv..." ) { id customerId subscriptionId currency amountPaid amountDue status object metadata createdAt lineItems { data { id description currency amount quantity } } }}참고:
- 고객의 기본 결제 방법을 사용하여 인보이스 결제를 시도합니다.
- 결제가 실패하면 오류를 반환합니다.
- 성공 시 인보이스 상태를 “paid”로 업데이트합니다.
환불 (Refunds)
섹션 제목: “환불 (Refunds)”stripe_refunds
섹션 제목: “stripe_refunds”페이지네이션 및 선택적 필터링을 사용하여 환불을 나열합니다.
Query:
query stripe_refunds ( $first: Int, $after: String, $paymentIntentId: String) { stripe_refunds ( first: $first, after: $after, paymentIntentId: $paymentIntentId ) { edges { node { id paymentIntentId reason status currency amount metadata object createdAt } cursor } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } }}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서paymentIntentId: 결제 의도 ID로 필터링 (선택 사항)
stripe_createRefund
섹션 제목: “stripe_createRefund”결제 의도에 대한 환불을 생성합니다.
Mutation:
mutation stripe_createRefund { stripe_createRefund ( input: { paymentIntentId: "pi_3Sv...", amount: 200, reason: "requested_by_customer" } ) { id reason paymentIntentId status currency amount object metadata createdAt }}참고:
- 전액 환불의 경우
amount를 생략하십시오. reason은 “duplicate”, “fraudulent”, “requested_by_customer” 중 하나일 수 있습니다.- 환불 상태는 “pending”으로 시작하여 “succeeded” 또는 “failed”로 업데이트됩니다.
결제 방법 (Payment Methods)
섹션 제목: “결제 방법 (Payment Methods)”stripe_paymentMethods
섹션 제목: “stripe_paymentMethods”페이지네이션 및 선택적 필터링을 사용하여 결제 방법을 나열합니다.
Query:
query stripe_paymentMethods ( $first: Int, $after: String, $customerId: String) { stripe_paymentMethods( first: $first, after: $after, customerId: $customerId ) { edges { node { id customerId type object metadata createdAt card { brand expMonth expYear last4 } } cursor } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } }}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서customerId: 고객 ID로 필터링 (선택 사항)
참고:
- 안전한 카드 정보 (마지막 4자리, 브랜드, 만료일)만 반환됩니다.
- 전체 카드 번호는 절대 노출되지 않습니다.
stripe_attachPaymentMethod
섹션 제목: “stripe_attachPaymentMethod”고객에게 결제 방법을 연결합니다.
Mutation:
mutation stripe_attachPaymentMethod { stripe_attachPaymentMethod ( id: "pm_1Sv...", input: { customerId: "cus_Ts4..." } ) { id customerId type card { brand expMonth expYear last4 } metadata object createdAt }}참고:
- 결제 방법은 먼저 생성되어야 합니다 (일반적으로 Stripe.js를 통해).
- 연결된 결제 방법은 구독 및 결제에 사용할 수 있습니다.
stripe_detachPaymentMethod
섹션 제목: “stripe_detachPaymentMethod”고객에게서 결제 방법을 분리합니다.
Mutation:
mutation stripe_detachPaymentMethod { stripe_detachPaymentMethod ( id: "pm_1Sv..." ) { id customerId type card { brand expYear expMonth last4 } metadata object createdAt }}참고:
- 분리된 결제 방법은 더 이상 결제에 사용할 수 없습니다.
customerId가 null로 설정된 결제 방법을 반환합니다.
Webhook 이벤트
섹션 제목: “Webhook 이벤트”stripe_webhookEvents
섹션 제목: “stripe_webhookEvents”서비스에서 수신한 Webhook 이벤트를 나열합니다.
Query:
query ListWebhookEvents ( $first: Int, $after: String) { stripe_webhookEvents ( first: $first, after: $after ) { edges { node { id type data processed createdAt } cursor } pageInfo { hasNextPage hasPreviousPage endCursor } }}Response:
type StripeWebhookEvent { id: ID! type: String! # Event type (e.g., "payment_intent.succeeded") data: String! # JSON string of event data processed: Boolean! # Whether event has been processed createdAt: Time!}Parameters:
first: 반환할 항목 수 (기본값: 10)after: 페이지네이션용 커서
참고:
- 이벤트는 Webhook 엔드포인트를 통해 자동으로 수신됩니다.
- 이벤트는 서명 확인 후 저장됩니다.
data필드에는 전체 이벤트 페이로드가 JSON 문자열로 포함됩니다.
페이지네이션
섹션 제목: “페이지네이션”모든 목록 쿼리는 Relay 연결 패턴을 사용하는 커서 기반 페이지네이션을 지원합니다.
PageInfo
섹션 제목: “PageInfo”type PageInfo { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String endCursor: String}사용 예
섹션 제목: “사용 예”query ListCustomers ( $first: Int, $after: String) { stripe_customers ( first: $first, after: $after ) { edges { node { id email } cursor } pageInfo { hasNextPage endCursor } }}페이지네이션 흐름:
- 초기 요청:
first: 10, after: null - 응답의
pageInfo.endCursor를 다음 요청의after로 사용 hasNextPage를 확인하여 더 많은 페이지가 있는지 확인
기본값:
first: 제공되지 않은 경우 기본값 10after: 제공되지 않은 경우 처음부터 시작
오류 처리
섹션 제목: “오류 처리”모든 작업은 사용자 친화적인 메시지와 함께 GraphQL 오류를 반환합니다. 오류는 명확한 피드백을 제공하기 위해 Stripe API 오류에서 매핑됩니다.
일반적인 오류 시나리오
섹션 제목: “일반적인 오류 시나리오”구성 오류:
400: 잘못된 Stripe 키 형식404: 프로젝트 또는 구성을 찾을 수 없음400: 구성이 이미 존재함
고객 오류:
404: 고객을 찾을 수 없음400: 잘못된 고객 데이터
결제 의도 오류:
404: 결제 의도를 찾을 수 없음400: 잘못된 금액 또는 통화402: 결제 실패 (카드 거부, 잔액 부족 등)
구독 오류:
404: 구독을 찾을 수 없음400: 잘못된 구독 매개변수400: 취소된 구독을 업데이트할 수 없음
Stripe 오류 코드: 일반적인 Stripe 오류 코드는 사용자 친화적인 메시지로 매핑됩니다.
card_declined: “카드가 거부되었습니다”insufficient_funds: “잔액이 부족합니다”invalid_number: “잘못된 카드 번호입니다”expired_card: “카드가 만료되었습니다”incorrect_cvc: “잘못된 CVC 코드입니다”
오류 응답 형식
섹션 제목: “오류 응답 형식”{ "errors": [ { "message": "Customer not found", "extensions": { "code": "NOT_FOUND", "stripeErrorCode": "resource_missing" } } ], "data": null}데이터 유형
섹션 제목: “데이터 유형”StripeEnvironment
섹션 제목: “StripeEnvironment”enum StripeEnvironment { TEST # Test mode LIVE # Live/production mode}Scalar Map
섹션 제목: “Scalar Map”Map 스칼라 유형은 키-값 맵을 나타냅니다.
- 키는 문자열입니다.
- 값은 문자열, 숫자, 부울 또는 중첩된 맵일 수 있습니다.
- 메타데이터 필드에 사용됩니다.
예:
{ "metadata": { "order_id": "12345", "user_id": "67890", "premium": true }}Scalar Time
섹션 제목: “Scalar Time”Time 스칼라 유형은 ISO 8601 형식의 타임스탬프를 나타냅니다.
예: "2025-11-16T00:28:48.081Z"