RORK LABEN
MAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまでを対象にしますAPIS — SwiftUI・ARKit・HealthKit・HomeKit・Core ML・MetalといったネイティブAPIに手が届き、AR/LiDARスキャンやオンデバイス機械学習も扱えますCLOUD — Swiftコードを書き、クラウド上のMacでコンパイルし、実機タッチ入力に対応したライブシミュレータをストリーミングしますSUBMIT — 実機インストール用、あるいはApp Store提出用のビルドまで用意されますSEED — Rorkは4月にLeft Lane Capital主導の$15Mシードを調達しました。Peak XVとa16z Speedrunも参加していますPRICE — 無料で始められ(週5プロンプト前後)、有料プランは$25/月から。Rork Maxは$200/月ですMAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまでを対象にしますAPIS — SwiftUI・ARKit・HealthKit・HomeKit・Core ML・MetalといったネイティブAPIに手が届き、AR/LiDARスキャンやオンデバイス機械学習も扱えますCLOUD — Swiftコードを書き、クラウド上のMacでコンパイルし、実機タッチ入力に対応したライブシミュレータをストリーミングしますSUBMIT — 実機インストール用、あるいはApp Store提出用のビルドまで用意されますSEED — Rorkは4月にLeft Lane Capital主導の$15Mシードを調達しました。Peak XVとa16z Speedrunも参加していますPRICE — 無料で始められ(週5プロンプト前後)、有料プランは$25/月から。Rork Maxは$200/月です
記事一覧/開発ツール
開発ツール/2026-07-16上級

生成された課金コードを Sandbox の前に検証する — SKTestSession で返金・失効・購入失敗を自動テストする

Rork Max が生成した StoreKit 2 のコードは、買えることは確かめられても、返金・失効・購入失敗までは確かめられません。StoreKitTest の SKTestSession で、これらのエッジケースを Sandbox に入る前に自動テストする実装をまとめます。

StoreKit 216StoreKitTestSKTestSessionRork Max225テスト7課金8

プレミアム記事

Rork Max が吐き出した購入処理を初めて読んだとき、目が止まったのは Transaction.currentEntitlements を舐めて Bool を返す、十数行の関数でした。読む限り、間違っていません。実際に買えば、ちゃんと機能が開きます。

困ったのは、その先を確かめる手段のほうでした。返金されたら何が起きるのか。更新に失敗したら何が起きるのか。Sandbox アカウントを作って、購入して、1ヶ月待つ。そういうわけにもいきません。

個人開発で課金まわりが怖いのは、バグが「動かない」形で出てこないからです。買えている人の画面には何も起きません。壊れているのは返金された数人の権利だけで、その数人は何も言わずに離れていきます。

StoreKitTest は、この空白を埋めるために Apple が用意したフレームワークです。App Store を呼びに行かず、端末の中に閉じた偽の App Store を立てて、返金も失効も自分の手で起こせます。

Sandbox に入る前に落とせるバグがある

課金の検証というと Sandbox から始めがちですが、Sandbox は「Apple のサーバーと正しく話せるか」を見る場所です。「自分のコードが状態変化に正しく反応するか」を見る場所ではありません。

この2つを混ぜると、確認したいことに対して手続きが重すぎます。返金を1回試すために、Sandbox アカウントを作り、購入し、App Store Connect から返金を発行し、通知が届くのを待つ。1シナリオに数十分かかり、しかも失敗したときに原因がコードなのか環境なのか切り分けられません。

StoreKitTest が担うのは前者ではなく後者です。ネットワークもサーバーも出てきません。テストプロセスの中で完結します。

私はこの2つを、次のように分けて考えています。

確かめたいこと使う場所1回あたりの手間
返金されたら権利が消えるかSKTestSession数百ミリ秒
期限が切れたら権利が消えるかSKTestSession数百ミリ秒
購入失敗を握り潰していないかSKTestSession数百ミリ秒
署名検証がサーバーで通るかSandbox数分
サーバー通知が届いて処理されるかSandbox数分〜
実際の請求と価格表示が合うかSandbox / 本番数分〜

上3行は Sandbox でもできますが、やる意味が薄い作業です。下3行は SKTestSession では絶対にできません。境界はここに引くのが現実的だと考えています。

StoreKitTest は端末の中に偽の App Store を立てます

必要なのは .storekit の Configuration ファイルと、テストターゲットでの import StoreKitTest です。Configuration ファイルは Xcode で作れますが、Rork Max で生成したプロジェクトなら App Store Connect の商品定義から同期させるのが早い方法です。

SKTestSession を作った瞬間から、そのプロセス内の StoreKit 2 API はすべてこのセッションを向きます。Product.products(for:)Transaction.currentEntitlements も、Apple ではなくセッションが答えます。

import XCTest
import StoreKit
import StoreKitTest
@testable import MyApp
 
final class EntitlementTests: XCTestCase {
    var session: SKTestSession!
 
    override func setUpWithError() throws {
        try super.setUpWithError()
        // Products.storekit をテストターゲットに含めておきます
        session = try SKTestSession(configurationFileNamed: "Products")
 
        // 購入確認ダイアログを出さない。出すとテストが人間の指を待ち続けます
        session.disableDialogs = true
 
        // 前のテストのトランザクションを持ち越さない
        session.clearTransactions()
        session.resetToDefaultState()
    }
 
    override func tearDownWithError() throws {
        session = nil
        try super.tearDownWithError()
    }
}

disableDialogsclearTransactions() は、忘れると必ず痛い目を見る2行です。前者を落とすとテストがダイアログの前で固まり、後者を落とすと前のテストで買った購読が次のテストに漏れて、原因の分からない成功が出ます。テストが「なぜか通る」ときは、だいたいここです。

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

この記事の続きを読む

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

この記事で得られること
「買えることは確認したが返金と失効は未検証」という状態の人が、返金・期限切れ・購入失敗を数秒で再現する動く XCTest を今日手に入れられる
SKTestSession の timeRate・expireSubscription・refundTransaction・setSimulatedError を使い、Sandbox で1ヶ月かかる更新シナリオを1テストに畳み込む書き方を習得できる
生成コードが最も落としやすい返金経路の穴を塞ぎ、$99 の Apple Developer Program 契約前でも課金ロジックを検証できる状態になれる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

開発ツール2026-05-02
Rork のサブスクリプションを Sandbox でテストする実践 — Apple/Google で詰まる箇所と検証手順
Rork で実装したサブスクリプションを Sandbox 環境でテストする際の落とし穴を、Apple/Google の両側から実装コード付きでまとめました。本番ビルド前に必ず潰しておきたい検証ポイントを順序立てて確認できます。
開発ツール2026-07-13
HealthKitの差分同期でデータを取りこぼす — HKAnchoredObjectQueryのアンカーを設計する
HealthKitの差分同期で歩数や睡眠が二重に数えられたり欠けたりする原因は、HKQueryAnchorの永続化設計にあります。newAnchorとdeletedObjectsを正しく扱い、再インストールやバックグラウンド更新をまたいでも整合するローカル取り込みの実装を、動くSwiftコードでまとめました。
開発ツール2026-07-12
Rork Maxのアプリで、アイコンを気持ちよく動かすsymbolEffect実装メモ
Rork Maxが生成したSwiftアプリで、SF Symbolsをbounce・pulse・variableColor・contentTransitionで動かす実装を、動くコードとOSバージョンの出し分け、そして動かしすぎて後悔した落とし穴つきで整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →