定制 bnpl-partners/factoring004 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

bnpl-partners/factoring004

Composer 安装命令:

composer require bnpl-partners/factoring004

包简介

Buy now pay later API SDK

README 文档

README

Requirements

  • PHP >=5.6
  • JSON extension
  • PSR-17, PSR-18 implementations (optional and PHP >=7.x only)

Version compatibility

Package version PHP version Note
3.x >= 7.4 Latest version. Supported.
2.x >= 5.6 < 7.4 Legacy version. Supported.
1.x >= 5.6 < 7.4 Legacy version. Unsupported.
Please upgrade to 2.x.
0.x >= 7.4 Unstable and unsupported version.
Please upgrade to 3.x.

Installation

composer require bnpl-partners/factoring004

Authentication

Create an instance of BnplPartners\Factoring004\OAuth\OAuthTokenManager.

use BnplPartners\Factoring004\OAuth\OAuthTokenManager;

$tokenManager = new OAuthTokenManager('https://dev.bnpl.kz/api/users/api/v1', 'username', 'password');

Generate access token

$token = $tokenManager->getAccessToken();
$accessToken = $token->getAccess();

Refresh access token

$newToken = $tokenManager->refreshToken($oldToken->getRefresh());

Cache access token

use BnplPartners\Factoring004\OAuth\CacheOAuthTokenManager;
use BnplPartners\Factoring004\OAuth\OAuthTokenManager;

$cache = ... // PSR-16 Cache
$tokenManager = new OAuthTokenManager('https://dev.bnpl.kz/api/users/v1', 'username', 'password');
$cacheTokenManager = new CacheOAuthTokenManager($tokenManager, $cache, 'cache key');

$token = $cacheTokenManager->getAccessToken();
$accessToken = $token->getAccess();

Cached Token Refresh Policy

There are two policies to refresh a cached token.

Always Retrieve

This is default behaviour. In this case any expired tokens always will refresh. If you need to refresh token instead of retrieve, you will have to call CacheOAuthTokenManager::refreshToken() method.

use BnplPartners\Factoring004\OAuth\CacheOAuthTokenManager;
use BnplPartners\Factoring004\OAuth\OAuthTokenRefreshPolicy;

$cacheTokenManager = new CacheOAuthTokenManager($tokenManager, $cache, 'cache key', OAuthTokenRefreshPolicy::ALWAYS_RETRIEVE());

$token = $cacheTokenManager->getAccessToken();
$accessToken = $token->getAccess();

Always Refresh

Expired tokens always will refresh. You won't need to refresh it manually by CacheOAuthTokenManager::refreshToken() method.

use BnplPartners\Factoring004\OAuth\CacheOAuthTokenManager;
use BnplPartners\Factoring004\OAuth\OAuthTokenRefreshPolicy;

$cacheTokenManager = new CacheOAuthTokenManager($tokenManager, $cache, 'cache key', OAuthTokenRefreshPolicy::ALWAYS_REFRESH());

$token = $cacheTokenManager->getAccessToken();
$accessToken = $token->getAccess();

Clear cached tokens

If you need to clear cache, you will clear cache manually.

$cacheTokenManager->clearCache();

If you get an authentication error, you will clear cache manually.

use BnplPartners\Factoring004\Exception\AuthenticationException;
use BnplPartners\Factoring004\OAuth\CacheOAuthTokenManager;
use BnplPartners\Factoring004\Order\OrderManager;

$cacheTokenManager = new CacheOAuthTokenManager($tokenManager, $cache, 'cache key');
$orderManager = OrderManager::create('https://dev.bnpl.kz/api', new BearerTokenAuth($cacheTokenManager->getAccessToken()->getAccess()));

try {
    $orderManager->preApp(...);
} catch (AuthenticationException $e) {
    $cacheTokenManager->clearCache();
}

Usage

We recommend to use the class BnplPartners\Factoring004\Order\OrderManager to call our endpoints.

Create an instance

use BnplPartners\Factoring004\Order\OrderManager;
use BnplPartners\Factoring004\Auth\BearerTokenAuth;

require_once __DIR__ . '/vendor/autoload.php';

$manager = OrderManager::create('https://dev.bnpl.kz/api', new BearerTokenAuth('Access Token'));

PreApp endpoint

$response = $manager->preApp([
    'partnerData' => [
        'partnerName' => 'test',
        'partnerCode' => 'test',
        'pointCode' => 'test',
    ],
    'billNumber' => '1',
    'billAmount' => 6000,
    'itemsQuantity' => 1,
    'successRedirect' => 'http://your-store.com/success',
    'postLink' => 'http://your-store.com/internal',
    'items' => [
        [
            'itemId' => '1',
            'itemName' => 'test',
            'itemQuantity' => 1,
            'itemPrice' => 6000,
            'itemSum' => 6000,
        ],
    ],
]);

var_dump($response->getRedirectLink());

Delivery endpoints

Send OTP

$response = $manager->delivery($merchantId, $orderId, $amount)->sendOtp();
var_dump($response->getMessage());

Check OTP

$response = $manager->delivery($merchantId, $orderId, $amount)->checkOtp($otp);
var_dump($response->getMessage());

Without OTP

$response = $manager->delivery($merchantId, $orderId, $amount)->confirmWithoutOtp();
var_dump($response->getMessage());

Full return endpoints

Send OTP

$response = $manager->fullRefund($merchantId, $orderId)->sendOtp();
var_dump($response->getMessage());

Check OTP

$response = $manager->fullRefund($merchantId, $orderId)->checkOtp($otp);
var_dump($response->getMessage());

Without OTP

$response = $manager->fullRefund($merchantId, $orderId)->confirmWithoutOtp();
var_dump($response->getMessage());

Partial return endpoints

Send OTP

$response = $manager->partialRefund($merchantId, $orderId, $amount)->sendOtp();
var_dump($response->getMessage());

Check OTP

$response = $manager->partialRefund($merchantId, $orderId, $amount)->checkOtp($otp);
var_dump($response->getMessage());

Without OTP

$response = $manager->partialRefund($merchantId, $orderId, $amount)->confirmWithoutOtp();
var_dump($response->getMessage());

Cancel endpoint

$response = $manager->cancel($merchantId, $orderId);
var_dump($response->getMessage());

Error handling

All methods can throw an instance of BnplPartners\Factoring004\Exception\PackageException.

use BnplPartners\Factoring004\Exception\PackageException;

try {
    $response = $manager->delivery($merchantId, $orderId, $amount)->sendOtp();
} catch (PackageException $e) {
    var_dump($e);
}

Advanced Usage

These classes are low level API, described in the section.

Create api instance

use BnplPartners\Factoring004\Api;
use BnplPartners\Factoring004\Auth\BearerTokenAuth;

require_once __DIR__ . '/vendor/autoload.php';

$api = Api::create('https://dev.bnpl.kz/api', new BearerTokenAuth('Access Token'));

PreApp endpoint

Create preApp

use BnplPartners\Factoring004\PreApp\Item;
use BnplPartners\Factoring004\PreApp\PreAppMessage;
use BnplPartners\Factoring004\PreApp\PartnerData;

$message = new PreAppMessage(
    new PartnerData('test', 'test', 'test'),
    '1',
    6000,
    1,
    'http://your-store.com/success',
    'http://your-store.com/internal',
    [new Item('1', 'test', 1, 6000, 6000)],
);

// Or
$message = PreAppMessage::createFromArray([
    'partnerData' => [
        'partnerName' => 'test',
        'partnerCode' => 'test',
        'pointCode' => 'test',
    ],
    'billNumber' => '1',
    'billAmount' => 6000,
    'itemsQuantity' => 1,
    'successRedirect' => 'http://your-store.com/success',
    'postLink' => 'http://your-store.com/internal',
    'items' => [
        [
            'itemId' => '1',
            'itemName' => 'test',
            'itemQuantity' => 1,
            'itemPrice' => 6000,
            'itemSum' => 6000,
        ],
    ],
]);

//Send request and receive response
$response = $api->preApps->preApp($message);

var_dump($response->getStatus(), $response->getPreAppId(), $response->getRedirectLink());
var_dump($response->toArray(), json_encode($response));

Get preapp status

Get status by preapp id

$status = $api->preApps->getStatus($preappID)->getStatus();

Get status by order id

$status = $api->bill->getStatus($orderID)->getStatus();

Delivery endpoints

Send OTP

use BnplPartners\Factoring004\Otp\SendOtp;

$sendOtp = new SendOtp('1', '1', 6000);

// or
$sendOtp = SendOtp::createFromArray(['merchantId' => '1', 'merchantOrderId' => '1', 'amount' => 6000]);

// send request and receive response
$response = $api->otp->sendOtp($sendOtp);

var_dump($response->getMsg());
var_dump($response->toArray(), json_encode($response));

Check OTP

use BnplPartners\Factoring004\Otp\CheckOtp;

$checkOtp = new CheckOtp('1', '1', '1111', 6000);

// or
$checkOtp = CheckOtp::createFromArray(['merchantId' => '1', 'merchantOrderId' => '1', 'otp' => '1111', 'amount' => 6000]);

// send request and receive response
$response = $api->otp->checkOtp($checkOtp);

var_dump($response->getMsg());
var_dump($response->toArray(), json_encode($response));

Without OTP

use BnplPartners\Factoring004\ChangeStatus\DeliveryOrder;
use BnplPartners\Factoring004\ChangeStatus\DeliveryStatus;
use BnplPartners\Factoring004\ChangeStatus\ErrorResponse;
use BnplPartners\Factoring004\ChangeStatus\MerchantsOrders;
use BnplPartners\Factoring004\ChangeStatus\SuccessResponse;

$orders = new MerchantsOrders('1', [new DeliveryOrder('1', DeliveryStatus::DELIVERY(), 6000)]);

// or
$orders = MerchantsOrders::createFromArray([
    'merchantId' => '1',
    'orders' => [
        ['orderId' => '1', 'status' => 'delivered', 'amount' => 6000],
    ],
]);

// send request and receive response
$response = $api->changeStatus->changeStatusJson($orders);

var_dump(array_map(fn(SuccessResponse $response) => $response->getMsg(), $response->getSuccessfulResponses()));
var_dump(array_map(fn(ErrorResponse $response) => $response->getMessage(), $response->getErrorResponses()));
var_dump($response->toArray(), json_encode($response));

Refund endpoints

Send OTP Return

use BnplPartners\Factoring004\Otp\SendOtpReturn;

$sendOtpReturn = new SendOtpReturn(6000, '1', '1');

// or
$sendOtpReturn = SendOtpReturn::createFromArray(['amountAr' => 6000, 'merchantId' => '1', 'merchantOrderId' => '1']);

// send request and receive response
$response = $api->otp->sendOtpReturn($sendOtpReturn);

var_dump($response->getMsg());
var_dump($response->toArray(), json_encode($response));

Check OTP Return

use BnplPartners\Factoring004\Otp\CheckOtpReturn;

$checkOtpReturn = new CheckOtpReturn(6000, '1', '1', '1111');

// or
$checkOtpReturn = CheckOtp::createFromArray(['amountAr' => 6000, 'merchantId' => '1', 'merchantOrderId' => '1', 'otp' => '1111']);

// send request and receive response
$response = $api->otp->checkOtpReturn($checkOtpReturn);

var_dump($response->getMsg());
var_dump($response->toArray(), json_encode($response));

Without OTP

use BnplPartners\Factoring004\ChangeStatus\ErrorResponse;
use BnplPartners\Factoring004\ChangeStatus\MerchantsOrders;
use BnplPartners\Factoring004\ChangeStatus\ReturnOrder;
use BnplPartners\Factoring004\ChangeStatus\ReturnStatus;
use BnplPartners\Factoring004\ChangeStatus\SuccessResponse;

$orders = new MerchantsOrders('1', [new ReturnOrder('1', ReturnStatus::RETURN(), 6000)]);

// or
$orders = MerchantsOrders::createFromArray([
    'merchantId' => '1',
    'orders' => [
        ['orderId' => '1', 'status' => 'return', 'amount' => 6000],
    ],
]);

// send request and receive response
$response = $api->changeStatus->changeStatusJson($orders);

var_dump(array_map(fn(SuccessResponse $response) => $response->getMsg(), $response->getSuccessfulResponses()));
var_dump(array_map(fn(ErrorResponse $response) => $response->getMessage(), $response->getErrorResponses()));
var_dump($response->toArray(), json_encode($response));

Cancel

use BnplPartners\Factoring004\ChangeStatus\ErrorResponse;
use BnplPartners\Factoring004\ChangeStatus\MerchantsOrders;
use BnplPartners\Factoring004\ChangeStatus\CancelOrder;
use BnplPartners\Factoring004\ChangeStatus\CancelStatus;
use BnplPartners\Factoring004\ChangeStatus\SuccessResponse;

$orders = new MerchantsOrders('1', [new CancelOrder('1', CancelStatus::CANCEL())]);

// or
$orders = MerchantsOrders::createFromArray([
    'merchantId' => '1',
    'orders' => [
        ['orderId' => '1', 'status' => 'canceled'],
    ],
]);

// send request and receive response
$response = $api->changeStatus->changeStatusJson($orders);

var_dump(array_map(fn(SuccessResponse $response) => $response->getMsg(), $response->getSuccessfulResponses()));
var_dump(array_map(fn(ErrorResponse $response) => $response->getMessage(), $response->getErrorResponses()));
var_dump($response->toArray(), json_encode($response));

Error handling

Whenever api returns an error client will throw an instance of BnplPartners\Factoring004\Exception\ApiException.

use BnplPartners\Factoring004\Exception\ApiException;
use BnplPartners\Factoring004\Exception\AuthenticationException;
use BnplPartners\Factoring004\Exception\EndpointUnavailableException;
use BnplPartners\Factoring004\Exception\ErrorResponseException;
use BnplPartners\Factoring004\Exception\NetworkException;
use BnplPartners\Factoring004\Exception\PackageException;
use BnplPartners\Factoring004\Exception\TransportException;
use BnplPartners\Factoring004\Exception\UnexpectedResponseException;
use BnplPartners\Factoring004\Exception\ValidationException;

try {
    $api->preApps->preApp($message);
} catch (AuthenticationException $e) {
    // authentication errors, token invalid, token expired, etc
    var_dump($e->getCode(), $e->getMessage(), $e->getDescription());
} catch (EndpointUnavailableException $e) {
    // to catch all internal server errors 500, 503, etc
    var_dump($e->getResponse());
} catch (ErrorResponseException $e) {
    // to catch all client errors 400, 405, etc
    var_dump($e->getErrorResponse());
} catch (UnexpectedResponseException $e) {
    // to catch all responses with unexpected schema
    var_dump($e->getResponse());
} catch (ValidationException $e) {
    // endpoint validation error
    $details = $e->getResponse()->getDetails();
    var_dump($details[0]->getError(), $details[0]->getField());
} catch (ApiException $e) {
    // to catch all api layer exceptions
} catch (NetworkException $e) {
    // network issues, connection refused, etc
} catch (TransportException $e) {
    // to catch all transport layer exceptions
} catch (PackageException $e) {
    // to catch all the package exceptions
}

Exception Hierarchy

  • PackageException
    • ApiException
      • AuthenticationException
      • ValidationException
      • ErrorResponseException
      • UnexpectedResponseException
        • EndpointUnavailableException
    • TransportException
      • NetworkException
      • DataSerializationException

Customization

PSR HTTP clients

First install any PSR-17 and PSR-18 packages. See PSR-17 packages and PSR-18 packages.

For instance, we install popular Guzzle HTTP client. Since version 7 it has already implemented PSR-17 and PSR-18.

composer require guzzlehttp/guzzle

For Guzzle 6 you may use GuzzleTransport or PsrTransport with additional PSR-17 and PSR-18 adapters. See bellow.

Install PSR-17 and PSR-18 adapters for Guzzle 6.

composer require http-interop/http-factory-guzzle mjelamanov/psr18-guzzle

Transport layer

Transport is an abstraction layer over HTTP clients.

For Guzzle 6 and 7

use BnplPartners\Factoring004\Transport\GuzzleTransport;

require_once __DIR__ . '/vendor/autoload.php';

$transport = new GuzzleTransport(new GuzzleHttp\Client());

For PSR-17 and PSR-18 client.

use BnplPartners\Factoring004\Transport\PsrTransport;

require_once __DIR__ . '/vendor/autoload.php';

$transport = new PsrTransport(
    new GuzzleHttp\Psr7\HttpFactory(),
    new GuzzleHttp\Psr7\HttpFactory(),
    new GuzzleHttp\Psr7\HttpFactory(),
    new GuzzleHttp\Client(),
);

For Guzzle 6 client with PSR-17 and PSR-18 adapters.

use BnplPartners\Factoring004\Transport\PsrTransport;

require_once __DIR__ . '/vendor/autoload.php';

$transport = new PsrTransport(
    new Http\Factory\Guzzle\RequestFactory(),
    new Http\Factory\Guzzle\StreamFactory(),
    new Http\Factory\Guzzle\UriFactory(),
    new Mjelamanov\GuzzlePsr18\Client(new GuzzleHttp\Client()),
);

For other PSR-17 and PSR-18 clients.

use BnplPartners\Factoring004\Transport\PsrTransport;

require_once __DIR__ . '/vendor/autoload.php';

$transport = new PsrTransport(
    new RequestFactory(), // PSR-17 instance
    new StreamFactory(), // PSR-17 instance
    new UriFactory(), // PSR-17 instance
    new Client() // PSR-18 instance
);

You can create your own transport. Just implement BnplPartners\Factoring004\Transport\TransportInterface.

Send requests

$response = $transport->post('/bnpl/v3/preapp', ['partnerData' => [...]], ['Content-Type' => 'application/json']);

var_dump($response->getStatusCode()); // HTTP response status code
var_dump($response->getHeaders()); // HTTP response headers
var_dump($response->getBody()); // parsed HTTP response body

Resources

Each resource is a set of grouped endpoints.

use BnplPartners\Factoring004\Auth\BearerTokenAuth;
use BnplPartners\Factoring004\Otp\OtpResource;
use BnplPartners\Factoring004\PreApp\PreAppResource;

require_once __DIR__ . '/vendor/autoload.php';

...

$preApp = new PreAppResource($transport, 'https://dev.bnpl.kz/api', new BearerTokenAuth('Access Token'));
$response = $preApp->preApp(...);

$otp = new OtpResource($transport, 'https://dev.bnpl.kz/api', new BearerTokenAuth('Access Token'));
$response = $otp->sendOtp(...);

Test

./vendor/bin/phpunit

bnpl-partners/factoring004 适用场景与选型建议

bnpl-partners/factoring004 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3.15k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2022 年 02 月 11 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 bnpl-partners/factoring004 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 bnpl-partners/factoring004 我们能提供哪些服务?
定制开发 / 二次开发

基于 bnpl-partners/factoring004 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 3.15k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 11
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 3
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-02-11