truelayer / client
TrueLayer的支付平台客户端
Requires
- php: ^8.1
- ext-json: *
- ext-openssl: *
- nesbot/carbon: ^2.62.1|^3.0.0
- php-http/discovery: ^1.15.1
- psr/http-client-implementation: ^1.0
- psr/http-factory-implementation: *
- psr/http-message-implementation: ^1.0
- psr/simple-cache: ^1.0|^2.0|^3.0
- ramsey/uuid: ^3.7|^4.1
- truelayer/signing: ^1.0.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.3
- guzzlehttp/guzzle: ^7.4
- mockery/mockery: ^1.4
- nyholm/psr7: ^1.4
- pestphp/pest: ^1.20
- phpstan/phpstan: ^1.3.1
- symfony/dotenv: ^5.4
- symfony/http-client: ^v5.4
Suggests
- psr/simple-cache-implementation: Avoid making redundant network requests and improve performance by providing a PSR-16 Cache implementation.
README
为什么使用此包?
此包通过以下方式简化与TrueLayer API的工作:
- 处理身份验证(包括令牌过期)和缓存
- 签名请求
- 管理幂等性键,包括在冲突时重试
- 在需要时重试失败的请求
- 提供类型提示的方法和类进行工作
入门
安装
此库需要实现PSR-18的HTTP客户端。
composer require truelayer/client
如果没有安装PSR-18客户端,Composer会通知您。您可以简单地要求一个,例如Guzzle
composer require guzzlehttp/guzzle truelayer/client
初始化
您需要前往TrueLayer控制台并创建凭据,然后您可以将其提供给客户端配置器
$client = \TrueLayer\Client::configure() ->clientId($clientId) ->clientSecret($clientSecret) ->keyId($kid) ->pemFile($pemFilePath) // Or ->pem($contents) Or ->pemBase64($contents) ->create();
默认情况下,客户端库将在sandbox
模式下初始化。要切换到生产环境,请调用useProduction()
$client = \TrueLayer\Client::configure() ... ->useProduction() // optionally, pass a boolean flag to toggle between production/sandbox mode. ->create();
此库假设您的client_id是以payments
作用域发布的。根据您的账户类型,这可能不适用,并且认证服务器将返回一个invalid_scope
错误。您可以使用scopes()
方法覆盖库使用的范围
$client = \TrueLayer\Client::configure() ... ->scopes('foo', 'bar') ->create();
如果需要,您也可以提供自己的HTTP客户端实例
$client = \TrueLayer\Client::configure() ... ->httpClient($myPSR18Client) ->create();
缓存
客户端库支持缓存访问TrueLayer系统上所需资源的client_credentials
授权令牌。为了启用它,您需要提供一个实现PSR-16公共缓存接口的实例和32字节的加密密钥。
您可以通过运行openssl rand -hex 32
生成一个随机的加密密钥。此密钥必须被视为机密,并存储在从TrueLayer控制台获取的客户端机密旁边。
$client = \TrueLayer\Client::configure() ... ->cache($cacheImplementation, $encryptionKey) ->create();
实现PSR-16的缓存库的好例子是illuminate/cache。
数组之间的转换
如果您想跳过调用每个设置方法,可以使用数组创建任何资源
$client->beneficiary()->fill($beneficiaryData); $client->user()->fill($userData); $client->payment()->fill($paymentData); // etc...
您还可以将任何资源转换为数组。如果您需要将其输出到json等,这可能很方便
$paymentData = $client->getPayment($paymentId)->toArray();
创建付款
1. 创建受益人
商家账户受益人
// If the merchant account id is known: $beneficiary = $client->beneficiary()->merchantAccount() ->merchantAccountId('a2dcee6d-7a00-414d-a1e6-8a2b23169e00'); // Alternatively you can retrieve merchant accounts and use one of them directly: $merchantAccounts = $client->getMerchantAccounts(); // Select the merchant account you need... $merchantAccount = $merchantAccounts[0]; $beneficiary = $client->beneficiary()->merchantAccount($merchantAccount);
如果您已配置商户账户进行支付验证,则可以为您商户账户的支付启用自动汇款方验证。
$remitterVerification = $client ->remitterVerification() ->automated() ->remitterName(true) ->remitterDateOfBirth(true); $beneficiary = $client->beneficiary() ->merchantAccount() ->merchantAccountId('a2dcee6d-7a00-414d-a1e6-8a2b23169e00') ->verification($remitterVerification);
外部账户收款人 - 邮编 & 账号
$beneficiary = $client->beneficiary()->externalAccount() ->reference('Transaction reference') ->accountHolderName('John Doe') ->accountIdentifier( $client->accountIdentifier()->sortCodeAccountNumber() ->sortCode('010203') ->accountNumber('12345678') );
外部账户收款人 - IBAN
$beneficiary = $client->beneficiary()->externalAccount() ->reference('Transaction reference') ->accountHolderName('John Doe') ->accountIdentifier( $client->accountIdentifier()->iban() ->iban('GB53CLRB04066200002723') );
2. 创建用户
use TrueLayer\Constants\UserPoliticalExposures; $user = $client->user() ->name('Jane Doe') ->phone('+44123456789') ->email('jane.doe@truelayer.com') ->dateOfBirth('2024-01-01'); // You can also set the user's political exposure field if you need to $user->politicalExposure(UserPoliticalExposures::CURRENT);
您还可以设置用户的地址
$address = $client->user() ->address() ->addressLine1('The Gilbert') ->addressLine2('City of') ->city('London') ->state('London') ->zip('EC2A 1PX') ->countryCode('GB');
3. 创建支付方式
您可以通过最少的配置创建银行转账支付方式
$paymentMethod = $client->paymentMethod()->bankTransfer() ->beneficiary($beneficiary);
可选地,您可以筛选授权流程中将返回的提供商
use TrueLayer\Constants\Countries; use TrueLayer\Constants\CustomerSegments; use TrueLayer\Constants\ReleaseChannels; // You can filter the providers that will be returned: $filter = $client->providerFilter() ->countries([Countries::GB, Countries::ES]) ->customerSegments([CustomerSegments::RETAIL, CustomerSegments::CORPORATE]) ->releaseChannel(ReleaseChannels::PRIVATE_BETA) ->excludesProviderIds(['provider-id']) // You can also filter providers by the schemes they support: $schemeSelection = $client->schemeSelection()->userSelected(); // Let the user select. You must provide your own UI for this. $schemeSelection = $client->schemeSelection()->instantOnly(); // Only allow providers that support instant payments $schemeSelection = $client->schemeSelection()->instantPreferred(); // Prefer providers that allow instant payments, but allow defaulting back to non-instant payments if unavailable. // For instant only and instant preferred, you can also allow or disallow remitter fees: $schemeSelection->allowRemitterFee(true); // Unless explicitly set, this will default to false. // Create the provider selection configuration $providerSelection = $client->providerSelection()->userSelected() ->filter($filter) ->schemeSelection($schemeSelection); // Create the payment method $paymentMethod = $client->paymentMethod()->bankTransfer() ->providerSelection($providerSelection);
或者,您可以选择在授权流程中使用的提供商以及支付方案
// Preselect the payment scheme $schemeSelection = $client->schemeSelection() ->preselected() ->schemeId('faster_payments_service'); // Preselect the provider $providerSelection = $client->providerSelection() ->preselected() ->providerId('mock-payments-gb-redirect') ->schemeSelection($schemeSelection); // Create the payment method $paymentMethod = $client->paymentMethod()->bankTransfer() ->providerSelection($providerSelection);
您还可以启用支付重试,但请确保您可以预先处理 attempt_failed
支付状态
$paymentMethod = $client->paymentMethod()->bankTransfer() ->enablePaymentRetry() ->beneficiary($beneficiary);
4. 创建支付
$payment = $client->payment() ->user($user) ->amountInMinor(1) ->currency(\TrueLayer\Constants\Currencies::GBP) // You can use other currencies defined in this class. ->paymentMethod($paymentMethod) ->create();
然后您将获得以下方法
$payment->getId(); // The payment id $payment->getResourceToken(); // The resource token $payment->getDetails(); // Get the payment details, same as $client->getPayment($paymentId) $payment->hostedPaymentsPage(); // Get the Hosted Payments Page helper, see below. $payment->toArray(); // Convert to array
5. 从数组创建支付
如果您喜欢,您可以直接通过调用 fill
方法与数组一起工作
$paymentData = [ 'amount_in_minor' => 1, 'currency' => Currencies::GBP, 'payment_method' => [ 'type' => PaymentMethods::BANK_TRANSFER, 'beneficiary' => [ 'account_identifier' => [ 'account_number' => '12345678', 'sort_code' => '010203', 'type' => 'sort_code_account_number', ], 'reference' => 'Transaction reference', 'account_holder_name' => 'John Doe', 'type' => 'external_account', ], 'provider_selection' => [ 'type' => PaymentMethods::PROVIDER_TYPE_USER_SELECTION, 'filter' => [ 'countries' => [ Countries::GB, ], 'release_channel' => ReleaseChannels::PRIVATE_BETA, 'customer_segments' => [ CustomerSegments::RETAIL, ], 'provider_ids' => [ 'mock-payments-gb-redirect', ], 'excludes' => [ 'provider_ids' => [], ], ], ], ], ]; $payment = $client->payment()->fill($paymentData)->create();
6. 跳转到托管支付页面
TrueLayer的托管支付页面提供了一个高转换率的支付授权UI,默认支持所有动作类型。您可以在创建支付后轻松获取跳转的URL
$url = $client->payment() ... ->create() ->hostedPaymentsPage() ->returnUri('http://www.mymerchantwebsite.com') ->primaryColour('#000000') ->secondaryColour('#e53935') ->tertiaryColour('#32329f') ->toUrl();
获取付款详情
$payment = $client->getPayment($paymentId); $payment->getId(); $payment->getUserId(); $payment->getAmountInMinor(); $payment->getCreatedAt(); $payment->getCurrency(); $payment->getPaymentMethod(); $payment->toArray();
获取支付方式和受益人
use TrueLayer\Interfaces\PaymentMethod\BankTransferPaymentMethodInterface; use TrueLayer\Interfaces\Beneficiary\ExternalAccountBeneficiaryInterface; use TrueLayer\Interfaces\Beneficiary\MerchantBeneficiaryInterface; $method = $client->getPayment($paymentId)->getPaymentMethod(); if ($method instanceof BankTransferPaymentMethodInterface) { $providerSelection = $method->getProviderSelection(); $beneficiary = $method->getBeneficiary(); $beneficiary->getAccountHolderName(); if ($beneficiary instanceof ExternalAccountBeneficiaryInterface) { $beneficiary->getReference(); $beneficiary->getAccountIdentifier(); // See account identifiers documentation } if ($beneficiary instanceof MerchantBeneficiaryInterface) { $beneficiary->getReference(); $beneficiary->getMerchantAccountId(); } }
检查付款的状态
您可以使用以下辅助方法之一检查状态
$payment = $client->getPayment($paymentId); $payment->isAuthorizationRequired(); $payment->isAuthorizing(); $payment->isAuthorized(); // Will also return false when the payment has progressed to executed, failed or settled states. $payment->isExecuted(); // Will also return false when the payment has progressed to failed or settled states. $payment->isSettled(); $payment->isFailed(); // Payment has failed $payment->isAttemptFailed(); // Payment attempt has failed, only available if payment retries are enabled.
或者,您可以将状态作为字符串获取,并将其与PaymentStatus
中提供的常量进行比较
$payment = $client->getPayment($paymentId); $payment->getStatus() === \TrueLayer\Constants\PaymentStatus::AUTHORIZATION_REQUIRED;
处理特定状态的付款字段
授权所需状态
具有此状态的支付处于初始阶段,在此阶段中,除了创建支付外,未采取任何其他操作。
use TrueLayer\Interfaces\Payment\PaymentAuthorizationRequiredInterface; if ($payment instanceof PaymentAuthorizationRequiredInterface) { // Your logic here, you would normally start the authorization process. }
授权状态
支付已开始其授权流程,但授权尚未完成
处于 Authorizing
状态的支付将暴露2个额外的检索方法
- 以获取授权流程配置
- 支付授权用户旅程中的下一步操作
use TrueLayer\Interfaces\Payment\PaymentAuthorizingInterface; if ($payment instanceof PaymentAuthorizingInterface) { $payment->getAuthorizationFlowConfig(); // see authorization flow config // Will return a \TrueLayer\Interfaces\Payment\AuthorizationFlow\Action\ActionInterface $payment->getAuthorizationFlowNextAction(); }
提供商选择操作
此操作表示用户需要从提供的列表中选择一个提供商。为了渲染提供商列表,每个提供商都提供了获取名称、标志、ID等的有用方法。
use TrueLayer\Interfaces\Payment\AuthorizationFlow\Action\ProviderSelectionActionInterface; $nextAction = $payment->getAuthorizationFlowNextAction(); if ($nextAction instanceof ProviderSelectionActionInterface) { foreach ($nextAction->getProviders() as $provider) { $provider->getId(); $provider->getDisplayName(); $provider->getCountryCode(); $provider->getLogoUri(); $provider->getIconUri(); $provider->getBgColor(); } }
重定向操作
此操作表示用户需要被重定向以完成授权过程。
use TrueLayer\Interfaces\Payment\AuthorizationFlow\Action\RedirectActionInterface; $nextAction = $payment->getAuthorizationFlowNextAction(); if ($nextAction instanceof RedirectActionInterface) { $nextAction->getUri(); // The URL the end user must be redirected to $nextAction->getProvider(); // The provider object, see available methods above. }
等待操作
use TrueLayer\Interfaces\Payment\AuthorizationFlow\Action\WaitActionInterface; $nextAction = $payment->getAuthorizationFlowNextAction(); if ($nextAction instanceof WaitActionInterface) { // your logic here }
已授权状态
支付已成功完成其授权流程
use TrueLayer\Interfaces\Payment\PaymentAuthorizedInterface; if ($payment instanceof PaymentAuthorizedInterface) { $payment->getAuthorizationFlowConfig(); // see authorization flow config }
执行状态
支付已被银行接受
use TrueLayer\Interfaces\Payment\PaymentExecutedInterface; if ($payment instanceof PaymentExecutedInterface) { $payment->getExecutedAt(); // The date and time the payment was executed at $payment->getAuthorizationFlowConfig(); // See authorization flow config }
结算状态
如果收款账户是Truelayer中的商户账户,并且Truelayer已观察到资金已结算,支付可以过渡到此状态。
use TrueLayer\Interfaces\Payment\PaymentSettledInterface; if ($payment instanceof PaymentSettledInterface) { $payment->getExecutedAt(); // The date and time the payment was executed at $payment->getSettledAt(); // The date and time the payment was settled at $payment->getAuthorizationFlowConfig(); // See authorization flow config $payment->getSourceOfFunds(); // See source of funds }
失败状态
支付已失败。失败原因可以在支付资源上的
failure_reason
字段中观察到
use TrueLayer\Interfaces\Payment\PaymentFailedInterface; if ($payment instanceof PaymentFailedInterface) { $payment->getFailedAt(); // The date and time the payment failed at $payment->getFailureStage(); // The status the payment was when it failed, one of `authorization_required`, `authorizing` or `authorized` $payment->getFailureReason(); // The reason the payment failed. Handle unexpected values gracefully as an unknown failure. $payment->getAuthorizationFlowConfig(); // see authorization flow config }
尝试失败状态
仅在启用支付重试时才可用。
use TrueLayer\Interfaces\Payment\PaymentAttemptFailedInterface; if ($payment instanceof PaymentAttemptFailedInterface) { $payment->getFailedAt(); // The date and time the payment failed at $payment->getFailureStage(); // The status the payment was when it failed, one of `authorization_required`, `authorizing` or `authorized` $payment->getFailureReason(); // The reason the payment failed. Handle unexpected values gracefully as an unknown failure. $payment->getAuthorizationFlowConfig(); // see authorization flow config }
授权流程配置
此对象提供了有关支付所经历的授权流程的信息。
use TrueLayer\Interfaces\Payment\PaymentExecutedInterface; if ($payment instanceof PaymentExecutedInterface) { $config = $payment->getAuthorizationFlowConfig(); $config->isRedirectSupported() // Is redirect supported or not $config->getRedirectReturnUri(); // The URL the user will be redirected back once the flow on the third-party's website is completed $config->isProviderSelectionSupported(); // Is provider selection supported or not }
资金来源
use TrueLayer\Interfaces\Payment\PaymentExecutedInterface; use TrueLayer\Interfaces\Payment\PaymentSettledInterface; use TrueLayer\Interfaces\SchemeIdentifier\ScanDetailsInterface; use TrueLayer\Interfaces\SchemeIdentifier\IbanDetailsInterface; use TrueLayer\Interfaces\SchemeIdentifier\BbanDetailsInterface; use TrueLayer\Interfaces\SchemeIdentifier\NrbDetailsInterface; if ($payment instanceof PaymentExecutedInterface || $payment instanceof PaymentSettledInterface) { $paymentSource = $payment->getPaymentSource(); $paymentSource->getAccountHolderName(); // The unique ID for the external account $paymentSource->getId(); $paymentSource->toArray(); foreach ($paymentSource->getAccountIdentifiers() as $accountIdentifier) { // See 'Account identifiers' for available methods. } }
授权付款
使用托管支付页面
我们鼓励您使用我们的HPP,它收集从您的用户处所需的所有支付信息,并引导他们完成支付授权旅程。为此,只需在创建支付后重定向到HPP即可。有关如何开始,请参阅跳转到HPP。
手动启动授权流程
在某些情况下,您可能希望手动启动授权流程(例如,如果您想渲染自己的提供商选择屏幕)。
此库对授权流程的支持不完整。要完成授权流程,您最终需要将用户重定向到HPP或使用直接API调用实现缺失的功能(请参阅自定义API调用)。
use TrueLayer\Constants\FormInputTypes; $payment = $client->payment()->create(); // If you are planning to start the authorization flow manually then hand over to the HPP: $payment->authorizationFlow() ->returnUri($myReturnUri) ->useHPPCapabilities() ->start(); // If you are planning to build a fully custom UI, you need to manually specify which features your UI is able to support: $payment->authorizationFlow() ->returnUri($myReturnUri) ->enableProviderSelection() // Can the UI render a provider selection screen? ->enableSchemeSelection() // Can the UI render a scheme selection screen? ->enableUserAccountSelection() // Can the UI render a user account selection screen? ->formInputTypes([FormInputTypes::TEXT, FormInputTypes::TEXT_WITH_IMAGE, FormInputTypes::SELECT]) // Can the UI render form inputs for the end user to interact with? Which input types can it handle? ->start();
一旦授权流程开始,请参考授权支付了解如何处理返回的操作。
提交服务提供商
如果您的支付需要选择一个服务提供商作为其下一步操作,您可以使用submitProvider
方法来渲染提供商列表,然后提交用户选择。
$client->submitPaymentProvider($payment, $provider);
退款
仅支持已结算的商户账户支付退款。
在客户端创建和检索退款
use TrueLayer\Interfaces\Payment\RefundRetrievedInterface; use TrueLayer\Interfaces\Payment\RefundExecutedInterface; use TrueLayer\Interfaces\Payment\RefundFailedInterface; // Create and get the refund id $refundId = $client->refund() ->payment($paymentId) // Payment ID, PaymentRetrievedInterface or PaymentCreatedInterface ->amountInMinor(1) ->reference('My reference') ->create() ->getId(); // Get a refund's details $refund = $client->getRefund($paymentId, $refundId); // Common refund methods $refund->getId(); $refund->getAmountInMinor(); $refund->getCurrency(); $refund->getReference(); $refund->getStatus(); $refund->getCreatedAt(); $refund->isPending(); $refund->isAuthorized(); $refund->isExecuted(); $refund->isFailed(); // Executed refunds if ($refund instanceof RefundExecutedInterface) { $refund->getExecutedAt(); } // Failed refunds if ($refund instanceof RefundFailedInterface) { $refund->getFailureReason(); $refund->getFailedAt(); } // Get all refunds for a payment $refunds = $client->getRefunds($paymentId); // RefundRetrievedInterface[]
从已结算的支付创建和检索退款
或者,如果您已经有了支付实例,可以使用以下便捷方法
use TrueLayer\Interfaces\Payment\PaymentSettledInterface; if ($payment instanceof PaymentSettledInterface) { // Create a refund $refundId = $payment->refund() ->amountInMinor(1) ->reference('My reference') ->create() ->getId(); // Get a refund's details $payment->getRefund($refundId) // Get all refunds $payment->getRefunds(); }
支付
创建向外部受益人付款
$accountIdentifier = $client->accountIdentifier() ->iban() ->iban('GB29NWBK60161331926819'); $beneficiary = $client->payoutBeneficiary()->externalAccount() ->accountHolderName('John Doe') ->reference('My reference') ->accountIdentifier($accountIdentifier); $payout = $client->payout() ->amountInMinor(1) ->beneficiary($beneficiary) ->currency(\TrueLayer\Constants\Currencies::GBP) ->merchantAccountId($merchantAccount->getId()) ->create(); $payout->getId();
创建向支付来源(退款)付款
$beneficiary = $client->payoutBeneficiary()->paymentSource() ->paymentSourceId($paymentSourceId) ->reference('My reference') ->userId($user->getId()); $payout = $client->payout() ->amountInMinor(1) ->beneficiary($beneficiary) ->currency(\TrueLayer\Constants\Currencies::GBP) ->merchantAccountId($merchantAccount->getId()) ->create(); $payout->getId();
创建向预选的商户账户付款
$beneficiary = $client->payoutBeneficiary() ->businessAccount() ->reference('My reference'); $payout = $client->payout() ->amountInMinor(1) ->beneficiary($beneficiary) ->currency(\TrueLayer\Constants\Currencies::GBP) ->merchantAccountId($merchantAccount->getId()) ->create(); $payout->getId();
检索付款
use TrueLayer\Interfaces\Payout\PayoutRetrievedInterface; use TrueLayer\Interfaces\Payout\PayoutPendingInterface; use TrueLayer\Interfaces\Payout\PayoutAuthorizedInterface; use TrueLayer\Interfaces\Payout\PayoutExecutedInterface; use TrueLayer\Interfaces\Payout\PayoutFailedInterface; use TrueLayer\Constants\PayoutStatus; $payout = $client->getPayout($payoutId); // All payout statuses implement this common interface if ($payout instanceof PayoutRetrievedInterface) { $payout->getId(); $payout->getCurrency(); $payout->getAmountInMinor(); $payout->getMerchantAccountId(); $payout->getStatus(); $payout->getBeneficiary(); $payout->getCreatedAt(); } // Pending payouts if ($payout instanceof PayoutPendingInterface) { $payout->getStatus(); //PayoutStatus::PENDING } // Authorized payouts if ($payout instanceof PayoutAuthorizedInterface) { $payout->getStatus(); //PayoutStatus::AUTHORIZED } // Executed payouts if ($payout instanceof PayoutExecutedInterface) { $payout->getStatus(); //PayoutStatus::EXECUTED $payout->getExecutedAt(); } // Failed payouts if ($payout instanceof PayoutFailedInterface) { $payout->getStatus() // PayoutStatus::FAILED $payout->getFailedAt(); $payout->getFailureReason(); }
商家账户
列出所有商户账户
$merchantAccounts = $client->getMerchantAccounts(); // MerchantAccountInterface[]
通过ID检索账户
$merchantAccount = $client->getMerchantAccount('a2dcee6d-7a00-414d-a1e6-8a2b23169e00'); $merchantAccount->getAccountHolderName(); $merchantAccount->getAvailableBalanceInMinor(); $merchantAccount->getCurrentBalanceInMinor(); $merchantAccount->getCurrency(); $merchantAccount->getId(); foreach ($merchantAccount->getAccountIdentifiers() as $accountIdentifier) { // See 'Account identifiers' for available methods. }
接收webhook通知
您可以通过webhooks注册接收关于您的支付或授权状态的通知。webhook的URI端点可以在控制台中进行配置
⚠️ 所有传入的webhook请求都必须验证其签名,否则您可能会接受欺诈性支付状态事件。
这个库使处理webhook事件变得简单且安全。您不需要手动验证传入请求的签名,因为已经为您完成。您应将以下代码添加到您的webhook端点;或者,可以将webhook服务配置在您的IoC容器中,在您的端点中,您可以简单地调用$webhook->execute()
。
获取webhook实例
如果您已经可以访问客户端实例,这很简单
$webhook = $client->webhook();
或者,您也可以从头创建实例
$webhook = \TrueLayer\Webhook::configure() ->httpClient($httpClient) ->cache($cacheImplementation, $encryptionKey) // optional, but recommeded. See Caching ->useProduction($useProduction) // bool ->create();
处理事件
您通过为关心的事件类型注册处理程序(闭包或可调用类)来处理事件。您可以有任意多的处理程序,但请注意执行顺序没有保证。
您的处理程序将在请求签名验证后以及传入的webhook类型与您在处理程序中指定的接口相匹配后执行。
闭包处理程序
use TrueLayer\Interfaces\Webhook; $client->webhook() ->handler(function (Webhook\EventInterface $event) { // Do something on any event }) ->handler(function (Webhook\PaymentEventInterface $event) { // Do something on any payment event }) ->handler(function (Webhook\PaymentExecutedEventInterface $event) { // Do something on payment executed event only }) ->execute();
可调用类
use TrueLayer\Interfaces\Webhook; class LogEvents { public function __invoke(Webhook\EventInterface $event) { // Log event } } class UpdateOrderStatus { public function __invoke(Webhook\PaymentExecutedEventInterface $event) { // Update your order when the payment is executed } } // You can use ->handler()... $client->webhook() ->handler(LogEvents::class) ->handler(UpdateOrderStatus::class) ->execute(); // Or you can use ->handlers()... $client->webhook() ->handlers( LogEvents::class, UpdateOrderStatus::class ) ->execute(); // If you need to, you can also provide instances: $client->webhook() ->handlers( new LogEvents(), new UpdateOrderStatus() ) ->execute();
支持的处理器类型
该库支持以下事件类型的处理器
- payment_executed
- payment_settled
- payment_failed
- refund_executed
- refund_failed
- payout_executed
- payout_failed
您还可以通过在处理程序中类型提示TrueLayer\Interfaces\Webhook\EventInterface
来处理其他事件类型。然后,您可以通过调用您的变量的getBody()
方法来获取负载数据。
所有事件都继承自EventInterface
。
use TrueLayer\Interfaces\Webhook; $client->webhook() ->handler(function (Webhook\EventInterface $event) { // handle any incoming event $event->getEventId(); $event->getEventVersion(); $event->getSignature(); $event->getTimestamp(); $event->getType(); $event->getBody(); }) ->handler(function (Webhook\PaymentEventInterface $event) { // handle any payment event $event->getPaymentId(); $paymentMethod = $event->getPaymentMethod(); $paymentMethod->getType(); if ($paymentMethod instanceof Webhook\PaymentMethod\BankTransferPaymentMethodInterface) { $paymentMethod->getProviderId(); $paymentMethod->getSchemeId(); } if ($paymentMethod instanceof Webhook\PaymentMethod\MandatePaymentMethodInterface) { $paymentMethod->getMandateId(); } }) ->handler(function (Webhook\PaymentExecutedEventInterface $event) { // handle payment executed // Inherits from PaymentEventInterface so provides same methods plus: $event->getExecutedAt(); $event->getSettlementRiskCategory(); }) ->handler(function (Webhook\PaymentSettledEventInterface $event) { // handle payment settled // Inherits from PaymentEventInterface so provides same methods plus: $event->getSettledAt(); $event->getSettlementRiskCategory(); $paymentSource = $event->getPaymentSource(); $paymentSource->getId(); $paymentSource->getAccountHolderName(); $paymentSource->getAccountIdentifiers(); // See Account Identifiers }) ->handler(function (Webhook\PaymentFailedEventInterface $event) { // handle payment failed // Inherits from PaymentEventInterface so provides same methods plus: $event->getFailedAt(); $event->getFailureReason(); $event->getFailureStage(); }) ->handler(function (Webhook\RefundEventInterface $event) { // handle any refund event $event->getPaymentId(); $event->getRefundId(); }) ->handler(function (Webhook\RefundExecutedEventInterface $event) { // handle refund executed // Inherits from RefundEventInterface so provides same methods plus: $event->getExecutedAt(); }) ->handler(function (Webhook\RefundFailedEventInterface $event) { // handle refund failed // Inherits from RefundEventInterface so provides same methods plus: $event->getFailedAt(); $event->getFailureReason(); }) ->handler(function (Webhook\PayoutEventInterface $event) { // handle any payout event $event->getPayoutId(); $beneficiary = $event->getBeneficiary(); $beneficiary->getType(); if ($beneficiary instanceof Webhook\Beneficiary\BusinessAccountBeneficiaryInterface) { $beneficiary->getType(); } if ($beneficiary instanceof Webhook\Beneficiary\PaymentSourceBeneficiaryInterface) { $beneficiary->getPaymentSourceId(); $beneficiary->getUserId(); } }) ->handler(function (Webhook\PayoutExecutedEventInterface $event) { // handle payout executed // Inherits from PayoutEventInterface so provides same methods plus: $event->getExecutedAt(); }) ->handler(function (Webhook\PayoutFailedEventInterface $event) { // handle payout failed // Inherits from PayoutEventInterface so provides same methods plus: $event->getFailedAt(); $event->getFailureReason(); }) ->execute();
重写全局变量
默认情况下,webhook服务将使用php全局变量来读取端点路径和请求头和正文。如果需要,可以覆盖此行为(例如,您可能需要在队列作业中调用execute()
。)
$client->webhook() ->handlers(...) ->path('/my/custom/path') ->headers($headers) // flat key-value array ->body($body) // the raw request body string ->execute();
签名验证失败
如果无法验证webhook签名,将抛出\TrueLayer\Exceptions\WebhookVerificationFailedException。当webhook服务配置错误时,还会抛出其他一些异常,请参阅错误处理。
账户标识符
所有账户标识符实现了一个公共接口,因此您可以访问
$accountIdentifier->getType(); $accountIdentifier->toArray();
根据特定类型,您可以获取更多信息
use TrueLayer\Interfaces\AccountIdentifier\ScanDetailsInterface; use TrueLayer\Interfaces\AccountIdentifier\IbanDetailsInterface; use TrueLayer\Interfaces\AccountIdentifier\NrbDetailsInterface; use TrueLayer\Interfaces\AccountIdentifier\BbanDetailsInterface; if ($accountIdentifier instanceof ScanDetailsInterface) { $accountIdentifier->getAccountNumber(); $accountIdentifier->getSortCode(); } if ($accountIdentifier instanceof IbanDetailsInterface) { $accountIdentifier->getIban(); } if ($accountIdentifier instanceof NrbDetailsInterface) { $accountIdentifier->getNrb(); } if ($accountIdentifier instanceof BbanDetailsInterface) { $accountIdentifier->getBban(); }
自定义幂等性键
默认情况下,客户端将为您生成和管理幂等键。但是,有些情况下您可能想设置自己的幂等键,您可以在创建资源时使用requestOptions
设置器来完成此操作。
// Create a RequestOptionsInterface instance and set your custom idempotency key $requestOptions = $client->requestOptions()->idempotencyKey('my-custom-idempotency-key'); // Creating a payment with a custom idempotency key $client->payment() ->paymentMethod($method) ->amountInMinor(10) ->currency('GBP') ->user($user) ->requestOptions($requestOptions) ->create(); // Creating a refund with a custom idempotency key $client->refund() ->payment($paymentId) ->amountInMinor(1) ->reference('My reference') ->requestOptions($requestOptions) ->create(); // Creating a payout with a custom idempotency key $client->payout() ->amountInMinor(1) ->currency(Currencies::GBP) ->merchantAccountId($accountId) ->beneficiary($payoutBeneficiary) ->requestOptions($requestOptions) ->create();
自定义API调用
您可以使用客户端库来执行自己的API调用,而无需担心身份验证或请求签名。
$responseData = $client->getApiClient()->request()->uri('/merchant-accounts')->get(); $responseData = $client->getApiClient()->request() ->uri('/payments') ->payload($myData) ->header('My Header', 'value') ->post();
错误处理
客户端库会抛出以下异常
PSR 异常
ClientExceptionInterface
根据 PSR-18 规范抛出,如果 HTTP 客户端无法发送请求,或者无法将响应解析为 PSR-7 响应对象。
Psr\Http\Client\ClientExceptionInterface
自定义异常
所有自定义异常都将继承自基本类 TrueLayer\Exceptions\Exception
。
ApiResponseUnsuccessfulException
如果 API 响应状态不是 2xx,则会抛出。
\TrueLayer\Exceptions\ApiResponseUnsuccessfulException $e->getErrors(); // Get the errors provided by the API, as an array $e->getStatusCode(); // The response status code $e->getType(); // The error type, as a link to the TrueLayer docs $e->getDetail(); // A description of the error message $e->getTraceId(); // The TrueLayer error trace id
ApiRequestJsonSerializationException
在调用 API 之前,如果请求数据无法进行 JSON 编码,则会抛出。
\TrueLayer\Exceptions\ApiRequestJsonSerializationException
InvalidArgumentException
当提供的参数无效时抛出,例如无效的受益人类型。
\TrueLayer\Exceptions\InvalidArgumentException
SignerException
如果请求签名器无法初始化或签名失败,则会抛出。
\TrueLayer\Exceptions\SignerException
EncryptException
当客户端库无法加密需要缓存的负载时抛出。
\TrueLayer\Exceptions\EncryptException
DecryptException
如果客户端库无法解密缓存密钥的值,则会抛出。
\TrueLayer\Exceptions\DecryptException
TLPublicKeysNotFound
当 webhook 服务无法检索 TL 的公钥时抛出。
\TrueLayer\Exceptions\TLPublicKeysNotFound
WebhookHandlerException
当 webhook 服务提供了一个无效的处理程序时抛出。
\TrueLayer\Exceptions\WebhookHandlerException
WebhookHandlerInvalidArgumentException
当 webhook 服务无法获取请求体、签名头或提供的处理程序有无效参数时抛出。
\TrueLayer\Exceptions\WebhookHandlerInvalidArgumentException
WebhookVerificationFailedException
当 webhook 签名无法验证时抛出。
\TrueLayer\Exceptions\WebhookVerificationFailedException