execute-promotion API에서 개발 스펙에 없는 응답이 내려오는데
내용을 보니 지급 실패인데 성공으로 내려오는 장애가 발생하고 있습니다.
해당 현상은 오늘 2026-05-20 17:42:22 KST부터 현재까지 발생 중입니다.
로그상 1,000건 이상 확인되었고, 해당 응답을 받은 유저가 재시도하면서 발생 건수가 계속 증가하고 있습니다.
{
"resultType": "SUCCESS",
"success": {
"blocked": true,
"retryAfterSeconds": 57,
"message": "요청 한도를 초과했습니다. 잠시 후 다시 시도해주세요."
}
}
지급이 실패 또는 차단된 상황이라면 개발가이드 기준대로 errorCode/message 형태로 내려와야 하는데
resultType이 SUCCESS로 내려와 저희 서버가 정상 지급되었다고 판단하고 유저 재화를 차감하고 있습니다. 당연히 토스에서는 포인트 지급 처리가 안되고 있습니다.
요청 한도 초과로 지급이 차단되는 케이스라면 resultType: FAIL로 내려와야 하고,
에러코드는 하위 호환을 고려해 4110으로 내려주시고, retryAfterSeconds 등 추가 정보는 기존 에러 응답 패턴처럼 error.data 안에 포함해 주시기 바랍니다.
{
"resultType": "FAIL",
"success": null,
"error": {
"errorCode": "4110",
"reason": "요청 한도를 초과했습니다. 잠시 후 다시 시도해주세요.",
"data": {
"blocked": true,
"retryAfterSeconds": 57
}
}
}
3 서비스/API에 반영하기 위해 해당 에러가 발생하는 기준 문의드립니다. (예: 1초에 3건 이상 요청시 발생 이라던지)
4 여러번 시도하면 성공되는 케이스가 있습니다. 60초 막으려면 다 막아야지 몇 번 시도하면 중간중간 성공하는 케이스가 발생하는걸로 봐서는 API 서버중 일부만 배포된거 아닌가 의심됩니다.
멤버/빌링 관련 스펙 변경은 서비스 장애로 바로 이어질 수 있습니다.
사전 공지 없이 잠수함 패치가 되면 정말 곤란합니다. ㅠㅠ
제가 정확히 이해 못했는데,
파트너사쪽에서 프로모션 지급을 하면 유저에게 푸시가 가고 → 그 민원이 들어와서 정책을 조정하신거로 이해하면 될까요?
그렇다면 유저가 앱에서 직접 토스 포인트 받기를 하는 경우는 고려가 안된거 같습니다.
서비스레이어에서는 유저가 보유 재화를 토스 포인트로 교환하는 액션이 짧은 시간 내 반복할 수 있는데,
아마 앱테크는 모두 이런 방식이라 생각됩니다.
이 경우 분당 10회 제약이 걸리면, 서비스레이어에서 쿨타임 UX를 적용해야 하는데 이게 좀 애로사항이 큽니다.
예를 들어
“토스 포인트로 교환하세요. 단, 분당 10회까지만 가능합니다.” 내지는
“57초 후 재시도 해주세요” 같은..정말 이상한 UX가 됩니다.
그래서 요청 드리는 부분이 최소한 userKey 기준 분당 60회 수준으로 조정 요청드립니다. 분당 60회라면 서비스 레이어에서 교환 액션에 1초 인터벌 등을 적용해 UX적으로 대응 가능한 마지 노선이라고 봅니다.
더불어 이건 걱정되어 말씀드리는건데
execute-promotion API에서 지급이 실패하거나 차단된 경우라면 당연히 SUCCESS가 아니라 FAIL 응답으로 내려와야 합니다. (에러코드 하위호환 무관)
지금 아마 많은 파트너사들이 에러가 발생하는지도 모르고 있을거에요. SUCCESS로 판단할거라고 보거든요.
저희 쪽에서도 약 100명 정도의 고객에게 영향이 있었고, 일부 고객이 직접 제보해서 인지하게 되었습니다.
이 패치와 관련해 재지급 처리 및 방어 코드 적용으로 새벽에 약 5시간가량 대응했고, 오늘도 동일 현상이 계속 발생하고 있어요.
아무튼 결론은
분당 10회는 UX적으로 해소하기 어렵기에 파트너사들이 UX 대응 가능하도록 적어도 분당 60회로 수정 요청 드립니다.
@Albert 님 혹시 최대 지급 금액을 조정해서 60초 간 지급해야하는 금액을 하나로 뭉쳐서 지금하는 것은 어려우실까요? 유저 + 앱 당 QPM이 60이 되면 하나의 앱에서만 최대 분 당 60건의 푸시를 받게 될 수 있어서, 민원으로 들어왔던 케이스들을 해소하지 못할 것 같습니다.
1.일단 금액 조정으로 그룹핑해서 지급하는 방법은 근본적인 해결책이 아닌것 같습니다. 완화는 되겠지만요
유저들은 리워드를 모아서 한번에 교환하는 방식을 선호하는 그룹군이 있는데,
그렇게 본다면 유저가 가지고 있는 보유 리워드 전체교환 개념이 있어야만 해소가 됩니다.
그리고 1회 지급 한도가 5,000원 제약이 있어서 상단에서 또 걸려요.
예를 들어 재화 3,000개 (재화 1개당 100원) 보유한 유저가
재화 50개씩 토스포인트 5,000원으로 교환하도록 그룹핑해도 연속으로 하면결국 10회 제약이 걸립니다.
결국에는 그룹핑을 하더라도 xx초후 재시도하세요 라던지 이런 방어코드가 필요하게 됩니다.
2.그렇다면 QPM 20은 어려울까요?
1회 지급시 3초 인터벌까지는 테스트해보니 답답하긴 하지만 그래도 차선으로 수용가능해 보입니다.
교환 버튼 클릭 → 응답 → 인터벌 (이게 총 3초) → 60초에 20회 가능
3.민원 케이스가 예상이 안되어서..이거 혹시 푸시쪽이 메인인가요?
토스 포인트 지급이 핵심이 아니라 푸시 민원으로 인해 푸시에 정책을 걸었다면..
토스 포인트 지급에 푸시가 함께 트랜젝션이 걸려 있어 이런 상황이 된 걸까요?
제 머리에서는 이거밖에 예상이 안되네요
만약에 이게 맞다면..푸시와 지급을 분리하고
푸시는 QPM에 걸리면 발송되지 않는 정도로 하면 될거 같은데..
혹은 A앱에서 토스포인트 지급시 해당 유저가 A앱에 접속되어 있는 상황이면 푸시는 제외한다던지..
(이건 더 복잡해보이지만 UX적으로 이게 방향은 맞습니다. 포그라운드상태에서 푸시는 보통 배제하니까요, 그리고 보통 토스포인트 지급시 미니앱이 자체적으로 얼마 지급했다라고 알리고 있어서, 이미 현재상태가 중복 알림이기는 합니다. 자체알림+푸시알림)
깔끔한 해결책이 나오지 않아 아쉽네요.
다만 정상적인 비즈니스가 대부분일거 같은데 일부 민원해소를 위해 다수의 유저 및 파트너사에게 불편함을 초래하는 정책이 되어버리는거 같습니다..