자사몰 상품 구조화 데이터 점검법: 가격·재고·리뷰가 검색결과와 어긋날 때

상품 페이지에는 29,000원으로 보이는데 Google 검색결과에는 25,000원으로 나타나거나, 판매 중지한 상품에 ‘재고 있음’이 남아 있는 경우가 있습니다. 리뷰 평점과 리뷰 수도 실제 상세페이지와 다르게 보일 수 있습니다. 이때 구조화 데이터 블록을 무작정 더 넣는 것부터 시작하면 어느 값이 어긋났는지 찾기 어려워집니다.

> **먼저 할 일:** 상품 한 개를 정해 `페이지에 보이는 값 → 대표 URL(canonical) → JSON-LD → Rich Results Test → Search Console 보고서` 순서로 같은 값을 대조하세요. 구조화 데이터가 유효하다는 결과와 Google 검색에 리치 결과가 실제로 표시된다는 결과는 서로 다릅니다.

Google은 Product 구조화 데이터를 상품 페이지의 내용을 설명하는 신호로 사용합니다. 가격·재고·리뷰처럼 구매 판단에 직접 영향을 주는 값은 마크업에만 넣을 것이 아니라 실제 페이지에도 보여야 합니다. [Google의 Product 구조화 데이터 안내](https://developers.google.com/search/docs/appearance/structured-data/product?hl=ko)와 [구조화 데이터 기본 원칙](https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data?hl=ko)을 기준으로, 이 글에서는 오류를 네 가지 증상으로 나눠 점검하겠습니다.

먼저 태그 수가 아니라 상품의 기준값을 고정합니다

구조화 데이터 문제를 진단할 때 가장 먼저 만들어야 하는 것은 코드가 아니라 기준값 한 줄입니다. 상품 상세를 일반 브라우저와 모바일 브라우저에서 열고 아래 항목을 그대로 적습니다.

상품 한 개의 기준값을 먼저 기록합니다.

| 기준값 | 상품 페이지에서 확인할 위치 | 구조화 데이터에서 대조할 필드 |
| — | — | — |
| 상품명·브랜드·상품번호 | 제목, 기본 정보, 옵션 선택 영역 | `Product.name`, `brand`, `sku` |
| 현재 판매가·통화 | 정상가, 할인가, 결제 버튼 주변 | `Offer.price`, `priceCurrency` |
| 판매 상태 | 구매 버튼, 품절 문구, 재입고 안내 | `Offer.availability` |
| 리뷰 평점·개수 | 해당 상품 리뷰 탭과 요약 영역 | `aggregateRating` 또는 `review` |
| 대표 상품 URL | 주소창, canonical, 옵션별 URL | `url`, `ProductGroup`, `hasVariant` |

여기서 ‘실제 페이지에 보인다’는 말은 이미지 속 글자가 아니라, 소비자가 상품을 선택하고 결제하기 전에 확인할 수 있는 상품 정보라는 뜻입니다. 다른 상품의 리뷰를 합치거나, 화면에는 없는 최저가를 마크업에만 넣는 방식으로 검색결과를 유리하게 만들 수는 없습니다. 기존의 [아임웹 SEO·메타태그 설정 글](/imweb-seo-metatag-setup/)은 사이트 전반의 설정을 볼 때 참고하고, 이 글에서는 상품 단위의 불일치 진단에 집중합니다.

같은 상품 URL을 기준으로 삼아야 하는 이유

자사몰에서는 상품 상세 URL, 옵션 선택 후의 URL, 추적 파라미터가 붙은 URL, 모바일용 URL이 함께 생길 수 있습니다. 그런데 운영자가 본 URL과 Google이 읽은 대표 URL이 다르면 같은 상품을 비교하고도 서로 다른 결론을 내릴 수 있습니다.

1. 브라우저에서 상품을 열고 대표 상품 URL을 복사합니다.
2. 소스의 canonical이 다른 상품·카테고리·파라미터 URL을 가리키지 않는지 확인합니다.
3. 구조화 데이터의 `url`과 `offers.url`이 실제 구매 페이지와 맞는지 적습니다.
4. 옵션별로 별도 URL이 있다면 부모 상품과 변형 상품을 구분합니다.

상품 하나를 고칠 때도 이 네 줄을 기록하면 “JSON-LD는 맞는데 왜 검색결과는 다르지?”라는 질문을 페이지 자체의 문제와 수집·처리 시점의 문제로 나눌 수 있습니다.

가격이 다르면 Offer부터 대조합니다

가격 불일치는 정가와 할인가 중 무엇이 노출되는지, 통화가 제대로 표시되는지, 세일 기간이 끝났는데 이전 값이 남아 있는지에서 시작합니다. [Google의 Product snippets 문서](https://developers.google.com/search/docs/appearance/structured-data/product-snippet?hl=ko)는 Product와 Offer 예시에서 상품 가격·통화·리뷰 정보를 함께 다룹니다.

다음 네 가지를 한 묶음으로 비교하세요.

  • 상품 상세에 소비자에게 보이는 현재 판매가
  • `Offer.price`의 숫자와 소수점 처리
  • `Offer.priceCurrency`의 통화 코드
  • 할인 종료일을 사용하는 경우 `priceValidUntil`의 실제 유효기간

`priceValidUntil`은 단순히 “언젠가 끝나는 행사”를 적는 메모가 아닙니다. 문서 형식에 맞는 날짜여야 하고, 이미 지난 값이 남아 있으면 상품 스니펫이 표시되지 않을 수 있습니다. 반대로 페이지에는 할인 종료 후의 가격이 보이는데 JSON-LD에 과거 할인가를 그대로 두면, 검색결과의 가격이 실제 구매 조건과 달라질 여지가 생깁니다.

가격 증상별로 수정 위치를 좁히는 표

| 보이는 증상 | 먼저 대조할 값 | 다음 행동 |
| — | — | — |
| 검색에는 더 싼 가격이 보임 | 정상가·할인가·`priceValidUntil` | 행사 종료 시각과 현재 판매가를 한 줄로 기록하고 만료된 할인값을 제거하거나 갱신 |
| 검색에는 가격이 없고 상품명만 보임 | `price`, `priceCurrency`, Offer 구조 | 숫자 형식·통화·Offer 중첩 위치를 테스트하고 페이지의 결제 가격과 재비교 |
| 옵션마다 가격이 다른데 검색에는 한 가격만 보임 | 부모 `Product`와 variant별 `Offer` | 대표 상품의 공통값과 옵션별 값을 분리하고 변형 URL 설계를 확인 |
| 원화 상품인데 다른 통화가 표시됨 | 화면의 통화 표기와 `priceCurrency` | 가격 숫자와 통화 코드를 같은 상점 지역 기준으로 맞춘 뒤 테스트 |

가격을 고친 뒤에도 바로 검색결과가 바뀐다고 약속할 수는 없습니다. 먼저 라이브 URL에서 현재 가격이 보이는지, 그 다음 테스트 도구에서 읽히는 값을 확인하고, Search Console에서 재수집·검증 상태를 따로 기록해야 합니다.

재고가 다르면 availability와 canonical을 같이 봅니다

“품절인데 재고 있음”은 `availability` 한 필드만 바꾸면 끝나는 문제가 아닐 수 있습니다. 상품 시스템이 품절 페이지를 별도 URL로 보내거나, 재입고 페이지를 대표 URL로 지정하거나, 캐시된 HTML과 구매 버튼 상태가 서로 다를 수 있기 때문입니다.

다음 순서로 확인합니다.

1. 시크릿 창에서 상품 페이지를 열고 실제 구매 버튼의 상태를 봅니다.
2. 옵션을 선택해야 재고가 결정되는 상품인지 확인합니다.
3. 페이지에 표시된 상태와 `Offer.availability`가 같은 의미인지 비교합니다.
4. canonical이 품절 상품의 대표 URL을 가리키는지 확인합니다.
5. 판매 중지·품절·예약판매가 각각 다른 URL이라면 어떤 URL이 실제 상품 페이지인지 정합니다.

[Merchant listings 구조화 데이터 문서](https://developers.google.com/search/docs/appearance/structured-data/merchant-listing?hl=ko)는 실제로 구매할 수 있는 상품 페이지를 별도의 판매자 목록 관점에서 설명합니다. 이 경우 가격과 재고만 보지 말고 배송·판매 조건이 같은 상품 URL에 연결되어 있는지도 확인해야 합니다. 화면에는 “재입고 알림”만 있고 구매할 수 없다면, 무조건 판매 중인 상품처럼 표시하는 쪽으로 마크업을 맞추면 안 됩니다.

재고 대조에서 자주 놓치는 세 가지

첫째, 옵션을 고르기 전에는 재고 있음으로 보이지만 특정 사이즈를 고르면 품절인 상품입니다. 이때 부모 상품의 상태를 모든 variant에 복사하면 안 됩니다. 둘째, 장바구니에는 담기지만 결제 단계에서 품절 처리되는 상품입니다. 상품 페이지에 표시된 판매 상태와 주문 가능 상태의 차이를 운영 기록에 남겨야 합니다. 셋째, CDN이나 플러그인 캐시가 이전 HTML을 내보내는 경우입니다. 관리자에서 재고를 바꾼 시각과 라이브 소스에 새 상태가 반영된 시각을 별도로 기록하세요.

리뷰·평점이 다르면 집계 범위를 의심합니다

리뷰 문제는 별점 숫자만 맞추는 문제가 아닙니다. 현재 상품의 리뷰인지, 동일 상품의 다른 옵션 리뷰까지 합친 것인지, 브랜드 전체 리뷰를 상품 리뷰처럼 보이게 만든 것은 아닌지 확인해야 합니다.

다음 질문에 모두 답할 수 있어야 합니다.

  • 상세페이지에 보이는 평점과 리뷰 수가 마크업의 `aggregateRating`과 같은가?
  • 리뷰가 이 상품 또는 이 상품군에 속한다는 것을 확인할 수 있는가?
  • 품절·단종·이전 상품의 리뷰를 새 상품에 자동으로 합치지 않았는가?
  • 평점이 화면에 보이지 않거나 리뷰를 실제로 제공하지 않는데 마크업에만 넣지는 않았는가?
  • 리뷰 수가 페이지 로딩 후 JavaScript로 바뀐다면, 테스트 도구가 최종 렌더링 결과를 어떻게 읽었는가?

리뷰가 많아 보이게 만드는 것이 목표가 아니라, 구매자가 보는 상품 정보와 검색엔진에 설명하는 정보가 같은지를 확인하는 것이 목표입니다. [Google 구조화 데이터 기본 안내](https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data?hl=ko)의 정확성 원칙을 적용하면, 확신할 수 없는 리뷰 수를 추가하는 것보다 확인 가능한 Product·Offer 정보만 남기는 편이 안전합니다.

옵션 상품은 ProductGroup과 변형 URL을 따로 봅니다

색상·사이즈·용량에 따라 가격과 재고가 달라지는 상품은 단일 Product 예시를 복사해 모든 옵션에 넣으면 오류가 생기기 쉽습니다. [Google의 상품 변형 문서](https://developers.google.com/search/docs/appearance/structured-data/product-variants?hl=ko)는 공통 상품군과 개별 변형을 `ProductGroup`, `variesBy`, `hasVariant`, `productGroupID` 관계로 설명합니다.

운영자는 코드를 보기 전에 상품 구조를 먼저 그립니다.

| 구분 | 확인 질문 | 기록할 값 |
| — | — | — |
| 상품군 | 여러 변형이 한 상품군에 속하는가? | 공통 상품명·브랜드·상품군 ID |
| 변형 | 색상·사이즈·용량 중 무엇이 달라지는가? | variant 이름과 변형 속성 |
| 가격 | 변형마다 실제 가격이 다른가? | variant별 `Offer.price` |
| 재고 | 옵션별로 구매 가능 상태가 다른가? | variant별 `availability` |
| URL | 옵션별 대표 URL이 있는가? | variant URL과 canonical |

상품군의 공통 설명과 변형의 가격·재고를 섞지 않으면 “한 옵션은 품절인데 전체 상품은 판매 중”인 상태를 더 정확히 표현할 수 있습니다. [자사몰 상품 사진 제작 기준](/jasa-mall-product-photo-guide/)과 [상품 상세페이지 길이와 전환율](/product-detail-page-length-conversion-rate/)도 함께 보면, 검색용 데이터만 고치지 않고 실제 상품 상세에서 옵션·가격·이미지가 이해되는지까지 확인할 수 있습니다.

ProductGroup은 부모 상품과 변형 상품을 나누고, variant별 가격·재고·URL을 따로 대조하게 하는 기준입니다.

5단계로 한 상품을 끝까지 진단합니다

1단계: 화면의 기준값을 저장합니다

상품 URL, 확인 시각, 로그인 여부, 선택한 옵션, 화면의 가격·재고·평점·리뷰 수를 캡처하거나 운영표에 적습니다. 모바일과 데스크톱의 정보가 다르면 두 환경을 별도 행으로 기록합니다.

2단계: 대표 URL과 소스의 JSON-LD를 비교합니다

페이지 소스에서 `Product`, `Offer`, `AggregateRating`, `Review`, `ProductGroup`을 찾고, 화면 기준값과 다른 필드만 표시합니다. 코드가 여러 개라면 같은 상품을 설명하는 블록이 중복되거나 서로 다른 값을 내보내는지 확인합니다. 이 단계에서는 새 코드를 추가하지 않고 차이만 적습니다.

3단계: Rich Results Test에서 라이브 URL을 검사합니다

Google의 [Rich Results Test 도움말](https://support.google.com/webmasters/answer/7445569?hl=ko)에 따라 라이브 URL 또는 코드를 검사합니다. 결과의 유효·경고·오류를 상품 URL과 함께 저장합니다. 코드 붙여넣기 결과만 통과하고 라이브 URL에서 오류가 난다면, 배포·캐시·렌더링 차이를 먼저 확인해야 합니다.

4단계: 가격·재고·리뷰 중 어디에서 끊겼는지 분리합니다

이제 증상을 한 가지로 좁힙니다. 가격이면 Offer, 재고면 availability와 canonical, 리뷰면 집계 범위, 옵션이면 ProductGroup과 variant URL을 담당자에게 전달합니다. “구조화 데이터 오류”라고만 적으면 개발자가 모든 상품 템플릿을 다시 확인해야 하므로, 필드와 실제 화면값을 함께 보내는 것이 좋습니다.

5단계: 보고서와 재수집 상태를 별도로 기록합니다

수정 후에는 같은 URL을 다시 테스트하고 Search Console 보고서의 오류 상태를 확인합니다. 오류가 줄었다는 것은 검증 단계의 진전이지, 특정 검색어에서 상품 카드가 노출된다는 뜻은 아닙니다. 이 구분을 운영표에 남겨야 검증 통과를 SEO 성과로 잘못 보고하지 않습니다.

Search Console에서 어느 보고서를 볼지 고릅니다

판매자가 운영하는 상품 상세처럼 실제 구매가 가능한 페이지라면 Merchant listings 관점이 우선입니다. 구매 페이지가 아닌 상품 정보·리뷰 중심의 페이지라면 Product snippets 보고서가 더 가까울 수 있습니다. 두 보고서는 목적이 다르므로 하나의 보고서에 오류가 없다고 다른 유형까지 모두 정상이라고 판단하지 않습니다.

[Search Console 리치 결과 보고서 개요](https://support.google.com/webmasters/answer/7552505?hl=ko)는 보고서가 유효 상태와 오류 샘플을 보여주는 점검 수단이며 모든 URL의 완전한 목록은 아니라고 설명합니다. 따라서 다음 세 증거를 세 칸으로 기록하세요.

| 검증 칸 | 통과의 의미 | 아직 말할 수 없는 것 |
| — | — | — |
| Rich Results Test | 테스트한 URL·코드가 특정 리치 결과 요구사항을 만족 | 검색결과에 반드시 표시됨 |
| Search Console 보고서 | 발견된 URL 집합에서 오류·경고 상태가 확인됨 | 모든 상품 URL이 정상임 |
| 실제 검색결과 | 확인한 검색 시점에 해당 상품 정보가 표시됨 | 다른 검색어·다른 기기에서도 계속 표시됨 |

Search Console에서 오류가 사라지지 않을 때는 같은 URL을 반복해서 테스트하기보다, canonical과 실제 HTML이 바뀌었는지 먼저 확인합니다. 상품 템플릿이 여러 개라면 오류 URL 한 개를 고친 뒤 다른 카테고리의 상품 URL에서도 같은 필드가 바뀌었는지 샘플링합니다.

수정했는데도 그대로라면 수집·canonical·피드를 분리합니다

구조화 데이터가 유효해도 Google이 즉시 새 값을 검색결과에 반영한다고 할 수는 없습니다. 다음 원인을 서로 다른 티켓으로 나누면 재작업이 줄어듭니다.

  • **라이브 HTML 문제:** 관리자 화면은 새 가격인데 공개 페이지 소스는 이전 가격이다.
  • **대표 URL 문제:** 수정한 URL이 canonical이 아니거나, 변형 URL이 부모 URL로 합쳐진다.
  • **캐시 문제:** 일부 지역·기기에서 이전 HTML 또는 이전 재고 상태가 제공된다.
  • **피드 문제:** Merchant Center를 함께 사용한다면 페이지 데이터와 피드 데이터가 서로 다르다.
  • **처리 지연 문제:** 테스트와 보고서는 정상인데 아직 검색결과에 새 정보가 나타나지 않는다.

이 사이트의 [상품 상세페이지 수정 주기와 데이터 신호 글](/product-page-refresh-signal-data/)은 변경할 내용을 정하는 데 참고할 수 있지만, 그 글이 구조화 데이터 오류의 검증을 대신하지는 않습니다. 반대로 [네이버 쇼핑 SEO 조건](/naver-shopping-seo-conditions/)은 네이버 채널의 상품 노출 조건을 확인하는 글이므로 Google Product 데이터와 동일한 규칙으로 섞어 적용하지 마세요.

상품별 운영 기록표를 남기고 마칩니다

아래 표를 상품마다 복사해 한 번의 진단을 닫습니다. 빈칸이 남아 있으면 “수정 완료”가 아니라 “추가 확인 필요”로 표시합니다.

| 기록 항목 | 작성 예시 형식 |
| — | — |
| 상품 URL·확인 시각 | `https://example.com/product/…` · 2026-08-02 14:00 KST |
| 선택 옵션 | 색상/사이즈/용량 또는 기본 옵션 |
| 화면 기준값 | 가격·통화·재고·평점·리뷰 수 |
| canonical | 화면 URL과 같음/다름 |
| JSON-LD 차이 | `price`, `availability`, `aggregateRating` 등 |
| Rich Results Test | 오류 0 / 경고 / 실패와 검사 URL |
| Search Console | Merchant listings 또는 Product snippets 상태 |
| 피드 확인 | 미사용/동일/불일치와 확인 시각 |
| 다음 담당자·행동 | 템플릿 수정, 상품 데이터 수정, 재수집 확인 등 |

마지막으로 “페이지에 보이는 값”을 다시 읽습니다. 가격과 재고가 고객 화면에서 바뀌지 않았거나 리뷰 집계 범위가 설명되지 않는다면 JSON-LD가 유효해도 글을 닫지 않습니다. 구조화 데이터의 품질은 코드 블록의 길이가 아니라 상품 페이지와 검색엔진에 설명하는 값이 한 상품을 가리키는지로 판단해야 합니다.

자사몰 상품 구조화 데이터 자주 묻는 질문

구조화 데이터 테스트가 통과하면 검색 상위에 올라가나요?

아닙니다. 테스트 통과는 특정 리치 결과의 기술적 조건을 확인했다는 뜻입니다. Google이 실제 검색결과에 어떤 기능을 표시할지, 어느 위치에 노출할지, 언제 다시 수집할지는 별개의 처리 결과입니다. 이 글에서는 상위 노출이나 매출을 보장하지 않습니다.

Product snippets와 Merchant listings 중 하나만 보면 되나요?

판매 가능한 상품 상세라면 Merchant listings 관점을 먼저 확인하고, 상품 정보·리뷰 중심 페이지라면 Product snippets 관점도 봅니다. 사이트가 두 유형의 페이지를 모두 운영한다면 보고서와 URL을 나누어 기록하는 편이 안전합니다.

다른 옵션의 리뷰를 상품군 전체에 합쳐도 되나요?

상품 페이지에 실제로 어떤 범위의 리뷰가 표시되는지 먼저 확인해야 합니다. 상품·변형·상품군의 관계가 설명되지 않거나 다른 상품 리뷰를 가져온 것이라면, 숫자가 많다는 이유로 `AggregateRating`에 합치는 방식은 피해야 합니다. 상품 구조와 리뷰 정책이 애매하면 마크업 추가보다 데이터 출처를 먼저 정리하세요.

가격만 바뀌었는데 구조화 데이터를 다시 점검해야 하나요?

네. 가격 변경이 할인 종료일, 통화, 옵션별 Offer, 피드 값과 함께 바뀌는지 확인해야 합니다. 특히 행사 종료 뒤 `priceValidUntil`과 화면 가격이 서로 다른 상태로 남지 않았는지 보세요.

개발자에게 무엇을 전달하면 가장 빠른가요?

상품 URL, 확인 시각, 선택 옵션, 화면 캡처, JSON-LD에서 다른 필드, Rich Results Test 결과, 해당 보고서 이름을 한 묶음으로 전달하세요. “검색에 안 나옵니다”보다 “이 URL에서 화면은 29,000원인데 `Offer.price`는 25,000원이고 `priceValidUntil`이 지났다”가 훨씬 작은 수정 단위입니다.

이 콘텐츠는 AI 도구를 활용해 공개된 자사몰 운영 데이터·플랫폼 가이드·사례를 정리한 것입니다.