opaweb/juno-laravel

Juno for Laravel 集成

dev-main 2021-03-23 13:42 UTC

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_TOKENJUNO_CLIENT_IDJUNO_CLIENT_SECRET 添加到您的 .env 文件中,以便在每个请求中识别您的账户。

JUNO_PRIVATE_TOKEN 也称为文档中的 X-Resource-Token

安装

使用 Composer

$ composer require opaweb/juno-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。 production | sandbox
  • logging:启用 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发送自定义请求,您需要创建两个类,即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)