정기결제 (구독)


정기결제

SaasMold에서는 정기결제와 관련한 아래 기능들이 개발되어있습니다.

  • 정기결제 상품 관리
  • 정기결제 cronjob
  • 정기결제 webhook
  • 정기결제 결제수단(카드) 등록/삭제
  • 정기결제 취소


포트원(Portone)

SaasMold 정기결제는 포트원을 이용합니다. 포트원에서 가입하시면 별도의 가입비 없이 PG사와 연동할 수 있습니다. SaasMold는 나이스 페이먼츠 PG사를 기본으로 만들어졌습니다. API를 통한 정기결제가 가능한 PG사라면 다른 PG사도 이용 가능합니다. 포트원에서 발급받은 채널 키api secret.env.local에 추가하세요.


.env.local
PORTONE_API_SECRET=
PORTONE_CHANNEL_KEY=

webhook 연동을 위해 포트원에서 webhook url을 설정하세요.

  • 연동관리 > 결제알림(Webhook)관리 > 결제모듈 V2 > EndpointURL 에 아래 url을 추가하세요.
  • {YOUR DOMAIN}/api/portone/webhook


데이터베이스

정기결제(구독)을 위해서 database에 아래 3개의 table이 사용됩니다.

products : 상품 정보를 저장하는 테이블
orders : 구매내역을 저장하는 테이블
order_receipts : 결제내역을 저장하는 테이블 subscriptions : 구독정보를 저장하는 테이블


prisma/seed.js에서 상품정보를 수정하고 npx prisma db seed를 실행하여 상품정보를 database에 추가하세요.

prisma/seed.js
const recurringProduct1 = await prisma.product.upsert({
  where: {
    name: "SaasMold Monthly Subscription",
  },
  update: {},
  create: {
    name: "SaasMold Monthly Subscription",
    active: true,
    prices: {
      create: {
        type: PriceType.subscription,
        interval: PriceInterval.month,
        currency: "krw",
        amount: 100,
      },
    },
  },
});
const oneTimeProduct1 = await prisma.product.upsert({
  where: {
    name: "스타터",
  },
  update: {},
  create: {
    name: "스타터",
    active: true,
    prices: {
      create: {
        type: PriceType.onetime,
        currency: "krw",
        amount: 100,
      },
    },
  },
});

product의 type은 subscription(정기결제)onetime(단일결제)이 있습니다.



결제 페이지

결제페이지 파일은 src/app/(order)/payment/[[...id]]/page.tsx입니다.
페이지 url /payment/{productId}으로 이동하면 결제페이지가 나타납니다.

payment_page_1.png

결제를 진행하기 위해 사용자가 카드 등록을 먼저해야 됩니다. 카드 등록을 위해 ButtonRegisterCard 컴포넌트를 사용합니다.

payment_page_2.png

카드 등록이 완료되면 등록한 카드의 정보를 보여줍니다.

payment_page_3.png

결제를 진행하면 결제가 완료됩니다. 결제가 완료되면 orderorder_receipt, subscription 레코드가 생성됩니다.