Apple Receipt Verification — Ruby on Rails Implementation

ADMAT Bandara
2 min readJan 7, 2021

I hope you have some idea about in-app purchase. Anyway this article is about how I validated the apple in-App purchase receipt via

Basically the process includes 2 basic things.

  1. Mobile application (iOS) should have the receipt to be validated.
  2. Web server should receive the receipt and send the response once validated.

Actually there are many wonderfull gems to get the job done. Somehow my requirment is do the solution without using any gems. So I created the library myself.

Here are some of the gems I’ve found. Use them if you like.

Step 01

I created the library class to call http calls to with the httparty gem. Both Sandbox and the production is include in the same class.

PS: if the status is equals to “21007” the request should be sent to the sandbox (dev environment).

Step 02

The validation should happen with the expiry date. There is an attribute in the response called max_expires_date_mswhich is exported in miliseconds. Next is compare the database last payment date and receipt’s expire date.

I created a method to convert the max_expires_date_ms to a readable format.

def get_expire_date(max_expires_date_ms)
sec = (max_expires_date_ms.to_f / 1000).to_s
return Time.strptime(sec, '%s')

Also retrive the last payment datetime

def get_last_payment_expire_date(subscription)
last_payment = [Query to get the last payment record]
if last_payment && last_payment.expire_date != nil
return last_payment.expire_date.to_time
return nil

Then I wrote the verifiyReceipt method by comparing the retuned values from the above methods.

This will do the validation usingthe expiry time and do the needful actions. (such as updating the subscrition database record). At the same time I am sending the expire date as the response in the API for the mobile application in order to show the user feedback messages in the phone.

I have saved the receipt details in the database in case we need to resend and stuff. This might not be needed in all cases.

def save_details_of_the_receipt(subscription, should_activate,    product_id, expire_date, receipt)  save_subscription(details)  if should_activate
# When < expire_date
make_payment(subscription, expire_date, receipt)

That’s all.

Stay awesome !!!