# `Accrue.Processor`
[🔗](https://github.com/szTheory/accrue/blob/accrue-v0.3.0/lib/accrue/processor.ex#L1)

Behaviour every processor adapter implements, plus a runtime-dispatching
facade so every caller looks like `Accrue.Processor.create_customer(...)`
regardless of which adapter is wired.

## Callback surface

Phase 1 shipped the customer callbacks (`create_customer/2`,
`retrieve_customer/2`, `update_customer/3`). Phase 3 (this plan, 03-03)
grows the behaviour to the full Stripe Billing surface needed by Wave 2
billing context functions:

- **Subscription** — `create_subscription/2`, `retrieve_subscription/2`,
  `update_subscription/3`, `cancel_subscription/2`,
  `cancel_subscription/3`, `resume_subscription/2`,
  `pause_subscription_collection/4`
- **Invoice** — `create_invoice/2`, `retrieve_invoice/2`,
  `update_invoice/3`, `finalize_invoice/2`, `void_invoice/2`,
  `pay_invoice/2`, `send_invoice/2`, `mark_uncollectible_invoice/2`,
  `create_invoice_preview/2`
- **PaymentIntent** — `create_payment_intent/2`,
  `retrieve_payment_intent/2`, `confirm_payment_intent/3`
- **SetupIntent** — `create_setup_intent/2`, `retrieve_setup_intent/2`,
  `confirm_setup_intent/3`
- **PaymentMethod** — `create_payment_method/2`,
  `retrieve_payment_method/2`, `attach_payment_method/3`,
  `detach_payment_method/2`, `list_payment_methods/2`,
  `update_payment_method/3`, `set_default_payment_method/3`
- **Charge** — `create_charge/2`, `retrieve_charge/2`, `list_charges/2`
- **Refund** — `create_refund/2`, `retrieve_refund/2`
- **Generic fetch** — `fetch/2` routes `(object_type_atom, id)` to the
  right `retrieve_*` for the webhook DefaultHandler refetch path
  (D3-48 step 3).

All adapters return plain maps (`{:ok, map}`) or
`{:error, Accrue.Error.t()}`; Billing context functions wrap the
3DS/SCA branches into the `intent_result` union where applicable
(D3-06..D3-12).

## Runtime dispatch

The Phase 1 customer functions resolve the concrete adapter at call
time via `Application.get_env(:accrue, :processor, Accrue.Processor.Fake)`.
The Phase 3 callbacks are called directly on the adapter module by
Billing context functions; adapter resolution is via `__impl__/0`.

## Telemetry

Each public Phase 1 call is wrapped in `Accrue.Telemetry.span/3`.
Phase 3 callbacks are telemetered inside the Billing context (Wave 2)
so the instrumentation sees the full business op name, not just the
processor leg.

# `id`

```elixir
@type id() :: String.t()
```

# `intent_result`

```elixir
@type intent_result(ok) ::
  {:ok, ok} | {:ok, :requires_action, map()} | {:error, Accrue.Error.t()}
```

3DS/SCA-aware return type for intent-carrying ops (D3-06). Billing
context functions use this; the processor behaviour returns plain
`{:ok, map()}` and lets the context decide when to tag.

# `opts`

```elixir
@type opts() :: keyword()
```

# `params`

```elixir
@type params() :: map()
```

# `result`

```elixir
@type result() :: {:ok, map()} | {:error, Exception.t()}
```

# `attach_payment_method`

```elixir
@callback attach_payment_method(id(), params(), opts()) :: result()
```

# `cancel_subscription`

```elixir
@callback cancel_subscription(id(), opts()) :: result()
```

# `cancel_subscription`

```elixir
@callback cancel_subscription(id(), params(), opts()) :: result()
```

# `checkout_session_create`

```elixir
@callback checkout_session_create(params(), opts()) :: result()
```

# `checkout_session_fetch`

```elixir
@callback checkout_session_fetch(id(), opts()) :: result()
```

# `confirm_payment_intent`

```elixir
@callback confirm_payment_intent(id(), params(), opts()) :: result()
```

# `confirm_setup_intent`

```elixir
@callback confirm_setup_intent(id(), params(), opts()) :: result()
```

# `coupon_create`

```elixir
@callback coupon_create(params(), opts()) :: result()
```

# `coupon_retrieve`

```elixir
@callback coupon_retrieve(id(), opts()) :: result()
```

# `create_account`
*optional* 

```elixir
@callback create_account(params(), opts()) :: result()
```

# `create_account_link`
*optional* 

```elixir
@callback create_account_link(params(), opts()) :: result()
```

# `create_charge`

```elixir
@callback create_charge(params(), opts()) :: result()
```

# `create_customer`

```elixir
@callback create_customer(params(), opts()) :: result()
```

# `create_invoice`

```elixir
@callback create_invoice(params(), opts()) :: result()
```

# `create_invoice_preview`

```elixir
@callback create_invoice_preview(params(), opts()) :: result()
```

# `create_login_link`
*optional* 

```elixir
@callback create_login_link(id(), opts()) :: result()
```

# `create_payment_intent`

```elixir
@callback create_payment_intent(params(), opts()) :: result()
```

# `create_payment_method`

```elixir
@callback create_payment_method(params(), opts()) :: result()
```

# `create_refund`

```elixir
@callback create_refund(params(), opts()) :: result()
```

# `create_setup_intent`

```elixir
@callback create_setup_intent(params(), opts()) :: result()
```

# `create_subscription`

```elixir
@callback create_subscription(params(), opts()) :: result()
```

# `create_transfer`
*optional* 

```elixir
@callback create_transfer(params(), opts()) :: result()
```

# `delete_account`
*optional* 

```elixir
@callback delete_account(id(), opts()) :: result()
```

# `detach_payment_method`

```elixir
@callback detach_payment_method(id(), opts()) :: result()
```

# `fetch`

```elixir
@callback fetch(atom(), id()) :: result()
```

# `finalize_invoice`

```elixir
@callback finalize_invoice(id(), opts()) :: result()
```

# `list_accounts`
*optional* 

```elixir
@callback list_accounts(params(), opts()) :: result()
```

# `list_charges`

```elixir
@callback list_charges(params(), opts()) :: result()
```

# `list_payment_methods`

```elixir
@callback list_payment_methods(params(), opts()) :: result()
```

# `mark_uncollectible_invoice`

```elixir
@callback mark_uncollectible_invoice(id(), opts()) :: result()
```

# `pause_subscription_collection`

```elixir
@callback pause_subscription_collection(id(), atom(), params(), opts()) :: result()
```

# `pay_invoice`

```elixir
@callback pay_invoice(id(), opts()) :: result()
```

# `portal_session_create`

```elixir
@callback portal_session_create(params(), opts()) :: result()
```

# `promotion_code_create`

```elixir
@callback promotion_code_create(params(), opts()) :: result()
```

# `promotion_code_retrieve`

```elixir
@callback promotion_code_retrieve(id(), opts()) :: result()
```

# `reject_account`
*optional* 

```elixir
@callback reject_account(id(), params(), opts()) :: result()
```

# `report_meter_event`

```elixir
@callback report_meter_event(Accrue.Billing.MeterEvent.t()) ::
  {:ok, map()} | {:error, Exception.t() | term()}
```

# `resume_subscription`

```elixir
@callback resume_subscription(id(), opts()) :: result()
```

# `retrieve_account`
*optional* 

```elixir
@callback retrieve_account(id(), opts()) :: result()
```

# `retrieve_charge`

```elixir
@callback retrieve_charge(id(), opts()) :: result()
```

# `retrieve_customer`

```elixir
@callback retrieve_customer(id(), opts()) :: result()
```

# `retrieve_invoice`

```elixir
@callback retrieve_invoice(id(), opts()) :: result()
```

# `retrieve_payment_intent`

```elixir
@callback retrieve_payment_intent(id(), opts()) :: result()
```

# `retrieve_payment_method`

```elixir
@callback retrieve_payment_method(id(), opts()) :: result()
```

# `retrieve_refund`

```elixir
@callback retrieve_refund(id(), opts()) :: result()
```

# `retrieve_setup_intent`

```elixir
@callback retrieve_setup_intent(id(), opts()) :: result()
```

# `retrieve_subscription`

```elixir
@callback retrieve_subscription(id(), opts()) :: result()
```

# `retrieve_transfer`
*optional* 

```elixir
@callback retrieve_transfer(id(), opts()) :: result()
```

# `send_invoice`

```elixir
@callback send_invoice(id(), opts()) :: result()
```

# `set_default_payment_method`

```elixir
@callback set_default_payment_method(id(), params(), opts()) :: result()
```

# `subscription_item_create`

```elixir
@callback subscription_item_create(params(), opts()) :: result()
```

# `subscription_item_delete`

```elixir
@callback subscription_item_delete(id(), params(), opts()) :: result()
```

# `subscription_item_update`

```elixir
@callback subscription_item_update(id(), params(), opts()) :: result()
```

# `subscription_schedule_cancel`

```elixir
@callback subscription_schedule_cancel(id(), opts()) :: result()
```

# `subscription_schedule_create`

```elixir
@callback subscription_schedule_create(params(), opts()) :: result()
```

# `subscription_schedule_fetch`

```elixir
@callback subscription_schedule_fetch(id(), opts()) :: result()
```

# `subscription_schedule_release`

```elixir
@callback subscription_schedule_release(id(), opts()) :: result()
```

# `subscription_schedule_update`

```elixir
@callback subscription_schedule_update(id(), params(), opts()) :: result()
```

# `update_account`
*optional* 

```elixir
@callback update_account(id(), params(), opts()) :: result()
```

# `update_customer`

```elixir
@callback update_customer(id(), params(), opts()) :: result()
```

# `update_invoice`

```elixir
@callback update_invoice(id(), params(), opts()) :: result()
```

# `update_payment_method`

```elixir
@callback update_payment_method(id(), params(), opts()) :: result()
```

# `update_subscription`

```elixir
@callback update_subscription(id(), params(), opts()) :: result()
```

# `void_invoice`

```elixir
@callback void_invoice(id(), opts()) :: result()
```

# `create_customer`

```elixir
@spec create_customer(params(), opts()) :: result()
```

Creates a customer through the configured processor adapter.

# `retrieve_customer`

```elixir
@spec retrieve_customer(id(), opts()) :: result()
```

Retrieves a customer by id through the configured processor adapter.

# `update_customer`

```elixir
@spec update_customer(id(), params(), opts()) :: result()
```

Updates a customer by id through the configured processor adapter.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
