Skip to content

Instantly share code, notes, and snippets.

@guillermo
Last active August 29, 2015 14:17
Show Gist options
  • Save guillermo/bc6ac32939e54a7fd610 to your computer and use it in GitHub Desktop.
Save guillermo/bc6ac32939e54a7fd610 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
def trace(msg)
$stderr.puts msg
end
begin
require "rest"
rescue LoadError => e
trace("Install nap dependency")
trace("gem install nap")
exit(-1)
end
require 'base64'
require 'json'
require 'yaml'
ENDPOINT = {
:production => 'https://buy.itunes.apple.com/verifyReceipt',
:sandbox => 'https://sandbox.itunes.apple.com/verifyReceipt'
}
STATUS = {
0 => :active,
21000 => :bad_json,
21002 => :malformed,
21003 => :authentication_error,
21004 => :authentication_failed,
21005 => :service_unavailable,
21006 => :inactive,
21007 => :sandbox_receipt_in_production,
21008 => :production_receipt_in_sandbox
}
def ios7_receipt?(transaction_receipt_decoded)
!transaction_receipt_decoded.start_with?('{')
end
def verify_with_apple(transaction_receipt)
transaction_receipt_decoded = Base64.decode64(transaction_receipt)
is_sandbox_receipt = false
response = call_apple(transaction_receipt, :production)
if response && response.status == :sandbox_receipt_in_production
is_sandbox_receipt = true
response = call_apple(transaction_receipt, :sandbox)
end
if response
if ios7_receipt?(transaction_receipt_decoded)
#trace("Apple validation data: #{response}\n\tApple validation receipt #{transaction_receipt}\n\tFull response: #{response.delete_field(:full_response).body}")
begin
in_app_data = response.receipt_data.fetch('in_app', [{}])
transaction_id = in_app_data.first.fetch('transaction_id', '')
product_id = in_app_data.first.fetch('product_id', '')
response.receipt_data['transaction_id'] = transaction_id
response.receipt_data['product_id'] = product_id
rescue
#trace("Error received when trying to read receipt data from response: \"#{response}\" for transaction receipt: \"#{transaction_receipt}\"")
raise
end
end
response.receipt_data['sandbox'] = is_sandbox_receipt
response
end
end
def call_apple(transaction_receipt, endpoint)
response = REST.post ENDPOINT[endpoint], {'receipt-data' => transaction_receipt}.to_json
if response.ok?
response_data = JSON.parse(response.body)
payment_status = STATUS[response_data['status']]
OpenStruct.new(receipt_data: response_data['receipt'] || {}, status: payment_status, active?: payment_status == :active)
end
end
if ARGV.include?("-h") || ARGV.include?("--help")
trace("Usage: #{$0} file")
trace(" where file is a base64 encoded payment")
end
puts verify_with_apple(ARGF.read.strip).to_yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment