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

The adapter contract between Accrue and payment processors.

`Accrue.Processor` is an Elixir behaviour that defines every processor
operation Accrue can perform — from creating customers to reporting
metered usage. It also acts as a runtime-dispatching facade: callers
always write `Accrue.Processor.create_customer(...)` and the configured
adapter (Stripe in production, Fake in tests) handles the actual work.

## When you reach for this module

Most of the time you won't call `Accrue.Processor` directly — the
`Accrue.Billing` context does that for you. You care about this module
when:

- **Implementing a custom processor adapter** — implement this behaviour
  in your adapter module and point `:processor` config at it.
- **Wiring a test double** — `Accrue.Processor.Fake` already does this;
  configure it in `test.exs` or use `Accrue.Test.setup_fake_processor/1`.
- **Reading telemetry events** — every facade call emits
  `[:accrue, :processor, <resource>, <action>]` spans.

## Callback groups

### Customer
`create_customer/2`, `retrieve_customer/2`, `update_customer/3`

### Subscription
`create_subscription/2`, `retrieve_subscription/2`,
`update_subscription/3`, `cancel_subscription/2`,
`cancel_subscription/3`, `resume_subscription/2`,
`pause_subscription_collection/4`

### SubscriptionItem
`subscription_item_create/2`, `subscription_item_update/3`,
`subscription_item_delete/3`

### SubscriptionSchedule
`subscription_schedule_create/2`, `subscription_schedule_update/3`,
`subscription_schedule_release/2`, `subscription_schedule_cancel/2`,
`subscription_schedule_fetch/2`

### 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`

### Charge and PaymentIntent
`create_charge/2`, `retrieve_charge/2`, `list_charges/2`,
`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`

### Refund
`create_refund/2`, `retrieve_refund/2`

### Coupon and PromotionCode
`coupon_create/2`, `coupon_retrieve/2`,
`promotion_code_create/2`, `promotion_code_retrieve/2`

### Checkout and BillingPortal
`checkout_session_create/2`, `checkout_session_fetch/2`,
`portal_session_create/2`

### Connect
`create_account/2`, `retrieve_account/2`, `update_account/3`,
`delete_account/2`, `reject_account/3`, `list_accounts/2`,
`create_account_link/2`, `create_login_link/2`,
`create_transfer/2`, `retrieve_transfer/2`

### Usage/Meters
`report_meter_event/1`

### Generic refetch
`fetch/2` — routes `(object_type_atom, id)` to the appropriate
`retrieve_*` callback. Used by the webhook handler to re-fetch
objects after receiving an event.

## Return types

All adapter callbacks return `{:ok, map()} | {:error, Accrue.Error.t()}`.
Billing context functions promote the 3DS/SCA path to an
`intent_result` tagged tuple (`{:ok, :requires_action, payment_intent}`)
where applicable.

## Runtime dispatch

The configured adapter is resolved at call time via
`Application.get_env(:accrue, :processor, Accrue.Processor.Fake)`.
To use Stripe in production, add to `config/runtime.exs`:

    config :accrue, processor: Accrue.Processor.Stripe

## Telemetry

The three facade functions (`create_customer/2`, `retrieve_customer/2`,
`update_customer/3`) emit `[:accrue, :processor, :customer, <action>]`
spans. All other operations are instrumented at the `Accrue.Billing`
context level, where the full business operation name is available.

# `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 operations that may require additional
customer authentication. Billing context functions use this union;
processor behaviour callbacks return plain `{:ok, map()}` and the
context layer decides when to promote to `{:ok, :requires_action, map()}`.

# `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*
