#2430·nakama

Question: Does Apple Purchase Validation Support StoreKit 2 JWS Format?

Author: utkarshtrivedimdzCreated Nov 28, 2025Updated Jul 7, 2026

Summary

We're implementing server-side purchase validation for a Godot mobile game using Nakama. For Android, validate_purchase_google_async() works perfectly and stores purchases in the Nakama Console's Purchases section.

For iOS, we're using StoreKit 2 which no longer provides unified receipts. Instead, each transaction has a jwsRepresentation (JSON Web Signature) string.

Question

Does Nakama's Apple purchase validation support StoreKit 2's JWS format?

Client SDK:

gdscript
var result = await nkc.validate_purchase_apple_async(session, jws_string)

Server Runtime (Go):

go
validation, err := nk.PurchaseValidateApple(ctx, userID, jwsString, persist, passwordOverride)

Context

StoreKit 1 (Legacy)

  • Unified receipt at Bundle.main.appStoreReceiptURL
  • Base64 encoded receipt sent to Apple's verifyReceipt endpoint
  • verifyReceipt is being deprecated by Apple

StoreKit 2 (Current)

  • No unified receipt
  • Each Transaction has a jwsRepresentation property
  • JWS is self-contained and cryptographically signed by Apple
  • Can be verified using Apple's public key or App Store Server API

What We're Trying to Achieve

  1. Validate iOS purchases server-side (prevent fraud on jailbroken devices)
  2. Store validated purchases in Nakama's purchase ledger (visible in Console UI)
  3. Detect replay attacks via seen_before flag

Current Workaround

We're considering a custom RPC that:

  1. Receives JWS from client
  2. Verifies JWS signature using Apple's certificates
  3. Manually writes to storage

But this bypasses Nakama's built-in purchase tracking, losing the Console UI integration.

Environment

  • Nakama: Latest (self-hosted via Docker)
  • Client: Godot 4.5 with nakama-godot addon
  • iOS: StoreKit 2 via SwiftGodot plugin

References

Thank you!