* ios purchase finalization

This commit is contained in:
Seth Call 2016-01-28 11:31:57 -06:00
parent a9d92b2250
commit e451c4be3d
4 changed files with 86 additions and 19 deletions

View File

@ -69,14 +69,66 @@ module JamRuby
}
end
# The expectation is that this code would throw an exception (breaking the transaction that encompasses it),
# 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)
# 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'}
# communicate with Apple; populate price_info
price_info
end
def self.ios_purchase(current_user, jam_track, receipt)
current_user.redeem_free_credit
jam_track_right = JamRuby::JamTrackRight.find_or_create_by_user_id_and_jam_track_id(current_user.id, jam_track.id) do |jam_track_right|
jam_track_right.redeemed = false
jam_track_right.version = jam_track.version
jam_track_right = nil
# everything needs to go into a transaction! If anything goes wrong, we need to raise an exception to break it
Sale.transaction do
using_free_credit = current_user.redeem_free_credit
sale = create_jam_track_sale(current_user)
if sale.valid?
# JONATHAN: the 'redeem freebie' path has no communication to Apple. That's OK I assume?
if using_free_credit
SaleLineItem.create_from_jam_track(current_user, sale, jam_track, using_free_credit)
sale.recurly_subtotal_in_cents = 0
sale.recurly_tax_in_cents = 0
sale.recurly_total_in_cents = 0
sale.recurly_currency = 'USD'
sale.save!
else
price_info = validateIOSReceipt(receipt)
SaleLineItem.create_from_jam_track(current_user, sale, jam_track, using_free_credit)
sale.recurly_subtotal_in_cents = price_info[:subtotal_in_cents]
sale.recurly_tax_in_cents = price_info[:tax_in_cents]
sale.recurly_total_in_cents = price_info[:total_in_cents]
sale.recurly_currency = price_info[:currency]
sale.save!
end
else
# should not get out of testing. This would be very rare (i.e., from a big regression). Sale is always valid at this point.
raise "invalid sale object"
end
# if we make it this far, all is well!
jam_track_right = JamRuby::JamTrackRight.find_or_create_by_user_id_and_jam_track_id(current_user.id, jam_track.id) do |jam_track_right|
jam_track_right.redeemed = using_free_credit
jam_track_right.version = jam_track.version
end
end
jam_track_right
end
# place_order will create one or more sales based on the contents of shopping_carts for the current user

View File

@ -73,6 +73,14 @@ module JamRuby
end
# in a shopping-cart less world (ios purchase), let's reuse as much logic as possible
def self.create_from_jam_track(current_user, sale, jam_track, mark_redeem)
shopping_cart = ShoppingCart.create(current_user, jam_track, 1, mark_redeem)
line_item = create_from_shopping_cart(sale, shopping_cart, nil, nil, nil)
shopping_cart.destroy
line_item
end
def self.create_from_shopping_cart(sale, shopping_cart, recurly_subscription_uuid, recurly_adjustment_uuid, recurly_adjustment_credit_uuid)
product_info = shopping_cart.product_info

View File

@ -1785,18 +1785,18 @@ module JamRuby
end
def redeem_free_credit
yn = false
using_free_credit = false
if self.has_redeemable_jamtrack
User.where(id: self.id).update_all(has_redeemable_jamtrack: false)
self.has_redeemable_jamtrack = false
yn = true
using_free_credit = true
elsif 0 < self.gifted_jamtracks
User.where(id: self.id).update_all(gifted_jamtracks: self.gifted_jamtracks - 1)
self.gifted_jamtracks = self.gifted_jamtracks - 1
yn = true
using_free_credit = true
end
yn
using_free_credit
end
private

View File

@ -315,18 +315,25 @@ class ApiJamTracksController < ApiController
def ios_order_placed
jam_track = JamTrack.find(params[:jam_track_id])
sales = Sale.ios_purchase(current_user, jam_track, nil)
jam_track_right = jam_track.right_for_user(current_user)
# the user already owns this JamTrac, so just short-circuit out
if jam_track_right
response = {name: jam_track.name, id: jam_track.id, jam_track_right_id: jam_track_right.id, version: jam_track.version}
render :json => response, :status => 200
return
end
begin
Sale.ios_purchase(current_user, jam_track, nil)
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}
render :json => response, :status => 422
return
end
#
# sales.each do |sale|
# if sale.is_jam_track_sale?
# sale.sale_line_items.each do |line_item|
# jam_track = line_item.product
# jam_track_right = jam_track.right_for_user(current_user)
# response[:jam_tracks] << {name: jam_track.name, id: jam_track.id, jam_track_right_id: jam_track_right.id, version: jam_track.version}
# end
# end
# end
response = {name: jam_track.name, id: jam_track.id, jam_track_right_id: jam_track.right_for_user(current_user).id, version: jam_track.version}
render :json => response, :status => 200
end