요약
Braintree API는 신용카드, PayPal, Venmo, 디지털 지갑 등 다양한 결제 수단을 처리할 수 있습니다. 서버 측 SDK(Node.js, Python, Ruby 등)를 통해 통합하며, 클라이언트 토큰을 생성해 프런트엔드 보안을 강화합니다. 거래, 환불, 구독 처리는 필수입니다. 실제 서비스 출시 전 샌드박스 데이터로 웹훅 페이로드를 검증하고 통합 테스트를 하려면 Apidog를 활용하세요.
서론
Braintree는 Uber, Airbnb, GitHub 등에서 사용하는 결제 처리 플랫폼으로, 매년 수십억 달러의 결제를 처리합니다. 신용카드, PayPal, Venmo, Apple Pay, Google Pay, ACH 송금을 지원합니다.
결제 API는 다른 API와 달리 실수 시 실제 금전 손실과 신뢰 훼손을 초래할 수 있으니, 정확한 처리가 필수입니다.
Braintree는 드롭인 UI(사전 구축 결제 양식)와 커스텀 UI(완전 제어) 두 가지 통합 방식을 제공합니다. 실 결제 처리는 모두 동일한 서버 측 API를 사용합니다. 아래에서는 고객이 "결제"를 클릭한 이후 서버에 필요한 작업을 집중적으로 다룹니다.
💡 결제 통합을 구축 중이라면, Apidog는 웹훅 핸들러 테스트와 결제 응답 검증을 지원합니다. Braintree 웹훅을 로컬에서 모의 테스트해 성공, 실패, 예외 처리가 잘 동작하는지 사전 확인하세요.
Apidog로 Braintree 웹훅 테스트하기 - 무료
Braintree 설정
Braintree 계정 생성
- braintreepayments.com 접속 후 샌드박스 계정을 생성하세요.
- 아래 정보를 획득합니다:
- 판매자 ID:
abc123xyz - 공개 키:
def456... - 개인 키:
ghi789...
- 판매자 ID:
Tip: 개인 키는 비밀번호와 같으므로 안전하게 보관하고 Git 등 버전 관리 시스템에 절대 커밋하지 마세요.
SDK 설치
Braintree는 주요 언어에 대한 서버 SDK를 제공합니다.
Node.js:
npm install braintree
Python:
pip install braintree
Ruby:
gem install braintree
게이트웨이 초기화 예시:
const braintree = require('braintree')
const gateway = new braintree.BraintreeGateway({
environment: braintree.Environment.Sandbox,
merchantId: process.env.BRAINTREE_MERCHANT_ID,
publicKey: process.env.BRAINTREE_PUBLIC_KEY,
privateKey: process.env.BRAINTREE_PRIVATE_KEY
})
클라이언트 토큰 생성
결제 양식 표시 전 클라이언트 토큰을 생성해야 합니다. 이 토큰을 프런트엔드에 전달하여 Braintree와의 통신을 승인하게 합니다.
app.get('/checkout/token', async (req, res) => {
const clientToken = await gateway.clientToken.generate()
res.json({ clientToken: clientToken.clientToken })
})
프런트엔드는 이 토큰을 사용해 드롭인 UI나 커스텀 통합을 초기화합니다.
결제 처리
결제 흐름
- 프런트엔드가 결제 수단 논스를 서버로 전송
- 서버가 논스를 사용해 거래 생성
- Braintree가 결제를 처리
- 서버가 성공/실패 응답 수신
- 주문 이행 또는 오류 표시
신용카드 청구
app.post('/checkout', async (req, res) => {
const { paymentMethodNonce, amount, orderId } = req.body
const result = await gateway.transaction.sale({
amount: amount,
paymentMethodNonce: paymentMethodNonce,
orderId: orderId,
options: {
submitForSettlement: true
}
})
if (result.success) {
res.json({
success: true,
transactionId: result.transaction.id
})
} else {
res.status(400).json({
success: false,
message: result.message
})
}
})
저장된 결제 수단으로 청구
첫 거래 후 결제 수단을 저장하고, 저장된 결제 수단으로 재청구할 수 있습니다.
// 결제 수단으로 고객 생성
const result = await gateway.customer.create({
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
paymentMethodNonce: nonce
})
// 결제 수단이 저장됨
const paymentMethodToken = result.customer.paymentMethods[0].token
// 저장된 결제 수단으로 청구
await gateway.transaction.sale({
amount: '49.99',
paymentMethodToken: paymentMethodToken,
options: {
submitForSettlement: true
}
})
PayPal 거래
PayPal 논스를 받아 아래처럼 청구할 수 있습니다.
const result = await gateway.transaction.sale({
amount: '99.00',
paymentMethodNonce: paypalNonce,
orderId: 'ORDER-123',
options: {
submitForSettlement: true
}
})
환불 및 취소
전체 환불
const result = await gateway.transaction.refund('transaction_id')
if (result.success) {
console.log('환불됨:', result.transaction.id)
}
부분 환불
const result = await gateway.transaction.refund('transaction_id', '50.00')
if (result.success) {
console.log('부분 환불 처리됨')
}
거래 취소
승인됐으나 정산 전인 거래에 취소를 적용합니다.
const result = await gateway.transaction.void('transaction_id')
if (result.success) {
console.log('거래 취소됨')
}
거래 상태 흐름
승인됨 → 정산 제출됨 → 정산 완료됨
↓
취소됨
정산 완료됨 → 환불됨
구독 및 정기 결제
Braintree는 정기 결제를 위한 구독 기능을 지원합니다.
플랜 생성
const result = await gateway.plan.create({
id: 'monthly-premium',
name: 'Monthly Premium',
billingFrequency: 1,
currencyIsoCode: 'USD',
price: '29.99'
})
구독 생성
const result = await gateway.subscription.create({
paymentMethodToken: paymentMethodToken,
planId: 'monthly-premium',
firstBillingDate: new Date()
})
if (result.success) {
console.log('구독 생성됨:', result.subscription.id)
}
구독 취소
const result = await gateway.subscription.cancel('subscription_id')
if (result.success) {
console.log('구독 취소됨')
}
구독 업데이트
const result = await gateway.subscription.update('subscription_id', {
planId: 'annual-premium',
price: '299.99'
})
결제 이벤트용 웹훅
거래 이벤트마다 웹훅을 통해 서버로 알림을 받습니다.
웹훅 엔드포인트 생성
app.post('/webhooks/braintree', (req, res) => {
const signature = req.body.bt_signature
const payload = req.body.bt_payload
// 웹훅 확인 및 파싱
gateway.webhookNotification.parse(
signature,
payload,
(err, webhookNotification) => {
if (err) {
return res.status(400).send('유효하지 않은 웹훅')
}
switch (webhookNotification.kind) {
case 'subscription_charged_successfully':
handleSuccessfulCharge(webhookNotification.subscription)
break
case 'subscription_charged_unsuccessfully':
handleFailedCharge(webhookNotification.subscription)
break
case 'dispute_opened':
handleDispute(webhookNotification.dispute)
break
case 'transaction_settled':
handleSettledTransaction(webhookNotification.transaction)
break
}
res.status(200).send('OK')
}
)
})
Braintree에 웹훅 등록
Braintree 제어판 → 설정 → 웹훅에서 엔드포인트 URL을 추가하세요. 개발 환경에서는 ngrok 등 터널링 서비스를 활용해 로컬 서버에서 웹훅을 수신할 수 있습니다.
Apidog로 테스트하기
결제 API는 실제 운영 데이터를 사용할 수 없으므로, Apidog를 활용해 안전하게 모의 테스트하세요.
1. 웹훅 페이로드 모의 테스트
Braintree가 웹훅을 보내기까지 기다릴 필요 없이, 아래와 같은 테스트 페이로드를 생성해 엔드포인트로 전송할 수 있습니다.
{
"bt_signature": "test_signature",
"bt_payload": "eyJraW5kIjoidHJhbnNhY3Rpb25fc2V0dGxlZCIsInRyYW5zYWN0aW9uIjp7ImlkIjoiYWJjMTIzIiwiYW1vdW50IjoiNDkuOTkiLCJzdGF0dXMiOiJzZXR0bGVkIn19"
}
2. 환경 분리
환경별로 설정을 분리해 안전하게 테스트하세요.
# 샌드박스
BRAINTREE_MERCHANT_ID: sandbox_merchant
BRAINTREE_PUBLIC_KEY: sandbox_public
BRAINTREE_PRIVATE_KEY: sandbox_private
BRAINTREE_ENVIRONMENT: sandbox
# 프로덕션
BRAINTREE_MERCHANT_ID: live_merchant
BRAINTREE_PUBLIC_KEY: live_public
BRAINTREE_PRIVATE_KEY: live_private
BRAINTREE_ENVIRONMENT: production
3. 웹훅 응답 검증
pm.test('웹훅이 성공적으로 처리됨', () => {
pm.response.to.have.status(200)
pm.response.to.have.body('OK')
})
pm.test('거래 ID가 기록됨', () => {
const transactionId = pm.environment.get('last_transaction_id')
pm.expect(transactionId).to.not.be.empty
})
Apidog로 Braintree 웹훅 테스트하기 - 무료
일반적인 오류 및 해결 방법
프로세서 거부됨
원인: 은행 거래 거부
해결: 자금 부족/사기 필터가 원인일 수 있습니다. 고객에게 오류 메시지를 안내하고 다른 카드를 시도하도록 하세요. processorResponseCode를 로그로 남기세요.
if (!result.success) {
if (result.transaction.processorResponseCode === '2000') {
return res.status(400).json({
error: '은행이 이 거래를 거부했습니다. 다른 카드를 사용해 보세요.'
})
}
}
게이트웨이 거부됨
원인: Braintree 사기 방지 필터
해결: gatewayRejectionReason을 확인하세요.
if (result.transaction.gatewayRejectionReason === 'cvv') {
// CVV 불일치
}
if (result.transaction.gatewayRejectionReason === 'avs') {
// 주소 인증 실패
}
if (result.transaction.gatewayRejectionReason === 'fraud') {
// 고급 사기 방지 도구가 차단함
}
정산 실패
원인: 승인 후 정산 실패
해결: transaction_settlement_declined 웹훅을 모니터링하세요. 원인: 결제 수단 만료, 발급사 차단, 자금 부족 등
중복 거래
원인: 고객이 여러 번 결제 시도
해결: orderId 매개변수로 중복 방지
const result = await gateway.transaction.sale({
amount: '49.99',
paymentMethodNonce: nonce,
orderId: 'UNIQUE-ORDER-123',
options: {
submitForSettlement: true
}
})
대안 및 비교
| 기능 | Braintree | Stripe | PayPal |
|---|---|---|---|
| 가격 | 2.9% + 30¢ | 2.9% + 30¢ | 2.9% + 30¢ |
| PayPal 지원 | 기본 지원 | 추가 기능 | 기본 지원 |
| 구독 | 예 | 예 | 제한적 |
| 국제 | 46개국 | 46개국 | 200개국 이상 |
| 사기 방지 도구 | 내장 | 내장 | 기본 |
| SDK 품질 | 우수 | 우수 | 양호 |
| 지급 | 예 | 예 | 예 |
Braintree의 주요 장점은 PayPal 및 Venmo의 기본 지원입니다. 카드와 PayPal 모두 필요하다면 Stripe + PayPal 별도 통합보다 더 간단하게 구성할 수 있습니다.
실제 사용 사례
SaaS 구독 플랫폼:
한 프로젝트 관리 도구는 월 구독 결제에 Braintree를 사용합니다. 웹훅으로 결제 실패(카드 만료, 잔액 부족 등) 시 이메일 알림이 전송되며, 사용자가 직접 결제 수단을 업데이트할 수 있습니다.
마켓플레이스 결제:
프리랜서 플랫폼에서는 플랫폼 수수료와 프리랜서 간 결제 분할 처리가 필요합니다. Braintree의 판매자/서브 판매자 설정으로 복잡한 지급 구조를 구현합니다.
PayPal을 이용한 전자상거래:
온라인 상점에서 신용카드와 PayPal을 모두 지원할 때 Braintree의 통합 API 하나로 모든 결제 수단을 처리할 수 있습니다.
결론
- Braintree SDK로 서버 측 결제 처리 구현
- 클라이언트 토큰으로 프런트엔드 통신 승인
- 거래 판매 API로 신용카드/PayPal 청구
- 구독 API로 정기 결제 처리
- 웹훅으로 결제 이벤트 수신
- 서비스 출시 전 Apidog로 샌드박스 환경에서 자동화된 테스트 필수
자주 묻는 질문
결제 수단 논스(nonce)란 무엇인가요?
논스는 결제 수단을 나타내는 일회용 토큰입니다. 고객 카드 정보 입력 후 프런트엔드에서 생성되며, 서버는 이 논스를 사용해 카드를 청구합니다. 논스는 3시간 후 만료됩니다.
승인(authorization)과 정산(settlement)의 차이점은?
승인은 카드에 자금 예약, 정산은 실제로 청구하는 것. 기본적으로 자동 정산이지만, 사전 주문의 경우 승인만 하고 나중에 정산할 수 있습니다.
// 승인만
await gateway.transaction.sale({
amount: '99.00',
paymentMethodNonce: nonce,
options: {
submitForSettlement: false // 승인만
}
})
// 나중에 정산
await gateway.transaction.submitForSettlement('transaction_id')
통화는 어떻게 처리하나요?
각 Braintree 판매자 계정에 기본 통화가 지정됩니다. 다중 통화 결제는 여러 판매자 계정이 필요하니, 추가 설정은 Braintree 지원팀에 문의하세요.
어떤 테스트 카드 번호를 사용해야 하나요?
Braintree 샌드박스 테스트 카드:
-
4111111111111111- Visa (성공) -
4000111111111115- Visa (거절) -
5555555555554444- Mastercard (성공) -
378282246310005- Amex (성공)
분쟁/차지백은 어떻게 처리하나요?
dispute_opened, dispute_won, dispute_lost 웹훅을 수신하고, 제어판에서 증거 업로드 및 상태를 확인하세요. 모든 고객 커뮤니케이션과 증빙 자료를 꼼꼼히 기록해두세요.
신용카드 번호를 저장할 수 있나요?
아니요. PCI 규정상 원시 카드 번호 저장은 불가합니다. 결제 수단 토큰을 저장하고, Braintree가 PCI 범위를 대신 처리합니다.
3D Secure란 무엇인가요?
3D Secure는 추가 인증(OTP 등) 절차로, Braintree에서 지원합니다. 제어판에서 활성화 후, authentication_required 응답을 처리하세요.
const result = await gateway.transaction.sale({
amount: '100.00',
paymentMethodNonce: nonce,
threeDSecure: {
required: true
}
})
환불에는 얼마나 걸리나요?
일반적으로 영업일 기준 3~5일 내 처리됩니다. 환불 완료 시 transaction_refunded 웹훅을 통해 알림을 받을 수 있습니다.


Top comments (0)