levizoesch / teller-sdk
一个简单的SDK,用于在Laravel框架中消费Teller.io。
Requires
- php: ^7.4|^8.0|^8.1|^8.2
- ext-curl: *
- illuminate/contracts: ^8.0|^9.0|^10.0|^11.0
- levizoesch/laravel-set-environment: ^1.0
- spatie/laravel-package-tools: ^1.0 | ^1.16.2
Requires (Dev)
- brianium/paratest: ^1.0|^2.0|^3.0|^4.0|^5.0|^6.0|^7.0
- nunomaduro/collision: ^1.0|^2.0|^3.0|^4.0|^5.0|^6.0|^7.0|^8.0
- orchestra/testbench: ^1.0|^2.0|^3.0|^4.0|^5.0|^6.0|^7.0|^8.0|^9.0
- pestphp/pest: ^1.0|^2.0|^3.0
- pestphp/pest-plugin-laravel: ^1.0|^2.0|^3.0
- phpunit/phpunit: ^1.0|^2.0|^3.0|^4.0|^5.0|^6.0|^7.0|^8.0|^9.0|^10.0
README
一个开源的PHP SDK,用于在Laravel框架中与Teller.io交互。
版本兼容性
如果您能帮助使此包在Laravel 6 & 7中稳定,请提交PR。
目标与计划
API端点。
捕获teller.io的所有可用端点。
剩余要做的是围绕支付/启用Zelle的机构。
异常与错误报告
扩展抛出的异常,以更好地帮助包含可能存在于生产中的边缘情况。
单元测试 - 进行中 (
)
单元测试对我来说非常重要,因为我不想向包用户引入错误。目标是扩展单元测试到90%或更高。
设置Codecov.com ✓ 已完成
webhook验证(仅严格从Teller.io消耗数据)
Blade视图与模板
创建一套易于使用和集成到用户应用程序中的blade视图和模板。
模型与迁移
开发对包功能至关重要的模型和迁移。
使用Rappasoft的Laravel Livewire Tables通过Livewire功能驱动表格。
贡献与社区
我鼓励其他人为此包做出贡献 ❤
要加入用于讨论和帮助的discord,请加入我们的Teller SDK Discord服务器
安装
composer require levizoesch/teller-sdk
配置文件
您需要发布配置文件。
php artisan vendor:publish --tag=teller-sdk-config
环境配置
您还需要将以下内容添加到您的.env
文件中。
TELLER_ENVIRONMENT=sandbox
TELLER_APP_ID=
TELLER_PUBLIC_KEY=
TELLER_WEBHOOK_SECRET_KEY=
TELLER_KEY_PATH=
TELLER_CERT_PATH=
TELLER_TEST_TOKEN=
包含辅助命令(《Laravel Set Environment》)
这对于使用CLI(如Bitbucket Pipeline或Github)自动将代码库推送到本地、预发布或生产服务器非常有帮助。
您可以使用它来创建或更新环境密钥。
php artisan env:set TELLER_ENIRONMENT=development
php artisan env:set TELLER_APP_ID=
php artisan env:set TELLER_PUBLIC_KEY=
php artisan env:set TELLER_WEBHOOK_SECRET_KEY=
...
可用的Teller.io环境。
可用的环境是sandbox
、development
和production
,用于您的TELLER_ENVIRONMENT
。
用于注册用户账户的环境。有效值是sandbox
、development
和production
。沙盒环境从不与真实机构通信,用于创建沙盒注册、账户和令牌。开发环境与生产环境相同,但不计费,有100个注册的硬限制。
Teller证书
此包要求您在主目录中具有teller提供的私钥和证书.pem文件。在您创建https://teller.io/开发者账户时提供给您。
../YourLaravelDirectory/teller_cert.pem
../YourLaravelDirectory/teller_pk.pem
或者,您可以修改 teller
配置文件并定义文件所在路径。
注意 文件名无关紧要,您可以为自己的 .pem
文件定义自己的命名规范。
'KEY_PATH' => base_path('your/directory/path/teller_pk.pem'), 'CERT_PATH' => base_path('your/directory/path/teller_cert.pem'),
Teller.io 文档
有关更多上下文和最新的 Teller API 信息,请参阅
https://teller.io/docs/api
包含的端点
Teller.io 将为您提供访问令牌。您将使用此提供的令牌初始化 TellerClient。
$accessToken = "test_token_xxxxxxxxxx";
列出账户
返回在 Teller Connect 注册过程中,终端用户授予访问权限的所有账户列表。
$teller = new TellerClient($accessToken); $listAccounts = $teller->listAccounts();
列出账户数量
返回与给定访问令牌链接的账户数量。
$teller = new TellerClient($accessToken); $totalCount = $teller->accountsCount();
销毁账户
这将删除您的应用程序访问指定账户(通过其 ID)的授权。这不会删除该账户本身。
$teller = new TellerClient($accessToken); $teller->destroyAccount($actId);
获取账户详情
通过其 ID 检索特定账户。
$teller = new TellerClient($accessToken); $accountDetails = $teller->getAccountDetails($actId);
获取账户余额
检索实时账户余额。
$teller = new TellerClient($accessToken); $balances = $teller->getAccountBalances($actId);
列出所有账户交易
返回属于账户的所有交易列表。
$teller = new TellerClient($accessToken); $transactions = $teller->listAccountTransactions($actId);
获取特定账户交易详情
返回单个交易详情。
$teller = new TellerClient($accessToken); $transactionDetails = $teller->getTransactionDetails($actId, $trxId);
身份
身份为您提供终端用户授予您的应用程序访问授权的所有账户以及每个账户的受益所有人身份信息。受益所有人信息附加到每个账户上,因为终端用户可能是受益所有人,例如企业账户,或者可能有多位受益所有人,例如终端用户与其伴侣共有的共同账户。
$teller = new TellerClient($accessToken); $identity = $teller->listIdentity($actId);
Zelle *有限
根据银行机构,您可能无法访问 zelle 功能。对于具有此功能的机构。
列出账户收款人
$teller = new TellerClient($accessToken); $listPayees = $teller->listAccountPayees($actId, $scheme);
付款
本节仍在开发中。请贡献力量以帮助完成它...
创建账户收款人
为从给定账户发送付款创建受益人。
$teller = new TellerClient($accessToken); $data = { "scheme": "zelle", "address": "jackson.lewis@teller.io", "name": "Jackson Lewis", "type": "person" } $allAccountTransactions = $teller->createAccountPayee($actId, $data);
Webhooks
您可能想使用 teller.io webhook。为此,您需要创建一个 TellerWebhookController。
php artisan make:controller TellerWebhookController
这将在您的 Controllers 目录中创建一个新的控制器
app/Http/Controllers/TellerWebhookController.php
要配置您的新控制器,请添加以下 store 方法。
/** * @throws JsonException */ public function store(Request $request) { $payload = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR); // Store Webhook TellerWebhooks::createWebhookRecord($payload); // Handle Webhook $found = TellerAccount::where('enrollmentId', $payload['payload']['enrollment_id']) ->first(); if ($found) { $status = match ($payload['payload']['reason']) { 'disconnected' => 'Disconnected', 'disconnected.account_locked' => 'Account Locked', 'disconnected.enrollment_inactive' => 'Inactive', 'disconnected.credentials_invalid' => 'Invalid Credentials', 'disconnected.user_action.captcha_required' => 'Captcha Required', 'disconnected.user_action.mfa_required' => 'MFA Required', 'disconnected.user_action.web_login_required' => 'Login Required', default => 'Unknown', }; TellerAccount::where('enrollmentId', $payload['payload']['enrollment_id']) ->update([ 'status' => $status ]); } return $payload; }
将路由添加到 web.php
文件中。
Route::resource('teller/webhook', TellerWebhookController::class, [ 'names' => [ 'store' => 'teller.webhook.store' ] ])->only('store');
现在更新您的 Teller.io 开发者仪表板,并将 webhook 指向您的项目。请参阅 Teller 上的 应用程序
菜单按钮
快速示例
我将在未来更新它...
要启动
添加按钮。
<button type="button" id="teller-connect" class="btn btn-primary btn-dark btn-lg"> <strong>Link Institution</strong> </button>
添加 JavaScript。
<script src="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/11.6.16/sweetalert2.all.js" integrity="sha512-OOP8+9w8oPEn71RWL6nuGSfcyHtxeNHHyA5jwf9ecn53OQr2aEizblDzG+Esl+6CByZBTfp/bn2At5oBqwGFYw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> document.addEventListener("DOMContentLoaded", function() { const tellerConnect = TellerConnect.setup({ applicationId: "{{ config('teller.APP_ID') }}", onInit: function () { //console.log("Teller Connect has initialized"); }, onSuccess: function (enrollment) { Swal.fire({ title: "Account Alias", text: "What is the account nick name?", input: 'text', showCancelButton: false, confirmButtonColor: 'green' }).then((result) => { if (result.value) { const url = "{{ route('teller.account.store') }}"; const formData = { "accessToken": enrollment.accessToken, "institution": enrollment.enrollment.institution.name, "enrollment_id": enrollment.enrollment.id, "user_id": enrollment.user.id, "alias": result.value, "_token": "{{ csrf_token() }}" }; $.ajax({ type: "POST", url: url, data: formData, success: function (data) { let result = JSON.parse(data); if (result.success) { Swal.fire({ icon: 'success', html: result.message }).then(function() { location.reload(); }); } else { Swal.fire({ icon: 'error', html: result.message }).then(function() { location.reload(); }); } } }); } }); }, onExit: function () { //console.log("User closed Teller Connect"); } }); const el = document.getElementById("teller-connect"); el.addEventListener("click", function() { tellerConnect.open(); }); });
异常
由于各种原因可能会抛出异常。异常如下
MissingTellerConfigurationException
Please run 'php artisan vendor:publish --tag=teller-sdk-config' to generate.
EnvironmentNullException
如果 .env 文件未正确定义,则会抛出此异常。配置文件会查找 TELLER_ENVIRONMENT
。如果找不到它,则会抛出此异常。
InvalidEnvironmentException
唯一接受的价值是 sandbox
、development
或 production
。检测到任何其他值,将抛出此异常。
MissingAccessTokenException
如果用户的银行机构的访问令牌为空或无效,则会抛出此异常。
MissingTellerCertException & MissingTellerKeyException
每个异常都将显示您缺少的是证书还是私钥 .pem
文件。请参阅您的 teller.php
配置文件以定义其路径。
UnexpectedErrorResponseException
如果生成的错误是不预期的,则会抛出此异常。如果您遇到此异常,请告诉我,因为可能需要进一步扩展错误报告以捕获这些差异。
致谢
许可
The MIT License (MIT)
Copyright (c) Levi Zoesch
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.