Installation
Add :marqeta to your mix.exs:
def deps do
[
{:marqeta, "~> 0.1"}
]
endThen run:
mix deps.get
Configuration
Sandbox
# config/config.exs
config :marqeta,
base_url: "https://sandbox-api.marqeta.com/v3",
application_token: System.fetch_env!("MARQETA_APP_TOKEN"),
admin_access_token: System.fetch_env!("MARQETA_ADMIN_TOKEN"),
sandbox: trueProduction
Production programs get a unique subdomain:
# config/runtime.exs
config :marqeta,
base_url: System.fetch_env!("MARQETA_BASE_URL"), # e.g. https://myprog-api.marqeta.com/v3
application_token: System.fetch_env!("MARQETA_APP_TOKEN"),
admin_access_token: System.fetch_env!("MARQETA_ADMIN_TOKEN"),
pool_size: 25,
sandbox: falseYour First Transaction
Below is a complete end-to-end flow in the sandbox:
# 1. Create a cardholder
{:ok, user} = Marqeta.Users.create(%{
first_name: "Alice",
last_name: "Smith",
email: "alice@example.com",
address1: "1 Market St",
city: "San Francisco",
state: "CA",
postal_code: "94105",
country: "USA",
birth_date: "1985-06-20",
identifications: [%{type: "SSN", value: "987654321"}]
})
# 2. Verify identity (KYC)
{:ok, kyc} = Marqeta.KYCVerification.perform(%{user_token: user["token"]})
IO.puts("KYC status: #{kyc["result"]["status"]}")
# 3. Create a card product
{:ok, cp} = Marqeta.CardProducts.create(%{
name: "My Prepaid Card",
start_date: "2024-01-01",
config: %{
card_life_cycle: %{activate_upon_issue: true},
fulfillment: %{payment_instrument: "VIRTUAL_PAN"},
jit_funding: %{
program_funding_source: %{
funding_source_token: System.fetch_env!("MARQETA_PROGRAM_FUNDING_TOKEN"),
enabled: true
}
}
}
})
# 4. Issue a virtual card
{:ok, card} = Marqeta.Cards.create(%{
user_token: user["token"],
card_product_token: cp["token"]
})
# 5. Fund the user
{:ok, _order} = Marqeta.GPAOrders.create(%{
user_token: user["token"],
amount: 500.00,
currency_code: "USD",
funding_source_token: System.fetch_env!("MARQETA_PROGRAM_FUNDING_TOKEN")
})
# 6. Simulate a purchase (sandbox only)
{:ok, auth} = Marqeta.Simulations.authorization(%{
card_token: card["token"],
amount: 49.99,
mid: "test_merchant_01"
})
IO.puts("Authorization: #{auth["state"]}") # => "PENDING"
{:ok, _} = Marqeta.Simulations.clearing(%{
original_transaction_token: auth["token"],
amount: 49.99
})
# 7. Check balance
{:ok, balance} = Marqeta.Users.balances(user["token"])
IO.puts("Remaining: $#{balance["gpa"]["available_balance"]}") # => "$450.01"Setting Up Webhooks
# Create a webhook endpoint
{:ok, webhook} = Marqeta.Webhooks.create(%{
name: "production",
active: true,
events: ["transaction.*", "cardtransition.*", "usertransition.*"],
config: %{
url: "https://yourapp.com/webhooks/marqeta",
secret: System.fetch_env!("MARQETA_WEBHOOK_SECRET"),
signature_algorithm: "HMAC_SHA_256"
}
})
# Verify it works
{:ok, _} = Marqeta.Webhooks.ping(webhook["token"])In your webhook handler (Phoenix example):
defmodule MyAppWeb.MarqetaController do
use MyAppWeb, :controller
def handle(conn, _params) do
sig = get_req_header(conn, "x-marqeta-signature") |> List.first("")
body = conn.assigns[:raw_body]
secret = Application.fetch_env!(:my_app, :marqeta_webhook_secret)
with true <- Marqeta.Webhooks.valid_signature?(body, sig, secret),
{:ok, event} <- Marqeta.Webhooks.parse_event(body) do
handle_event(event["type"], event)
send_resp(conn, 200, "ok")
else
_ -> send_resp(conn, 401, "unauthorized")
end
end
defp handle_event("transaction." <> _state, event) do
MyApp.TransactionWorker.enqueue(event)
end
defp handle_event("cardtransition." <> _state, event) do
MyApp.CardWorker.process(event)
end
defp handle_event(_type, _event), do: :ok
endTesting Your Integration
defmodule MyApp.MarqetaFlowTest do
use ExUnit.Case, async: true
use Marqeta.Test.BypassHelper
setup do
bypass = Bypass.open()
configure_marqeta(bypass)
{:ok, bypass: bypass}
end
test "full card issuance flow", %{bypass: bypass} do
user = build(:user)
cp = build(:card_product)
card = build(:card, "user_token" => user["token"])
expect_post(bypass, "/users", user, 201)
expect_post(bypass, "/cardproducts", cp, 201)
expect_post(bypass, "/cards", card, 201)
assert {:ok, u} = Marqeta.Users.create(%{first_name: "Test"})
assert {:ok, p} = Marqeta.CardProducts.create(%{name: "Test Product"})
assert {:ok, c} = Marqeta.Cards.create(%{
user_token: u["token"],
card_product_token: p["token"]
})
assert c["state"] == "ACTIVE"
assert c["instrument_type"] == "VIRTUAL_PAN"
end
end