◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SONNET 4.5 — Claude API での提供終了は 11/30、残り26日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SONNET 4.5 — Claude API での提供終了は 11/30、残り26日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/ビジネス
⟐ ビジネス/2026-06-14上級

海外ユーザーに「$3.99」をそのまま見せない — Rork Max の課金画面を StoreKit 2 で多通貨・多言語に整える

Rork Max が生成するネイティブアプリの課金画面を、価格をハードコードせず StoreKit 2 の displayPrice に任せて多通貨・多言語へ正しく対応させる実装を整理します。月額と年額の「お得感」を通貨ごとに破綻なく出す計算や、為替変動・地域価格で起きる本番のズレも実例で解説します。

Rork Max235StoreKit 217ペイウォール3ローカライズ7多通貨サブスクリプション66

✦ プレミアム記事

個人開発のアプリが少しずつ海外で使われ始めたとき、最初に恥ずかしい思いをしたのが課金画面でした。日本で作ったまま「月額 480 円」と数字を直接書いていたため、米国のユーザーには通貨記号も金額もちぐはぐに見えていたのです。App Store は国ごとに価格を持っているのに、アプリの表示がそれを無視していました。

Rork Max が生成するのはネイティブの Swift アプリなので、課金は StoreKit 2 で素直に書けます。そして StoreKit 2 を正しく使えば、価格の表示は Apple に任せられます。ここでは、価格をハードコードしないペイウォールの作り方を起点に、年額の「お得感」を通貨ごとに破綻なく出す計算や、本番で必ず遭遇する地域価格・為替のズレへの向き合い方まで整理します。

なぜ価格を自分で書いてはいけないのか

StoreKit 2 の Product は、ユーザーのストアフロントに応じた価格と通貨をすでに知っています。product.displayPrice は「¥480」「$3.99」「€4,49」のように、その地域の表記・記号・桁区切りまで整った文字列を返します。これを自分で "¥\(price)" のように組み立てた瞬間、ヨーロッパの小数点(カンマ区切り)や通貨記号の位置がすべて壊れます。

私はここで一度痛い目を見ました。価格を数値でハードコードしていたため、Apple 側で地域価格を調整したのに、アプリの表示は古いままという二重管理に陥ったのです。原則はひとつ、価格に関する文字列は StoreKit が返すものだけを表示する、です。

Step 1: 商品を読み込み、displayPrice をそのまま出す

まず商品を取得します。プロダクト ID は App Store Connect で設定したものを使います。

import StoreKit
 
@MainActor
final class PaywallModel: ObservableObject {
    @Published var products: [Product] = []
 
    func load() async {
        do {
            // ID は App Store Connect で定義したもの
            let ids = ["pro_monthly", "pro_yearly"]
            let fetched = try await Product.products(for: ids)
            // 月額→年額の順に安定ソート
            products = fetched.sorted { $0.price < $1.price }
        } catch {
            print("product load failed: \(error)")   // 本番では UI に再試行導線を出す
        }
    }
}

表示側では displayPrice をそのまま使います。

ForEach(model.products) { product in
    VStack(alignment: .leading) {
        Text(product.displayName)
        Text(product.displayPrice)          // ← 自前整形しない。これが全通貨対応の核
            .font(.title2).bold()
    }
}

この displayPrice だけで、円・ドル・ユーロ・ウォン、どの地域から見ても正しい表記になります。自分のコードに通貨記号が一文字も出てこないのが、正しく書けている合図です。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦価格を一切ハードコードせず、StoreKit 2 の displayPrice をそのまま表示して全通貨に自動対応する SwiftUI の実装が手に入る
✦年額が月額より何%お得かを、通貨やロケールが変わっても破綻せずに計算・表示する具体的なロジックが分かる
✦地域価格や為替変動で「数字が合わない」と問い合わせが来る本番の落とし穴を、私自身の対処の判断基準とともに回避できる
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⟐ ビジネス2026-10-01
すでに「有効」になっている複数シート購入を、10月22日の前に残すか外すか決める
App Store Connect で9月16日から既定で有効になった複数シート購入。10月22日の Volume Purchasing 開始前に、個人開発のサブスクで残すか外すかを4つの問いで決め、権限判定のコードと記録の残し方まで整理します。
⟐ ビジネス2026-05-05
Rork Max × RevenueCat Paywalls SDK で変わるペイウォール開発 — A/B テスト・リモート更新・コンバージョン改善の実装ガイド
RevenueCat Paywalls SDK を Rork Max アプリに統合し、審査なしでペイウォールをリモート更新・A/B テストする実装ガイド。コンバージョン率を改善するデザイン原則と実践コード、必要なサンプル数の計算までをまとめます。
⟐ ビジネス2026-05-03
Rork Max でリリースしたアプリの収益化フロー設計 — オファーコード・ウィンバック・プッシュ通知連動の実装
Rork Max でリリースしたアプリの継続課金を伸ばすために、オファー署名・ウィンバック判定・プッシュとメールの連動を StoreKit 2 と Google Play Billing の両方で実装します。署名のタイムスタンプ単位など、動いて見えて通らない箇所を公式仕様で確かめ直しました。