The project is in a healthy, maintained state
Manage your customers' App Store transactions from your server.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

~> 2.12
~> 2.8
~> 3.1
 Project Readme

App Store Server API Client

A Ruby client for the App Store Server API.

Support API Endpoints

Requirements

Ruby 3.3.0 or later.

Installation

add this line to your application's Gemfile:

gem 'app_store_server_api_client'

Usage

Prerequisites

To use this, please obtain an API Key. https://developer.apple.com/documentation/appstoreserverapi/creating-api-keys-to-authorize-api-requests

Configure

In your Rails application, create a client configure

# my_app/config/app_store_server.yml
default: &default
  private_key: |
    -----BEGIN PRIVATE KEY-----
    ...
    -----END PRIVATE KEY-----
  key_id: Z1BT391B21
  issuer_id: ef02153z-1290-3519-875e-237a15237e3c
  bundle_id: com.myapp.app
  environment: sandbox

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

load the configuration

config = Rails.application.config_for(:app_store_server)
client = AppStoreServerApi::Client.new(**config)

API

Get Transaction Info

Get Transaction Info

Get information about a single transaction for your app.

transaction_id = '2000000847061981'
client.get_transaction_info(transaction_id)
=>
  {
    "transactionId" => "2000000847061981",
    "originalTransactionId" => "2000000847061981",
    "bundleId" => "com.myapp.app",
    "productId" => "com.myapp.app.product",
    "type" => "Consumable",
    "purchaseDate" => 1738645560000,
    "originalPurchaseDate" => 1738645560000,
    "quantity" => 1,
    ...
  }

Request a Test Notification

Request a Test Notification

Ask App Store Server Notifications to send a test notification to your server.

result = client.request_test_notification
#=> {"testNotificationToken"=>"9f90efb9-2f75-4dbe-990c-5d1fc89f4546_1739179413123"}

Get Test Notification Status

Get Test Notification Status

Check the status of the test App Store server notification sent to your server.

test_notification_token = client.request_test_notification['testNotificationToken']
result = client.get_test_notification_status(test_notification_token)
#=> {
#  "signedPayload"=> "eyJhbGciOiJFUzI1NiIsIng1YyI6...",
#  "firstSendAttemptResult"=>"SUCCESS",
#  "sendAttempts"=>[{"attemptDate"=>1739179888814, "sendAttemptResult"=>"SUCCESS"}]
#}

signed_payload = AppStoreServerApi::Utils::Decoder.decode_jws!(result['signedPayload'])
# => {
#   "notificationType"=>"TEST",
#   "notificationUUID"=>"3838df56-31ab-4e2e-9535-e6e9377c4c77",
#   "data"=>{"bundleId"=>"com.myapp.app", "environment"=>"Sandbox"},
#   "version"=>"2.0",
#   "signedDate"=>1739180480080
# }

Get Transaction History

Get Transaction History

Get a customer’s in-app purchase transaction history for your app.

data = client.get_transaction_history(transaction_id,
  params: {
    sort: "DESCENDING"
  })

transactions = AppStoreServerApi::Utils::Decoder.decode_transactions(signed_transactions:
  data["signedTransactions"])

Get All Subscription Statuses

Get All Subscription Statuses

Get the statuses for all of a customer’s auto-renewable subscriptions in your app.

# all statuses
data = client.get_all_subscription_statuses(transaction_id)

# filter by status
data = client.get_all_subscription_statuses(transaction_id, params:{status: 1})

The status of an auto-renewable subscription

status possible values:

  • 1: The auto-renewable subscription is active.
  • 2: The auto-renewable subscription is expired.
  • 3: The auto-renewable subscription is in a billing retry period.
  • 4: The auto-renewable subscription is in a Billing Grace Period.
  • 5: The auto-renewable subscription is revoked. The App Store refunded the transaction or revoked it from Family Sharing.

Error Handling

begin
  # response success
  transaction_info = client.get_transaction_info('invalid_transaction_id')
rescue AppStoreServerApi::Error => e
  # response failure
  # case of error: 
  # - http status 40x, 50x
  # - json parse error 
  puts e.code # => Integer
  puts e.message # => String
end

License

The gem is available as open source under the terms of the MIT License.