mdhesari/cashier

官方Vander包,方便访问Vander文档

dev-master 2023-07-25 10:05 UTC

This package is auto-updated.

Last update: 2024-09-25 12:47:46 UTC


README

GitHub license GitHub Workflow Status Packagist Downloads Packagist PHP Version Support Laravel Version Support

Vandar Cashier 是一个Laravel包,提供了与Vandar服务的无缝集成。查看Vandar文档以获取我们提供的服务更多信息。

设置

要使用Vandar Cashier,您需要先通过Composer安装它

composer require vandarpay/cashier

然后,您需要发布包的资产并将您的项目数据库迁移以添加Vandar Cashier的表

php artisan vendor:publish --provider="Vandar\\Cashier\\VandarCashierServiceProvider"
php artisan migrate

之后,打开您的用户模型(位于大多数项目的 app/User.phpapp/Models/User.php)并添加 Billable 特性

use Vandar\Cashier\Traits\Billable;
// ...
class User extends Authenticatable
{
    use Billable;
// ...

您需要将必要的配置添加到您的 .env 文件中

VANDAR_MOBILE=
VANDAR_PASSWORD=
VANDAR_BUSINESS_SLUG=
VANDAR_API_KEY=

VANDAR_MOBILEVANDAR_PASSWORD 是您登录Vandar仪表板的凭证,VANDAR_BUSINESS_SLUG 是您在Vandar中添加业务时设置的,VANDAR_API_KEY 是通过您的业务仪表板获得的。

使用

目前,Vandar Cashier 支持Vandar的三项服务: IPG直接借记结算。IPG是一种更常见的提供用户支付服务链接的方法。直接借记服务通过请求从用户的银行账户访问并定期扣除,无需用户交互。

IPG

独立

如果您正在创建捐赠表单,或者不需要登录用户进行支付,您需要两个路径。第一个路径是启动支付并将其发送到支付网关。第二个路径(也称为回调URL)将在您的用户返回后验证交易。

use Vandar\Cashier\Models\Payment;
Route::get('/initiate-payment', function(Request $request) {
    // Amounts are in IRR
    // For more values, see Payment or https://vandarpay.github.io/docs/ipg/#step-1
    $payment = Payment::create(['amount' => 10000]);
    return redirect($payment->url);
});

用户依赖

在用户依赖场景中,我们假设任何进行支付的用户已经登录到您的系统,因此,您可以创建一个支付链接,并通过用户模型将其重定向到用户。

Route::get('/initiate-payment', function(Request $request){
    $user = auth()->user(); // Added as a separate variable for clarity
    // Amounts are in IRR
    // For more values, see Payment or https://vandarpay.github.io/docs/ipg/#step-1
    $payment = $user->payments()->create(['amount' => 10000]);
    return redirect($payment->url); // See documentation for info on payload and callback
});

回调URL

一旦交易完成(成功或不成功),他们将被重定向回您定义的回调路径,您可以使用 Payment::verify($request) 方法定义控制器或路由以验证支付。

use Vandar\Cashier\Models\Payment;
Route::get('/callback', function(Request $request){
    if(Payment::verifyFromRequest($request)){
        return 'Success!';
    } 
    else {
        return 'Failed!';
    }
});

验证方法会自动更新数据库中的交易状态。

对于IPG,您还需要为用户从Vandar返回到您的应用程序定义一个回调URL,您可以通过设置 VANDAR_CALLBACK_URL 环境变量或修改 config/vandar.php 来完成此操作。您还需要在Vandar的业务仪表板中添加回调URL,否则会导致错误。

直接借记

设置直接借记时,您需要采取两个主要步骤。

  1. 让用户允许访问他们的账户(也称为授权)
  2. 从用户的账户请求提款

授权

授权基本上是客户给予我们访问其账户的许可。在Vandar中,客户由他们的电话号码定义,这是客户的键。如果您计划在项目中使用订阅服务,您需要在用户表中添加一个 mobile_number 列。此代码可以用作迁移,将此类列添加到表中。

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddMobileNumbersColumnToUsersTable extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('mobile_number')->nullable();
        });
    }
    
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
           $table->dropColumn('mobile_number');
        });
    }
}

您还可以在传递给 authorizeMandate 的数组中传递 mobile_number 键。

然后,您可以为授权创建一个授权并重定向用户到银行进行授权

Route::get('/initiate-mandate', function(){
    $user = auth()->user();
    if(! $user->hasValidMandate()){ // You may use the hasValidMandate method if your design requires each user to have only one active mandate
    return redirect($user->authorizeMandate(['bank_code' => '062', 'count' => 3, 'limit' => '10000', 'expiration_date' => '2021-01-01']));
    }
})

您还需要为用户完成授权过程后返回的路径定义一个回调URL,此路径应通过 VANDAR_MANDATE_CALLBACK_URL 设置为绝对URL或通过编辑配置文件来设置。

您可以使用 Mandate::verifyFromRequest 方法验证授权是否成功执行,并相应地更新授权。

use Vandar\Cashier\Models\Mandate;
Route::get('/mandate-callback', function(Request $request){
    if(Mandate::verifyFromRequest($request)){
        return 'Success!';
    } else {
        return 'Failed!';
    }
})

您也可以通过授权模型的撤销功能撤销任何授权。

use Vandar\Cashier\Models\Mandate

$mandate = Mandate::find(1);
$mandate->revoke(); // true if mandate was revoked successfully

由于用户取消授权的唯一方式是通过您的平台,因此提供一种方便用户取消授权的方式是标准的。

提款

一旦授权成功创建,您可以通过授权创建提款。

$user->mandates()->active()->first()->createWithdrawal(['amount' => 10000, 'is_instant' => true, 'description' => 'Subscription renewal', 'max_retry_count' => 16]);

请注意,您可以使用任何您喜欢的方法查找您当前的授权,例如,如果您为每个用户有多个授权,您可以使用不同的查询来查找该特定的授权。

在创建新的提款时,传递 authorization_idnotify_url 不是必需的,因为 Cashier 会自动设置这些值。

注意:如果没有提供,Vandar Cashier 会自动将 withdrawal_date 设置为当前时间。(date('Y-m-d'))

如果您不是创建即时提款(is_instant = false),您还可以在提款运行之前取消提款。

$status = $withdrawal->cancel(); // Returns 'CANCELED' on success, any other status (DONE, PENDING, INIT, FAILED) on failure.

结算

Vandar Cashier 提供了发起结算请求的能力。

$settlement = Settlement::create(['amount' => 5000, 'iban' => 'IR000000000000000000000000']) // amount is in Toman

一旦结算成功创建,Vandar 将将结算排队并发送到银行。当结算最终确定后,将通过 vandar 配置中的 settlement_notify_url 指定的 URL 发送通知。

Vandar Cashier 提供了一条路由,可以自动处理结算更新并相应地更新您的数据库,因此除非您需要实现自己的解决方案,否则您不需要更新 settlement_notify_url

您也可以在结算完成之前通过取消方法取消结算,如果成功,将返回 CANCELED。如果取消尝试失败,则从数据库返回最后一个已知的状态。

$settlement->cancel(); // Returns `CANCELED` on success.

实用工具

您可以使用 Vandar::getBanksHealth() 方法获取一个包含所有银行及其是否健康的数组的数组。

错误处理

在与 Vandar API 通信时,由于在 API 中处理您的请求时出现错误,可能会引发一系列异常。所有这些错误都可以通过 Vandar\Exceptions\ResponseException 异常来捕获和处理。这意味着 Cashier 引发的所有异常都有以下方法

try {
    ...
} catch (\Vandar\Cashier\Exceptions\ResponseException $exception) {
    dump($exception->context()) // Dumps all the information passed into Guzzle, including headers and configuration
    dump($exception->getUrl()) // Dumps the url the request was sent to
    dump($exception->getPayload()) // Dumps the payload that was sent to Vandar APIs
    dump($exception->getResponse()) // Dumps the response object returned by Guzzle
    dump($exception->getResponse()->json()) // Returns an associative array of json response.
    dump($exception->errors()) // Useful especially in InvalidPayloadException, returns the "errors" key in the json response
}

您还可以尝试根据引发的异常来区分错误

  • ExternalAPIException 在发生任何 5xx 错误时引发
  • AuthenticationException 在出现 HTTP 401 错误时引发,这可能仅发生在您忘记设置您的环境或您的信息无效的情况下,如果这种情况发生,请让我们知道!
  • DeprecatedAPIException 在发生 HTTP 404、405 或 410 错误时引发,这通常意味着您使用的 Vandar Cashier 版本(及其背后的 API)不再由 Vandar 支持,运行 composer update
  • InvalidPayloadException 在尝试的操作以任何方式在 Vandar 方面无效并引发 HTTP 422 时引发。(例如,您有权限提取 1000 托曼,您尝试提取更多),我们计划在未来将其分解为更具体的异常。
  • TooManyRequestsException 在您在短时间内向 Vandar 发送大量请求时引发,导致 HTTP 429 错误。
  • UnexpectedAPIErrorException 在返回不在 Vandar Cashier 范围内的任何其他 4xx 系列错误时引发。如果发生这种情况,请考虑更新 Cashier 或提交有关您获得的异常完整上下文的错误报告。

许可

本项目中所有材料(除非另有说明)均可在 MIT 许可下获得。有关更多信息,请参阅 LICENSE。