본문으로 건너뛰기

결제 구현하기

오프라인 환경에서 구현해야 하는 결제 방식은 LINE Pay 사용자가 생성한 내 코드(My code)를 가맹전 단말기로 스캔해 결제하는 방식입니다. 이 방식의 작업 흐름은 다음과 같습니다.

위 작업 흐름 구조에 따라 LINE Pay 가맹점에서 구현할 내용을 설명합니다.

오프라인 결제 중 가맹점이 제공하는 바코드나 QR 코드를 LINE Pay 사용자가 스캔해 결제하는 방식은 가맹점에서 구현해야 할 내용이 없습니다.

내 코드 스캔

가맹점 단말기를 이용해 LINE Pay 사용자의 내 코드를 스캔합니다. 내 코드는 오른쪽 화면과 같이 바코드 형태 또는 QR 코드 형태로 표시됩니다.

테스트를 위해 샌드박스용 내 코드를 생성할 수 있습니다. 아래 URL로 접근해 임시로 생성한 내 코드를 테스트에 활용하세요.

// 대만 가맹점용:
https://sandbox-web-pay.line.me/web/sandbox/payment/oneTimeKey?countryCode=TW

// 태국 가맹점용:
https://sandbox-web-pay.line.me/web/sandbox/payment/oneTimeKey

위 URL을 호출할 때 아래와 같은 쿼리 파라미터를 설정할 수 있습니다.

이름설명
countryCode국가 코드이며, 각 국가의 통화를 사용하도록 설정하세요. TW(대만 달러) 또는 TH(태국 바트) 값을 입력할 수 있습니다. 기본 값은 TH입니다.
paymentMethod결제 수단이며, card(신용 카드), balance(LINE Pay 잔액), ipass(대만 전용 LINE Pay 계좌 결제)를 입력할 수 있습니다. 기본 값은 balance입니다.

가맹점 단말기를 이용해 LINE Pay 사용자의 내 코드를 스캔했다면 스캔한 내 코드 정보와 주문 정보를 가맹점 서버로 전달해야 합니다. 이후 가맹점 서버는 결제를 요청합니다. 가맹점 서버로부터 응답이 전달되면 필요한 정보를 단말기에 표시하세요.

바코드를 스캔하는 것과 같은 가맹점 단말기의 기능, 가맹점 단말기와 가맹점 서버 사이의 통신을 구현하는 방법은 가맹점이 직접 구현해야 하며, 여기서는 설명하지 않습니다.

결제 요청 및 승인

가맹점 서버는 단말기가 전달받은 정보를 이용해 LINE Pay 서버로 결제를 요청합니다. 다음은 단말기가 전달받은 내 코드 정보(oneTimeKey)와 주문 정보를 이용해 결제를 요청하는 API를 호출하는 예입니다.

오프라인 API를 호출할 때 필요한 자격 증명 정보를 얻는 방법은 API 자격 증명 준비를 참고하세요. 이 페이지에 설명된 코드 예제는 API 자격 증명 준비 코드 예제에 정의된 requestOfflineAPI() 함수를 이용합니다.

try {
let response = await requestOfflineAPI({
method: "POST",
baseUrl: targetAPIServer,
apiPath: "/v2/payments/oneTimeKeys/pay",
data: {
amount: 100,
currency: "TWD",
orderId: "EXAMPLE_ORDER_20230422_1000002",
productName: "Pen Brown",
oneTimeKey: "123456789012",
extras: {
branchName: "First branch",
branchId: "branch1",
},
},
});

console.log("Response: ", response);
} catch (error) {
console.log(error);
}

결제 요청 결과로 다음과 같은 응답을 받을 수 있습니다.

{
"returnCode": "0000",
"returnMessage": "success",
"info": {
"transactionId": 2019010112345678910,
"orderId": "test_order_1",
"transactionDate": "2023-05-16T18:01:00Z",
"payInfo": [
{
"method": "BALANCE",
"amount": 100
}
],
"balance": 9900
}
}

결제 요청이 처리되면 결제 승인까지 완료됩니다. 매입을 분리하지 않았다면 결제가 승인될 때 매입도 자동으로 처리돼 대금이 정산됩니다.

가맹점 서버는 LINE Pay 서버로 결제를 요청한 후 보통 20 초 정도 read 타임아웃을 설정합니다. Read 타임아웃 시간 안에 응답을 받지 못한다면 결제 상태 조회 API를 호출해 결제 상태를 확인하세요. 다음은 read 타임아웃을 20 초로 설정한 후 타임아웃이 발생하면 일정 간격으로 결제 상태를 조회하도록 하는 예입니다.

let intervalId = null;

// 결제 요청 상태 확인
const getPayRequestStatus = async function (orderId) {
try {
if (!orderId) throw new Error("Order ID is required!");

let response = await requestOfflineAPI({
method: "GET",
baseUrl: targetAPIServer,
apiPath: `/v2/payments/orders/${orderId}/check`,
});

console.log("Response: ", response);
switch (response.info.status) {
case "AUTH_READY":
console.log("In progress");
break;
case "COMPLETE":
console.log("Finished");
// Do something
case "CANCEL":
console.log("Cancelled");
// Do something
case "FAIL":
console.log("Failed");
// Do something
// ...
default:
clearInterval(intervalId);
}
} catch (error) {
console.log(error);
}
};

// 결제 요청
try {
let response = await requestOfflineAPI({
method: "POST",
baseUrl: targetAPIServer,
apiPath: "/v2/payments/oneTimeKeys/pay",
data: {
orderId: "test_order_1",
// ...
},
// Read 타임아웃 설정
signal: AbortSignal.timeout(20000),
});

console.log("Response: ", response);
} catch (error) {
if (err.name === "TimeoutError") {
// 1초 간격 결제 요청 상태 확인
intervalId = setInterval(getPayRequestStatus("test_order_1"), 1000);
} else {
// 다른 예외 처리
}
}

결제 상태 조회 API의 응답 중 info.status 필드에 결제 상태 정보가 반환됩니다. 상태 정보는 다음과 같습니다.

  • "AUTH_READY": 고객이 LINE Pay 인증을 기다리는 상태
  • "CANCEL": 고객이 결제를 취소한 상태
  • "COMPLETE": 결제를 완료한 상태
  • "FAIL": 결제에 실패한 상태