はじめに
この記事は バイセルテクノロジーズ Advent Calendar 2024の3日目の記事です。前日の記事は藤澤さんの「少数精鋭でユーザーの信頼を勝ち取る!大規模リリースを乗り越えるためのシステム監視とユーザーサポート」でした。
こんにちは、テクノロジー戦略本部 開発1部の尾沼です。
先日、私たちはバイセルリユースプラットフォームの出品管理基幹システム「EXS」をリリースしました。中古商品を大量に、効率的に複数のモールへ出品することを通じてバイセルのEC販売事業を支えています。
現在、EXSが連携しているECモールのほとんどは国内のものです。しかし、海外ECモールとして唯一、eBayとの連携をしています。 eBayのBUYSELL brandchéeはバイセルの商品を世界に届ける上で重要な存在であり、EXSとの連携は必須であったわけでありますが、連携を進める上でいくつか壁がありました。
本記事では、国内ECモール連携を前提としたシステムが、eBay連携を実現する際に直面した問題/課題と、その解決策についてご紹介します。eBay以外の海外モールへの連携にも共通していえる内容となっていますので、ぜひご覧ください。
EXSとは
本題に入る前に、前提となるEXSについて紹介します。
EXSは複数のECモールへの出品・受注業務を一元管理するWebアプリケーションです。
あらかじめEXSに保持しておいた商品情報や在庫情報を正として、連携先モールに出品できます。
もし連携しているいずれかのECモールで商品が売れた場合、そのECモール上に作られた注文データを、EXSに自動で取り込むことができます。 そして、受注された商品は、他の併売中のECモールから在庫を減らして売り切れにします。中古商品を複数のお客様に販売することはできないからです。
注文データの取り込み後、商品発送に至るまでに必要な業務を行うこともできます。
このように、EXSに商品データさえ取り込んでしまえば、ECモール販売にまつわるあらゆることを効率的に行うことができます。
詳しいプロダクトの要件や技術スタックについては、先日公開された早瀬さんの「3年間に及ぶ新規プロダクト開発の技術選定の振り返り」をご覧ください。
国内モールと海外モール(eBay)の違い
国内モール連携の特徴
EXSが連携している国内のECモールは、おおまかに見ると同じ構図をしています。
- ECモール上のお客様の多くは日本語話者で、日本在住
- 日本円で取引する
- 繁忙期や、アクセス集中時間も日本の暦やタイムゾーンに準拠
- 返品や発送といった商品の取引も日本国内に閉じている
バイセルを例にしてみると以下のような取引となっています。
そして、EXSは上記のような特徴をもつ日本国内のECモール連携が主軸であるため、データ構造や連携処理などはすべて、日本のモールに適したものとなっていました。
eBay連携の特徴
一方、eBayは世界中で展開されているグローバルなECモールです。
eBayというプラットフォームが、世界各所にマーケットプレイスと呼ばれる領域をもっています。マーケットプレイスごとに流通通貨や公用語、顧客のマス層の国籍が異なっており、そのマーケットプレイスがあるエリアに最適化された状態となっています。しかし、eBayというECモールであることには変わりはないので、システム的にはマーケットプレイスに関わらず類似の点が多いといった点が特徴的です。
世界的に展開しているECモールであれば、似たような構図になっているかと思います。
バイセルはeBay USのマーケットプレイスに、店舗であるBUYSELL brandchéeを構えています。他のマーケットプレイスには出店していません。したがって、EXSにおけるeBay連携とは、現状ではeBay US連携という意味になります。EXSからの連携先のマーケットプレイスを簡単に増やせるようにしておけば、eBayというプラットフォーム上でより多くの国へと販路拡大ができます。
こういった構図の違いにより、国内モール連携を前提とした作りとなっていたEXSでは、工夫をしなければeBayに連携できない状態でした。
eBay連携で直面した問題とその解決策
先述したような構図の違いのあるeBayへの連携なので、様々な問題が起きました。特に、システムのローカライゼーションの際に詰まった点が多くありました。
- 通貨
- タイムゾーン
- 配送
- 言語
- 単位系
今回は代表的なものにしぼって紹介します。
多言語対応をどうおこなうか
問題の詳細
EXSがこれまで連携していた国内ECモールでは、「ドメイン全体で公用語が日本語である」ことが当然の前提でした。EXSでの商品データも日本語で保持しており、EXSと国内ECモールで使用言語が日本語で統一されていました。これによる利点は以下の通りです。
- EXSのユーザーや開発者は、慣れた日本語で考え、商品情報として入力ができる
- 各モールごとに文章の体裁を少し調整するだけで、国内モールへの出品が可能
しかし、eBayの場合は状況が異なります。「ドメイン全体での公用語がマーケットプレイスに依存する」ため、具体的には以下のような問題が発生しました。
- eBay USに出品するために、すべての商品情報を英語で連携しなければならなくなった
- 事業の拡大により、将来的にeBay US以外の海外ECモールにも出品する可能性がある。そのため、非英語圏かつ非日本語圏のお客様にも対応できるよう、他言語での出品も視野にいれなければならない
- 海外のお客様が違和感を覚える表現では販売機会の損失につながる。そのため、専門用語を含め、原文の意味を損なわないようにしつつ、自然な翻訳を商品説明文に対して行う必要がでてきた
これらの問題を解決するために、以下の2つの課題の解決を目指し、策を考えました。
- 特定の言語に縛られない処理にする
- 原文の意味を損なわずに自然な翻訳を実現する
解決策
今回は、eBayへの出品リクエストを送る直前に、日本語の商品情報をDeepLで翻訳する形式を採用し、課題を解決しました。
「特定の言語に縛られない処理にする」について、次のようにすることで実現できると考えました。
- 保持する商品データの言語自体は多言語対応せずに、日本語で一貫させておく
- 機械翻訳で翻訳先言語を柔軟に指定できるようにしておく
EXSは国内ECモール連携がベースであり、商品データの入稿者も日本語話者です。そのため、英語のデータも別で保持するといった二重管理化の変革はせずに、日本語中心の作りを維持しておくことが、影響範囲や今後の運用コストが少なく良いと考えました。そして機械翻訳ならば、翻訳APIへ渡すパラメータを変えるだけで翻訳先の言語を容易に制御できるため、拡張性が高いと考えました。
「原文の意味を損なわずに自然な翻訳を実現すること」について。この観点でのみ考えた場合、理想は英語話者による商品データの入稿や校閲を入れることだと思います。しかし、人間に依存してしまうとバイセルの出品商品数の増加や事業拡大の可能性に対応しきれない可能性がありますし、マルチリンガルな人材でない限り、「特定の言語に縛られない処理にする」に抵触します。したがって、やはり本観点においても、検討する手段として機械翻訳が適切でした。専門用語がうまく訳せず、原文の意味を損なった翻訳結果になる懸念についても、あらゆる機械翻訳サービスが提供する「用語集」と呼ばれる機能を使えば払拭できると考えました。用語集に特定の単語の訳し方を事前に登録しておくことで、専門用語などを意図した通りに翻訳させることが可能です。
そして、チームで複数の機械翻訳APIを精査し、DeepLが最も期待する翻訳精度をだすと判断し、採用しました。
メートル法 vs ヤード・ポンド法
問題の詳細
国内モールのメインユーザーである日本人はメートル法を使用します。EXSに保持している数値のデータも、尺度はメートル法を前提とした値となっています。しかし、eBay USのメインユーザーたるアメリカ人にとってはヤード・ポンド法が主流です。したがって、「商品のサイズや重量をメートル法のまま出品すると、商品説明を見ても購入者にとって直感的に理解しづらく、購買意欲を下げる恐れがある」という問題が発生しました。
本問題を解決するための課題は以下でした。
- 商品説明文の組み立て時に、メートル法の値が登場したらヤード・ポンド法への単位変換を行う
解決策
この課題には、テンプレートエンジンの機能を活用して対応しました。EXSはGoで開発されているアプリケーションなので、標準ライブラリであるtext/template が具体的に用いたものとなります。これを使うと、指定した箇所のデータを柔軟に差し替えた上で、文字列の生成を行うことができます。
商品説明文は、その商品のデータを上手く組み合わせたり、加工したりして作成します。この加工の処理として、ヤード・ポンド法への単位変換を入れ込むことができれば課題が解決できます。
例えば、商品の「横幅」のデータを、メートル法固定で商品説明文に登場させるとします。text/templateを用いて出力するならば、以下のようなコードになります。
package main import ( "os" "text/template" ) func main() { itemData := map[string]any{ "横幅": 30, // 単位はcm } // 商品説明文のテンプレート description := "横幅は{{ .横幅 }}cm" tmpl, err := template.New("item").Parse(description) if err != nil { panic(err) } // 商品説明文の生成実行 if err := tmpl.Execute(os.Stdout, itemData); err != nil { panic(err) } }
上記を実行すると、{{ .横幅 }}
の部分が30に置換された上で出力されることがわかります。
メートル法からヤード・ポンド法への単位変換を入れ込むことは、text/templateのFuncMapを利用することで実現できます。FuncMapとは、任意の関数の呼び出し結果を置換結果として使用できるようにする機能です。
実際にメートル法からヤード・ポンド法へ変換するFuncMapを定義した上で、試してみると以下のようなコードとなります。
package main import ( "fmt" "math" "os" "text/template" ) func main() { funcMap := template.FuncMap{ // センチメートルをインチに変換する関数 "センチメートルをインチに変換": func(src int) string { // センチメートルをインチに変換(1センチメートル = 0.3937007874インチ) inches := float64(src) * 0.3937007874 // 小数点第1位で四捨五入 roundedInches := math.Round(inches*10) / 10 return fmt.Sprintf("%.1f", roundedInches) }, } itemData := map[string]any{ "横幅": 30, // 単位はcm } // 商品説明文のテンプレート description := "横幅は{{ センチメートルをインチに変換 .横幅 }}inch" // FuncMapを登録 tmpl, err := template.New("item").Funcs(funcMap).Parse(description) if err != nil { panic(err) } // 商品説明文の生成実行 if err := tmpl.Execute(os.Stdout, itemData); err != nil { panic(err) } }
上記を呼び出すと、30cmだった「横幅」が11.8インチに変換されて出力されることがわかります。
このように、text/templateとその機能であるFuncMapを組み合わせることで、商品説明文中でヤード・ポンド法に変換したい箇所だけを変換し、商品情報に入れ込むことができました。
通貨が異なる
問題の詳細
EXSは国内ECモール連携が前提の作りとなっていました。当たり前のこととして、「ドメイン全体にて、通貨が日本円」でした。
円建てで完結することで得られる恩恵とは、例えば以下となります。
- 為替レートが登場しない
- コンテキストスイッチが発生しない
- データベース、アプリケーション、ECモール、その他取り巻く箇所全てにおいて、価格を考える際に常日頃から慣れている日本円の意識のままでいられる
これがeBayだと「ドメイン全体にて、通貨が非日本円」となります。これによって、以下のような問題が発生しました。
- eBay USに出すため、すべて米ドルで出品しないといけなくなった
- 事業次第では、将来的にeBay US以外の海外ECモールに出品する可能性もある。したがって、米ドル以外の通貨でも出品できるよう、拡張の余地が必要
- 価格変換が必要になるたびに、どのタイミングのレートを使用するかを考えなければならない
これらの問題を解決するために、以下の2つの課題の解決を目指し、策を考えました。
- 処理それぞれで、いつの時点の為替レートを使うかを決める
- 通貨が特定の通貨に縛られないようにする
解決策
1日1回為替レート取得APIを用いて為替レートを取得、保存し、その日1日のEXSの公式為替レートとすることで、課題を解決しました。
為替レートは常に変動しています。 リアルタイムの為替レートを使用する場合のデメリットは以下です。
- システム負荷が高まる
- 商品の価格を見ても、いつ時点の為替レートで変換されたものなのかわかりにくい
逆に、過去のレートを使用すると以下のようなデメリットがあります。
- 価格が市場と乖離する可能性がある
どのタイミングを選んでも、何かしらの懸念は残ります。したがって、「処理それぞれで、いつの時点の為替レート使うか」に対する対策としては、事業的な影響を考えた上で、一番当たり障りのない頻度で更新される為替レートを使うのが良いと判断しました。EXS公式の為替レートを定義し、当たり障りのない頻度として、1日1回更新します。システム内での処理では、常に最新のEXS公式為替レートを使用するように統一し、処理によって適用される為替レートが異なるといった事態は発生しないようにすることにしました。
為替レートAPIとしては、Open Exchange Rates を採用しました。複数通貨に対応しており、「通貨が特定の通貨に縛られないようにする」という観点に対して適しています。また、私たちがまず連携するのはeBay USであり、そのためには日本円と米ドルの対応ができていれば良いです。当該APIはフリープランでも、米ドル → 他通貨 の変換が可能なため、低コストで需要を満たせるという点でも良いと考えました。
以上より、システムの負荷を抑えつつ、為替変動による価格のズレを許容できるラインで課題を解決することができました。
まとめ
国内ECモール連携を前提として設計されたシステムを、グローバルなECモールであるeBayに連携させるにあたり、言語、単位系、通貨をはじめ多くの問題に直面しました。しかし、技術レベルでの工夫や仕様レベルでの調整を駆使して、円滑な連携を実現することができました。
海外ECモールへの連携を検討している方にとって、少しでも役に立てたら幸いです。
最後に、バイセルでは一緒に働くエンジニアを募集しています、興味がある方は、以下よりご応募ください。 herp.careers
明日の バイセルテクノロジーズ Advent Calendar 2024 は 野口さんによる 「ハッシュベースの楽観ロックで解決する編集画面の整合性問題」です。お楽しみに!