결제 흐름

온누리PG 결제는 요청 → 인증 → 승인 3단계로 이루어집니다.

핵심 결제 흐름

온누리PG의 결제 흐름은 고객의 결제 경험과 가맹점의 안정적인 데이터 관리를 위해 인증승인이 분리되어 있습니다. 사용자가 인증을 완료해도, 가맹점 서버에서 최종 승인을 요청해야만 결제가 완료됩니다.

  1. 1
    결제 요청 (Client)

    구매자가 결제 버튼을 누르면, 클라이언트에서 SDK를 통해 주문 정보와 함께 결제를 요청하고 결제창을 호출합니다.

  2. 2
    사용자 인증 (온누리PG)

    구매자는 결제창에서 결제수단 정보를 입력하고 인증을 완료합니다. 인증 성공 시, 온누리PG는 paymentKey를 발급하여 가맹점의 성공 URL로 리디렉션합니다.

  3. 3
    결제 승인 (Server)

    가맹점 서버는 전달받은 paymentKey와 주문 정보를 검증한 후, 온누리PG에 최종 결제 승인을 요청합니다. 이 단계가 성공해야 실제 결제가 완료됩니다.

서버사이드 결제 검증

중요: 결제 위변조를 방지하기 위해, 결제 승인 전 반드시 가맹점 서버에서 결제 정보를 검증해야 합니다.

클라이언트에서 전달되는 결제 금액(amount)은 변조될 가능성이 있습니다. 따라서 항상 가맹점 데이터베이스에 저장된 주문 정보와 비교하는 과정이 필요합니다.

{// Node.js (Express) 예시
app.get('/success', async (req, res) => {
  const { paymentKey, orderId, amount } = req.query;

  // 1. DB에서 주문 정보 조회
  const order = await db.orders.findById(orderId);

  // 2. 결제 금액 검증
  if (order.amount !== Number(amount)) {
    // 금액이 일치하지 않으면 결제 위변조 시도일 수 있음
    return res.status(400).json({ message: '결제 정보가 올바르지 않습니다.' });
  }

  // 3. 결제 승인 API 호출
  try {
    // 시크릿 키를 Base64 인코딩하여 Authorization 헤더에 추가합니다.
    const secretKey = process.env.ONNURIPG_SECRET_KEY;
    const encodedSecretKey = Buffer.from(secretKey + ':').toString('base64');

    const response = await fetch('https://api.onnuripg.com/v1/payments/confirm', {
      method: 'POST',
      headers: {
        'Authorization': 'Basic ' + encodedSecretKey,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ paymentKey, orderId, amount }),
    });

    if (response.ok) {
      // 4. 결제 성공 처리 (DB 상태 업데이트 등)
      res.redirect('/order-complete');
    } else {
      // 5. 결제 실패 처리
      const error = await response.json();
      res.redirect('/fail?code=' + error.code + '&message=' + error.message);
    }
  } catch (error) {
    // 네트워크 오류 등
    res.redirect('/fail?code=NETWORK_ERROR&message=결제 승인 중 오류가 발생했습니다.');
  }
});
}