hugomarques62/juno-sdk-php-laravel

开发 Juno 集成分支

v1.1.2 2020-10-16 12:27 UTC

README

请确保将 JUNO_PRIVATE_TOKENJUNO_CLIENT_IDJUNO_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-Token
  • clientId: 与 secret 结合使用,构成授权头部 - base64(clientId:secret)
  • secret: 与 clientId 结合使用,构成授权头部 - base64(clientId:secret)
  • guzzle: 设置 Guzzle 的配置
    • base_uri: 资源服务器的请求基础 URI (info)
      • 沙盒
      • 生产
    • authorization_base_uri: 授权服务器的请求基础 URI (info)
      • 沙盒
      • 生产
    • connect_timeout: 尝试连接到服务器时等待的秒数。0 表示无限期等待
    • timeout: 发出请求后抛出超时异常所需的时间。0 表示无限期等待
    • debug: 将 Guzzle 的调试消息输出到 stdout
  • 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发送自定义请求,您需要创建两个类,分别是RequestResponse
假设我们需要向docs端点发送请求。
我们将需要创建DocsCustomRequestDocsCustomResponse,如下所示

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;

有关Juno API的更多信息,请参阅文档此处此处(详细PDF)