2025. 5. 26. 16:55ㆍ카테고리 없음
결제승인
Stripe는 글로벌 결제 처리 플랫폼으로, 온라인 및 오프라인에서 카드 결제, 간편 결제, 구독, 송금, 정산, 환불 등 다양한 결제 관련 기능을 API로 제공하는 서비스입니다. 개발자 친화적인 설계 덕분에 전 세계적으로 많이 사용됩니다.
🧾 Stripe 플랫폼 개요
항목 설명
주요 기능 | 카드 결제, 구독, 정기 결제, 결제 대시보드, 웹훅 등 |
지원 결제 수단 | 신용/체크카드, Apple Pay, Google Pay, Alipay, 계좌 이체 등 |
개발자 지원 | Node.js, Python, Java, PHP, Ruby, .NET 등 SDK 지원 |
주요 서비스 지역 | 미국, 유럽, 아시아 등 대부분 국가 (대한민국 포함) |
보안 인증 | PCI-DSS, TLS 1.2 이상, 3D Secure 등 지원 |
✅ Stripe 결제 흐름 요약 (기본 카드 결제)
- 클라이언트: 카드 정보 입력
- 서버:
- PaymentIntent 생성 요청
- 필요 시 3D Secure 인증 처리
- Stripe: 결제 처리
- 서버: 결제 결과 처리 후 사용자에게 응답
💻 예: Node.js 백엔드에서 Stripe 결제 처리하기
1. Stripe 설치
npm install stripe
2. .env 파일에 Stripe 키 설정
STRIPE_SECRET_KEY=sk_test_1234567890abcdef
3. 서버 코드 예제 (payment.service.ts 또는 controller)
import Stripe from 'stripe';
import { Injectable } from '@nestjs/common';
import * as dotenv from 'dotenv';
dotenv.config();
@Injectable()
export class PaymentService {
private stripe: Stripe;
private const defaultCurrency = 'usd';
constructor() {
this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, {
apiVersion: '2025-04-30.basil',
});
}
async createPaymentIntent(amount: number, currency: string) {
try {
const paymentIntent = await this.stripe.paymentIntents.create({
amount, // 단위: 센트 (예: ₩1,000 → 100000)
currency || defaultCurrency,
payment_method_types: ['card', 'alipay', 'grabpay'],
});
return {
clientSecret: paymentIntent.client_secret,
};
} catch (err) {
console.error('결제 생성 오류:', err);
throw err;
}
}
}
4. 클라이언트 코드 예 (React + Stripe.js)
function PaymentOptions({ clientSecret }) {
const stripe = useStripe();
const elements = useElements();
const [method, setMethod] = useState('card'); // 사용자가 선택
const handleSubmit = async (e) => {
e.preventDefault();
if (method === 'card') {
await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
});
} else if (method === 'alipay') {
await stripe.confirmAlipayPayment(clientSecret, {
return_url: 'https://yourdomain.com/payment-complete',
});
} else if (method === 'grabpay') {
await stripe.confirmGrabPayPayment(clientSecret, {
return_url: 'https://yourdomain.com/payment-complete',
});
}
};
return (
<form onSubmit={handleSubmit}>
<select onChange={(e) => setMethod(e.target.value)} value={method}>
<option value="card">카드 결제</option>
<option value="alipay">Alipay</option>
<option value="grabpay">GrabPay</option>
</select>
{method === 'card' && <CardElement />}
<button type="submit">결제하기</button>
</form>
);
}
🛠 통합 팁
- 금액은 센트 단위 (₩1,000 → 100000)로 요청
- 웹훅(webhook)을 통해 성공/실패 알림 처리 가능
- 카드 정보는 절대 서버로 전달하지 말 것! → Stripe.js로 직접 Stripe에 전송
🧩 예시: 회사 시스템에서 API 호출 흐름
📌 시나리오
고객이 골프 예약을 하고, 카드로 결제를 완료해야 함.
🔄 서버 처리 흐름
- 고객이 예약 → 프론트에서 결제 버튼 클릭
- 서버에서 /create-payment-intent API 호출
- 생성된 client_secret을 프론트로 전달
- Stripe.js로 카드 입력 → Stripe 서버와 통신
- 결제 완료 → 서버에서 Stripe 웹훅 또는 confirm 후 처리
📎 문서 링크
제공 UI 사용 방법
좋아요! Stripe에서 제공하는 기본 UI 방식인 Stripe Elements + Payment Element는 Stripe가 다양한 결제 수단을 자동으로 사용자에게 보여주고 처리까지 해주는 통합 컴포넌트입니다.
✅ 목표: 프론트에서 별도 결제 수단 선택 UI를 만들 필요 없이,
Stripe가 카드, Alipay, GrabPay 등 활성화된 결제 수단을 자동으로 표시하고 처리까지 해줍니다.
🧩 Stripe Payment Element란?
Stripe Payment Element는 다음을 통합한 컴포넌트입니다:
포함 요소 설명
카드 입력 폼 | 카드 번호, 만료일, CVC 등 |
간편결제 버튼 | Apple Pay, Google Pay |
로컬 결제 옵션 | Alipay, GrabPay 등 |
자동 결제 수단 표시 | 사용자의 국가, 디바이스, 설정된 payment_method_types에 따라 자동 |
🛠️ 기본 구성 흐름 (프론트 + 백엔드)
1️⃣ 백엔드: PaymentIntent 생성
// NestJS나 Express 기준
const paymentIntent = await stripe.paymentIntents.create({
amount: 5000, // 50.00 USD
currency: 'usd',
automatic_payment_methods: {
enabled: true, // 필수! → 여러 결제수단 자동 지원
},
});
return { clientSecret: paymentIntent.client_secret };
✅ automatic_payment_methods: { enabled: true } 설정 시,
Stripe가 카드, Alipay, GrabPay 등 자동으로 적용 가능한 결제 수단을 판단합니다.
2️⃣ 프론트엔드: Stripe.js + React 등에서 Elements 설정
👉 1. Stripe.js 초기화
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe('pk_test_...'); // 퍼블릭 키
👉 2. Elements 구성
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm />
</Elements>
3️⃣ 프론트엔드: PaymentElement 컴포넌트 사용
import { PaymentElement, useStripe, useElements } from '@stripe/react-stripe-js';
const CheckoutForm = () => {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event) => {
event.preventDefault();
const result = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: 'https://yourdomain.com/payment-complete',
},
});
if (result.error) {
console.error(result.error.message);
} else {
console.log("결제 완료");
}
};
return (
💡 자동 포함되는 결제 수단 예
결제 수단 포함 여부 (자동)
💳 카드 결제 | 기본 포함 |
💼 Apple Pay / Google Pay | 사용자의 디바이스에 따라 자동 노출 |
🌏 Alipay / GrabPay / FPX 등 | 백엔드에서 활성화되어 있고 사용자 위치가 지원되면 자동 표시 |
🎨 디자인 커스터마이징도 가능
const options = {
clientSecret,
appearance: {
theme: 'stripe', // 또는 'night', 'flat' 등
labels: 'floating',
},
};
✅ 테마, 글꼴, 폼 스타일 등 일부 커스터마이징 가능
📦 장점 vs 단점
장점 단점
✅ UI 구현 거의 불필요 | ❌ 디자인 커스터마이징 제한 |
✅ 다양한 결제 방식 자동 표시 | ❌ 완전한 UX 제어는 어려움 |
✅ 3D Secure 자동 처리 | ❌ 결제 방식 고정 불가 (무조건 자동 노출) |
📌 결론
Stripe Payment Element는 가장 빠르고 안전하게 결제 시스템을 구축하는 방법입니다.
- 서버에서 automatic_payment_methods: true 설정
- 프론트에서 <PaymentElement />로 자동 UI 렌더링
- 사용자는 카드/간편결제 등을 선택하고 결제
- 결제 완료 후 return_url로 이동
👇 원하시면:
- Next.js/React 프로젝트 통합 예제
- return_url에서 결제 결과 처리 방법
- 백엔드 NestJS 또는 Express 연동 코드
제공해드릴 수 있어요. 사용 중인 프레임워크를 알려주세요!
제공하는 UI 적용 - HTML
✅ 순수 HTML + JavaScript 환경에서 Stripe Payment Element 사용 방법
1️⃣ Stripe.js 스크립트 로드
HTML에 Stripe 라이브러리를 추가:
<script src="https://js.stripe.com/v3/"></script>
2️⃣ 백엔드에서 PaymentIntent 생성 → client_secret 반환
// 예: Node.js 서버에서
const paymentIntent = await stripe.paymentIntents.create({
amount: 5000,
currency: 'usd',
automatic_payment_methods: {
enabled: true,
},
});
res.json({ clientSecret: paymentIntent.client_secret });
3️⃣ 프론트엔드에 Payment Element 삽입
<form id="payment-form">
<div id="payment-element"><!-- Stripe 결제 UI 렌더링됨 --></div>
<button id="submit">결제하기</button>
<div id="error-message"></div>
</form>
<script>
const stripe = Stripe("pk_test_..."); // 퍼블릭 키
const clientSecret = "서버에서 받아온 client_secret";
const elements = stripe.elements({ clientSecret });
const paymentElement = elements.create("payment");
paymentElement.mount("#payment-element");
const form = document.getElementById("payment-form");
form.addEventListener("submit", async (event) => {
event.preventDefault();
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: "https://yourdomain.com/payment-complete",
},
});
if (error) {
document.getElementById("error-message").textContent = error.message;
}
});
</script>
🧩 실제로 자동으로 보여주는 예
사용자가 결제 페이지에 접근하면 Stripe는 자동으로:
- 카드 입력 UI
- Apple Pay / Google Pay 버튼
- Alipay, GrabPay, FPX 등 로컬 결제 수단
을 자동으로 판단해서 보여줍니다.
📦 이 방식의 장점
장점 설명
✅ 프레임워크 없이 가능 | React/Next.js 없이도 Stripe 결제 구현 가능 |
✅ 다양한 결제 수단 자동 지원 | 사용자의 디바이스와 위치에 따라 알맞은 결제 수단 자동 표시 |
✅ 가장 빠른 구현 방법 | UI, 인증, 보안 Stripe가 모두 관리 |
🧪 참고: 테스트 카드
- 카드 번호: 4242 4242 4242 4242
- 유효기간: 아무 미래 날짜
- CVC: 아무 숫자
✅ 결론
Stripe Payment Element는 일반 자바스크립트만으로도 쉽게 적용 가능하며,
결제 수단 선택 UI도 Stripe가 자동으로 구성해주기 때문에 별도 UI 없이도 구현할 수 있는 매우 편리한 방식입니다.
필요하다면:
- Node.js + HTML 예제 프로젝트 구조
- 서버 없는 클라이언트 테스트 코드 (정적 HTML 기반)
- 한국 결제 수단 대응 여부
도와드릴 수 있어요. 추가로 원하시면 알려주세요!
제공하는 UI 적용 - flutter
✅ Stripe Payment Sheet이란?
Stripe가 제공하는 모든 결제 수단을 자동으로 감지하고 하나의 UI로 통합해서 보여주는 표준 결제 창입니다.
예시 화면:
- 카드 정보 입력 필드
- Google Pay / Apple Pay 버튼
- Alipay, GrabPay 등 지역 결제 수단
- UI 및 보안, UX Stripe가 전담
✅ Flutter에서 Payment Sheet 띄우는 흐름
1️⃣ 서버에서 PaymentIntent 생성
백엔드(Node.js 등)에서 다음처럼 생성합니다:
const paymentIntent = await stripe.paymentIntents.create({
amount: 5000,
currency: 'usd',
automatic_payment_methods: { enabled: true },
});
res.json({ clientSecret: paymentIntent.client_secret });
2️⃣ Flutter 앱에서 Stripe Payment Sheet 띄우기
앱 시작
↓
서버에서 publishableKey 요청
↓
Stripe.publishableKey 설정 → applySettings()
↓
결제 시점에 server에서 clientSecret 요청
↓
initPaymentSheet → presentPaymentSheet
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 퍼블릭 키를 서버에서 받아오기
final response = await http.get(Uri.parse('http://yourserver.com/stripe/publishable-key'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
final publishableKey = data['publishableKey'];
// Stripe 초기화
Stripe.publishableKey = publishableKey;
await Stripe.instance.applySettings();
runApp(MyApp());
} else {
throw Exception('❌ 퍼블릭 키를 불러올 수 없습니다');
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Stripe 결제 테스트')),
body: Center(
child: ElevatedButton(
onPressed: () async {
await payWithStripe();
},
child: Text('결제하기'),
),
),
),
);
}
}
// ✅ 서버에서 PaymentIntent 생성 후 clientSecret을 받아오는 함수
Future<String> fetchClientSecretFromServer() async {
final response = await http.post(Uri.parse('http://yourserver.com/create-payment-intent'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
return data['clientSecret']; // 서버에서 받은 clientSecret 반환
} else {
throw Exception('❌ clientSecret 요청 실패');
}
}
// ✅ Stripe 결제 흐름
Future<void> payWithStripe() async {
try {
// 1. 서버에서 PaymentIntent 생성 후 clientSecret 받기
final clientSecret = await fetchClientSecretFromServer();
// 2. Stripe PaymentSheet 초기화
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: clientSecret,
merchantDisplayName: 'Your Company',
style: ThemeMode.light,
),
);
// 3. 결제 UI 띄우기 (Stripe 제공 화면)
await Stripe.instance.presentPaymentSheet();
// 4. 결제 성공 처리
print('✅ 결제 성공!');
} catch (e) {
print('❌ 결제 실패: $e');
}
}
💡 장점
항목 설명
✅ 완전한 Stripe UI 사용 | 카드 입력부터 간편결제 버튼까지 |
✅ 여러 결제 수단 자동 지원 | 카드, Apple Pay, Google Pay, Alipay 등 |
✅ Flutter에서도 그대로 사용 가능 | React Native 수준으로 지원 |
✅ UX, 보안, 인증 모두 Stripe가 처리 | 직접 구현할 필요 없음 |
📷 예시 화면
사용 환경 보여주는 결제 수단
iPhone | Apple Pay + 카드 UI |
Android | Google Pay + 카드 UI |
동남아 | GrabPay, FPX 등 로컬 결제 |
한국 | 카드 (Stripe가 계약된 카드사 기준) |
🛠️ 정리
Stripe의 Payment Sheet는 Flutter에서도 공식 지원되며,
Stripe가 만든 결제 UI를 그대로 앱 안에서 띄우고 사용할 수 있습니다.
flutter로 stripe에서 지원하는 결제 UI 실행하여 결제하기
✅ Stripe Payment Sheet이란?
Stripe가 제공하는 모든 결제 수단을 자동으로 감지하고 하나의 UI로 통합해서 보여주는 표준 결제 창입니다.
예시 화면:
- 카드 정보 입력 필드
- Google Pay / Apple Pay 버튼
- Alipay, GrabPay 등 지역 결제 수단
- UI 및 보안, UX Stripe가 전담
✅ Flutter에서 Payment Sheet 띄우는 흐름
1️⃣ 서버에서 PaymentIntent 생성
백엔드(Node.js 등)에서 다음처럼 생성합니다:
const paymentIntent = await stripe.paymentIntents.create({
amount: 5000,
currency: 'usd',
automatic_payment_methods: { enabled: true },
});
res.json({ clientSecret: paymentIntent.client_secret });
2️⃣ Flutter 앱에서 Stripe Payment Sheet 띄우기
import 'package:flutter_stripe/flutter_stripe.dart';
Future<void> payWithStripe() async {
// 1. 서버에서 PaymentIntent 생성 후 clientSecret 받기
final clientSecret = await fetchClientSecretFromServer();
// 2. Stripe PaymentSheet 초기화
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: clientSecret,
merchantDisplayName: 'Your Company',
style: ThemeMode.light, // 다크 모드 등 가능
),
);
// 3. 결제 UI 띄우기 (Stripe가 제공하는 화면)
await Stripe.instance.presentPaymentSheet();
// 4. 성공 시 처리
print('결제 성공!');
}
💡 장점
항목 설명
✅ 완전한 Stripe UI 사용 | 카드 입력부터 간편결제 버튼까지 |
✅ 여러 결제 수단 자동 지원 | 카드, Apple Pay, Google Pay, Alipay 등 |
✅ Flutter에서도 그대로 사용 가능 | React Native 수준으로 지원 |
✅ UX, 보안, 인증 모두 Stripe가 처리 | 직접 구현할 필요 없음 |
📷 예시 화면
사용 환경 보여주는 결제 수단
iPhone | Apple Pay + 카드 UI |
Android | Google Pay + 카드 UI |
동남아 | GrabPay, FPX 등 로컬 결제 |
한국 | 카드 (Stripe가 계약된 카드사 기준) |
🛠️ 정리
Stripe의 Payment Sheet는 Flutter에서도 공식 지원되며,
Stripe가 만든 결제 UI를 그대로 앱 안에서 띄우고 사용할 수 있습니다.
필요하다면:
- Flutter 전체 결제 예제 프로젝트
- 테스트용 카드 번호/에러 시나리오 처리
- 서버 연동 코드 (Node.js / NestJS 등)
도움드릴 수 있어요. 추가로 궁금한 부분 있으신가요?
결제취소
좋습니다! Stripe에서는 결제 취소(취소 또는 환불)를 두 가지 방식으로 처리할 수 있어요:
✅ Stripe 결제 취소의 두 가지 방법
방법 설명 API
결제 취소(Cancel PaymentIntent) | 결제가 아직 완료되지 않은 상태에서 중단 | paymentIntents.cancel() |
환불(Refund) | 결제가 완료된 후, 전액 또는 일부 환불 | refunds.create() |
🧭 상황에 따라 사용하는 방식
상황 처리 방법
사용자가 결제 도중 창을 닫았거나 → 미승인 상태 | paymentIntent.cancel()로 취소 |
사용자가 결제 완료 후, 결제 취소 요청 | refunds.create()로 환불 처리 |
💳 환불 처리 (가장 일반적인 방법)
🛠️ Node.js 예시
const refund = await stripe.refunds.create({
payment_intent: 'pi_1NX3lq2eZvKYlo2CdqR8XXXX', // 결제된 PaymentIntent ID
amount: 5000, // 환불할 금액 (센트 기준, optional. 전액이면 생략 가능)
});
✔️ 설명
- payment_intent: 결제할 때 받은 ID (pi_...)
- amount: 생략 시 전체 환불, 넣으면 부분 환불
🔁 결제 취소 (아직 승인 전일 때)
await stripe.paymentIntents.cancel('pi_1NX3lq2eZvKYlo2CdqR8XXXX');
status가 requires_payment_method, requires_confirmation일 때만 취소 가능
✅ 환불 관련 참고 사항
항목 설명
⏱ 환불 처리 시간 | 일반적으로 5~10 영업일 (카드사에 따라 다름) |
🧾 부분 환불 가능 | 금액 지정 가능 (예: $50 중 $20만 환불) |
📥 환불 상태 확인 | Stripe Dashboard나 API로 refund.status 조회 가능 |
⚠ 결제 수수료 환불 여부 | 기본적으로 수수료는 환불되지 않습니다 (국가 및 약관에 따라 다름) |
🧠 정리
기능 메서드 언제 사용하나요?
❌ 결제 취소 | paymentIntents.cancel() | 결제 완료 전에 취소할 때 |
💸 환불 | refunds.create() | 결제 완료 후에 환불할 때 |
필요하다면:
- 환불 처리 흐름 전체 예제 (NestJS / Express)
- 사용자 요청으로 결제 내역 조회 및 취소 UI 처리
- Flutter 앱에서 결제 취소 시 연동 방법
도움드릴 수 있어요. 알려주세요!