Stancer.Auth (stancer v0.1.0)

Copy Markdown

3D Secure (Strong Customer Authentication) configuration helper.

Provides utilities to create and manage authentication requirements for payments. Inspired by Stancer's Python library, this module accepts multiple formats for auth:

  • String URL → automatically converts to auth object
  • Boolean true → minimal auth object
  • Boolean false → disables auth (returns nil)
  • Map object → uses as-is

Examples

Simple string URL (most common)

auth = Stancer.Auth.coerce("https://myapp.com/payment/success")
# => %{"return_url" => "https://myapp.com/payment/success"}

Using in create_payment

{:ok, payment} = Stancer.create_payment(%{
  "amount" => 5000,
  "currency" => "EUR",
  "card" => card_token,
  "auth" => Stancer.Auth.coerce("https://myapp.com/success")
})

Minimal auth (no return_url)

auth = Stancer.Auth.coerce(true)
# => %{}

Disable auth

auth = Stancer.Auth.coerce(false)
# => nil

Full auth object

auth = Stancer.Auth.new(%{"return_url" => "https://myapp.com/success"})
# => %{"return_url" => "https://myapp.com/success"}

Summary

Functions

Convert various formats to a standard auth map.

Check if auth verification failed.

Create a new auth object with the given attributes.

Extract redirect URL from payment auth response (if 3D Secure verification needed).

Check if payment auth requires 3D Secure verification.

Get the current auth status.

Check if auth is in success/ready state (no further action needed).

Functions

coerce(url)

@spec coerce(String.t() | boolean() | map()) :: map() | nil

Convert various formats to a standard auth map.

Accepts multiple formats for convenience:

  • String (URL) → %{"return_url" => url}
  • Boolean true → %{} (minimal auth)
  • Boolean false → nil (disable auth)
  • Map → returns as-is

This pattern is inspired by Stancer's Python library for ergonomics.

Parameters:

  • value (string | boolean | map) — Auth configuration in any accepted format

Returns: Normalized auth map or nil

Raises: ArgumentError if string is empty

Examples:

Stancer.Auth.coerce("https://myapp.com/success")
# => %{"return_url" => "https://myapp.com/success"}

Stancer.Auth.coerce(true)
# => %{}

Stancer.Auth.coerce(false)
# => nil

Stancer.Auth.coerce(%{"return_url" => "https://myapp.com/success"})
# => %{"return_url" => "https://myapp.com/success"}

failed?(payment)

@spec failed?(map()) :: boolean()

Check if auth verification failed.

Returns true if 3D Secure verification was attempted but failed.

Parameters:

  • payment (map) — Payment object returned from Stancer API

Returns: Boolean

new(attrs \\ %{})

@spec new(map() | nil) :: map() | nil

Create a new auth object with the given attributes.

Parameters:

  • attrs (map, optional) — Auth attributes. Typically just %{"return_url" => "..."}.

Returns: A map representing the auth object, or nil if empty attrs.

Examples:

Stancer.Auth.new(%{"return_url" => "https://myapp.com/success"})
# => %{"return_url" => "https://myapp.com/success"}

Stancer.Auth.new(%{})
# => %{}

redirect_url(payment, opts \\ [])

@spec redirect_url(map(), keyword()) :: String.t() | nil

Extract redirect URL from payment auth response (if 3D Secure verification needed).

When Stancer requires 3D Secure verification, the payment response includes auth.redirect_url. This helper safely extracts it.

Parameters:

  • payment (map) — Payment object returned from Stancer API
  • opts (keyword, optional) — Options (currently unused, for future extension)

Returns: The redirect URL string if present, nil otherwise

Examples:

{:ok, payment} = Stancer.create_payment(%{...})

case Stancer.Auth.redirect_url(payment) do
  url when is_binary(url) -> redirect(conn, external: url)
  nil -> # No 3D Secure needed
end

requires_verification?(payment)

@spec requires_verification?(map()) :: boolean()

Check if payment auth requires 3D Secure verification.

Returns true if the bank requires the customer to verify their identity.

Parameters:

  • payment (map) — Payment object returned from Stancer API

Returns: Boolean

Examples:

{:ok, payment} = Stancer.create_payment(%{...})

if Stancer.Auth.requires_verification?(payment) do
  redirect(conn, external: Stancer.Auth.redirect_url(payment))
else
  # No verification needed, safe to capture
end

status(payment)

@spec status(map()) :: String.t() | nil

Get the current auth status.

Returns the status string from payment auth, or nil if not present.

Possible values:

  • "success" — Verified or not required
  • "request" — Verification required (has redirect_url)
  • "failed" — Verification failed
  • "unavailable" — Card doesn't support 3D Secure

Parameters:

  • payment (map) — Payment object returned from Stancer API

Returns: Status string or nil

Examples:

{:ok, payment} = Stancer.create_payment(%{...})

case Stancer.Auth.status(payment) do
  "request" -> redirect(conn, external: Stancer.Auth.redirect_url(payment))
  "success" -> capture_payment()
  "failed" -> show_error("Verification failed")
  _ -> :ok
end

success?(payment)

@spec success?(map()) :: boolean()

Check if auth is in success/ready state (no further action needed).

Returns true if payment is authorized and ready to capture.

Parameters:

  • payment (map) — Payment object returned from Stancer API

Returns: Boolean

Examples:

{:ok, payment} = Stancer.create_payment(%{...})

if Stancer.Auth.success?(payment) do
  Stancer.API.payments_update(payment["id"], %{"capture" => true})
end