Current section
Files
Jump to
Current section
Files
lib/wallet_passes/google/save_url.ex
defmodule WalletPasses.Google.SaveUrl do
@moduledoc "Generates 'Save to Google Wallet' URLs via signed JWTs."
alias WalletPasses.Config
alias WalletPasses.PassType
@doc """
Builds a signed JWT containing the pass object for Google Wallet.
## Options
* `:origins` - List of allowed origins for the save button (optional)
"""
def build_jwt(pass_object, opts \\ []) do
origins = Keyword.get(opts, :origins, [])
pass_type = Keyword.get(opts, :pass_type, :event_ticket)
case load_credentials() do
{:ok, %{"client_email" => email, "private_key" => private_key_pem}} ->
now = DateTime.utc_now() |> DateTime.to_unix()
claims = %{
"iss" => email,
"aud" => "google",
"typ" => "savetowallet",
"iat" => now,
"payload" => %{PassType.google_save_objects_key(pass_type) => [pass_object]},
}
claims =
if origins != [] do
Map.put(claims, "origins", origins)
else
claims
end
signer = Joken.Signer.create("RS256", %{"pem" => private_key_pem})
case Joken.encode_and_sign(claims, signer) do
{:ok, jwt, _claims} -> {:ok, jwt}
{:error, reason} -> {:error, reason}
end
{:error, _} = error ->
error
end
end
@doc """
Builds a full "Save to Google Wallet" URL.
Returns `{:ok, url}` or `{:error, reason}`.
"""
def url(pass_object, opts \\ []) do
case build_jwt(pass_object, opts) do
{:ok, jwt} -> {:ok, "https://pay.google.com/gp/v/save/#{jwt}"}
error -> error
end
end
defp load_credentials do
json_str = Config.google_service_account_json()
json_str =
if File.exists?(json_str) do
File.read!(json_str)
else
json_str
end
Jason.decode(json_str)
rescue
_ -> {:error, :no_google_credentials}
end
end