Google의 새로운 태그 플랫폼 문서를 미리 확인해 주셔서 감사합니다. 이 사이트는 공개 베타 버전입니다 (의견 보내기).

Android용 유니버설 애널리틱스의 향상된 전자상거래

Google 애널리틱스에서는 유니버설 애널리틱스 속성에서 향상된 전자상거래를 지원합니다. 향상된 전자상거래를 통해 사용자의 쇼핑 환경 전반에서 제품과의 사용자 상호작용을 측정할 수 있습니다. 여기에는 프로모션 노출수, 프로모션 클릭수, 제품 노출수, 제품 클릭수, 제품 세부정보 조회수, 장바구니에 항목 추가, 장바구니에서 항목 삭제, 결제 시작, 거래, 환불 등이 포함될 수 있습니다.

최신 버전의 Google 태그 관리자 및 모바일 앱용 Google 애널리틱스 모두 Google의 모바일 앱 플랫폼인 Firebase와 함께 작동합니다. Firebase SDK로 앱을 측정할 때 자동으로 생성된 여러 모바일 앱 보고서에 액세스할 수 있으므로, 인앱 코드를 통해 이러한 보고서를 추가로 맞춤설정하고 보완할 수 있습니다. 이 보고서에는 iTunes의 App Store와 Google Play에서 처리되는 인앱 구매 데이터가 자동으로 포함됩니다. 전자상거래 앱용 추천 이벤트를 구현하면 전자상거래 관련 보고서를 추가로 생성할 수 있습니다. 쇼핑 행동(즉, 향상된 전자상거래)에 대한 심층 보고서는 현재 유니버설 애널리틱스 속성에서만 사용할 수 있습니다.

이 문서에서는 Firebase SDK와 함께 모바일 앱용 태그 관리자를 사용하여 향상된 향상된 전자상거래 데이터를 유니버설 애널리틱스 속성으로 전송하는 방법을 설명합니다.

첫 단계

시작하기 전에 앱에 다음과 같은 기본 요건을 설정합니다.

  1. 앱에 Firebase와 Google 태그 관리자를 설치하고 구성 합니다. Android용 Firebase SDK 버전 11 이상을 사용하고 있는지 확인합니다.
  2. 다음 두 패키지를 가져옵니다.

    • import com.google.firebase.analytics.FirebaseAnalytics.Event;
    • import com.google.firebase.analytics.FirebaseAnalytics.Param;
  3. 태그 관리자 컨테이너에서 다음 설정을 통해 'promotions'라는 사용자 정의 변수를 만듭니다.

    • 이벤트 유형: 맞춤 매개변수
    • 이벤트 매개변수 키: promotions
    • 기본값: 정의되지 않음

구현

다음 섹션에서는 향상된 전자상거래 활동을 측정하는 데 필요한 매개변수를 사용하여 이벤트를 로깅하는 방법을 보여줍니다.

제품 노출수

ITEM_LIST 매개변수와 더불어 관련성 높은 필드로 정의된 하나 이상의 항목(제품)을 통해 이벤트를 로깅하여 제품 노출수를 측정합니다.

// Define products with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234");  // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" );
product1.putLong( Param.INDEX, 1 );     // Position of the item in the list

Bundle product2 = new Bundle();
product2.putString( Param.ITEM_ID, "sku5678");
product2.putString( Param.ITEM_NAME, "Android Workout Capris");
product2.putString( Param.ITEM_CATEGORY, "Apparel/Women/Pants");
product2.putString( Param.ITEM_VARIANT, "Black");
product2.putString( Param.ITEM_BRAND, "Google");
product2.putDouble( Param.PRICE, 39.99 );
product2.putString( Param.CURRENCY, "USD" );
product2.putLong( Param.INDEX, 2 );

// Prepare ecommerce bundle

ArrayList <bundle>items = new ArrayList<bundle>();
items.add(product1);
items.add(product2);

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putParcelableArrayList( "items", items );

// Set relevant bundle-level parameters

ecommerceBundle.putString( Param.ITEM_LIST, "Search Results" ); // List name

// Log view_search_results or view_item_list event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.VIEW_SEARCH_RESULTS, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 화면 조회수
  • 설정할 필드: (필드 이름) screenName (예: 값) 검색 결과 화면
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 view_search_results와 같음

제품 클릭수/선택 횟수

관련성 높은 필드로 정의된 항목(제품)을 통해 SELECT_CONTENT 이벤트를 로깅하여 제품 클릭수를 측정합니다.

// Define product with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234"); // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today
product1.putLong( Param.INDEX, 1 ); // Position of the item in the list

// Prepare ecommerce bundle

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putBundle( "items", product1 );

// Set relevant action-level parameters

ecommerceBundle.putString( Param.ITEM_LIST, "Search Results" ); // Optional list name

// Log select_content event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.SELECT_CONTENT, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 이벤트
  • 이벤트 카테고리 예시: 전자상거래
  • 이벤트 액션 예시: 제품 클릭
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • Trigger, e.g.: (Custom > Some Events) Event Name equals select_content AND {{promotions}} equals undefined

제품 세부정보 조회수

관련성 높은 필드로 정의된 항목(제품)을 통해 VIEW_ITEM 이벤트를 로깅하여 제품 세부정보 조회수를 측정합니다.

// Define product with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234"); // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today

// Prepare ecommerce bundle

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putBundle( "items", product1 );

// Log view_item event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.VIEW_ITEM, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 화면 조회수
  • 설정할 필드: (필드 이름) screenName (예: 값) 제품 세부정보 화면
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 view_item과 같고
  • {{promotions}} equals undefined

장바구니에 추가된 제품

관련성 높은 필드로 정의된 항목(제품)을 통해 ADD_TO_CART 이벤트를 로깅하여 장바구니에 추가되는 제품을 측정합니다.

// Define product with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234"); // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today
product1.putLong( Param.QUANTITY, 1 );

// Prepare ecommerce bundle

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putBundle( "items", product1 );

// Log add_to_cart event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.ADD_TO_CART, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 이벤트
  • 이벤트 카테고리 예시: 전자상거래
  • 이벤트 액션 예시: 장바구니에 추가
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 add_to_cart와 같음

장바구니에서 삭제된 제품

관련성 높은 필드로 정의된 항목(제품)을 통해 REMOVE_FROM_CART 이벤트를 로깅하여 장바구니에서 삭제되는 제품을 측정합니다.

// Define product with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234"); // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today
product1.putLong( Param.QUANTITY, 1 );

// Prepare ecommerce bundle

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putBundle( "items", product1 );

// Log remove_from_cart event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.REMOVE_FROM_CART, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 이벤트
  • 이벤트 카테고리 예시: 전자상거래
  • 이벤트 액션 예시: 장바구니에서 삭제
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 remove_from_cart와 같음

프로모션 노출수

관련성 높은 필드로 정의된 프로모션 항목을 통해 VIEW_ITEM, VIEW_ITEM_LIST 또는 VIEW_SEARCH_RESULTS 이벤트를 로깅하여 프로모션 노출수를 측정합니다.

// Define promotion with relevant parameters

Bundle promotion = new Bundle();
promotion.putString( Param.ITEM_ID, "PROMO_1234" ); // promotion ID; either ITEM_ID or ITEM_NAME is required
promotion.putString( Param.ITEM_NAME, "Summer Sale" ); // promotion name
promotion.putString( Param.CREATIVE_NAME, "summer_banner2" );
promotion.putString( Param.CREATIVE_SLOT, "banner_slot1" );

// Prepare ecommerce bundle

ArrayList <bundle>promotions = new ArrayList<bundle>();
promotions.add(promotion);

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putParcelableArrayList("promotions", promotions );

// Log view_item, view_item_list, or view_search_results event with ecommerce bundle

mFirebaseAnalytics.logEvent(Event.VIEW_ITEM, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 이벤트
  • 이벤트 카테고리 예시: 내부 프로모션
  • 이벤트 액션 예시: 노출
  • 비 상호작용 조회: True
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • Trigger, e.g.: (Custom > Some Events) Event Name equals view_item AND
  • {{promotions}} does not equal undefined

프로모션 클릭수/선택 횟수

관련성 높은 필드로 정의된 프로모션을 통해 SELECT_CONTENT 이벤트를 로깅하여 프로모션 클릭수를 측정합니다.

// Define promotion with relevant parameters

Bundle promotion = new Bundle();
promotion.putString( Param.ITEM_ID, "PROMO_1234"); // promotion ID; either ITEM_ID or ITEM_NAME is required
promotion.putString( Param.ITEM_NAME, "Summer Sale"); // promotion name
promotion.putString( Param.CREATIVE_NAME, "summer_banner2");
promotion.putString( Param.CREATIVE_SLOT, "banner_slot1");

// Prepare ecommerce bundle

ArrayList <bundle>promotions = new ArrayList<bundle>();
promotions.add(promotion);

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putParcelableArrayList("promotions", promotions );

// Set properties for the event to be shown in the Google Analytics (Firebase) reports.
// These properties will not impact the Universal Analytics reporting.

ecommerceBundle.putString( Param.CONTENT_TYPE, “Internal Promotions” );
ecommerceBundle.putString( Param.ITEM_ID, "PROMO_1234" );

// Log select_content, view_item_list, or view_search_results event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.SELECT_CONTENT, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 이벤트
  • 이벤트 카테고리 예시: 내부 프로모션
  • 이벤트 액션 예시: 클릭
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • Trigger, e.g.: (Custom > Some Events) Event Name equals select_content AND {{promotions}} does not equal undefined

결제 프로세스

결제 시작

관련성 높은 필드로 정의된 하나 이상의 항목(제품)을 통해 BEGIN_CHECKOUT 이벤트를 로깅하여 결제 프로세스의 첫 번째 단계를 측정합니다.

// Define products with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234"); // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today
product1.putLong( Param.QUANTITY, 1 );

// Prepare ecommerce bundle

ArrayList <bundle>items = new ArrayList<bundle>();
items.add(product1);

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putParcelableArrayList( "items", items );

// Set checkout step and optional checkout option

ecommerceBundle.putLong( Param.CHECKOUT_STEP, 1 ); // Optional for first step
ecommerceBundle.putString( Param.CHECKOUT_OPTION, "Visa" ); // Optional

// Log BEGIN_CHECKOUT event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.BEGIN_CHECKOUT, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 화면 조회수
  • 설정할 필드: (필드 이름) screenName (예: 값) 장바구니 화면
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 begin_checkout과 같음

추가 결제 단계

관련 필드로 정의된 하나 이상의 항목(제품)으로 CHECKOUT_PROGRESS 이벤트를 로깅하여 결제 절차의 추가 단계를 측정합니다.

// Define products with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234"); // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today
product1.putLong( Param.QUANTITY, 1 );

// Prepare ecommerce bundle

ArrayList <bundle>items = new ArrayList<bundle>();
items.add(product1);

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putParcelableArrayList( "items", items );

// Set checkout step and optional checkout option

ecommerceBundle.putLong( Param.CHECKOUT_STEP, 2 );
ecommerceBundle.putString( Param.CHECKOUT_OPTION, "Visa" ); // Optional

// Log CHECKOUT_PROGRESS event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.CHECKOUT_PROGRESS, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 화면 조회수
  • 설정할 필드: (필드 이름) screenName (예: 값) 결제 2단계 화면
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 checkout_progress와 같음

결제 옵션

결제 옵션을 사용하면 결제 프로세스의 상태에 대한 추가 정보를 측정할 수 있습니다. 위와 같이 결제 단계 이벤트의 일환으로 또는 지정된 결제 단계의 이벤트가 이미 로깅된 후 사용자가 옵션을 선택한 경우 결제 옵션을 측정할 수 있습니다.

결제 단계가 끝나면 해당 CHECKOUT_STEPCHECKOUT_OPTION 매개변수로 SET_CHECKOUT_OPTION 이벤트를 로깅하여 결제 옵션을 측정합니다.

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putLong( Param.CHECKOUT_STEP, 2 );
ecommerceBundle.putString( Param.CHECKOUT_OPTION, "Mastercard" );
mFirebaseAnalytics.logEvent( Event.SET_CHECKOUT_OPTION, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 이벤트
  • 이벤트 카테고리 예시: 전자상거래
  • 이벤트 액션 예시: 결제 옵션 설정
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 set_checkout_option과 같음

구매

관련성 높은 필드로 정의된 하나 이상의 항목(제품)을 통해 ECOMMERCE_PURCHASE 이벤트를 로깅하여 구매를 측정합니다.

// Define product with relevant parameters

Bundle product1 = new Bundle();
product1.putString( Param.ITEM_ID, "sku1234"); // ITEM_ID or ITEM_NAME is required
product1.putString( Param.ITEM_NAME, "Donut Friday Scented T-Shirt");
product1.putString( Param.ITEM_CATEGORY, "Apparel/Men/Shirts");
product1.putString( Param.ITEM_VARIANT, "Blue");
product1.putString( Param.ITEM_BRAND, "Google");
product1.putDouble( Param.PRICE, 29.99 );
product1.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today
product1.putLong( Param.QUANTITY, 1 );

Bundle product2 = new Bundle();
product2.putString( Param.ITEM_ID, "sku5678");
product2.putString( Param.ITEM_NAME, "Android Workout Capris");
product2.putString( Param.ITEM_CATEGORY, "Apparel/Women/Pants");
product2.putString( Param.ITEM_VARIANT, "Black");
product2.putString( Param.ITEM_BRAND, "Google");
product2.putDouble( Param.PRICE, 39.99 );
product2.putString( Param.CURRENCY, "USD" ); // Item-level currency unused today
product2.putLong( Param.QUANTITY, 1 );

// Prepare ecommerce bundle

ArrayList <bundle>items = new ArrayList<bundle>();
items.add(product1);
items.add(product2);

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putParcelableArrayList( "items", items );

// Set relevant transaction-level parameters

ecommerceBundle.putString( Param.TRANSACTION_ID, "T12345" );
ecommerceBundle.putString( Param.AFFILIATION, "Google Store - Online" );
ecommerceBundle.putDouble( Param.VALUE, 37.39 );    // Revenue
ecommerceBundle.putDouble( Param.TAX, 2.85 );
ecommerceBundle.putDouble( Param.SHIPPING, 5.34 );
ecommerceBundle.putString( Param.CURRENCY, "USD" );
ecommerceBundle.putString( Param.COUPON, "SUMMER2017" );

// Log ecommerce_purchase event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.ECOMMERCE_PURCHASE, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 화면 조회수
  • 설정할 필드: (필드 이름) screenName (예: 값) 감사 화면
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 ecommerce_purchase와 같음

환불

관련성 높은 지정된 거래 ID와 더불어 원하는 경우(부분 환불의 경우) 상품 ID 및 수량으로 정의된 하나 이상의 항목(제품)을 통해 PURCHASE_REFUND 이벤트를 로깅하여 환불을 측정합니다.

// Prepare ecommerce bundle with transaction ID to be refunded

Bundle ecommerceBundle = new Bundle();
ecommerceBundle.putString( Param.TRANSACTION_ID, "T12345" ); // Required
ecommerceBundle.putDouble( Param.VALUE, 37.39 ); // Optional in Universal Analytics

// (OPTIONAL) For partial refunds, define the item IDs and quantities of products being refunded

Bundle refundedProduct = new Bundle();
refundedProduct.putString( Param.ITEM_ID, "sku1234" ); // Required for partial refund
refundedProduct.putLong( Param.QUANTITY, 1 ); // Required for partial refund

ArrayList <bundle>items = new ArrayList<bundle>();
items.add(refundedProduct);
ecommerceBundle.putParcelableArrayList( "items", items );

// Log purchase_refund event with ecommerce bundle

mFirebaseAnalytics.logEvent( Event.PURCHASE_REFUND, ecommerceBundle );

이 예시에 대한 태그 구성 보기

  • 태그 유형: 유니버설 애널리틱스
  • 추적 유형: 이벤트
  • 이벤트 카테고리 예시: 전자상거래
  • 이벤트 액션 예시: 환불
  • 향상된 전자상거래 기능 사용: True
  • 데이터 읽기 출처: Firebase 이벤트
  • 트리거 예시: (맞춤 > 일부 이벤트) 이벤트 이름이 purchase_refund와 같음