앱인토스 미니앱 환율 계산기 화면 세 장
|

앱인토스 미니앱 6 – 환율 계산기

앱인토스 미니앱 제작기 여섯 번째는 환율 계산기입니다. 해외 쇼핑몰 가격을 볼 때나 여행 가기 전에 “이게 원화로 얼마지” 하고 가늠해 보는 앱이에요.

환율 앱은 숫자 하나가 전부라서, 그 숫자를 어디까지 믿어도 되는지 같이 알려 주는 게 중요하다고 봤습니다. 이 글은 그 기준으로 화면과 코드를 짠 기록입니다.

로컬에서 앱을 직접 실행해 찍은 시연 영상 (소리 없음)

환율 계산기는 어떤 앱인토스 미니앱인가

환율 계산기 첫 화면. 보낼 금액 100,000원이 예시로 들어가 있고 미국 달러 환산 참고 금액이 보인다
첫 화면: 예시 금액과 결과
금액을 50,000원으로 바꾸고 목표 통화를 일본 엔으로 고른 화면. 환산 참고 금액이 엔으로 나온다
통화를 바꾼 결과
화면 아래쪽. 저장한 통화쌍과 여행 예산 열기 버튼, 기준 갱신 시각과 다음 갱신 예정 시각, 출처 링크가 보인다
기준시각과 출처

원화와 함께 미국 달러, 일본 엔, 유로를 포함한 15개 외화를 다룹니다. 금액과 통화쌍을 고르면 참고 금액이 나오고, 자주 쓰는 통화쌍은 저장해 뒀다가 다음에 한 번에 불러와요. 여행 예산 화면도 있는데, 직접 정한 총예산을 숙박이나 식비 같은 항목으로 나눠 현지 통화로 환산해 보는 보조 도구입니다.

실제 환전이나 송금, 결제는 하지 않습니다. 어디까지나 계산만 하는 앱이에요.

첫 화면에는 환산 결과 하나만

환율 앱이라고 하면 통화별 환율이 빽빽하게 늘어선 표가 먼저 떠오르죠. 이 앱은 표를 두지 않았습니다. 사람들이 알고 싶은 건 환율표가 아니라 “내 돈이 얼마가 되느냐”라고 봤기 때문이에요.

환율표 중심

  • 통화마다 숫자가 줄지어 있다
  • 내 금액은 따로 계산해야 한다

환산 카드 중심

  • 금액을 넣으면 결과 하나가 크게 보인다
  • 금액이나 통화를 바꾸면 결과가 바로 따라 바뀐다

앱을 열면 100,000원이 미리 들어가 있고 달러 결과가 바로 보입니다. 입력란 위에는 “예시 금액 · 수정 가능”이라고 적어서 이 숫자가 예시라는 걸 알려 줘요. 금액은 직접 입력해도 되고, 10,000원·50,000원·100,000원 버튼을 눌러도 됩니다.

함께 읽기앱인토스 미니앱 7 – K패스 환급 계산기앱인토스 미니앱 K패스 환급 계산기 제작기입니다. 한 달 교통비로 두 가지 환급 기준을 비교하고 월 15회 탑승을 직접 세는 앱을 만들면…

환율이 언제 기준인지 화면에 적었다

이 앱이 쓰는 환율은 제공자가 하루 한 번 갱신하는 공개 데이터입니다. 실시간 시세가 아니에요. 그래서 결과와 함께 시각 세 개를 보여줍니다.

– 기준 갱신제공자가 환율을 마지막으로 갱신한 시각
– 다음 갱신 예정제공자가 알려 준 다음 갱신 시각
– 마지막 확인앱이 제공자에게 마지막으로 물어본 시각

그 아래에는 참고용 기준 환율이고 실제 환전이나 카드 청구 금액은 금융기관 환율과 수수료에 따라 달라질 수 있다는 안내, 그리고 데이터 출처 링크가 붙습니다. 숫자만 덜렁 보여주는 것보다 “어제 오전 기준이구나” 하고 알고 쓰는 편이 낫다고 생각했어요.

데이터 기준을 설명하는 안내 시트도 따로 있습니다. 환율을 받아 올 때 달러 기준 환율만 요청하고, 입력한 금액이나 고른 통화쌍은 제공자에게 보내지 않는다는 내용이 여기에 적혀 있어요.

달러를 거쳐서 계산한다

제공자에게 받는 값은 “1달러가 각 통화로 얼마인지”입니다. 원화를 엔화로 바꾸는 것처럼 달러가 끼지 않는 계산도 이 값 두 개로 풉니다.

api.tsts
/** Convert through the provider's USD-base rates; never substitutes a fallback rate. */
export function convertCurrency(
  rates: Record<string, number>,
  fromCode: string,
  toCode: string,
  amount: number
): number | null {
  if (!Number.isFinite(amount) || amount < 0) return null;
  if (fromCode === toCode) return amount;
  const fromPerUsd = fromCode === 'USD' ? 1 : rates[fromCode];
  const toPerUsd = toCode === 'USD' ? 1 : rates[toCode];
  if (!positiveFinite(fromPerUsd) || !positiveFinite(toPerUsd)) return null;
  const result = (amount * toPerUsd) / fromPerUsd;
  return Number.isFinite(result) && result >= 0 ? result : null;
}

값이 없으면 계산하지 않는다

두 통화의 환율이 모두 0보다 큰 정상 숫자일 때만 계산하고, 하나라도 없으면 null을 돌려줍니다. 화면은 null을 받으면 결과 대신 환율을 확인할 수 없다는 안내를 보여줘요. 빠진 값을 임의의 숫자로 채워서 그럴듯한 결과를 만들지 않으려는 겁니다.

함께 읽기앱인토스 미니앱 9 – 이자 계산기앱인토스 미니앱 이자 계산기 제작기입니다. 대출 월 상환액을 계산하고 금리가 1%p 움직일 때 매달 얼마가 달라지는지 보여주는 앱을 만들…

받아 둔 환율은 다음 갱신 때까지 쓴다

하루 한 번 바뀌는 데이터를 앱을 열 때마다 새로 받을 필요는 없습니다. 환율을 가져오는 함수는 먼저 기기에 받아 둔 값을 봅니다.

api.tsts
export async function fetchRates(options: FetchRatesOptions = {}): Promise<RatesResult> {
  const now = Date.now();
  const cached = readCache();

  if (cached && now <= cached.nextUpdateAt && withinDisplayAge(cached, now) && !options.force) {
    return { status: 'ready', data: asCurrentData(cached, now) };
  }

  if (cached && cached.retryAfterAt && now < cached.retryAfterAt) {
    return resultFromCache(cached, now);
  }

첫 번째 조건이 핵심이에요. 받아 둔 값이 있고 제공자가 알려 준 다음 갱신 시각이 아직 안 됐으면, 요청을 보내지 않고 그 값을 그대로 씁니다. withinDisplayAge는 기준 갱신 시각에서 72시간이 지나지 않았는지 확인하는 함수고, 화면의 “다시 확인” 버튼을 누르면 force가 켜져서 이 첫 번째 조건을 건너뜁니다.

연결이 안 될 때

새로 받으려다 실패하는 경우도 있습니다. 지하철 안이거나 제공자 쪽 응답이 늦을 때요. 요청은 10초까지 기다리고, 실패하면 이렇게 처리합니다.

api.tsts
    if (cached && withinDisplayAge(cached, Date.now())) {
      const retryData: RatesData = {
        ...cached,
        lastCheckedAt: Date.now(),
        isStale: true,
        retryAfterAt: reason === 'cancelled' ? undefined : Date.now() + RETRY_INTERVAL_MS,
      };
      safeSet(CACHE_KEY, retryData);
      return { status: 'ready', data: retryData };
    }

    return { status: 'error', reason };

받아 둔 값이 72시간 이내 것이면 그 값으로 계산은 계속하되, isStale을 켜서 화면에 “갱신 지연”이라고 표시합니다. 다음 재시도 시각은 6시간 뒤로 잡아 둬요. 받아 둔 값이 없거나 너무 오래됐으면 결과를 내지 않고, 연결 문제인지 시간 초과인지에 따라 다른 안내 문구를 보여줍니다.

오래된 값의 한계를 정해 둔다

72시간이 지난 환율로는 계산하지 않습니다. 오래된 숫자를 계속 보여주는 것보다 “지금은 확인할 수 없다”고 말하는 쪽을 골랐어요.

광고와 공유는 계산을 방해하지 않게

전면 광고는 여행 예산을 저장한 직후에만, 안내를 거쳐서 나올 수 있습니다. 금액을 넣거나 통화를 바꾸는 동안에는 나오지 않아요. 계산하러 들어온 사람이 숫자를 보기도 전에 광고부터 만나면 안 된다고 봤습니다.

공유 버튼은 앱 소개 한 줄과 링크를 보냅니다. 환율 숫자나 환산 결과를 카드로 만들어 내보내는 기능은 넣지 않았어요. 제공자가 환율 데이터를 그대로 다시 배포하는 것을 금지하고 있어서, 결과 공유는 허용 범위가 확인될 때까지 미뤄 뒀습니다.

다음에 할 일

환율 추이 그래프는 실제 과거 데이터를 쓸 수 있게 되면 따로 기획하려고 합니다. 그때까지는 지금의 환산 화면을 다듬는 데 집중할 생각이에요.

프로젝트를 어떤 식으로 진행하는지는 프로젝트 진행 방식에, 숫자를 다루는 또 다른 앱 이야기는 카드값 페이스 글에 있습니다.

환율 계산기 자주 묻는 질문

환율 계산기는 어떤 앱인가요?

미국 달러, 일본 엔, 유로 등 15개 통화 가운데 통화쌍과 금액을 골라 참고 금액을 계산하는 앱입니다. 실제 환전이나 송금, 결제 기능은 없습니다.

실시간 환율인가요?

아닙니다. 환율 제공자가 마지막으로 갱신한 기준값이고, 결과 아래에 기준 갱신 시각과 다음 갱신 예정 시각을 함께 보여줍니다. 은행이나 카드사가 적용하는 환율과 수수료에 따라 실제 금액은 달라질 수 있습니다.

입력한 금액이 외부로 전송되나요?

환율을 받아 올 때는 고정된 달러 기준 환율만 요청합니다. 입력한 금액과 고른 통화쌍, 여행 예산은 환율 제공자에게 보내지 않습니다.

이 글은 앱인토스 미니앱 「환율 계산기」의 기록입니다. 앱인토스는 토스 앱 안에서 미니앱을 서비스하는 플랫폼이고, 공식 안내는 앱인토스 개발자센터에 있습니다.

이 글은 직접 만들고 운영하며 남긴 기록입니다. 적힌 수치는 작성 시점의 제 계정 기준이며, 같은 결과나 수익을 보장하지 않습니다.

Similar Posts

3 Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다