Browse documentationOpen

byrcsc/laravel-payrex · 1.x

Billing statements.

Build, finalize, send, void, and reconcile PayRex billing statements and their line items.

Billing statements are itemized bills PayRex can send to a customer. They are also the package's natural building block for application-managed recurring billing because PayRex has no subscription resource.

The required lifecycle

A payable statement follows this order:

  1. Create a draft.
  2. Add one or more line items.
  3. Update the draft with dueAt.
  4. Finalize the statement.
  5. Send it to the customer.

PayRex drops due_at during creation but requires it during finalization, so the separate update step is intentional.

Create a draft

use ByRcsc\LaravelPayrex\Enums\BillingDetailsCollection;
use ByRcsc\LaravelPayrex\Enums\Currency;
use ByRcsc\LaravelPayrex\Facades\Payrex;

$statement = Payrex::billingStatements()->create(
    customerId: 'cus_...',
    currency: Currency::PHP,
    description: 'July 2026 plan',
    billingDetailsCollection: BillingDetailsCollection::Auto,
    paymentSettings: [
        'payment_methods' => ['card', 'gcash'],
    ],
    metadata: ['billing_cycle' => '2026-07'],
);

Create accepts customerId, currency, description, billingDetailsCollection, paymentSettings, metadata, and options.

Add and change line items

$lineItem = Payrex::billingStatementLineItems()->create(
    billingStatementId: $statement->id,
    unitPrice: 100_000,
    quantity: 5,
    description: 'Five seats',
);

$lineItem->total(); // 500_000

$lineItem = Payrex::billingStatementLineItems()->update(
    id: $lineItem->id,
    quantity: 6,
);

Payrex::billingStatementLineItems()->delete($lineItem->id);

Line items can only change while the parent statement is a draft. PayRex does not expose a retrieve endpoint for a single line item. Retrieve the parent statement and read its lineItems.

Set the due date and finalize

dueAt is a Unix timestamp:

$statement = Payrex::billingStatements()->update(
    id: $statement->id,
    dueAt: now()->addDays(14)->timestamp,
);

$statement = Payrex::billingStatements()->finalize($statement->id);

Updating a draft also supports customerId, description, billingDetailsCollection, paymentSettings, metadata, and options. Finalization locks the contents and makes the statement payable.

Send the statement

$result = Payrex::billingStatements()->send($statement->id);

PayRex currently answers this operation with HTTP 204 and no body, so the method returns null. Its nullable return type leaves room for PayRex to return the resource later.

Void or mark uncollectible

Void a finalized statement that should not have been issued:

$statement = Payrex::billingStatements()->void($statement->id);

Write off a statement that will not be paid:

$statement = Payrex::billingStatements()->markUncollectible($statement->id);

Deleting is available for statements PayRex allows to be deleted:

$deleted = Payrex::billingStatements()->delete($statement->id);

Retrieve and list

$statement = Payrex::billingStatements()->retrieve('bs_...');

$page = Payrex::billingStatements()->list(limit: 25);

foreach (Payrex::billingStatements()->autoPaging() as $statement) {
    // ...
}

$statements = Payrex::billingStatements()->paginate(perPage: 20);

Response properties

The BillingStatement object includes amount, currency, status, customerId, description, statementDescriptor, billingStatementNumber, billingStatementUrl, billingStatementMerchantName, billingDetailsCollection, setupFutureUsage, lineItems, paymentSettings, paymentIntent, customer, dueAt, finalizedAt, metadata, timestamps, and raw.

React to lifecycle events

Typed events cover creation, update, deletion, finalization, sending, payment, overdue and upcoming-due states, voiding, and marking uncollectible. Use them to reconcile local invoices and schedule follow-up work. Keep listeners queued and idempotent.

Laravel PayRex is an unofficial community SDK and is not affiliated with PayRex.

View source