VRFS-3800 ios receipt validation

This commit is contained in:
Jonathan Kolyer 2016-02-07 14:54:49 +00:00
parent e446c3ff44
commit 8c6d553823
6 changed files with 66 additions and 9 deletions

View File

@ -332,4 +332,5 @@ chat_channel.sql
jamblaster.sql
test_drive_lessons.sql
whitelist.sql
teacher_student_flags.sql
teacher_student_flags.sql
add_sale_source_col.sql

View File

@ -0,0 +1 @@
ALTER TABLE sales ADD COLUMN source VARCHAR NOT NULL DEFAULT 'recurly';

View File

@ -73,17 +73,53 @@ module JamRuby
# if it can't validate the receipt, or communicate with Apple at all, etc
#
# So, if this raises exceptions, you can handle them in the stubbed out begin/rescue in ApiJamTracksController#ios_order_placed
def self.validateIOSReceipt(receipt)
def self.validateIOSReceipt(receipt, price_data)
byebug
# these are all 'in cents' (as painfully named to be very clear), and all expected to be integers
price_info = {subtotal_in_cents:nil, total_in_cents:nil, tax_in_cents:nil, currency: 'USD'}
price = price_data['product_price'].to_f * 100.0
price_info = {
subtotal_in_cents: price,
total_in_cents: price,
tax_in_cents: nil,
currency: price_data['product_currency']
}
# communicate with Apple; populate price_info
url = 'production' != Rails.env ? "https://sandbox.itunes.apple.com/verifyReceipt" : "https://buy.itunes.apple.com/verifyReceipt"
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new("/v1.1/auth")
request.add_field('Content-Type', 'application/json')
request.body = { 'receipt-data' => receipt }
begin
response = http.request(request)
rescue
raise $!
end
json_resp = JSON.parse(response.body)
# https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1
if 0 != json_resp.status
err_msgs = {
21000 => 'The App Store could not read the JSON object you provided.',
21002 => 'The data in the receipt-data property was malformed or missing.',
21003 => 'The receipt could not be authenticated.',
21005 => 'The receipt server is not currently available.',
21007 => 'This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.',
21008 => 'This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.'
}
raise err_msgs[json_resp.status]
end
price_info
end
def self.ios_purchase(current_user, jam_track, receipt)
def self.ios_purchase(current_user, jam_track, receipt, price_data)
jam_track_right = nil
@ -93,7 +129,7 @@ module JamRuby
using_free_credit = current_user.redeem_free_credit
sale = create_jam_track_sale(current_user)
sale = create_jam_track_sale(current_user, 'ios')
if sale.valid?
@ -106,7 +142,7 @@ module JamRuby
sale.recurly_currency = 'USD'
sale.save!
else
price_info = validateIOSReceipt(receipt)
price_info = validateIOSReceipt(receipt, price_data)
SaleLineItem.create_from_jam_track(current_user, sale, jam_track, using_free_credit)
@ -454,11 +490,12 @@ module JamRuby
sale_type == JAMTRACK_SALE
end
def self.create_jam_track_sale(user)
def self.create_jam_track_sale(user, sale_source=nil)
sale = Sale.new
sale.user = user
sale.sale_type = JAMTRACK_SALE # gift cards and jam tracks are sold with this type of sale
sale.order_total = 0
sale.source = sale_source if sale_source
sale.save
sale
end

View File

@ -0,0 +1,7 @@
module JamRuby
class SaleReceiptIOS < JsonStore
belongs_to :sale, class_name: "JamRuby::Sale", foreign_key: :foreign_key1_id
end
end

View File

@ -336,11 +336,14 @@ class ApiJamTracksController < ApiController
end
begin
Sale.ios_purchase(current_user, jam_track, nil)
Sale.ios_purchase(current_user,
jam_track,
params[:receipt],
params[:price_data])
rescue
# JONATHAN - this definitely needs beefing up so that you can communicate back to the app any errors you might raise.
# ... Go wild with this response; I just stubbed something.
response = {message:"Unable to complete purchase.", reason: nil}
response = { message: $!.to_s }
render :json => response, :status => 422
return
end

View File

@ -0,0 +1,8 @@
require 'httparty'
class IosReceiptValidator
include HTTParty
base_uri 'production' != Rails.env ? "https://sandbox.itunes.apple.com/verifyReceipt" : "https://buy.itunes.apple.com/verifyReceipt"
default_params :output => 'json'
format :json
end