Packages

Elixir client library for Stancer payment processor. Provides compile-time metaprogramming-generated API functions for all Stancer endpoints.

Current section

Files

Jump to
ex_stancer README.md
Raw

README.md

# Stancer

Elixir client library for [Stancer](https://stancer.com), a French payment processor. 

Built with **compile-time metaprogramming** to automatically generate 51+ API functions from the OpenAPI specification. Provides a simple, type-safe interface to tokenize cards, create payments, manage refunds, and more.

## Features

- πŸ”§ **51+ API functions** automatically generated from OpenAPI spec at compile time
- πŸ” **Secure by default**: Never logs sensitive data, supports 3D Secure (SCA)
- ⚑ **Minimal dependencies**: Uses `Req` for HTTP and `Jason` for JSON
- πŸ“¦ **Zero config secrets**: API key via standard Elixir config
- πŸ“š **Complete API coverage**: All Stancer endpoints (customers, payments, cards, etc.)
- πŸ§ͺ **Fully tested**: Comprehensive test suite with mocking

## Installation

Add `ex_stancer` to your `mix.exs` dependencies:

```elixir
def deps do
  [
    {:ex_stancer, "~> 0.1"}
  ]
end
```

Then run:
```bash
mix deps.get
```

## Configuration

Add your Stancer API key to your Elixir config:

```elixir
# config/config.exs
config :stancer,
  api_key: System.get_env("STANCER_API_KEY"),
  api_url: "https://api.stancer.com",
  api_version: "v1"
```

## Quick Start

### Tokenize a Card

```elixir
{:ok, card} = Stancer.API.tokens_create(%{
  "card" => %{
    "number" => "4111111111111111",
    "exp_month" => 12,
    "exp_year" => 2026,
    "cvc" => "123"
  }
})
```

### Create a Payment

```elixir
{:ok, payment} = Stancer.API.payments_create(%{
  "amount" => 5000,  # in cents (50€)
  "currency" => "EUR",
  "card" => card["id"],
  "capture" => false  # auth only, capture later
})
```

### Capture a Payment

```elixir
{:ok, result} = Stancer.API.payments_capture(payment["id"], 5000)
```

### Refund a Payment

```elixir
{:ok, result} = Stancer.API.payments_refund(payment["id"])
```

## API Reference

All endpoints follow the pattern `Stancer.API.resource_action(...)`:

- `Stancer.API.customers_list()` β†’ `GET /customers`
- `Stancer.API.customers_create(data)` β†’ `POST /customers`
- `Stancer.API.customers_get(id)` β†’ `GET /customers/{id}`
- `Stancer.API.customers_update(id, data)` β†’ `PUT /customers/{id}`
- `Stancer.API.payments_create(data)` β†’ `POST /payments`
- `Stancer.API.payments_capture(id, amount)` β†’ `POST /payments/{id}/capture`
- ... and 45+ more

See [HexDocs](https://hexdocs.pm/stancer) for the complete API reference.

## Error Handling

All functions return `{:ok, result} | {:error, reason}`:

```elixir
case Stancer.API.payments_create(payment_data) do
  {:ok, payment} -> 
    IO.inspect(payment)
  {:error, reason} -> 
    IO.warn("Payment failed: #{reason}")
end
```

Common errors:
- `"Access Denied"` β†’ Invalid or missing API key
- `"Invalid card"` β†’ Card data incomplete or malformed
- `"Amount too low"` β†’ Minimum is €0.50 (50 cents)

## How It Works

The library uses **compile-time metaprogramming** to generate all API functions:

1. `Stancer.OpenAPILoader` fetches the OpenAPI spec from `https://docs.stancer.com/api/openapi.json`
2. On failure, falls back to a cached version in `priv/openapi.json`
3. The spec is parsed to extract all operations/endpoints
4. An Elixir `for` loop with `unquote` generates each function at compile time
5. Each function has a unique name, correct arity, and type guards

No runtime reflection. No magic. Just pure Elixir metaprogramming.

## Documentation

Documentation can be generated locally with:

```bash
mix docs
open doc/index.html
```

Or view the latest version on [HexDocs](https://hexdocs.pm/stancer).