# Yookassa Elixir Client
An idiomatic Elixir client for the YooKassa API v3. This library provides a simple and convenient way to integrate YooKassa payment processing into your Elixir applications.
## Features
- Create one-stage and two-stage payments.
- Capture or cancel authorized payments.
- Create full and partial refunds.
- Get details for any payment or refund.
- Includes a ready-to-use Plug for handling webhook notifications.
## Installation
Add `yookassa` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:yookassa, "~> 0.1.2"}
]
end
```
Then, run `mix deps.get`.
## Configuration
Add the following configuration to your `config/dev.exs` (for development) or `config/releases.exs` (for production). Using environment variables for secrets is highly recommended.
```elixir
# in config/dev.exs
import Config
config :yookassa,
shop_id: "YOUR_SHOP_ID",
secret_key: "YOUR_TEST_SECRET_KEY",
api_url: "https://api.yookassa.ru/v3"
# Recommended for production:
# config :yookassa,
# shop_id: System.get_env("YOOKASSA_SHOP_ID"),
# secret_key: System.get_env("YOOKASSA_SECRET_KEY"),
# api_url: "https://api.yookassa.ru/v3"
```
## Usage
All functions return `{:ok, response_body}` on success or `{:error, reason}` on failure.
The `response_body` is the decoded JSON from the YooKassa API.
### Idempotency
All `POST` requests automatically include an `Idempotence-Key` header with a unique
UUIDv4 value. This prevents accidental duplicate operations, ensuring that if a
request is sent multiple times, it is processed only once.
### Creating a Payment
By default, payments are created with `capture: true` (one-stage).
```elixir
Yookassa.create_payment("199.50", "RUB", "https://example.com/thanks", "Order #72")
```
### Two-Stage Payments
To create a two-stage payment, pass the `capture: false` option. This will authorize the amount on the user's card without charging it.
```elixir
# Step 1: Authorize the payment
{:ok, payment} = Yookassa.create_payment("500.00", "RUB", "https://example.com/hold", "Table reservation", capture: false)
payment_id = payment["id"]
# After the user pays, the status will be "waiting_for_capture".
# You can now either capture or cancel this payment.
# Step 2 (Option A): Capture the payment to charge the card
{:ok, captured_payment} = Yookassa.capture_payment(payment_id)
# Step 2 (Option B): Cancel the authorization
{:ok, canceled_payment} = Yookassa.cancel_payment(payment_id)
```
### Creating a Refund
You can only refund payments with a `succeeded` status.
```elixir
{:ok, refund} = Yookassa.create_refund("succeeded_payment_id", "50.00", "RUB")
```
### Getting Information
```elixir
# Get details about a specific payment
{:ok, payment_info} = Yookassa.get_payment_info("any_payment_id")
# Get details about a specific refund
{:ok, refund_info} = Yookassa.get_refund_info("any_refund_id")
```
## Handling Webhooks (Optional)
This library provides a `Yookassa.WebhookHandler` Plug to process incoming notifications. **This library does not start a web server for you.** You are responsible for integrating the handler into your own application.
### Example with Plug and Cowboy
1. Add `:plug_cowboy` to your dependencies in `mix.exs`.
2. Add the server to your supervision tree in `lib/my_app/application.ex`. You can choose any port.
```elixir
def start(_type, _args) do
children = [
# ... your other application processes ...
{Plug.Cowboy, scheme: :http, plug: Yookassa.WebhookHandler, options: [port: 8080]}
]
Supervisor.start_link(children, opts)
end
```
3. Set your YooKassa Webhook URL to: `https://your-domain.com/webhook`
### Example with Phoenix Framework
1. Add the route to your `lib/my_app_web/router.ex`. You can choose any path.
```elixir
post "/yookassa_notifications", to: Yookassa.WebhookHandler
```
2. Set your YooKassa Webhook URL to: `https://your-domain.com/yookassa_notifications`