Download the PHP package atannex/billing without Composer

On this page you can find all versions of the php package atannex/billing. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package billing

atannex/billing

Tests

Payments for Laravel across Stripe, MTN Mobile Money, Orange Money, PayPal and Flutterwave, behind one API. It was built for Cameroon first (XAF, MTN and Orange numbers, mobile money that settles minutes later) and works the same for card payments anywhere.

What you get:

Install

The provider is auto-discovered. It registers its tables (billing_payments, billing_refunds, billing_payment_events, billing_webhook_calls), three routes and a scheduled billing:reconcile every minute. Make sure the scheduler runs (php artisan schedule:work locally, or cron in production).

Configure

Each gateway turns on when its credentials are present. php artisan billing:gateways shows what is enabled and in which routing order.

In the MTN sandbox, API users are created through the API rather than a dashboard:

The sandbox only accepts EUR, so currency_map sends XAF as EUR there and reads it back as XAF. The same mechanism maps XAF → OUV in the Orange sandbox.

Callback URLs to give each provider

Provider URL
Stripe (dashboard → Webhooks) https://your-site/billing/webhooks/stripe
PayPal (app → Webhooks) https://your-site/billing/webhooks/paypal
Flutterwave (settings → Webhooks) https://your-site/billing/webhooks/flutterwave
MTN, Orange Sent with each payment (…/webhooks/mtn_momo/PAY-…); nothing to set up

Taking payments

Narrow the choice with ->method('card' | 'mobile_money' | 'wallet' | 'bank'), or force a gateway with ->via('stripe'). A forced gateway skips routing and failover. Billing::minor(1250, 'USD') takes cents.

What to do next depends on the status:

For the "approve the prompt on your phone" screen, poll the status route. It checks with the provider when the payment hasn't been updated for a few seconds, so the page learns the outcome even when the callback never arrives:

Hosted pages send the payer back to GET /billing/return/{reference}. Billing asks the provider for the status (it never trusts the query string), captures PayPal orders, then redirects to your returnTo() URL with ?payment=PAY-…&status=succeeded.

Models

Override billingName(), billingEmail() or billingPhone() on a Billable model when its attributes have other names. Payable and Billable both define payments(), so don't use both on one model.

Payment API

Refunds

Refunds lock the payment and count refunds still in flight, so two concurrent refunds can't exceed the amount paid. Providers that settle refunds later (MTN, sometimes Stripe and PayPal) are followed up by billing:reconcile and webhooks. Orange Money has no public refund API, so refund() throws UnsupportedCapability for it.

Events

All payment events fire once, after the database commit:

Event When
PaymentInitiated The provider accepted the payment
PaymentStatusChanged Any transition ($from, $to, $source: api, webhook, return, poll, reconcile)
PaymentSucceeded Money confirmed, amount checked. Fulfil orders here.
PaymentFailed Failed, cancelled or expired
PaymentRequiresAction The payer must act
PaymentRefunded / RefundFailed A refund settled
AmountMismatch The provider reported another amount. Investigate.
WebhookHandled Any verified notification, including types billing ignores

Routing

A gateway is eligible when it is enabled, its currencies include the payment's currency (or the list is empty), its methods include the requested method, and, if it lists operators, the payer's number belongs to one of them. Push gateways (MTN, Orange merchant) also need a phone number. Billing::router()->candidates('XAF', null, Msisdn::parse('699…')) shows the decision, and billing:gateways shows the table.

Phone numbers are normalized by Atannex\Billing\Support\Msisdn ("677 12 34 56", "+237677123456", "00237…" all become 237677123456). Operator prefixes and calling codes live in config/billing.php; adjust them when a regulator reassigns a range.

Reconciliation

Mobile money is asynchronous, and callbacks get lost or arrive late. Each open payment carries next_check_at and expires_at (from the gateway's expires_after). billing:reconcile runs every minute and checks due payments on the reconcile.backoff schedule, with the last check placed exactly at expiry. A payment still unanswered at expiry becomes expired. If the provider later reports success through a callback or a manual refresh, it moves to succeeded and the ledger records a late_success.

Set BILLING_QUEUE=payments to check payments through queued ReconcilePayment jobs instead of inline. Set reconcile.schedule to false if you schedule the command yourself.

Testing your app

For local development without credentials, enable the fake gateway ('enabled' => true, 'outcome' => 'requires_action'). Its redirect goes straight to the return page and the payment succeeds.

Writing a driver

Then add it under gateways with 'driver' => 'cinetpay'. Drivers only translate. send() applies the error policy (unreachable or 5xx → GatewayUnavailable, other failures → GatewayException with the provider's message), token() caches OAuth tokens, and the processor handles state, amounts, locking, the ledger and events. Return the provider's charged amount in Snapshot::$amount to get mismatch protection.

Commands

Notes

Testing the package

License

MIT


All versions of billing with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
guzzlehttp/guzzle Version ^7.8
illuminate/cache Version ^11.0|^12.0
illuminate/console Version ^11.0|^12.0
illuminate/database Version ^11.0|^12.0
illuminate/events Version ^11.0|^12.0
illuminate/http Version ^11.0|^12.0
illuminate/queue Version ^11.0|^12.0
illuminate/routing Version ^11.0|^12.0
illuminate/support Version ^11.0|^12.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package atannex/billing contains the following files

Loading the files please wait ...