hugomarques62 / juno-sdk-php-laravel
开发 Juno 集成分支
Requires
- php: ^7.4
- ext-json: *
- guzzlehttp/guzzle: ^7.2
Requires (Dev)
- orchestra/testbench: ^6.2
- phpunit/phpunit: ^9.4
README
请确保将 JUNO_PRIVATE_TOKEN
、JUNO_CLIENT_ID
和 JUNO_CLIENT_SECRET
添加到您的 .env
文件中,以便在每次请求中识别您的账户。
JUNO_PRIVATE_TOKEN
在文档中也称为X-Resource-Token
。
安装
使用 Composer
$ composer require hugomarques62/juno-sdk-php-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。 生产 | 沙盒logging
: 启用对 Laravel 日志外观的记录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
是必需的,以确保请求正在使用正确的凭据发送到正确的端点。
简单请求,如 DocumentListRequest
,可以通过传递类到 request
函数来执行
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
外观中,请确保正确配置。
如果您将环境从
生产环境
更改为沙盒
或反之,您必须使用以下命令清除缓存: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;