Accrue.Processor behaviour (accrue v1.4.0)

Copy Markdown View Source

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 doubleAccrue.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

InvoiceItem

invoice_item_create/2, invoice_item_delete/3

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.

Summary

Types

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()}.

Callbacks

Functions

Returns the declared capability map for the configured processor.

Creates a customer through the configured processor adapter.

True when the configured processor both supports a capability and that capability is part of Accrue's official first-party contract.

Creates an invoice item through the configured processor adapter.

Deletes an invoice item through the configured processor adapter.

Returns the configured processor name used in persisted rows and telemetry.

Retrieves a customer by id through the configured processor adapter.

Returns the public support label for a capability path when one is defined.

True when the configured processor supports the given capability path.

Updates a customer by id through the configured processor adapter.

Types

id()

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

intent_result(ok)

@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()

@type opts() :: keyword()

params()

@type params() :: map()

result()

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

Callbacks

attach_payment_method(id, params, opts)

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

cancel_subscription(id, opts)

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

cancel_subscription(id, params, opts)

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

capabilities()

(optional)
@callback capabilities() :: map()

checkout_session_create(params, opts)

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

checkout_session_fetch(id, opts)

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

confirm_payment_intent(id, params, opts)

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

confirm_setup_intent(id, params, opts)

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

coupon_create(params, opts)

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

coupon_retrieve(id, opts)

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

create_account(params, opts)

(optional)
@callback create_account(params(), opts()) :: result()

create_account_link(params, opts)

(optional)
@callback create_account_link(params(), opts()) :: result()

create_charge(params, opts)

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

create_customer(params, opts)

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

create_invoice(params, opts)

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

create_invoice_preview(params, opts)

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

create_login_link(id, opts)

(optional)
@callback create_login_link(id(), opts()) :: result()

create_payment_intent(params, opts)

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

create_payment_method(params, opts)

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

create_refund(params, opts)

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

create_setup_intent(params, opts)

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

create_subscription(params, opts)

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

create_transfer(params, opts)

(optional)
@callback create_transfer(params(), opts()) :: result()

delete_account(id, opts)

(optional)
@callback delete_account(id(), opts()) :: result()

detach_payment_method(id, opts)

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

fetch(atom, id)

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

finalize_invoice(id, opts)

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

invoice_item_create(params, opts)

@callback invoice_item_create(params(), opts()) :: result()

invoice_item_delete(id, params, opts)

@callback invoice_item_delete(id(), params(), opts()) :: result()

list_accounts(params, opts)

(optional)
@callback list_accounts(params(), opts()) :: result()

list_charges(params, opts)

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

list_payment_methods(params, opts)

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

mark_uncollectible_invoice(id, opts)

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

pause_subscription_collection(id, atom, params, opts)

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

pay_invoice(id, opts)

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

portal_session_create(params, opts)

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

processor_name()

(optional)
@callback processor_name() :: String.t()

promotion_code_create(params, opts)

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

promotion_code_retrieve(id, opts)

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

reject_account(id, params, opts)

(optional)
@callback reject_account(id(), params(), opts()) :: result()

report_meter_event(t)

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

resume_subscription(id, opts)

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

retrieve_account(id, opts)

(optional)
@callback retrieve_account(id(), opts()) :: result()

retrieve_charge(id, opts)

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

retrieve_customer(id, opts)

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

retrieve_invoice(id, opts)

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

retrieve_payment_intent(id, opts)

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

retrieve_payment_method(id, opts)

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

retrieve_refund(id, opts)

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

retrieve_setup_intent(id, opts)

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

retrieve_subscription(id, opts)

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

retrieve_transfer(id, opts)

(optional)
@callback retrieve_transfer(id(), opts()) :: result()

send_invoice(id, opts)

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

set_default_payment_method(id, params, opts)

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

subscription_item_create(params, opts)

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

subscription_item_delete(id, params, opts)

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

subscription_item_update(id, params, opts)

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

subscription_schedule_cancel(id, opts)

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

subscription_schedule_create(params, opts)

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

subscription_schedule_fetch(id, opts)

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

subscription_schedule_release(id, opts)

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

subscription_schedule_update(id, params, opts)

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

update_account(id, params, opts)

(optional)
@callback update_account(id(), params(), opts()) :: result()

update_customer(id, params, opts)

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

update_invoice(id, params, opts)

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

update_payment_method(id, params, opts)

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

update_subscription(id, params, opts)

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

void_invoice(id, opts)

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

Functions

capabilities()

@spec capabilities() :: map()

Returns the declared capability map for the configured processor.

New first-party adapters should implement capabilities/0 so callers can branch on supported slices without assuming Stripe parity.

create_customer(params, opts \\ [])

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

Creates a customer through the configured processor adapter.

first_party_supported?(path)

@spec first_party_supported?(atom() | [atom()]) :: boolean()

True when the configured processor both supports a capability and that capability is part of Accrue's official first-party contract.

invoice_item_create(params, opts \\ [])

@spec invoice_item_create(params(), opts()) :: result()

Creates an invoice item through the configured processor adapter.

invoice_item_delete(id, params \\ %{}, opts \\ [])

@spec invoice_item_delete(id(), params(), opts()) :: result()

Deletes an invoice item through the configured processor adapter.

name()

@spec name() :: String.t()

Returns the configured processor name used in persisted rows and telemetry.

Adapters may expose processor_name/0 for an explicit identifier. Legacy adapters that do not implement it fall back to a snake-cased module tail.

retrieve_customer(id, opts \\ [])

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

Retrieves a customer by id through the configured processor adapter.

support_label(path)

@spec support_label(atom() | [atom()]) :: String.t() | nil

Returns the public support label for a capability path when one is defined.

supports?(path)

@spec supports?(atom() | [atom()]) :: boolean()

True when the configured processor supports the given capability path.

Accrue.Processor.supports?([:checkout, :embedded])
Accrue.Processor.supports?([:subscription, :cancel_immediately])

update_customer(id, params, opts \\ [])

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

Updates a customer by id through the configured processor adapter.