Compare commits
4 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
c2b61d1a3b | |
|
|
48873f3485 | |
|
|
dc13534bd6 | |
|
|
a2d0992e65 |
|
|
@ -332,3 +332,4 @@ chat_channel.sql
|
||||||
jamblaster.sql
|
jamblaster.sql
|
||||||
test_drive_lessons.sql
|
test_drive_lessons.sql
|
||||||
whitelist.sql
|
whitelist.sql
|
||||||
|
add_sale_source_col.sql
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE sales ADD COLUMN source VARCHAR NOT NULL DEFAULT 'recurly';
|
||||||
|
|
@ -269,6 +269,7 @@ require "jam_ruby/models/jam_track_session"
|
||||||
require "jam_ruby/models/jamblaster"
|
require "jam_ruby/models/jamblaster"
|
||||||
require "jam_ruby/models/jamblaster_user"
|
require "jam_ruby/models/jamblaster_user"
|
||||||
require "jam_ruby/models/jamblaster_pairing_request"
|
require "jam_ruby/models/jamblaster_pairing_request"
|
||||||
|
require "jam_ruby/models/sale_receipt_ios"
|
||||||
|
|
||||||
include Jampb
|
include Jampb
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,9 @@ module JamRuby
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
query = query.where("jam_tracks.status = ?", 'Production') unless user && user.admin
|
if (! user.try(:admin) && 'development' != Rails.env)
|
||||||
|
query = query.where("jam_tracks.status = ?", 'Production')
|
||||||
|
end
|
||||||
|
|
||||||
unless options[:genre].blank?
|
unless options[:genre].blank?
|
||||||
query = query.joins(:genres)
|
query = query.joins(:genres)
|
||||||
|
|
|
||||||
|
|
@ -73,17 +73,44 @@ module JamRuby
|
||||||
# if it can't validate the receipt, or communicate with Apple at all, etc
|
# 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
|
# 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, user, sale)
|
||||||
|
|
||||||
# these are all 'in cents' (as painfully named to be very clear), and all expected to be integers
|
# 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
|
||||||
|
|
||||||
# communicate with Apple; populate price_info
|
price_info = {
|
||||||
|
subtotal_in_cents: price,
|
||||||
|
total_in_cents: price,
|
||||||
|
tax_in_cents: nil,
|
||||||
|
currency: price_data['product_currency']
|
||||||
|
}
|
||||||
|
response = IosReceiptValidator.post('/verifyReceipt',
|
||||||
|
body: { 'receipt-data' => receipt }.to_json,
|
||||||
|
headers: { 'Content-Type' => 'application/json' })
|
||||||
|
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']]
|
||||||
|
else
|
||||||
|
receiptJson = SaleReceiptIOS.new
|
||||||
|
receiptJson.user = user
|
||||||
|
receiptJson.sale = sale
|
||||||
|
receiptJson.data_blob = json_resp
|
||||||
|
receiptJson.save!
|
||||||
|
end
|
||||||
price_info
|
price_info
|
||||||
end
|
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
|
jam_track_right = nil
|
||||||
|
|
@ -93,7 +120,7 @@ module JamRuby
|
||||||
|
|
||||||
using_free_credit = current_user.redeem_free_credit
|
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?
|
if sale.valid?
|
||||||
|
|
||||||
|
|
@ -106,7 +133,7 @@ module JamRuby
|
||||||
sale.recurly_currency = 'USD'
|
sale.recurly_currency = 'USD'
|
||||||
sale.save!
|
sale.save!
|
||||||
else
|
else
|
||||||
price_info = validateIOSReceipt(receipt)
|
price_info = validateIOSReceipt(receipt, price_data, current_user, sale)
|
||||||
|
|
||||||
SaleLineItem.create_from_jam_track(current_user, sale, jam_track, using_free_credit)
|
SaleLineItem.create_from_jam_track(current_user, sale, jam_track, using_free_credit)
|
||||||
|
|
||||||
|
|
@ -454,11 +481,12 @@ module JamRuby
|
||||||
sale_type == JAMTRACK_SALE
|
sale_type == JAMTRACK_SALE
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.create_jam_track_sale(user)
|
def self.create_jam_track_sale(user, sale_source=nil)
|
||||||
sale = Sale.new
|
sale = Sale.new
|
||||||
sale.user = user
|
sale.user = user
|
||||||
sale.sale_type = JAMTRACK_SALE # gift cards and jam tracks are sold with this type of sale
|
sale.sale_type = JAMTRACK_SALE # gift cards and jam tracks are sold with this type of sale
|
||||||
sale.order_total = 0
|
sale.order_total = 0
|
||||||
|
sale.source = sale_source if sale_source
|
||||||
sale.save
|
sale.save
|
||||||
sale
|
sale
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
module JamRuby
|
||||||
|
class SaleReceiptIOS < JsonStore
|
||||||
|
|
||||||
|
belongs_to :sale, class_name: "JamRuby::Sale", foreign_key: :foreign_key1_id
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -336,11 +336,12 @@ class ApiJamTracksController < ApiController
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Sale.ios_purchase(current_user, jam_track, nil)
|
Sale.ios_purchase(current_user,
|
||||||
|
jam_track,
|
||||||
|
params[:receipt],
|
||||||
|
params[:price_data])
|
||||||
rescue
|
rescue
|
||||||
# JONATHAN - this definitely needs beefing up so that you can communicate back to the app any errors you might raise.
|
response = { message: $!.to_s }
|
||||||
# ... Go wild with this response; I just stubbed something.
|
|
||||||
response = {message:"Unable to complete purchase.", reason: nil}
|
|
||||||
render :json => response, :status => 422
|
render :json => response, :status => 422
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
require 'httparty'
|
||||||
|
|
||||||
|
class IosReceiptValidator
|
||||||
|
include HTTParty
|
||||||
|
base_uri 'production' != Rails.env ? "https://sandbox.itunes.apple.com" : "https://buy.itunes.apple.com"
|
||||||
|
default_params :output => 'json'
|
||||||
|
format :json
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue