smskin/laravel-billing

laravel项目的计费模块

1.0.0 2024-05-06 13:27 UTC

This package is auto-updated.

Last update: 2024-09-06 14:17:52 UTC


README

描述

此模块支持与计费系统的同步和异步交互。

概念

任何对象都可以参与计费。为此,只需实现Billingable接口并包含BillingableTrait。计费系统不在乎它是一个数据库中的对象还是只是一个具有静态声明属性的类。

应用

  • 作为用户的计费对象(从一个用户向另一个用户转账资金)
  • 作为会计系统中的账户的计费对象(例如,用户的自有账户和信用账户)
  • 作为业务流程的一部分的计费对象(例如,客户 -> 任务 -> 执行者)

安装

composer require smskin/laravel-billing
php artisan vendor:publish --provider="SMSkin\Billing\Providers\ServiceProvider"

这将创建

  • 一个配置文件在/config/billing.php
  • 一个数据库迁移文件在/database/migrations/<date>_create_billing_operations_table.php

如果需要,您可以在配置文件中更改存储计费操作的表名(billing.table)。

php artisan migrate

基本用法

要开始使用计费,您需要创建一个实现Billingable接口的对象。为了方便,准备了一个Trait,它实现了部分接口方法 - BillingableTrait。

<?php

namespace App\Console\Commands;

use SMSkin\Billing\Contracts\Billingable;
use SMSkin\Billing\Traits\BillingableTrait;

class User1 implements Billingable
{
    use BillingableTrait;

    /**
     * Object subsystem
     * @return string
     */
    function getBillingSubsystem(): string
    {
        return 'internal';
    }

    /**
     * Object type
     * @return string
     */
    function getBillingType(): string
    {
        return 'user';
    }

    /**
     * Object identity
     * @return string
     */
    function getBillingId(): string
    {
        return 1;
    }
}

现在您可以创建一个User1对象的实例,并获取其在系统中的余额

$user1 = new User1;
$balance = $user1->getBalance();

余额 = 收入操作的总和 - 支出操作的总和

模块功能

  • getBalances - 批量检索多个实体的余额(在一个数据库操作中执行)
  • increaseBalance - 增加实体余额(同步)
  • increaseBalanceAsync - 增加实体余额(异步)
  • decreaseBalance - 减少实体余额(同步)
  • decreaseBalanceAsync - 减少实体余额(异步)
  • transfer - 从一个实体的余额向另一个实体的余额转账资金(同步)
  • transferAsync - 从一个实体的余额向另一个实体的余额转账资金(异步)
  • transferToMultipleRecipients - 从一个实体的余额向多个实体的余额转账资金(同步)
  • transferToMultipleRecipientsAsync - 从一个实体的余额向多个实体的余额转账资金(异步)
  • createOperationsReport - 报告计费操作

getBalances

有时需要同时检索多个实体的余额。

Example usage:
We have 2 accounts belonging to one user. For example, an account in the system and a card account. With this method, you can retrieve the balances of both objects with a single request.
$account1 = new User1Own;
$account2 = new User1Card;
$balances = (new Billing)->getBalances(
    (new GetBalancesRequest)
        ->setAccounts(collect([$account1, $account2]))
);
Illuminate\Support\Collection {#681
  #items: array:2 [
    0 => SMSkin\Billing\Models\Balance {#678
      #account: App\Console\Commands\User1Own {#661}
      #balance: 680.0
    }
    1 => SMSkin\Billing\Models\Balance {#674
      #account: App\Console\Commands\User1Card {#662}
      #balance: 150.0
    }
  ]
  #escapeWhenCastingToString: false
} 

increaseBalance

此方法用于从系统外部为实体余额充值。

$user1 = new User1Own();
(new Billing())->increaseBalance(
    (new BalanceOperationRequest())
        ->setOperationId(Str::uuid())
        ->setTarget($user1)
        ->setAmount(1000)
);

在同步执行中,您可能会收到以下异常之一

  • NotUniqueOperationId - 传递了一个非唯一操作ID
  • AmountMustBeMoreThan0 - 操作金额必须 > 0
$user1 = new User1Own();
(new Billing())->increaseBalanceAsync(
    (new BalanceOperationRequest())
        ->setOperationId(Str::uuid())
        ->setTarget($user1)
        ->setAmount(1000)
);

在异步执行中,当接收到事件时,将向EventBus发送一个事件

  • EBalanceIncreaseCompleted
  • EBalanceIncreaseFailed

这两个事件都将传递输入属性,而EBalanceIncreaseFailed事件将传递一个异常实例。

decreaseBalance

此方法用于从系统中提取实体的余额。

$user1 = new User1Own();
(new Billing())->decreaseBalance(
    (new BalanceOperationRequest())
        ->setOperationId(Str::uuid())
        ->setTarget($user1)
        ->setAmount(1000)
);

在同步执行中,您可能会收到以下异常之一

  • MutexException - 锁定付款发送方实体时出错(并行操作)
  • NotUniqueOperationId - 传递了一个非唯一操作ID
  • AmountMustBeMoreThan0 - 操作金额必须 > 0
  • InsufficientBalance - 余额不足
$user1 = new User1Own();
(new Billing())->decreaseBalanceAsync(
    (new BalanceOperationRequest())
        ->setOperationId(Str::uuid())
        ->setTarget($user1)
        ->setAmount(1000)
);

在异步执行中,当接收到MutexException时,5秒后提供重启。

在异步执行中,当接收到事件时,将向EventBus发送一个事件

  • EDecreaseBalanceCompleted
  • EDecreaseBalanceFailed

这两个事件都将传递输入属性,而EDecreaseBalanceFailed事件将传递一个异常实例。

transfer

此方法用于从一个实体的余额向另一个实体的余额转账资金。

$user1 = new User1();
$user2 = new User2();
(new Billing())->transfer(
    (new TransferRequest())
        ->setOperationId(Str::uuid())
        ->setSender($user1)
        ->setRecipient($user2)
        ->setAmount(100)
);

在同步执行中,您可能会收到以下异常之一

  • MutexException - 锁定付款发送方实体时出错(并行操作)
  • NotUniqueOperationId - 传递了一个非唯一操作ID
  • AmountMustBeMoreThan0 - 操作金额必须 > 0
  • InsufficientBalance - 余额不足
  • RecipientIsSender - 发送方和接收方是同一实体

在异步执行中,当接收到MutexException时,5秒后提供重启。

在异步执行中,当接收到事件时,将向EventBus发送一个事件

  • ETransferCompleted
  • ETransferFailed

这两个事件都将传递输入属性,而ETransferFailed事件将传递一个异常实例。

transferToMultipleRecipients

此方法用于向多个收款实体转账。

Example usage:
With a single transaction, you need to send a payment to the recipient + withhold a commission fee on the system's account. If there are not enough funds for both operations, an error should be issued.
$user1 = new User1();
$user2 = new User2();
$user3 = new User3();
(new Billing())->transferToMultipleRecipients(
    (new TransferToMultipleRecipientsRequest())
        ->setSender($user1)
        ->setPayments(collect([
            (new Payment())
                ->setOperationId(\Str::uuid())
                ->setRecipient($user2)
                ->setAmount(50),
            (new Payment())
                ->setOperationId(Str::uuid())
                ->setRecipient($user3)
                ->setAmount(170)
            ]))
);

在同步执行中,您可能会收到以下异常之一

  • MutexException - 锁定付款发送方实体时出错(并行操作)
  • NotUniqueOperationId - 传递了一个非唯一操作ID
  • AmountMustBeMoreThan0 - 操作金额必须 > 0
  • InsufficientBalance - 余额不足
  • RecipientIsSender - 发送方和接收方是同一实体

在异步执行中,当接收到MutexException时,5秒后提供重启。

在异步执行中,当接收到事件时,将向EventBus发送一个事件

  • EBulkTransferCompleted
  • EBulkTransferFailed

这两个事件将传递输入属性,EBulkTransferFailed 事件将传递一个 Exception 实例。

createOperationsReport

生成余额报告的方法。 开发中

$report = (new Billing)->createOperationsReport(
    (new CreateOperationsReportRequest)
        ->setPerPage(25)
        ->setPage(1)
);