Last active
October 1, 2015 15:23
-
-
Save sqlninja/3714b7a262d8ac4b8a10 to your computer and use it in GitHub Desktop.
Apple IAP receipt verification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module AppleHelper | |
APPLE_RECEIPT_VERIFY_URL_SANDBOX = "https://sandbox.itunes.apple.com" | |
APPLE_RECEIPT_VERIFY_URL_PRODUCTION = "https://buy.itunes.apple.com" | |
def self.verify_receipt_for(b64_receipt, receipt_verify_url) | |
json_resp = nil | |
url = URI.parse(receipt_verify_url) | |
json_request = { 'receipt-data' => b64_receipt, 'password' => ENV!['APPLE_SHARED_SECRET'] }.to_json | |
resp, resp_body = Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https') do |http| | |
response = http.post('/verifyReceipt', json_request.to_s) | |
json_resp = JSON.parse response.body | |
end | |
json_resp | |
end | |
def self.verify_receipt(b64_receipt) | |
json_resp = AppleHelper.verify_receipt_for(b64_receipt, APPLE_RECEIPT_VERIFY_URL_PRODUCTION) | |
unless json_resp.nil? | |
if json_resp.is_a? Hash | |
if json_resp['status'] == 21007 | |
# try the sandbox then | |
json_resp = AppleHelper.verify_receipt_for(b64_receipt, APPLE_RECEIPT_VERIFY_URL_SANDBOX) | |
end | |
end | |
end | |
json_resp | |
end | |
def self.validate_receipt(_receipt, _userId) | |
result = verify_receipt(_receipt) | |
# https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html | |
# status | |
# Either 0 if the receipt is valid, or one of the error codes listed in Table 2-1. | |
# For iOS 6 style transaction receipts, the status code reflects the status of the specific transaction’s receipt. | |
# For iOS 7 style app receipts, the status code is reflects the status of the app receipt as a whole. For example, if you send a valid app receipt that contains an expired subscription, the response is 0 because the receipt as a whole is valid. | |
status = result['status'] == 0 ? 'active' : 'inactive' | |
if status == 'active' | |
receipt_info = result['latest_receipt_info'].last | |
# Get Stripe Plan info | |
Stripe.api_key = ENV!['STRIPE_API_KEY'] | |
plan_id = receipt_info['product_id'] == 'JT1YR' ? 'JTA' : 'JTM' | |
plan_info = Stripe::Plan.retrieve(plan_id) | |
subscription = "{ | |
\"subscriptions\":[ | |
{ | |
\"id\":#{receipt_info['transaction_id']}, | |
\"plan\":{ | |
\"id\":\"#{plan_info.id}\", | |
\"interval\":\"#{plan_info.interval}\", | |
\"name\":\"#{plan_info.name}\", | |
\"created\":#{receipt_info['original_purchase_date_ms']}, | |
\"amount\":#{plan_info.amount}, | |
\"currency\":\"#{plan_info.currency}\", | |
\"object\":\"#{plan_info.object}\", | |
\"livemode\":\"#{plan_info.livemode}\", | |
\"interval_count\":#{plan_info.interval_count}, | |
\"trial_period_days\":#{plan_info.trial_period_days}, | |
\"metadata\":{ | |
}, | |
\"statement_descriptor\":\"#{plan_info.statement_descriptor}\" | |
}, | |
\"object\":\"subscription\", | |
\"start\":#{result['receipt']['original_purchase_date_ms']}, | |
\"status\":\"#{status}\", | |
\"customer\":#{_userId}, | |
\"cancel_at_period_end\":false, | |
\"current_period_start\":#{receipt_info['purchase_date_ms']}, | |
\"current_period_end\":#{receipt_info['expires_date_ms']}, | |
\"ended_at\":null, | |
\"trial_start\":null, | |
\"trial_end\":null, | |
\"canceled_at\":null, | |
\"quantity\":1, | |
\"application_fee_percent\":null, | |
\"discount\":null, | |
\"tax_percent\":null, | |
\"metadata\":{ | |
} | |
} | |
] | |
}" | |
JSON.parse(subscription) | |
else | |
Rails.logger.info "Checking itunes receipt status returned: #{result['status']} for User: #{_userId}" | |
'' | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MIIceAYJKoZIhvcNAQcCoIIcaTCCHGUCAQExCzAJBgUrDgMCGgUAMIIMKQYJKoZIhvcNAQcBoIIMGgSCDBYxggwSMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQECAQEEAwIBADALAgELAgEBBAMCAQAwCwIBDgIBAQQDAgFeMAsCAQ8CAQEEAwIBADALAgEQAgEBBAMCAQAwCwIBGQIBAQQDAgEDMAwCAQoCAQEEBBYCNCswDQIBDQIBAQQFAgMBOawwDQIBEwIBAQQFDAMxLjAwDgIBCQIBAQQGAgRQMjM0MA8CAQMCAQEEBwwFMi4wLjIwGAIBBAIBAgQQUbkhc8pJBTDo pkCW9bAcDAbAgEAAgEBBBMMEVByb2R1Y3Rpb25TYW5kYm94MBwCAQUCAQEEFKvOivuxwYYctPrzjUmfRHqvYzMqMB4CAQwCAQEEFhYUMjAxNS0wOC0yNVQxMDoxMzo1NVowHgIBEgIBAQQWFhQyMDEzLTA4LTAxVDA3OjAwOjAwWjAjAgECAgEBBBsMGWNvbS5ibG9vbW1lZGlhLmplbGx5dGVsbHkwSAIBBgIBAQRAKll2wFsujgYT9hGvxyd7Rcb0nDConAgcKYnVhuU1Amzza8dqmSl0/TUk4tc64sZd7 MrbYuTEW22PYkiCWFJ5DBJAgEHAgEBBEEpXtoDScD5m7uwvRPWMt06ySAFyrSPuw Z53goaYw3UnN5l5O4/AA 7J/0NjMJ z0t7TFfepm853uj5aoq 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 8iCOt7WRQRn3M0Lea5OaY79 Y 7Mqm 6uvJt PiIECAwEAAaOCAdgwggHUMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwTQYDVR0fBEYwRDBCoECgPoY8aHR0cDovL2RldmVsb3Blci5hcHBsZS5jb20vY2VydGlmaWNhdGlvbmF1dGhvcml0eS93d2RyY2EuY3JsMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQUdXYkomtiDJc0ofpOXggMIr9z774wggERBgNVHSAEggEIMIIBBDCCAQAGCiqGSIb3Y2QFBgEwgfEwgcMGCCsGAQUFBwICMIG2DIGzUmVsaWFuY2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cuYXBwbGUuY29tL2FwcGxlY2EvMBAGCiqGSIb3Y2QGCwEEAgUAMA0GCSqGSIb3DQEBBQUAA4IBAQCgO/GHvGm0t4N8GfSfxAJk3wLJjjFzyxw 3CYHi/2e8 2 Q9aNYS3k8NwWcwHWNKNpGXcUv7lYx1LJhgB/bGyAl6mZheh485oSp344OGTzBMtf8vZB wclywIhcfNEP9Die2H3QuOrv3ds3SxQnICExaVvWFl6RjFBaLsTNUVCpIz6EdVLFvIyNd4fvNKZXcjmAjJZkOiNyznfIdrDdvt6NhoWGphMhRvmK0UtL1kaLcaa1maSo9I2UlCAIE0zyLKa1lNisWBS8PX3fRBQ5BK/vXG tIDHbcRvWzk10ee33oEgJ444XIKHOnNgxNbxHKCpZkR zgwomyN/rOzmoDvdMIIEIzCCAwugAwIBAgIBGTANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDgwMjE0MTg1NjM1WhcNMTYwMjE0MTg1NjM1WjCBljELMAkGA1UEBhMCVVMxEzARBgNVBAoMCkFwcGxlIEluYy4xLDAqBgNVBAsMI0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVsYXRpb25zMUQwQgYDVQQDDDtBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9ucyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMo4VKbLVqrIJDlI6Yzu7F 4fyaRvDRTes58Y4Bhd2RepQcjtjn UC0VVlhwLX7EbsFKhT4v8N6EGqFXya97GP9q hUSSRUIGayq2yoy7ZZjaFIVPYyK7L9rGJXgA6wBfZcFZ84OhZU3au0Jtq5nzVFkn8Zc0bxXbmc1gHY2pIeBbjiP2CsVTnsl2Fq/ToPBjdKT1RpxtWCcnTNOVfkSWAyGuBYNweV3RY1QSLorLeSUheHoxJ3GaKWwo/xnfnC6AllLd0KRObn1zeFM78A7SIym5SFd/Wpqu6cWNWDS5q3zRinJ6MOL6XnAamFnFbLw/eVovGJfbs Z3e8bY/6SZasCAwEAAaOBrjCBqzAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUiCcXCam2GGCL7Ou69kdZxVJUo7cwHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL3d3dy5hcHBsZS5jb20vYXBwbGVjYS9yb290LmNybDAQBgoqhkiG92NkBgIBBAIFADANBgkqhkiG9w0BAQUFAAOCAQEA2jIAlsVUlNM7gjdmfS5o1cPGuMsmjEiQzxMkakaOY9Tw0BMG3djEwTcV8jMTOSYtzi5VQOMLA6/6EsLnDSG41YDPrCgvzi2zTq GGQTG6VDdTClHECP8bLsbmGtIieFbnd5G2zWFNe8 0OJYSzj07XVaH1xwHVY5EuXhDRHkiSUGvdW0FY5e0FmXkOlLgeLfGK9EdB4ZoDpHzJEdOusjWv6lLZf3e7vWh0ZChetSPSayY6i0scqP9Mzis8hH4L aWYP62phTKoL1fGUuldkzXfXtZcwxN8VaBOhr4eeIA0p1npsoy0pAiGVDdd3LOiUjxZ5X C7O0qmSXnMuLyV1FTCCBLswggOjoAMCAQICAQIwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTA2MDQyNTIxNDAzNloXDTM1MDIwOTIxNDAzNlowYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5JGpCR R2x5HUOsF7V55hC3rNqJXTFXsixmJ3vlLbPUHqyIwAugYPvhQCdN/QaiY dHKZpwkaxHQo7vkGyrDH5WeegykR4tb1BY3M8vED03OFGnRyRly9V0O1X9fm/IlA7pVj01dDfFkNSMVSxVZHbOU9/acns9QusFYUGePCLQg98usLCBvcLY/ATCMt0PPD5098ytJKBrI/s61uQ7ZXhzWyz21Oq30Dw4AkguxIRYudNU8DdtiFqujcZJHU1XBry9Bs/j743DN5qNMRX4fTGtQlkGJxHRiCxCDQYczioGxMFjsWgQyjGizjx3eZXP/Z15lvEnYdp8zFGWhd5TJLQIDAQABo4IBejCCAXYwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFCvQaUeUdgn 9GuNLkCm90dNfwheMB8GA1UdIwQYMBaAFCvQaUeUdgn 9GuNLkCm90dNfwheMIIBEQYDVR0gBIIBCDCCAQQwggEABgkqhkiG92NkBQEwgfIwKgYIKwYBBQUHAgEWHmh0dHBzOi8vd3d3LmFwcGxlLmNvbS9hcHBsZWNhLzCBwwYIKwYBBQUHAgIwgbYagbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjANBgkqhkiG9w0BAQUFAAOCAQEAXDaZTC14t 2Mm9zzd5vydtJ3ME/BH4WDhRuZPUc38qmbQI4s1LGQEti 9HOb7tJkD8t5TzTYoj75eP9ryAfsfTmDi1Mg0zjEsb aTwpr/yv8WacFCXwXQFYRHnTTt4sjO0ej1W8k4uvRt3DfD0XhJ8rxbXjt57UXF6jcfiI1yiXV2Q/Wa9SiJCMR96Gsj3OBYMYbWwkvkrL4REjwYDieFfU9JmcgijNq9w2Cz97roy/5U2pbZMBjM3f3OgcsVuvaDyEO2rpzGU 12TZ/wYdV2aeZuTJC 9jVcZ5 oVK3G72TQiQSKscPHbZNnF5jyEuAF1CqitXa5PzQCQc3sHV1ITGCAcswggHHAgEBMIGjMIGWMQswCQYDVQQGEwJVUzETMBEGA1UECgwKQXBwbGUgSW5jLjEsMCoGA1UECwwjQXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMxRDBCBgNVBAMMO0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVsYXRpb25zIENlcnRpZmljYXRpb24gQXV0aG9yaXR5AggYWUMhcnSc/DAJBgUrDgMCGgUAMA0GCSqGSIb3DQEBAQUABIIBAAwHb3QsBnvdF3gmQ4Z8PJzBrgXX2qBP50hq8AHH4nnV6OVDnLm58M2qJsjU6rvAVcdoiZwvEaMUTYUIsaV7IHZIL0D2J8qKbrZfrLcNVb1gc2DiZY1BsKZpXObv/ck1xRfT/ppuc2LNxdjL VBbWbDTMcm7Ee1K84GAzZw/HlFdykKC3m0inbkZzTrkaFz9UoJZTPH732NP/YOQbuXB2te9dC/Zbd0P17xRnVcGGHV j2nk4apcmRrRAGAhhXLFUlvJJU3JecxEB0KCgfEusRAEGKb4oraWh/zc90mF5icQcMs5EGiNZnCvu3pl3PHjiTGjbNqwcGEMbOa6P4TlEGY= |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment