매입을 분리해 결제 구현하기
오프라인으로 결제할 때 결제 승인과 매입을 분리할 수 있습니다. 대금 정산을 늦춰야 하거나 결제 금액이 변동될 수 있는 가능성에 대비해 결제 승인과 매입을 분리할 수 있습니다.
대만에서는 자동 매입이 기본 결제 방식이며, 사전 신청 없이 매입을 분리해 결제할 수 없습니다. 대만에서 매입을 분리해 결제하려면, LINE Pay 담당자에게 연락하세요.
오프라인 결제에서 결제 승인과 매입을 분리해 결제하는 흐름은 다음과 같습니다.
매입을 분리하면 다음을 가맹점 서버에서 구현해야 합니다.
매입 분리 요청
결제 승인과 매입을 분리하려면 결제를 요청할 때 자동 매입 여부를 설정하는 필드(capture
) 값을 false
로 설정하세요. 다음은 승인과 매입을 분리하는 결제 요청 API 호출 예입니다.
try {
let response = await requestOfflineAPI({
method: "POST",
baseUrl: targetAPIServer,
apiPath: "/v2/payments/oneTimeKeys/pay",
data: {
amount: 100,
currency: "TWD",
orderId: "EXAMPLE_ORDER_20230422_1000001",
// ...
capture: false,
},
});
console.log("Response: ", response);
} catch (error) {
console.log(error);
}
위와 같이 결제를 요청하면 결제 승인까지 완료되며, 해당 결제를 매입하거나 결제 승인을 취소할 수 있는 상태가 됩니다.
승인 내역 조회
결제 승인과 매입을 분리한 상태에서 매입 또는 승인 취소하려면 결제가 승인된 상태인지 파악해야 합니다. 승인 정보 조회 API를 호출해 특정 결제의 승인 상태를 파악하세요. 다음과 같이 주문 번호 또는 트랜잭션 ID 정보를 이용해 승인 정보를 조회하세요.
const getConfirmedPaymenrtInfo = async function ({
orderId = "",
transactionId = "",
}) {
let queryString = "";
if (orderId === "" && transactionId === "") {
throw new Error(
"At least one of order ID or transaction ID must be input."
);
} else if (orderId !== "") {
queryString = `orderId=${orderId}`;
} else {
queryString = `transactionId=${transactionId}`;
}
let response = await requestOfflineAPI({
method: "GET",
baseUrl: targetAPIServer,
apiPath: `/v2/payments/authorizations?${queryString}`,
});
return response;
};
// ...
try {
response = await getConfirmedPaymenrtInfo({ orderId: "test_order_1" });
console.log(response);
} catch (error) {
console.error(error);
}
트랜잭션 ID 정보를 다룰 때 서비스 구현 언어에 따라 트랜잭션 ID를 문자열로 처리해야 할 수도 있습니다. 자세한 설명은 트랜잭션 ID를 참고하세요.
승인 정보를 조회한 결과로 아래와 같은 응답을 받습니다.
{
"returnCode": "0000",
"returnMessage": "success",
"info": [
{
"transactionId": 2019049910005498410,
"orderId": "20190408003",
"payStatus": "VOIDED_AUTHORIZATION",
"transactionDate": "2019-04-08T07:02:38Z",
"transactionType": "PAYMENT",
"productName": "test product",
"currency": "THB",
"authorizationExpireDate": "2019-04-13T07:02:38Z",
"payInfo": [
{
"method": "BALANCE",
"amount": 100
}
]
}
]
}
응답의 결제 상태 정보(info.payStatus
)로 상태를 파악할 수 있으며 결제 승인이 완료된 결제를 매입 또는 승인 취소할 수 있습니다. 결제 상태 정보로 다음과 같은 값이 반환됩니다.
"AUTHORIZATION"
: 결제 승인 완료됨"EXPIRED_AUTHORIZATION"
: 결제 승인 만료됨(허용한 시간 내에 매입이 처리되지 않음)"VOIDED_AUTHORIZATION"
: 결제 승인 취소됨
결제 승인이 완료된 결제 중 이미 매입까지 완료된 결제가 있을 수 있습니다. 이 경우 매입이나 승인을 취소할 수 없고 환불만 가능합니다.
매입
고객과 거래가 정상적으로 이뤄졌고, 정산해야 할 금액이 확정됐다면 매입 요청 API를 호출하세요. 결제 요청 시 입력했던 주문 번호를 사용해 승인된 결제를 매입하도록 요청해야 합니다. 다음은 매입을 요청하는 예입니다.
try {
// 결제 요청
let requestResponse = await requestOfflineAPI({
method: "POST",
baseUrl: targetAPIServer,
apiPath: "/v2/payments/oneTimeKeys/pay",
data: {
amount: 100,
currency: "TWD",
// ...
capture: false,
},
});
console.log("Request response: ", requestResponse);
// ...
// 매입 요청
let captureResponse = await requestOfflineAPI({
method: "POST",
baseUrl: targetAPIServer,
apiPath: `/v2/payments/orders/${requestResponse.info.orderId}/capture`,
data: {
amount: 100,
currency: "TWD",
},
});
console.log("Capture response: ", captureResponse);
} catch (error) {
console.log(error);
}
매입을 분리해 결제 승인을 요청하면 LINE Pay 서버는 결제 승인 만료 일시 정보(
info.authorizationExpireDate
)를 응답에 포함시킵니다. 결제 승인 만료 일시 전까지 매입하지 않으면 승인된 결제가 자동 취소됩니다. 직접 결제 승인을 취소할 수도 있습니다.
매입을 완료하면 아래와 같은 응답을 받습니다.
{
"returnCode": "0000",
"returnMessage": "success",
"info": {
"transactionId": 2019010112345678910,
"orderId": "test_order_1",
"transactionDate": "2019-01-01T01:01:00Z",
"payInfo": [
{
"method": "BALANCE",
"amount": 100
}
]
}
}
결제 요청에 입력했던 결제 금액보다 큰 금액을 매입할 수 없고, 결제 금액과 같거나 적은 금액을 매입할 수 있습니다. 결제 금액보다 적은 금액을 매입하면 부분 매입으로 처리되며, 매입되지 않은 금액은 부분 취소 처리됩니다. 매입이 완료되면 승인 취소할 수 없으며, 환불 처리해야 합니다.
승인 취소
매입을 분리해 결제를 진행할 때, 결제 승인 이후 매입을 진행하지 않고 결제 승인을 취소할 수도 있습니다. 결제 승인을 취소하는 작업은 다음과 같이 진행됩니다.
매입할 때와 같이 결제 요청 API를 호출할 때 입력한 주문 번호를 이용해 승인 취소 API를 호출하세요. 다음은 결제 승인을 취소하는 예제입니다.
try {
// 승인 취소 요청
let voidResponse = await requestOfflineAPI({
method: "POST",
baseUrl: targetAPIServer,
apiPath: `/v2/payments/orders/${requestResponseBody.info.orderId}/void`,
});
console.log("Response: ", voidResponse);
} catch (error) {
console.log(error);
}
승인 취소가 정상 처리됐다면 다음과 같은 응답을 받습니다.
{
"returnCode": "0000",
"returnMessage": "OK"
}