はじめに
私はFinTech・暗号資産業界で8年以上、オペレーションやプロダクト業務に関わってきました。
一方で、私は伝統的な意味でのソフトウェアエンジニアではありません。
それでも今回、AI-assisted workflowを活用しながら、海外送金・FX・暗号資産・ステーブルコインのルートを比較するプロダクト TransferIQ を企画し、Web版とAndroid版まで公開しました。
使用した主な技術は以下です。
- React Native
- Expo
- JavaScript
- Supabase
- REST API
- Netlify
- GitHub
この記事では、単なる「作ってみた」ではなく、実際にMVPを作る過程で特に難しかった設計上のポイントを5つ共有します。
1. 「手数料比較」ではなく「最終受取額比較」にする
最初に考えたのは、送金サービスの手数料を一覧表示することでした。
しかし、実際に比較を始めると、すぐに問題が見つかりました。
例えば、同じ1,000 USDを送金する場合でも、以下の条件によって結果が変わります。
- 送金手数料
- FXスプレッド
- 支払方法
- 受取方法
- 金額帯
- 国別条件
単純化すると、例えば次のようなケースがあります。
Provider A
- Fee: 5 USD
- FX Rate: 1 USD = 4.90 BRL
- Final Receive: 4,875 BRL
Provider B
- Fee: 10 USD
- FX Rate: 1 USD = 4.98 BRL
- Final Receive: 4,930 BRL
手数料だけを見ると、Provider Aの方が安く見えます。
しかし、最終的な受取額を見ると、Provider Bの方が多く受け取れる可能性があります。
この経験から、比較の中心を「手数料」から「推定最終受取額」に変更しました。
つまり、ユーザーにとって本当に重要なのは、
いくら払うか
だけではなく、
最終的にいくら受け取れるか
だと考えました。
これはTransferIQの設計で最も重要な判断の一つでした。
2. 共通FX Benchmarkを1つ持たないと比較結果が壊れる
次に問題になったのが、FX基準値です。
例えば送金サービスA、B、Cを比較する時に、それぞれ異なるタイミング、異なるAPI、異なる基準レートを使うと、公平な比較になりません。
あるProviderだけ古いレートを使い、別のProviderだけ新しいレートを使っていれば、UI上では比較できているように見えても、実際には基準が揃っていません。
そこで、まず共通のFX benchmarkを持つ構造にしました。
概念的には以下のような形です。
const midMarketRate = 5.20;
const providers = [
{
name: "Provider A",
fee: 5,
spread: 0.012,
},
{
name: "Provider B",
fee: 8,
spread: 0.006,
},
];
Providerごとの概算レートは、例えば次のように計算できます。
function estimateProviderRate(midRate, spread) {
return midRate * (1 - spread);
}
さらに、最終受取額の簡略モデルは次のようになります。
function estimateReceiveAmount({
sendAmount,
fee,
midRate,
spread,
}) {
const netSendAmount = sendAmount - fee;
const providerRate = midRate * (1 - spread);
return netSendAmount * providerRate;
}
もちろん、実際のサービスではこれだけでは足りません。
さらに以下のような要素を考慮する必要があります。
- fixed fee
- variable fee
- amount band
- corridor adjustment
- payout method
- payment method
- dynamic pricing
重要なのは、各サービスを比較する前に、共通のBenchmarkを1つ持つことでした。
これがないと、UI上はきれいでも比較ロジック自体が不公平になります。
私はこの部分を作りながら、比較サービスでは「データをたくさん集めること」よりも、「何を共通基準にするか」の方が重要な場合があると学びました。
3. 「Live API」と表示してはいけないデータがある
これはかなり重要な学びでした。
最初は、外部データを使っているため、
- Live API
- Official API
- Official Rate
のようなラベルを付けたくなります。
しかし実際には、すべての送金会社が一般公開されたリアルタイムQuote APIを提供しているわけではありません。
また、公開市場データとProvider固有のQuoteは全く別のものです。
そこで、データの性質を明確に分離することにしました。
現在は例えば、以下のように区別しています。
- Live exchange market
- Provider benchmark
- Market benchmark
- Variable pricing
- P2P pricing
- Crypto only
公開取引所の市場データと、Providerのベンチマーク推定値は同じものではありません。
市場基準値とP2P価格推定も同じではありません。
そのため、UIでも同じラベルにしないようにしました。
JavaScript上では、例えば次のようにデータタイプを分けられます。
const DATA_BADGE_TYPES = {
LIVE_MARKET: "Live exchange market",
PROVIDER_BENCHMARK: "Provider benchmark",
MARKET_BENCHMARK: "Market benchmark",
VARIABLE_PRICING: "Variable pricing",
P2P_PRICING: "P2P pricing",
CRYPTO_ONLY: "Crypto only",
};
この設計変更は、単なるUI改善ではありません。
主な目的は以下です。
- ユーザーの誤解を減らす
- データの性質を正直に伝える
- 推定値と市場データを区別する
- プロダクトへの信頼を守る
特にFinTech領域では、
どのデータがリアルタイムなのか
どのデータが推定なのか
どのデータがProvider固有のQuoteなのか
を明確にする必要があると学びました。
便利に見せるために強い表現を使うより、データの限界を正直に表示する方が重要だと考えています。
4. FiatとCryptoを同じ比較エンジンに入れるとUXが複雑になる
TransferIQでは、Fiat-to-Fiatだけでなく、以下のルートも扱いたいと考えました。
- Remittance
- FX
- Crypto
- Stablecoin
- P2P
- Crypto-to-Crypto
しかし、ここでUI設計が急に複雑になりました。
例えば、
USD → BRL
と、
USDT → BTC
は全く異なる比較です。
前者では、ユーザーは法定通貨を送って法定通貨を受け取ります。
そのため、重要なのは、
- Sending Currency
- Receiving Currency
です。
一方、後者では暗号資産同士を交換します。
そのため、
- Sending Coin
- Receiving Coin
という表現の方が自然です。
そこで、モードによって入力ラベルを切り替える必要がありました。
概念的には次のような実装です。
const isCryptoMode = mode === "crypto";
const fromLabel = isCryptoMode
? "Sending coin"
: "Sending currency";
const toLabel = isCryptoMode
? "Receiving coin"
: "Receiving currency";
さらに、Crypto Convertではフィルタの意味も重要でした。
例えば、
USDT → BTC
の場合、ユーザーが最終的に受け取るのはBTCです。
そのため、結果画面のコインフィルタは「送信コイン」ではなく「最終受取コイン」を基準にした方が自然です。
一見すると小さな違いですが、ユーザーの操作感は大きく変わります。
FiatとCryptoを同じ画面に入れる場合、単純に通貨コードだけ置き換えるのでは不十分でした。
ユーザーが、
- 何を送るのか
- 何を受け取るのか
- どの市場を比較しているのか
- 最終結果がFiatなのかCryptoなのか
を明確に理解できる必要があります。
この部分は、実際に作ってみて初めて複雑さを実感したポイントでした。
5. AI-assisted developmentでも「仕様を決める人」は必要
今回の開発ではAIをかなり活用しました。
私は伝統的なソフトウェアエンジニアではないため、AI-assisted workflowは非常に重要でした。
AIは、例えば以下のような作業を高速に支援できます。
- コンポーネント作成
- UI修正
- エラー調査
- API接続コードの作成
- 条件分岐の修正
- リファクタリング
- 多言語テキストの整理
しかし、実際にやってみて分かったのは、
AIにコードを書かせること
と、
正しいプロダクトを作ること
は別問題だということです。
例えば、次のような判断は人間側に残ります。
- 何を比較するのか
- 何を比較しないのか
- どのデータを信頼するのか
- どの表現が誤解を生むのか
- どの機能を削るのか
- MVPで何を優先するのか
- どの問題を今は解かないのか
実際、TransferIQでも何度も仕様変更をしました。
例えば、「Official API」という表現を削除しました。
理由は、すべてのProviderについて公式リアルタイムQuote APIを直接利用しているわけではないからです。
また、単純なFee比較ではなく「Final Receive Amount」を比較の中心に変更しました。
Crypto Convertでも、フィルタの意味を「送信コイン」ではなく「最終受取コイン」に変更しました。
AIはコード生成を加速してくれます。
しかし、以下の判断は依然として非常に重要です。
- Product Decision
- Data Definition
- Risk Judgment
- UX Priority
AI-assisted developmentであっても、最終的に「何を作るか」を決める役割は必要だと感じました。
むしろAIによって実装速度が上がるほど、間違った仕様も速く作れてしまいます。
そのため、Product Decisionの重要性は下がるのではなく、逆に上がる可能性があると考えています。
現在のアーキテクチャ
非常に簡略化すると、現在の構造は以下のようなイメージです。
- React Native / Expo App
- Comparison Logic
- FX Benchmark / Crypto Market / Provider Models
- Estimated Route Results
- Official Provider Quote Page
比較ロジックでは、異なる性質のデータをできるだけ分離して扱います。
例えば、
- FX benchmark
- Public crypto market data
- Provider benchmark
- Variable pricing model
- P2P pricing
などです。
そして最終的に、ユーザーには推定されたRoute Resultsを表示します。
重要な原則は次の3つです。
- No custody
- No payment execution
- No firm quote
つまりTransferIQ自体は、
- ユーザー資金を保管しない
- 送金を実行しない
- 最終確定Quoteを提供しない
という設計です。
基本コンセプトは、
Estimate first. Official quote before sending.
です。
ユーザーはまず異なるルートを比較し、その後、実際に送金や取引を行う前に公式ProviderまたはExchangeで最終Quoteを確認します。
今後改善したいこと
現在、特に改善したいのは次の領域です。
- 実際の受取額データの精度向上
- Provider別データ品質の可視化
- Corridor別の比較精度向上
- Stablecoin off-ramp routeの拡張
- より多くの実ユーザーフィードバック収集
今後、実際のQuoteや受取結果に近いデータをさらに蓄積できれば、単純な手数料比較ではなく、
- Route quality
- Final receive amount
- Corridor differences
- Payout options
- Data confidence
まで含めた比較に近づけると考えています。
最終的には、単純な「手数料比較」ではなく、より広い意味での Route Intelligence に近いものを目指しています。
おわりに
非エンジニア出身でも、AI-assisted workflowを使えば実際のプロダクトを作ることは可能です。
今回、私は企画、UX、データ構造、比較ロジック、アプリ開発、Web公開、Google Playリリースまで進めました。
ただし、AIだけでは解決しない問題も多くありました。
特に重要だったのは以下です。
- データ定義
- 比較基準
- UX設計
- 表現の正確性
- 仕様の優先順位
AIは「作る速度」を上げてくれます。
しかし、「何を作るべきか」「何を表示すべきではないか」を決める役割は依然として必要です。
今回作ったプロジェクトはこちらです。
- Web: https://transferiq.org
- GitHub: https://github.com/jkim1285/TransferIQ
- Android: https://play.google.com/store/apps/details?id=com.jkim1285.TransferIQMobile
現在も改善を続けています。
特に以下の分野に関心がある方の技術的なフィードバックを歓迎します。
- 海外送金比較
- FX
- Crypto
- Stablecoin
- P2P
- React Native / Expo
- AI-assisted development