opaweb / juno-laravel
Juno for Laravel 集成
Requires
- php: ^7.4
- ext-json: *
- guzzlehttp/guzzle: 6.5.5
Requires (Dev)
- orchestra/testbench: ^6.2
- phpunit/phpunit: ^9.4
This package is auto-updated.
Last update: 2024-09-23 21:20:15 UTC
README
从 jetimob/juno-sdk-php-laravel 分支而来。
完成
- 信用卡令牌化(必须使用 Juno 的 JS 令牌化)。
待办事项
- 信用卡 UI
- Juno JS 令牌化的本地 JS 接口。
请确保将 JUNO_PRIVATE_TOKEN
、JUNO_CLIENT_ID
和 JUNO_CLIENT_SECRET
添加到您的 .env
文件中,以便在每个请求中识别您的账户。
JUNO_PRIVATE_TOKEN
也称为文档中的X-Resource-Token
。
安装
使用 Composer
$ composer require opaweb/juno-laravel
发布配置
以下命令将配置文件发布到 Laravel 的配置文件夹。
$ php artisan juno:install
配置文件
private_token
:设置授权端点的 X-Resource-TokenclientId
:与secret
结合,它们组成授权头部 - base64(clientId
:secret
)secret
:与clientId
结合,它们组成授权头部 - base64(clientId
:secret
)guzzle
:设置 Guzzle 的配置version
:Juno 的 API 版本environment
:设置当前环境以构建请求的 URL。 production | sandboxlogging
:启用 Laravel 的 Log 门面记录request_max_attempts
:由于 Juno 的 API 目前不稳定,因此通常需要执行多次请求才能使请求成功。选择一个您认为可接受的价值。如果在 N 次设置后请求仍然失败,则将抛出异常request_attempt_delay
:在尝试执行新的请求尝试之前等待的时间(毫秒)recoverable_status_codes
:表示可恢复状态的代码数组。只有该数组中指定的状态代码会在请求失败时触发重试。
用法
导入 API 命名空间并使用它
use Juno; $response = Juno::request($requestObject, $resourceToken);
其中 $requestObject
必须是 Request 类的实例。
Jetimob\Juno\Lib\Http
命名空间内的每个类都实现了 Request。$response
将 始终 返回Response
类的实例。
$resourceToken
是必需的,以确保请求正在使用正确的凭据向正确的端点进行。
可以传递类和 request
函数来执行简单的请求,如 DocumentListRequest
Juno::request(DocumentListRequest::class, $resourceToken);
复杂对象必须手动配置,如下所示
$billing = new Billing(); $billing->name = 'NAME'; $billing->document = 'document'; $billing->phone = 'phone'; $billing->email = 'email@xxxxxxx.com'; $billing->notify = true; $charge = new Charge(); $charge->description = 'description'; $charge->amount = 99999.99; $charge->dueDate = Juno::formatDate(2020, 2, 25); $charge->maxOverdueDays = 99; $charge->fine = 9.9; $charge->interest = 9.9; /** @var ChargeCreationResponse $response */ $response = Juno::request(new ChargeCreationRequest($charge, $billing), $resourceToken);
响应
使用 API 执行的每个请求都将返回 Response
对象的实例。
所有实现 Request
的对象都有自己的 Response
对象。例如:ChargeConsultRequest
有自己的 ChargeConsultResponse
。
如果在请求过程中发生错误(非200代码),返回的对象将是ErrorResponse
的实例。
错误
当发起请求时,可能会出现几个问题,因此为了防止这种情况发生,请将request
调用包裹在try
/catch
块中。
每个Juno异常都是JunoException
的子类,所以所有在请求过程中可能出现的异常都可以在单个try
块内处理。
try { Juno::request(DocumentListRequest::class, $resourceToken); } catch (JunoAccessTokenRejection $e) { [...] } catch (JunoException $e) { [...] } catch (Exception $e) { [...] }
访问令牌缓存
授权令牌(访问令牌)被缓存到Laravel的默认Cache
外观中,请确保正确配置。
如果您将环境从
production
更改为sandbox
或反之,您必须使用以下命令清除缓存:php artisan juno:clear-cache
。否则,将使用缓存的访问令牌,并且您会收到401错误。
创建自定义请求
如果您需要向Juno的API发送自定义请求,您需要创建两个类,即Request
和Response
。
让我们假设我们需要向docs
端点发送请求。
我们将需要创建DocsCustomRequest
和DocsCustomResponse
,如下所示
DocsCustomRequest.php
use Jetimob\Juno\Lib\Http\Method; use Jetimob\Juno\Lib\Http\Request; use Jetimob\Juno\Lib\Http\BodyType; class DocsCustomRequest extends Request { /** @var string $id pathParam */ public string $id; public string $param1; public string $param2; /** * @var string $responseClass overrides the response serialization class. * * Every successful request will have its response cast to an instance of the class defined by * this property. * * If the response class has the same name with 'Request' exchanged with 'Response', you can leave * don't need to set this property. */ protected string $responseClass = DocsCustomResponse::class; /** * @var string $bodyType overrides the request body type * @see http://docs.guzzlephp.org/en/stable/request-options.html */ protected string $bodyType = BodyType::JSON; /** @var string[] $bodySchema specifies which properties of the current instance should be sent with the body */ protected array $bodySchema = [ 'param1', 'param2', ] /** * Specifies the request method */ protected function method(): string { return Method::GET; } /** * Specifies the endpoint to be merged with base_uri defined in the configuration file. * Anything inside brackets {} will trigger the request to update the matched identifier with this * instance's property with the same name. e.g.: the {id} below will be exchanged to the value of * $this->id; */ protected function urn(): string { return 'docs/{id}'; } }
OddResponseObject.php
use Jetimob\Juno\Lib\Traits\Serializable; class OddResponseObject { use Serializable; public string $property1; public int $property2; }
DocsCustomResponse.php
use Jetimob\Juno\Lib\Http\Response; /** * All properties defined in this class MUST match the object keys defined in Juno's API response. * * Complex objects can be typed so that the SDK can cast an instance and define this instance property * ($param in the class example below) * * If there is data inside an '_embedded' key, you MUST override the initComplexObjects function and * use the helper functions of Response class. * * @see https://dev.juno.com.br/api/v2 */ class DocsCustomResponse extends Response { protected string $id; protected int $value; protected OddResponseObject $param; /** @var OddResponseObject $embeddedData */ protected array $embeddedData; /** * This function is mainly used to deserialize embedded data. * * The first parameter given to deserializeEmbeddedArray specifies in which key, inside the * _embedded object, is the data that we are trying to deserialize. */ public function initComplexObjects(): void { $this->embeddedData = $this->deserializeEmbeddedArray( 'propertyInsideEmbedded', // key name inside _embedded OddResponseObject::class, // deserialize each element to the given class [], // default value if the key is non existent ); } [... getters] }
用法
$requestData = new DocsCustomRequest(); $requestData->id = 'XXXXXXXXXXXXXXXXXXXXXXXXX'; $requestData->param1 = 'XXXXXXXXXXXXXXXXXXXXXXXXX'; $requestData->param2 = 'XXXXXXXXXXXXXXXXXXXXXXXXX'; // error handling ignored for example readability /** @var DocsCustomResponse $response */ $response = Juno::request($requestData, $resourceToken); // all properties are initialized and can be easily accessed: $response->getParam()->property1;