쇼핑몰 프로젝트에서 이니시스 PG를 이용한 결제 시스템을 구축하고 있었다.
모바일 기준이긴 하지만 대충 요런 구조로 구축을 하면 된다.
여기서 P_MID, P_OID같은 속성 값들만 PC에 맞게 바꿔주면 되는거고, 기본적인 처리 순서는 동일하다.
주문서에서 PG창을 띄우는 것 까지는 수월했다.
PG창에서 사용자가 인증한 인증 결과 값을 수신할 수 있도록 PG창을 띄울 때 파라미터로 returnUrl을 보내는데, 이 부분을 어떻게 넘겨야 할지 미궁에 빠졌다.
만약, spring 서버의 컨트롤러로 view 페이지로 리다이렉트 하는 구조라면 controller의 mapping url을 적으면 그만이다.
그리고, Nuxt.js 2 같은 경우도, asyncData라는 SSR로 들어오는 데이터를 받을 수 있는 내장 메소드가 존재하여, context의 req.body 값으로 인증 결과 값을 수신할 수 있었다.
https://v2.nuxt.com/docs/features/data-fetching/
Next.js에는 어떤 방식으로 받을 수 있을까?
처음에 구글링을 했을 때, 발견했던 것은 getServerSideProps였다.
https://nextjs.org/docs/pages/api-reference/functions/get-server-side-props
근데 이것은 page router 구조 기반의 Function이었다.
내가 하고 있는 프로젝트는 Next14의 app router 구조여서 저것은 쓸 수 없었다.
그러다가 발견한 route handlers !!
https://nextjs.org/docs/app/building-your-application/routing/route-handlers
HTTP 메소드들을 지원해주는데 이니시스가 인증결과 값 요청하는 메소드는 FormData의 POST 메소드.
먼저 이니시스에서 호출 할 api를 만든다.
api url은 app 폴더 밑의 패키지 경로를 따르며 파일은 route.ts로 한다.
route.ts
import { NextRequest } from 'next/server'
import { redirect } from 'next/navigation'
export async function POST(request: NextRequest) {
const formData = await request.formData()
formData.forEach((value, key) => {
authResult[key] = value
})
const queryString = Object.keys(authResult)
.map(
(key) =>
`${encodeURIComponent(key)}=${encodeURIComponent(authResult[key])}`
)
.join('&')
redirect(`${process.env.DB_HOST}/payment/payReturn?${queryString}`)
}
returnUrl을 '/api/payment'로 넣어서 pg창을 호출하면 사용자가 인증을 완료하면 이 화면의 request로 인증결과 값이 담겨 넘어오게 되고 이 값들을 queryString으로 붙여서 새로운 react 페이지로 리다이렉트 해준다.
그리고 그 react 페이지에 인증 결과 성공/실패의 분기 처리, 성공 시의 주문 생성 api 호출을 작성하면 된다.
사실 저 인증 결과 값을 쿼리스트링 말고 url에 노출되지 않게 페이지로 넘기고 싶었는데 cookie, session, store 다 실패해서 일단은 쿼리스트링으로 해놨따 ..
그래도 next.js app router 구조에서 서버 요청 데이터를 받는 방식을 알게 되어 유익한 경험이었다.