Receive server notifications for iOS "automatic renewal subscription" in Ruby

Receive server notifications for iOS "automatic renewal subscription" in Ruby

I need to receive the server notification of iOS "automatic renewal subscription" in Ruby, and I checked various things, so I will summarize it as a memorandum!

Constitution

Multi-platform service iOS app: Swift Server side: Ruby (Ruby on Rails)

Review: What is server notification?

By registering your server-side URL in App Store Connect, you can be notified by Apple when the status of your auto-renewable subscription changes.

With this function, the distributor can check and know on-time membership, cancellation, upgrade, downgrade, etc.

Registration of URL (server) to receive server notifications

AppStoreConnect> Open the relevant app page. If you register the URL in "URL of App Store server notification" at the bottom right of the App information (where you register the name etc.) of the corresponding application page, the notification from the Apple Store will be sent to the registered URL at the timing described later. Will be!

When server notifications are sent

User event Notification type
First purchase INITIAL_BUY
upgrade CANCEL,DID_CHANGE_RENEWAL_STATUS, INTERACTIVE_RENEWAL
Downgrade DID_CHANGE_RENEWAL_PREF
Resubscribe after expiration DID_CHANGE_RENEWAL_STATUS
Subscribe to another subscription after it expires INTERACTIVE_RENEWAL, DID_CHANGE_RENEWAL_STATUS
Cancel subscription DID_CHANGE_RENEWAL_STATUS
Refund by Apple CANCEL,DID_CHANGE_RENEWAL_STATUS
Subscription renewal failed due to payment issue DID_FAIL_TO_RENEW
Refund to user REFUND
I agreed to raise the subscription price PRICE_INCREASE_CONSENT
Successful automatic update DID_RENEW

JSON format sent

{
    "notification_type": "DID_RENEW",
    "password": " "
    "environment": "Sandbox",
    "auto_renew_product_id": " ",
    "auto_renew_status": "false",
    "unified_receipt": {
        "status":0,
        "environment":"Sandbox",
        "latest_receipt_info": [{
            "quantity": "1",
            "product_id": " ",
            "transaction_id": "000000000000000",
            "purchase_date":"2000-00-00 00:00:00 Etc/GMT", 
            "purchase_date_ms": "0000000000000",
            "purchase_date_pst": "2000-00-00 00:00:00America/Los_Angeles",
            "original_purchase_date": "2000-00-00 00:00:00 Etc/GMT",
            "original_purchase_date_ms": "0000000000000",
            "original_purchase_date_pst": "2000-00-00 00:00:00 America/Los_Angeles",
            "original_transaction_id": "000000000000000",
            "expires_date": "0000000000000",
            "expires_date_ms": "2000-00-00 00:00:00 Etc/GMT",
            "expires_date_pst": "2000-00-00 00:00:00 America/Los_Angeles",
            "web_order_line_item_id": "000000000000000"
            "is_trial_period": "false",
            "is_in_intro_offer_period": "false",
            "original_transaction_id": "00000000",
            "subscription_group_identifier": "00000000"
        },{
           #The column is the same as above. Each item contains the value for the previous time.
        }],
        "latest_receipt":"",  #Base64 encoded receipt
        "pending_renewal_info":[{
            "auto_renew_status": "false",
            "auto_renew_product_id": " ",
            "product_id": " ",
            "original_transaction_id": "000000000000000",
        }]
    },
    "bid": " ",
    "bvrs": "1",
    "controller":"",#Ruby 
    "action":"", #Ruby 
    "appstore_notification": {
        "auto_renew_product_id":"", 
        "auto_renew_status":"true", 
        "environment":"Sandbox", 
        "bid":"jp.〇〇.〇〇",
        "bvrs":"1",
        "notification_type":"DID_RENEW",
        "password":""
        "cancellation_date": "0000000000000",
    }

}

Meaning of each JSON property sent

You can see the basics by looking at this official website! Official reference site

I will summarize only the values ​​that I want to use in the main

Field name meaning
auto_renew_status Current renewal status of auto-renewable subscription products
auto_renew_status_change_date The time when the user turned on or off the renewal status of an auto-renewable subscription.
original_transaction_id Transaction ID of the first purchase. This value is the same unless the user restores the purchase or renews the subscription.
environment The environment in which the App Store generated the receipt.
latest_receipt Base64-encoded latest transaction receipt
latest_receipt_info JSON representation of the value. This field is an array of receipts, but a single object for server-to-server notifications
cancellation_date The time when Apple Customer Support canceled the transaction. This field only appears for refunded transactions.
cancellation_reason The reason for the refunded transaction. If the customer cancels the transaction, the App Store will refund the customer and provide the value of this key. A value of “1” indicates that the customer canceled the transaction due to a real or recognized issue within the app. The value of is “0”, which indicates that the transaction was canceled for another reason. For example, if a customer makes an accidental purchase.
expires_date The time your subscription expires or the time your subscription renews
is_trial_period An indicator of whether your subscription is within the free trial period.
is_upgraded An indicator that the system has canceled the subscription because the user has upgraded. This field only appears for upgrade transactions.
product_id A unique identifier for the purchased product. This value corresponds to the property of the object that you specify when you create the product in App Store Connect and is stored in the transaction properties.
purchase_date The time the App Store charges your account for a subscription purchase or renewal in a date and time format similar to the ISO 8601 standard.
quantity The number of consumables purchased.
subscription_group_identifier The identifier of the subscription group to which the subscription belongs. The value of this field is the same as the property of SKProduct.
transaction_id Unique identifier for transactions such as purchases, restores, updates, etc.
notification_type Subscription event that triggered the notification
password Same value as the shared secret sent to the password field of requestBody when validating the receipt

Code to process incoming JSON in Ruby

In a word, process the above JSON format and describe the processing of the application according to the timing and the value of each property.

#Receive as an example_appserver_Create as notification method
def receive_appserver_notification
    unified_receipt = params['unified_receipt'].as_json
    latest_receipt = unified_receipt['latest_receipt']
    latest_receipt_info = unified_receipt['latest_receipt_info']
    
   @mTestObj = TestObj.new()  #Prepare models and objects for storage
   @mTestObj.auto_renew_product_id = unified_receipt['auto_renew_product_id']
   @mTestObj.expires_date = latest_receipt_info['expires_date']
   #==Omitted below==

   #Describe if there is processing
   if @mTestObj.notification_type == 'INITIAL_BUY'
       #For example, processing when it was an initial purchase ...
   end

   #Save
   begin 
      @mTestObj.save
      puts "Save completed!!"
   rescue => exception
                
   end

end


Summary

  1. Let's set the URL to be received by AppStore Connect
  2. Understand the format and parameters sent
  3. Receive it on the server and process the json
  4. Implement the necessary processing according to the value

Recommended Posts

Receive server notifications for iOS "automatic renewal subscription" in Ruby
Receive parameterized PUSH notifications on iOS
Tips for gRPC error handling in Ruby