사전 준비하기
온라인 API v4나 온라인 API v3, 오프라인 API v4를 호출하려면 HTTP 요청 헤더에 자격 증명 정보(credentials)를 명시해야 합니다.
가맹점 가입 후 가맹점 센터에서 채널 ID와 채널 비밀키를 얻을 수 있는데, 이를 이용해 자격 증명 정보를 생성할 수 있습니다.
샌드박스 계정을 신청해 샌드박스용 채널 ID와 채널 비밀키를 신청하여 테스트해볼 수 있습니다.
이미 가맹점으로 가입해 발급 받은 채널 ID와 채널 비밀키가 있다면, 별도의 신청없이 샌드박스 환경에 이를 바로 사용할 수 있습니다.
자격 증명 정보를 명시하는 HTTP 요청 헤더는 다음과 같습니다.
X-LINE-ChannelIdX-LINE-AuthorizationX-LINE-Authorization-Nonce
X-LINE-ChannelId 헤더에는 채널 ID 값을 입력하고 X-LINE-Authorization-Nonce 헤더에는 UUID v1나 v4 또는 타임스탬프와 같은 임시 토큰 값을 입력하세요.
X-LINE-Authorization 헤더에 입력하는 값은 채널 비밀키와 대상 메시지를 이용해 HMAC 방식으로 생성한 MAC(message authentication code)를 Base64 방식으로 인코딩한 값입니다. 호출하는 API의 HTTP 메서드에 따라 MAC 생성용 메시지는 다음과 같이 구성하세요.
| HTTP 메서드 | MAC 생성용 메시지 |
|---|---|
| GET | 채널 비밀키 + API 경로(apiPath) + 쿼리 스트링(queryString) + 임시 토큰(nonce) |
| POST | 채널 비밀키 + API 경로(apiPath) + 요청 본문 + 임시 토큰(nonce) |
다음은 HTTP 요청 헤더에 자격 정보를 추가하여 온라인 API를 호출할 수 있게 해주는 코드 예제입니다.
아래 코드 예제 중
handleBigInteger()함수는 트랜잭션 ID 값을 다룰 때 필요합니다. 트랜잭션 ID와handleBigInteger()함수에 대한 자세한 내용은 온라인 API v4나 오프라인 API v4의 트랜잭션 ID 절 설명을 참고하세요.
const crypto = require("crypto");
function signKey(clientKey, msg) {
const encoder = new TextEncoder();
return crypto
.createHmac("sha256", encoder.encode(clientKey))
.update(encoder.encode(msg))
.digest("base64");
}
async function requestLINEPayAPI({
method,
baseUrl = "https://sandbox-api-pay.line.me",
apiPath,
queryString = "",
data = null,
signal = null,
}) {
const nonce = crypto.randomUUID();
let signature = "";
// 각 방식(method)별로 MAC 생성
if (method === "GET") {
signature = signKey(
YOUR_CHANNEL_SECRET,
YOUR_CHANNEL_SECRET + apiPath + queryString + nonce
);
} else if (method === "POST") {
signature = signKey(
YOUR_CHANNEL_SECRET,
YOUR_CHANNEL_SECRET + apiPath + JSON.stringify(data) + nonce
);
}
const headers = {
"X-LINE-ChannelId": YOUR_CHANNEL_ID,
"X-LINE-Authorization": signature,
"X-LINE-Authorization-Nonce": nonce,
};
const response = await fetch(
`${baseUrl}${apiPath}${queryString !== "" ? "&" + queryString : ""}`,
{
method: method,
headers: {
"Content-Type": "application/json",
...headers,
},
body: data ? JSON.stringify(data) : null,
signal: signal,
}
);
const processedResponse = handleBigInteger(await response.text());
return processedResponse;
}