# `PhoenixKitBilling`
[🔗](https://github.com/BeamLabEU/phoenix_kit_billing/blob/0.5.1/lib/phoenix_kit_billing.ex#L1)

Main context for PhoenixKit Billing system.

Provides comprehensive billing functionality including currencies, billing profiles,
orders, and invoices with manual bank transfer payments (Phase 1).

## Features

- **Currencies**: Multi-currency support with exchange rates
- **Billing Profiles**: User billing information (individuals & companies)
- **Orders**: Order management with line items and status tracking
- **Invoices**: Invoice generation with receipt functionality
- **Bank Payments**: Manual bank transfer workflow

## System Enable/Disable

    # Check if billing is enabled
    PhoenixKitBilling.enabled?()

    # Enable/disable billing system
    PhoenixKitBilling.enable_system()
    PhoenixKitBilling.disable_system()

## Order Workflow

    # Create order
    {:ok, order} = Billing.create_order(user, %{...})

    # Confirm order
    {:ok, order} = Billing.confirm_order(order)

    # Generate invoice
    {:ok, invoice} = Billing.create_invoice_from_order(order)

    # Send invoice
    {:ok, invoice} = Billing.send_invoice(invoice)

    # Mark as paid (generates receipt)
    {:ok, invoice} = Billing.mark_invoice_paid(invoice)

# `available_payment_methods`

Returns list of available payment methods for manual recording.
Bank transfer is always available, plus any enabled providers (Stripe/PayPal/Razorpay).

## Examples

    iex> Billing.available_payment_methods()
    ["bank"]  # Only bank if no providers enabled

    iex> Billing.available_payment_methods()
    ["bank", "stripe", "paypal"]  # Bank + enabled providers

# `calculate_invoice_paid_amount`

Calculates the total paid amount for an invoice from all transactions.

# `calculate_receipt_status`

Calculates the current receipt status based on invoice state and transactions.

# `cancel_order`

Cancels an order.

# `cancel_subscription`

Cancels a subscription.

## Options

- `immediately: true` - Cancel immediately instead of at period end

## Examples

    Billing.cancel_subscription(subscription)
    Billing.cancel_subscription(subscription, immediately: true)

# `change_billing_profile`

Returns a changeset for billing profile form.

# `change_order`

Returns an order changeset for form building.

# `change_payment_option`

Returns a changeset for tracking payment option changes.

# `change_subscription_type`

Changes a subscription's type.

By default, the new type takes effect at the next billing cycle.

# `confirm_order`

Confirms an order.

# `create_billing_profile`

Creates a billing profile.

# `create_checkout_session`

Creates a checkout session for paying an invoice.

Returns the checkout URL to redirect the user to.

## Parameters

- `invoice` - The invoice to pay
- `provider` - Payment provider atom (:stripe, :paypal, :razorpay)
- `opts` - Options forwarded to the provider:
  - `:success_url` - URL to redirect after success (required)
  - `:cancel_url` - URL to redirect if cancelled (defaults to `:success_url`)
  - `:customer_email`, `:save_payment_method`, `:metadata` - optional, provider-dependent

## Examples

    {:ok, url} = Billing.create_checkout_session(invoice, :stripe, success_url: "/success")

# `create_currency`

Creates a currency.

# `create_invoice`

Creates a standalone invoice (without order).

# `create_invoice_from_order`

Creates an invoice from an order.

# `create_order`

Creates an order from attributes (user_uuid included in attrs).

# `create_order`

Creates an order for a user.

# `create_payment_method`

Creates a payment method record.

Usually called after a successful setup session webhook.

# `create_payment_option`

Creates a new payment option.

# `create_setup_session`

Creates a setup session for saving a payment method.

Returns the setup URL to redirect the user to.

## Parameters

- `user_uuid` - The user saving the payment method
- `provider` - Payment provider atom
- `opts` - Options (success_url required)

# `create_subscription`

Creates a new subscription for a user.

This creates the master subscription record. The first payment should be
processed separately via checkout session.

## Parameters

- `user_uuid` - The user creating the subscription (UUID)
- `attrs` - Subscription attributes:
  - `:subscription_type_uuid` - Required: subscription type UUID
  - `:billing_profile_uuid` - Optional: billing profile UUID to use
  - `:payment_method_uuid` - Optional: saved payment method UUID for renewals
  - `:trial_days` - Optional: override type's trial days
  - `:plan_uuid` - Alternative: can use `:plan_uuid` instead of `:subscription_type_uuid`

## Examples

    Billing.create_subscription(user.uuid, %{subscription_type_uuid: type.uuid})
    Billing.create_subscription(user.uuid, %{subscription_type_uuid: type.uuid, trial_days: 14})

    # Using plan_uuid parameter
    Billing.create_subscription(user.uuid, %{plan_uuid: type.uuid})

# `create_subscription_type`

Creates a subscription type.

# `delete_billing_profile`

Deletes a billing profile.

# `delete_currency`

Deletes a currency.

The default currency and currencies referenced by orders cannot be deleted.

# `delete_order`

Deletes an order (only drafts).

# `delete_payment_option`

Deletes a payment option.

# `delete_subscription_type`

Deletes a subscription type.

Types with active subscriptions cannot be deleted.

# `disable_system`

Disables the billing system.

# `enable_system`

Enables the billing system.

# `enabled?`

Checks if the billing system is enabled.

# `format_company_address`

Formats company address from a `company_info` map for document printing.

The map is required (callers pass the result of
`Organization.get_company_info/0`), keeping this function pure.

# `generate_receipt`

Generates a receipt for an invoice.

Receipts can be generated:
- When invoice is fully paid (status: "paid")
- When invoice has any payment (paid_amount > 0) - partial receipt

Receipt status:
- "paid" - fully paid
- "partially_paid" - partial payment received
- "refunded" - fully refunded after payment

# `generate_transaction_number`

Generates a unique transaction number.

# `get_billing_profile`

Gets a billing profile by ID or UUID, returns nil if not found.

# `get_billing_profile!`

Gets a billing profile by ID or UUID, raises if not found.

# `get_company_info`

Returns the company info map used by the printable document views
(invoice, receipt, credit note, payment confirmation).

Combines organization company details and bank details into a single
map of formatted, print-ready strings.

# `get_config`

Returns the current billing configuration.

# `get_currency`

Gets a currency by ID or UUID.

# `get_currency!`

Gets a currency by ID or UUID, raises if not found.

# `get_currency_by_code`

Gets a currency by code.

# `get_dashboard_stats`

Returns dashboard statistics.

# `get_default_billing_profile`

Gets the default billing profile for a user.

# `get_default_currency`

Gets the default currency.

# `get_default_payment_method`

Gets the default payment method for a user.

# `get_invoice`

Gets an invoice by ID or UUID with optional preloads.

# `get_invoice!`

Gets an invoice by ID or UUID.

# `get_invoice_by_number`

Gets an invoice by invoice number.

# `get_invoice_remaining_amount`

Gets the remaining amount for an invoice.

# `get_order`

Gets an order by ID or UUID with optional preloads.

# `get_order!`

Gets an order by ID or UUID.

# `get_order_by_number`

Gets an order by order number.

# `get_order_by_uuid`

Gets an order by UUID with optional preloads.
Used for public-facing URLs to prevent ID enumeration.

# `get_payment_method`

Gets a payment method by ID or UUID.

# `get_payment_option`

Gets a payment option by ID.

# `get_payment_option_by_code`

Gets a payment option by code.

# `get_subscription`

Gets a subscription by ID or UUID.

## Options
  * `:preload` - list of associations to preload (default: [])

# `get_subscription!`

Gets a subscription by ID or UUID, raises if not found.

# `get_subscription_type`

Gets a subscription type by ID or UUID.

# `get_subscription_type_by_slug`

Gets a subscription type by slug.

# `get_tax_rate`

Returns the default tax rate as a Decimal (e.g., Decimal.new("0.20") for 20%).

Uses the billing settings value. When company country is configured,
the suggested rate from BeamLabCountries can be applied via billing settings UI.

# `get_tax_rate_percent`

Returns the default tax rate as integer percentage (e.g., 20 for 20%).

# `get_transaction`

Gets a transaction by ID or UUID.

# `get_transaction!`

Gets a transaction by ID or UUID, raises if not found.

# `get_transaction_by_number`

Gets a transaction by number.

# `list_active_payment_options`

Lists active payment options for checkout.

# `list_billing_profiles`

Lists billing profiles with optional filters.

## Options
- `:user_uuid` - Filter by user UUID
- `:type` - Filter by type ("individual" or "company")
- `:search` - Search in name/email/company fields
- `:page` - Page number
- `:per_page` - Items per page
- `:preload` - Associations to preload

# `list_billing_profiles_with_count`

Lists billing profiles with count for pagination.

# `list_currencies`

Lists all currencies with optional filters.

## Options
- `:enabled` - Filter by enabled status
- `:order_by` - Custom ordering

# `list_enabled_currencies`

Lists enabled currencies.

# `list_invoice_transactions`

Gets transactions for a specific invoice.

# `list_invoices`

Lists all invoices with optional filters.

# `list_invoices_for_order`

Lists invoices for a specific order.

# `list_invoices_with_count`

Lists invoices with count for pagination.

# `list_orders`

Lists all orders with optional filters.

# `list_orders_with_count`

Lists orders with count for pagination.

# `list_payment_methods`

Lists saved payment methods for a user.

# `list_payment_options`

Lists all payment options.

# `list_subscription_types`

Lists all subscription types.

## Options

- `:active_only` - Only return active types (default: true)

# `list_subscriptions`

Lists all subscriptions for a user.

## Options

- `:status` - Filter by status (e.g., "active", "cancelled")
- `:preload` - Associations to preload (default: [:subscription_type])

## Examples

    Billing.list_subscriptions(user_uuid)
    Billing.list_subscriptions(user_uuid, status: "active")

# `list_transactions`

Lists all transactions with optional filters.

## Options

- `:invoice_uuid` - Filter by invoice UUID
- `:user_uuid` - Filter by user who created the transaction
- `:payment_method` - Filter by payment method
- `:type` - Filter by type: "payment" (amount > 0) or "refund" (amount < 0)
- `:search` - Search by transaction number
- `:limit` - Limit results
- `:offset` - Offset for pagination
- `:preload` - Associations to preload

## Examples

    Billing.list_transactions(invoice_uuid: "some-uuid")
    Billing.list_transactions(type: "payment", limit: 10)

# `list_transactions_with_count`

Lists transactions with count for pagination.

# `list_user_billing_profiles`

Lists billing profiles for a user (shorthand).

# `list_user_invoices`

Lists invoices for a specific user.

# `list_user_orders`

Lists orders for a specific user.

# `list_user_subscriptions`

Lists all subscriptions for a specific user.

## Options
  * `:status` - filter by status (e.g., "active", "cancelled")
  * `:preload` - list of associations to preload (default: [:subscription_type])

## Examples

    Billing.list_user_subscriptions(user.uuid)
    Billing.list_user_subscriptions(user.uuid, status: "active")

# `mark_invoice_paid`

Marks an invoice as paid (generates receipt).

# `mark_order_paid`

Marks an order as paid.

## Options

- `:payment_method` - The payment method used (e.g., "bank", "stripe", "paypal")

# `mark_order_refunded`

Marks an order as refunded.

# `mark_overdue_invoices`

Marks overdue invoices.

# `module_stats`

Returns stats for the module card on the admin Modules page.

Runs `get_config/0`, which issues three `count` queries (orders,
invoices, currencies). This is invoked once per render of the admin
Modules card, so the cost is bounded; it is not cached.

# `pause_subscription`

Pauses a subscription.

Paused subscriptions don't renew until resumed.

# `payment_option_requires_billing?`

Checks if a payment option requires a billing profile.

# `record_payment`

Records a payment for an invoice.

Creates a transaction with positive amount and updates invoice's paid_amount.
If paid_amount >= total, marks invoice as paid and generates receipt.

## Parameters

- `invoice` - The invoice to pay
- `attrs` - Transaction attributes including :amount, :payment_method, :description
- `admin_user` - The admin user recording the payment

## Examples

    {:ok, transaction} = Billing.record_payment(invoice, %{amount: "100.00", payment_method: "bank"}, admin)

# `record_refund`

Records a refund for an invoice.

Creates a transaction with negative amount and updates invoice's paid_amount.

## Parameters

- `invoice` - The invoice to refund
- `attrs` - Transaction attributes including :amount (positive value), :description (reason)
- `admin_user` - The admin user recording the refund

## Examples

    {:ok, transaction} = Billing.record_refund(invoice, %{amount: "50.00", description: "Partial refund"}, admin)

# `remove_payment_method`

Removes a payment method.

Marks as removed in database. Should also delete from provider.

# `resume_subscription`

Resumes a paused subscription.

# `send_credit_note`

Sends a credit note email for a refund transaction.

## Parameters

- `invoice` - The invoice associated with the refund
- `transaction` - The refund transaction
- `opts` - Options:
  - `:to_email` - Override recipient email
  - `:credit_note_url` - URL to view credit note online

## Examples

    {:ok, invoice} = Billing.send_credit_note(invoice, transaction, credit_note_url: "https://...")

# `send_credit_note_email`

Sends credit note email to the customer.

# `send_invoice`

Sends an invoice (marks as sent and sends email).

Options:
- `:send_email` - Whether to send email (default: true)
- `:invoice_url` - URL to view invoice online (optional)

# `send_invoice_email`

Sends invoice email to the customer.

# `send_payment_confirmation`

Sends a payment confirmation email for an individual payment transaction.

## Parameters

- `invoice` - The invoice associated with the payment
- `transaction` - The payment transaction
- `opts` - Options including:
  - `:to_email` - Override recipient email address
  - `:payment_url` - URL to view payment confirmation online
  - `:send_email` - Whether to send email (default: true)

# `send_payment_confirmation_email`

Sends payment confirmation email to the customer.

# `send_receipt`

Sends receipt for a paid invoice.

Options:
- `:send_email` - Whether to send email (default: true)
- `:to_email` - Override recipient email address
- `:receipt_url` - URL to view receipt online (optional)

# `send_receipt_email`

Sends receipt email to the customer.

# `set_default_billing_profile`

Sets a billing profile as default.

# `set_default_currency`

Sets a currency as default.

# `set_default_payment_method`

Sets a payment method as the default for a user.

Unsets any existing default.

# `tax_enabled?`

Returns whether tax is enabled in billing settings.

# `toggle_payment_option_active`

Toggles the active status of a payment option.

# `update_billing_profile`

Updates a billing profile.

# `update_currency`

Updates a currency.

# `update_invoice`

Updates an invoice.

# `update_invoice_paid_amount`

Updates an invoice's paid_amount based on its transactions.

# `update_order`

Updates an order.

# `update_payment_option`

Updates a payment option.

# `update_receipt_status`

Updates the receipt status based on current invoice state.
Call this after refunds to update the receipt status.

# `update_subscription`

Updates a subscription with the given attributes.

Useful for administrative adjustments such as extending the billing
period or correcting plan details. Status/lifecycle fields are *not*
updatable here — use the dedicated `cancel_subscription/1`,
`pause_subscription/1`, and `resume_subscription/1` functions instead,
so their broadcasts and bookkeeping always fire.

# `update_subscription_type`

Updates a subscription type.

# `void_invoice`

Voids an invoice.

---

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