Skip to content

Billing Statements

Create and manage billing statements for your customers. Billing statements are one-time payment links that contain customer information, a due date, and an itemized list of products or services.

Amounts in Cents

All monetary amounts are in cents (the smallest currency unit). For example, 100000 = ₱1,000.00.

Create a Billing Statement

php
use LegionHQ\LaravelPayrex\Facades\Payrex;

$statement = Payrex::billingStatements()->create([
    'customer_id' => $user->payrexCustomerId(), // or 'cus_xxxxx'
    'payment_settings' => [
        'payment_methods' => ['card', 'gcash'],
    ],
    'billing_details_collection' => 'always',
]);
php
use LegionHQ\LaravelPayrex\Facades\Payrex;

$statement = Payrex::billingStatements()->create([
    'customer_id' => $user->payrexCustomerId(), // or 'cus_xxxxx'
    'description' => 'February 2026 Invoice',
    'payment_settings' => [
        'payment_methods' => ['card', 'gcash', 'maya'],
    ],
]);
php
use LegionHQ\LaravelPayrex\Facades\Payrex;

$statement = Payrex::billingStatements()->create([
    'customer_id' => $user->payrexCustomerId(), // or 'cus_xxxxx'
    'payment_settings' => [
        'payment_methods' => ['card', 'gcash'],
    ],
    'metadata' => ['invoice' => 'INV-001'],
]);

Returns a Billing Statement resource.

Billable Customer

If you've set up the Billable Customer trait, use $user->payrexCustomerId() instead of hardcoding the customer ID:

php
'customer_id' => $request->user()->payrexCustomerId(),

Example Response:

json
{
    "id": "bstm_xxxxx",
    "resource": "billing_statement",
    "amount": 0,
    "currency": "PHP",
    "customer_id": "cus_xxxxx",
    "description": null,
    "status": "draft",
    "line_items": [],
    "livemode": false,
    "billing_statement_merchant_name": null,
    "billing_statement_number": null,
    "billing_statement_url": null,
    "finalized_at": null,
    "statement_descriptor": null,
    "customer": {
        "id": "cus_xxxxx",
        "name": "Juan Dela Cruz",
        "email": "juan@example.com"
    },
    "payment_intent": null,
    "metadata": null,
    "payment_settings": {
        "payment_methods": ["card", "gcash"]
    },
    "setup_future_usage": null,
    "billing_details_collection": "always",
    "due_at": null,
    "created_at": 1721726975,
    "updated_at": 1721726975
}

Parameters

ParameterTypeRequiredDescription
customer_idstringYesCustomer ID (cus_ prefix)
currencystringNoThree-letter ISO currency code. Defaults to config PAYREX_CURRENCY
descriptionstringNoReference text, copied to the payment intent on finalize
billing_details_collectionstringNoalways or auto (default: always)
metadataobjectNoKey-value pairs, copied to the payment intent on finalize
payment_settingsobjectNoPayment method configuration (see below)
payment_settings.payment_methodsarrayNoAllowed methods: card, gcash, maya, qrph. Defaults to your account's enabled methods
payment_settings.payment_method_optionsobjectNoModify payment method behavior (see below)

Payment Settings

php
'payment_settings' => [
    'payment_methods' => ['card', 'gcash', 'maya'],
    'payment_method_options' => [
        'card' => [
            'allowed_bins' => ['123456', '654321'],
            'allowed_funding' => ['credit', 'debit'],
        ],
    ],
],

When creating, supported payment methods are: card, gcash, maya, and qrph. When updating, billease is also available. BDO Installment is not available for billing statements.

Amount Limits

The total billing statement amount (sum of line_items.quantity * line_items.unit_price) must be between ₱20.00 (2,000 cents) and ₱59,999,999.99 (5,999,999,999 cents).

Draft Status

Newly created billing statements start in draft status. The billing_statement_url and payment_intent fields are null until you finalize the statement, which transitions it to open and generates the payment link and associated payment intent.

List Billing Statements

php
$statements = Payrex::billingStatements()->list(['limit' => 10]);

foreach ($statements->data as $statement) {
    echo "{$statement->id}: {$statement->status}";
}

Returns a list of Billing Statement resources.

Example Response:

json
{
    "resource": "list",
    "data": [
        {
            "id": "bstm_xxxxx",
            "resource": "billing_statement",
            "amount": 100000,
            "currency": "PHP",
            "customer_id": "cus_xxxxx",
            "description": null,
            "status": "open",
            "billing_statement_url": "https://bill.payrexhq.com/b/test_bstm_xxxxx_secret_xxxxx",
            "billing_details_collection": "always",
            "due_at": 1721813375,
            "metadata": null,
            "livemode": false,
            "created_at": 1721726975,
            "updated_at": 1721726975
        },
        {
            "id": "bstm_yyyyy",
            "resource": "billing_statement",
            "amount": 250000,
            "currency": "PHP",
            "customer_id": "cus_yyyyy",
            "description": null,
            "status": "draft",
            "billing_statement_url": null,
            "billing_details_collection": "always",
            "due_at": 1721899775,
            "metadata": null,
            "livemode": false,
            "created_at": 1721727000,
            "updated_at": 1721727000
        }
    ],
    "has_more": false
}

Pagination

php
// In a controller — returns a CursorPaginator for UI pagination
$statements = Payrex::billingStatements()->paginate(perPage: 10);

See Pagination for more details on cursor-based pagination.

Retrieve a Billing Statement

php
$statement = Payrex::billingStatements()->retrieve('bstm_xxxxx');

echo $statement->amount;      // 100000
echo $statement->status;      // BillingStatementStatus::Open
echo $statement->customerId;  // 'cus_xxxxx'
echo $statement->customer->name;   // 'Juan Dela Cruz'
echo $statement->billingStatementUrl;         // 'https://bill.payrexhq.com/b/test_...'

Returns a Billing Statement resource.

Update a Billing Statement

php
$statement = Payrex::billingStatements()->update('bstm_xxxxx', [
    'description' => 'Website Maintenance — March 2026',
    'due_at' => now()->addDays(45)->timestamp,
    'payment_settings' => [
        'payment_methods' => ['card', 'gcash', 'maya', 'qrph'],
    ],
]);

Returns a Billing Statement resource.

Parameters

ParameterTypeRequiredDescription
customer_idstringNoCustomer ID (cus_ prefix)
descriptionstringNoReference text, copied to the payment intent on finalize
due_atintegerNoPayment deadline (Unix timestamp). Customers can still pay after this date
billing_details_collectionstringNoalways or auto
metadataobjectNoKey-value pairs, copied to the payment intent on finalize
payment_settingsobjectYesPayment method configuration. The PayRex API requires this field on every update request, even if you're only changing other fields like description or due_at.
payment_settings.payment_methodsarrayNoAllowed methods: card, gcash, maya, billease, qrph
payment_settings.payment_method_optionsobjectNoModify payment method behavior

Example Response:

json
{
    "id": "bstm_xxxxx",
    "resource": "billing_statement",
    "amount": 100000,
    "currency": "PHP",
    "description": "Website Maintenance — March 2026",
    "status": "open",
    "...": "..."
}

Delete a Billing Statement

php
Payrex::billingStatements()->delete('bstm_xxxxx');

Returns a Deleted Resource.

Example Response:

json
{
    "id": "bstm_xxxxx",
    "resource": "billing_statement",
    "deleted": true
}

Finalize a Billing Statement

Finalize a draft billing statement to make it ready for payment. This transitions the status from draft to open, generates a payment URL, and creates the associated payment intent:

php
$statement = Payrex::billingStatements()->finalize('bstm_xxxxx');

echo $statement->status;      // BillingStatementStatus::Open
echo $statement->billingStatementUrl;         // 'https://bill.payrexhq.com/b/test_...'

Returns a Billing Statement resource.

Void a Billing Statement

php
$statement = Payrex::billingStatements()->void('bstm_xxxxx');

echo $statement->status; // BillingStatementStatus::Void

Returns a Billing Statement resource.

Example Response:

json
{
    "id": "bstm_xxxxx",
    "resource": "billing_statement",
    "status": "void",
    "payment_intent": null,
    "...": "..."
}

Mark as Uncollectible

php
$statement = Payrex::billingStatements()->markUncollectible('bstm_xxxxx');

echo $statement->status; // BillingStatementStatus::Uncollectible

Returns a Billing Statement resource.

Send to Customer

Send the billing statement to the customer via email:

php
$statement = Payrex::billingStatements()->send('bstm_xxxxx');

Returns a Billing Statement resource.

Billing Statement Resource

FieldTypeDescription
idstringUnique identifier (bstm_ prefix)
resourcestringAlways billing_statement
amountintegerTotal amount in cents
currencystringThree-letter ISO currency code
customer_idstringAssociated customer ID
statusstringSee BillingStatementStatus
descriptionstring|nullReference text
billing_statement_urlstring|nullCustomer payment link (available when status is open)
billing_statement_merchant_namestring|nullMerchant name on the statement
billing_statement_numberstring|nullStatement number (e.g. A3EAXLGV-0001)
billing_details_collectionstring|nullBilling info collection mode
due_atinteger|nullPayment deadline (Unix timestamp)
finalized_atinteger|nullTimestamp when the statement was finalized
statement_descriptorstring|nullStatement descriptor
line_itemsarray|nullArray of BillingStatementLineItem DTOs
customerstring|Customer|nullAssociated customer (string ID or expanded Customer object)
payment_intentstring|PaymentIntent|nullPayment intent (string ID or expanded PaymentIntent object)
payment_settingsobject|nullPayment method configuration
setup_future_usagestring|nullIndicates if the payment method should be saved for future use
metadataobject|nullKey-value pairs
livemodeboolean|nullLive or test mode (null on expanded relations where the API omits it)
created_atintegerUnix timestamp
updated_atintegerUnix timestamp

Billing Statement Statuses

See Billing Statements Guide — Lifecycle for the full status lifecycle diagram.

StatusDescription
draftThe billing statement is being prepared. Line items, payment settings, and other details can still be modified.
openThe billing statement has been finalized and a payment URL is generated. It is now awaiting payment from the customer.
paidThe customer has successfully paid the billing statement.
voidThe billing statement has been voided and is no longer payable. Use this for statements issued in error.
uncollectibleThe billing statement has been marked as uncollectible. Use this when payment is unlikely to be received.
overdueThe billing statement is past its due date and has not been paid.

Line Item Mutability

Line items can only be added, updated, or deleted while the billing statement is in draft status. Once finalized to open, line items are locked and cannot be modified.

Property Access

Response field names above are shown in snake_case (matching the raw API response). In PHP, access them as camelCase typed properties on the DTO — e.g., billing_statement_url becomes $statement->billingStatementUrl. See Response Data for details.

Further Reading

Released under the MIT License.