Skip to content

Instantly share code, notes, and snippets.

@roowe
Created July 2, 2015 02:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roowe/22c71c8aff031e344ae5 to your computer and use it in GitHub Desktop.
Save roowe/22c71c8aff031e344ae5 to your computer and use it in GitHub Desktop.
In-App Purchase Programming之Verifying Store Receipts
-module(lib_verifying_store_receipts).
-include("common.hrl").
-include("define_http.hrl").
-include("define_info_10.hrl").
-export([send/1]).
-define(APP_VERIFY_RECEIPT_URL, "https://buy.itunes.apple.com/verifyReceipt").
-define(APP_SANDBOX_VERIFY_RECEIPT_URL, "https://sandbox.itunes.apple.com/verifyReceipt").
-define(SANDBOX_MAGIC_STRING, "\"environment\" = \"Sandbox\";").
send(ReceiptData) ->
URL = case re:run(ReceiptData, ?SANDBOX_MAGIC_STRING) of
nomatch ->
?APP_VERIFY_RECEIPT_URL;
{match, _} ->
?APP_SANDBOX_VERIFY_RECEIPT_URL
end,
send_receipt_data_with_url(base64:encode_to_string(ReceiptData), URL).
send_receipt_data_with_url(Base64Data, URL) ->
Body = io_lib:format("{\"receipt-data\":\"~s\"}", [Base64Data]),
case ibrowse:send_req(URL, [],
post, Body, [{max_sessions, 200},
{max_pipeline_size, 50},
{response_format, binary}], 3000) of
{ok, "200", _ResponseHeaders, RecvBody} ->
?DEBUG("RecvBody ~p", [RecvBody]),
case catch jiffy:decode(RecvBody) of
{error, Error} ->
?WARNING_MSG("Error ~p~n", [Error]),
?FAIL(?INFO_HTTP_ERROR);
{'EXIT', Error} ->
?WARNING_MSG("Exit Error ~p~n", [Error]),
?FAIL(?INFO_HTTP_ERROR);
RecvJSON ->
?DEBUG("RecvJSON ~p~n", [RecvJSON]),
case ds_misc:json_get_v(RecvJSON, <<"status">>) of
0 ->
ReceiptData = ds_misc:json_get_v(RecvJSON, <<"receipt">>),
TransactionId = ds_misc:json_get_v(ReceiptData, <<"transaction_id">>),
ProductId = ds_misc:json_get_v(ReceiptData, <<"product_id">>),
{ok, ProductId, TransactionId};
21007 ->
?WARNING_MSG("This receipt is a sandbox receipt, but it was sent to the production service for verification.~n", []),
send_receipt_data_with_url(Base64Data, ?APP_SANDBOX_VERIFY_RECEIPT_URL);
21008 ->
?WARNING_MSG("This receipt is a production receipt, but it was sent to the sandbox service for verification.~n", []),
send_receipt_data_with_url(Base64Data, ?APP_VERIFY_RECEIPT_URL);
Other ->
?WARNING_MSG("fail, receive status:~w~n", [Other]),
?FAIL(?INFO_FAILED_VERIFY_STORE_RECEIPTS)
end
end;
Other ->
?WARNING_MSG("http request error ~p~n", [Other]),
?FAIL(?INFO_HTTP_ERROR)
end.
%% 21000 The App Store could not read the JSON object you provided.
%% 21002 The data in the receipt-data property was malformed.
%% 21003 The receipt could not be authenticated.
%% 21004 The shared secret you provided does not match the shared secret on file for your account.
%% 21005 The receipt server is not currently available.
%% 21006 This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.
%% 21007 This receipt is a sandbox receipt, but it was sent to the production service for verification.
%% 21008 This receipt is a production receipt, but it was sent to the sandbox service for verification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment