# WHMCS\Billing\Invoice

`Class` · extends `AbstractModel` · implements `ImmutableModelInterface`, `TaxableInterface`

A customer's invoice.

The Invoice is the central mechanic upon which the entire WHMCS billing process
is built upon.  Orders request Services based on Products, which are turned into
Invoices to handle payments.  Future payments are then made against invoices until
such time as the Client makes a CancellationRequest for the Product.

Each Invoice is attached to a specific clientId, and contains one or more
invoice line items which actually define the products and prices paid on the invoice.

Tax Rules are configured in Setup -> Payments -> Tax Rules.

Multiple tax rules from each level may be valid for an Invoice, but only the
lowest-numbered-ID tax rule will actually be applied to the Invoice.

Note that $id and $invoiceNumber are completely separate entities.  The $id is
used internally to track the invoice, while the $invoiceNumber is provided to
the client and may be used for other tracking purposes; for example,
VAT tax compliance.

## Traits

- `ImmutableModelTrait`


## Constants

| Name | Description |
|  --- | --- |
| `STATUS_CANCELLED` |  |
| `STATUS_COLLECTIONS` |  |
| `STATUS_DRAFT` |  |
| `STATUS_PAID` |  |
| `STATUS_PAYMENT_PENDING` |  |
| `STATUS_REFUNDED` |  |
| `STATUS_UNPAID` |  |
| `PAYMENT_CONFIRMATION_EMAIL` |  |
| `CC_CONFIRMATION_EMAIL` |  |
| `CC_FAILED_EMAIL` |  |
| `CC_PENDING_EMAIL` |  |
| `DD_CONFIRMATION_EMAIL` |  |
| `DD_FAILED_EMAIL` |  |
| `DD_PENDING_EMAIL` |  |
| `INVOICE_PAYMENT_EMAILS` |  |
| `PAYMENT_CONFIRMATION_EMAILS` |  |
| `PAYMENT_FAILED_EMAILS` |  |
| `PAYMENT_PENDING_EMAILS` |  |


## Properties

| Type | Name | Description |
|  --- | --- | --- |
| `?BillingModelCollection` | `$billingAdjustments` |  |


## Methods

### factoryWithoutStatusIndex

```php
public static function factoryWithoutStatusIndex(): self
```

**Returns** `self`

### boot

```php
public static function boot()
```

### isImmutable

```php
public function isImmutable(): bool
```

### throwImmutabilityException

```php
public function throwImmutabilityException(string $message = '', string $column = ''): never
```

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `string` | `$message` | Exception message, leave empty for default |
| `string` | `$column` | If specified, offending column name will be added to the exception message. |


**Returns** `never`

### validStatusTransitionMap

```php
public static function validStatusTransitionMap(): array
```

**Returns** `array<string,` — array<string>>

### terminalStatuses

```php
public static function terminalStatuses(): array
```

**Returns** `array<string>`

### isStatusTransitionAllowed

```php
public function isStatusTransitionAllowed(string $toStatus): bool
```

### validateMutability

```php
public function validateMutability(?string $attribute): void
```

### getViewInvoiceUrl

```php
public function getViewInvoiceUrl(?array $additionalQueryStringParams = null): string
```

Get view invoice url.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `array|null` | `$additionalQueryStringParams` |  |


**Returns** `string`

### getClientViewLinkMarkup

```php
public function getClientViewLinkMarkup(?string $targetValue = null): string
```

### getAdminViewLinkMarkup

```php
public function getAdminViewLinkMarkup()
```

### getEditInvoiceUrl

```php
public function getEditInvoiceUrl(?array $additionalQueryStringParams = null): string
```

Get Edit Invoice URL.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `array|null` | `$additionalQueryStringParams` |  |


**Returns** `string`

### getEditInvoiceTabUrl

```php
public function getEditInvoiceTabUrl(int $tab, $additionalQueryStringParams = null): string
```

### getRefundInvoiceUrl

```php
public function getRefundInvoiceUrl(?array $additionalQueryStringParams = null): string
```

### getInvoiceNumber

```php
public function getInvoiceNumber()
```

### getCurrency

```php
public function getCurrency()
```

Get currency object for the invoice.

**Returns** `array`

### getCurrencyCodeAttribute

```php
public function getCurrencyCodeAttribute()
```

Get currency code.

**Returns** `string`

### getCurrencyModel

```php
public function getCurrencyModel(): ?Currency
```

### client

```php
public function client()
```

Each invoice belongs to one client.

**Returns** `\Illuminate\Database\Eloquent\Relations\BelongsTo`

### transactions

```php
public function transactions()
```

Each invoice can have many transactions.

**Returns** `\Illuminate\Database\Eloquent\Relations\hasMany`

### items

```php
public function items()
```

Each invoice can have many line items.

**Returns** `\Illuminate\Database\Eloquent\Relations\HasMany`

### snapshot

```php
public function snapshot()
```

Each invoice can have one set of invoice snapshot data.

**Returns** `\Illuminate\Database\Eloquent\Relations\hasOne`

### order

```php
public function order()
```

An invoice can belong to a single order.

**Returns** `BelongsTo`

### servicesProduct

```php
public function servicesProduct(): BelongsToMany
```

### servicesAddon

```php
public function servicesAddon(): BelongsToMany
```

### servicesDomain

```php
public function servicesDomain(): BelongsToMany
```

### scopeUnpaid

```php
public function scopeUnpaid(Builder $query)
```

Where status is unpaid.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopeOverdue

```php
public function scopeOverdue(Builder $query)
```

Where status is overdue.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopePaid

```php
public function scopePaid(Builder $query)
```

Where status is paid.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopeCancelled

```php
public function scopeCancelled(Builder $query)
```

Where status is cancelled.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopeRefunded

```php
public function scopeRefunded(Builder $query)
```

Where status is refunded.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopeCollections

```php
public function scopeCollections(Builder $query)
```

Where status is collections.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopePaymentPending

```php
public function scopePaymentPending(Builder $query)
```

Where status is payment-pending.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopeUnpaidOrPaymentPending

```php
public function scopeUnpaidOrPaymentPending(Builder $query)
```

Where status is unpaid or payment-pending.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopeMassPay

```php
public function scopeMassPay(Builder $query, $isMassPay = true)
```

Where the invoice does not contain a line item that is of type "Invoice".

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |
| `bool` | `$isMassPay` | True if you want to find only Mass Pay invoices, false only non Mass Pay |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### scopeWithLastCaptureAttempt

```php
public function scopeWithLastCaptureAttempt(Builder $query, Carbon $date)
```

Where the last capture date is on a specific date

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `Builder` | `$query` |  |
| `Carbon` | `$date` | The carbon object for the date to obtain data for |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### getBalanceAttribute

```php
public function getBalanceAttribute()
```

Calculate balance remaining for the invoice.

**Returns** `float`

### getInvoiceAmountAttribute

```php
public function getInvoiceAmountAttribute(): float
```

### getPaymentGatewayNameAttribute

```php
public function getPaymentGatewayNameAttribute()
```

**Returns** `string`

### getAmountPaidAttribute

```php
public function getAmountPaidAttribute()
```

**Returns** `float`

### hasRemainingBalanceDue

```php
public function hasRemainingBalanceDue(): bool
```

Remaining balance is the invoice total minus the sum of all
transactions towards the invoice, with consideration of the currency's
decimal/no-decimal format.

Ex. if the invoice total was set to 666.66, and the payment history was
in Japanese Yen (JPY), once there is enough transactions totalling
>= 666.50, this method would return FALSE.  If the payment history was
in USD, the target sum would be >= 666.66 for this method to return FALSE.

**Returns** `bool`

### addPayment

```php
public function addPayment($amount, $transactionId = '', $fees = 0.0, $gateway = '', $suppressEmail = false, Carbon $date = null)
```

"add a payment" means to record a transaction for an invoice, and per
this method, also means updating the invoice status, managing overpayments,
updating services referenced in the invoice, and other invoice-adjacent
observable events.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `float` | `$amount` |  |
| `string` | `$transactionId` |  |
| `float` | `$fees` |  |
| `string` | `$gateway` |  |
| `bool` | `$suppressEmail` |  |
| `Carbon|null` | `$date` |  |


**Returns** `bool`

### addPaymentIfNotExists

```php
public function addPaymentIfNotExists($amount, $transactionId = '', $fees = 0.0, $gateway = '', $noEmail = false, Carbon $date = null)
```

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `float` | `$amount` |  |
| `string` | `$transactionId` |  |
| `float` | `$fees` |  |
| `string` | `$gateway` |  |
| `bool` | `$noEmail` |  |
| `Carbon|null` | `$date` |  |


**Returns** `bool`

### getBillingValues

```php
public function getBillingValues()
```

Calculate recurring billing data for each invoice item.
Each row data subarray can contain additional fields if the payment doesn't cover the entire amount.

**Returns** `array` — payment data [ 'overdue' => bool, [ 'itemId' => string, 'amount' => string, 'setupFee' => string, 'recurringCyclePeriod' => float, 'recurringCycleUnits' => "Months"|"Years"|"Days", 'description' => string, 'lineItemAmount' => string, // If a balance remains on the invoice, the following keys will be present: 'firstPaymentAmount' => string, 'firstCyclePeriod' => float, 'firstCycleUnits' => "Months"|"Years"|"Days" ], [ 'itemId' => string, // ... ] ]

### shouldRenewRun

```php
public function shouldRenewRun($relatedId, $registrationDate, $type = 'Hosting')
```

Checks if the module renewal should run for a provided related id, registration
date and type of item.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `integer` | `$relatedId` | The id of the item for the invoice being paid. tblhosting.id or tblhostingaddons.id |
| `string` | `$registrationDate` | in mysql date format |
| `string` | `$type` | Either one of Hosting or Addon. Exception will be thrown for other item types. |


**Returns** `bool`

### vat

```php
public function vat()
```

**Returns** `Vat`

### newInvoice

```php
public static function newInvoice($clientId, $gateway = null, $taxRate1 = null, $taxRate2 = null)
```

Create a new invoice in Draft and return the instance to be updated and saved.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `integer` | `$clientId` |  |
| `string` | `$gateway` |  |
| `float` | `$taxRate1` |  |
| `float` | `$taxRate2` |  |


**Returns** `Invoice`

### setStatusUnpaid

```php
public function setStatusUnpaid()
```

Set invoice status to unpaid.

**Returns** `Invoice`

### setStatusPending

```php
public function setStatusPending()
```

Set invoice status to payment pending.

**Returns** `Invoice`

### setStatusRefunded

```php
public function setStatusRefunded()
```

Set invoice status to refunded.

**Returns** `Invoice`

### setStatusCancelled

```php
public function setStatusCancelled()
```

Set invoice status to cancelled.

**Returns** `Invoice`

### data

```php
public function data()
```

Each invoice can have one set of invoice data.

**Returns** `\Illuminate\Database\Eloquent\Relations\hasOne`

### transactionHistory

```php
public function transactionHistory()
```

**Returns** `\Illuminate\Database\Eloquent\Relations\HasMany\|History[]`

### debitNotes

```php
public function debitNotes()
```

**Returns** `Builder\|DebitNote[]`

### payMethod

```php
public function payMethod()
```

**Returns** `\Illuminate\Database\Eloquent\Relations\BelongsTo\|PayMethod`

### getPayMethodRemoteToken

```php
public function getPayMethodRemoteToken()
```

**Returns** `string`

### setPayMethodRemoteToken

```php
public function setPayMethodRemoteToken($remoteToken)
```

### deletePayMethod

```php
public function deletePayMethod()
```

### convertLocalCardToRemote

```php
public function convertLocalCardToRemote($remoteToken)
```

### convertLocalBankAccountToRemote

```php
public function convertLocalBankAccountToRemote($remoteToken)
```

### saveRemoteCard

```php
public function saveRemoteCard($cardLastFour, $cardType, $expiryDate, $remoteToken)
```

### saveRemoteBankAccount

```php
public function saveRemoteBankAccount($bankName, $remoteToken)
```

### cart

```php
public function cart()
```

Build a cart object based on the current invoice.

**Returns** `CartCalculator`

### runCreationHooks

```php
public function runCreationHooks($source)
```

Run invoice creation hooks.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `string` | `$source` | One of 'adminarea', 'api', 'autogen' or 'clientarea' |


**Returns** `self`

### getSubscriptionIds

```php
public function getSubscriptionIds($paymentMethods = null)
```

Get subscription IDs from items that belong to this invoice.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `array|null` | `$paymentMethods` |  |


**Returns** `SupportCollection`

### saveSubscriptionId

```php
public function saveSubscriptionId($subscriptionId)
```

Save subscription ID.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `string` | `$subscriptionId` |  |


**Returns** `self`

### scopeSubscriptionId

```php
public function scopeSubscriptionId(Builder $query, $subscriptionId)
```

Where the invoices contain items that have a given subscription ID.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `\Illuminate\Database\Eloquent\Builder` | `$query` |  |
| `string` | `$subscriptionId` |  |


**Returns** `\Illuminate\Database\Eloquent\Builder`

### getLink

```php
public function getLink()
```

### getAdminViewLink

```php
public function getAdminViewLink(): string
```

### setPaymentMethod

```php
public function setPaymentMethod($gatewayName)
```

Set the invoice Payment Method.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `string` | `$gatewayName` | The name of the gateway. (e.g. 'paypal') |


**Returns** `$this`

### setPayMethodId

```php
public function setPayMethodId($payMethodId)
```

Set the Pay Method ID for the invoice.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `int` | `$payMethodId` | The ID of the clients Pay Method to associate. |


**Returns** `$this`

### clearPayMethodId

```php
public function clearPayMethodId()
```

Clear the associated Pay Method

**Returns** `$this`

### getTaxrateAttribute

```php
public function getTaxrateAttribute()
```

### getTaxrate2Attribute

```php
public function getTaxrate2Attribute()
```

### getGatewayInterface

```php
public function getGatewayInterface(): Gateway
```

**Returns** `Gateway`

### updateInvoiceTotal

```php
public function updateInvoiceTotal()
```

Update invoice totals will refresh the model loaded and then process
all the invoice items and appropriate taxes to update the totals on the
invoice and then save.
A save is required prior to calling this method to ensure any 'dirty' data
is not lost. The save should happen before any invoice hooks are run to ensure
that any hook functions have the most up to date information on the invoice
at the point of the hook running.

### calculateInvoiceTotal

```php
public function calculateInvoiceTotal()
```

### removeCredit

```php
public function removeCredit($amount)
```

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `scalar` | `$amount` |  |


### paidAffiliateCommissions

```php
public function paidAffiliateCommissions(): Relation
```

### pendingAffiliateCommissions

```php
public function pendingAffiliateCommissions(): Relation
```

### requiresPayment

```php
public function requiresPayment(): bool
```

Is the invoice in a state in which initiating payment against it is desirable?

**Returns** `bool`

### isUnpaid

```php
public function isUnpaid(): bool
```

Is the invoice marked as unpaid?

**Returns** `bool`

### isAwaitingPayment

```php
public function isAwaitingPayment(): bool
```

Is the invoice expecting a previously initiated payment's completion?

**Returns** `bool`

### isDraft

```php
public function isDraft(): bool
```

### isPaid

```php
public function isPaid(): bool
```

### isCollections

```php
public function isCollections(): bool
```

### isRefunded

```php
public function isRefunded(): bool
```

### isCancelled

```php
public function isCancelled(): bool
```

### canPaymentBeApplied

```php
public function canPaymentBeApplied(): bool
```

Is the invoice in a state in which applying a payment is expected and possible.

**Returns** `bool`

### isProformaInvoice

```php
public function isProformaInvoice(): bool
```

### productGroups

```php
public function productGroups(): SupportCollection
```

All groups related to products of services itemized in the invoice.

**Returns** `SupportCollection<int,` — Group> Group keyed by Group ID

### billingPaymentGateway

```php
public function billingPaymentGateway(): ?PaymentGatewayInterface
```

If the invoice has a PaymentGateway assigned, return it, otherwise NULL.

NOTE: the instance of PaymentGatewayInterface may not be serviceable or active.

**Returns** `PaymentGatewayInterface\|null` — NULL if nothing assigned

### allAvailablePaymentGatewayOptions

```php
public function allAvailablePaymentGatewayOptions(): Collection
```

Legacy understanding, and limited contextual consideration, of "All Gateways"
for use with this invoice.

Callers should consider using {@see Invoice::paymentGatewayOptionsFactory()}
and refining a list appropriate to their context.

Considerations for the returned collection:

* Excluded: non-active or non-serviceable PaymentGateway on the system
* Excluded: PaymentGateways which are "hidden"
* Excluded: The disallowed PaymentGateways of Product Groups related to
invoice's line item Services.
* Included: The payment gateway currently assigned to the invoice, if
active and serviceable (regardless of "hidden" state)


Note: Currency support is not a consideration due to external contexts

**Returns** `Collection<string,` — PaymentGatewayInterface>

### paymentGatewayOptionsFactory

```php
public function paymentGatewayOptionsFactory(): PaymentGatewayOptions
```

A PaymentGatewayOptions factory, primed with an instance of this class.

**Returns** `PaymentGatewayOptions`

### adjustInvoiceForPaymentGatewayOptions

```php
public function adjustInvoiceForPaymentGatewayOptions(PaymentGatewayOptions $options): self
```

Inspect the invoice's assigned PaymentGateway relative to the provided
PaymentGatewayOptions and update the payment method based on those
options.

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `PaymentGatewayOptions` | `$options` |  |


**Returns** `$this`

### credits

```php
public function credits(): HasMany
```

**Returns** `HasMany`

### isFullLineItemSet

```php
public function isFullLineItemSet(SupportCollection $lineItems): bool
```

Returns true if the provided collection of line items matches the full set of invoice line items
(in no specific order)

**Parameters**

| Type | Name | Description |
|  --- | --- | --- |
| `SupportCollection` | `$lineItems` |  |


**Returns** `bool`

### addPaymentForRemainingBalance

```php
public function addPaymentForRemainingBalance()
```

"Mark Paid" with blind application of payment for the remaining balance.

**Returns** `null\|Event\InvoicePayment;`

### allowances

```php
public function allowances(): Allowances
```

### getTax1Amount

```php
public function getTax1Amount(): float
```

### getTax2Amount

```php
public function getTax2Amount(): float
```

### getSubtotal

```php
public function getSubtotal(): float
```

### getAppliedCreditAttribute

```php
public function getAppliedCreditAttribute(): float
```

### appliedCreditAggregator

```php
public function appliedCreditAggregator()
```