add bitinflow payments subscriptions

This commit is contained in:
2022-05-08 22:53:02 +02:00
parent b5b4f9cf5e
commit 032c771e49
14 changed files with 274 additions and 403 deletions

View File

@@ -18,13 +18,12 @@ use GuzzleHttp\Exception\RequestException;
class BitinflowAccounts
{
use Traits\ChargesTrait;
use Traits\DocumentsTrait;
use Traits\OauthTrait;
use Traits\PaymentIntentsTrait;
use Traits\SshKeysTrait;
use Traits\UsersTrait;
use Traits\HasBitinflowPaymentsWallet;
use ApiOperations\Delete;
use ApiOperations\Get;
use ApiOperations\Post;

View File

@@ -1,17 +0,0 @@
<?php
declare(strict_types=1);
namespace GhostZero\BitinflowAccounts\Enums;
/**
* @author René Preuß <rene@preuss.io>
*/
class DocumentType
{
// Read authorized user´s email address.
public const TYPE_PDF_INVOICE = 'pdf.invoice';
// Manage a authorized user object.
public const TYPE_PDF_ORDER = 'pdf.order';
}

View File

@@ -22,7 +22,7 @@ class BitinflowAccountsServiceProvider extends ServiceProvider
public function boot()
{
$this->publishes([
dirname(__DIR__) . '/../../../config/bitinflow-accounts-api.php' => config_path('bitinflow-accounts-api.php'),
dirname(__DIR__, 4) . '/config/bitinflow-accounts.php' => config_path('bitinflow-accounts.php'),
], 'config');
}
@@ -32,9 +32,7 @@ class BitinflowAccountsServiceProvider extends ServiceProvider
*/
public function register()
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/../../../config/bitinflow-accounts-api.php', 'bitinflow-accounts-api'
);
$this->mergeConfigFrom(dirname(__DIR__, 4) . '/config/bitinflow-accounts.php', 'bitinflow-accounts');
$this->app->singleton(BitinflowAccounts::class, function () {
return new BitinflowAccounts;
});

View File

@@ -1,69 +0,0 @@
<?php
declare(strict_types=1);
namespace GhostZero\BitinflowAccounts\Traits;
use GhostZero\BitinflowAccounts\ApiOperations\Get;
use GhostZero\BitinflowAccounts\ApiOperations\Post;
use GhostZero\BitinflowAccounts\ApiOperations\Put;
use GhostZero\BitinflowAccounts\Result;
/**
* @author René Preuß <rene@preuss.io>
*/
trait ChargesTrait
{
use Get, Post, Put;
/**
* Create a Charge object
*
* @param array $parameters
*
* @return Result Result object
*/
public function createCharge(array $parameters): Result
{
return $this->post('charges', $parameters);
}
/**
* Get a Charge object
*
* @param string $id
*
* @return Result Result object
*/
public function getCharge(string $id): Result
{
return $this->get("charges/$id");
}
/**
* Update a Charge object
*
* @param string $id
* @param array $parameters
*
* @return Result Result object
*/
public function updateCharge(string $id, array $parameters): Result
{
return $this->put("charges/$id", $parameters);
}
/**
* Capture a Charge object
*
* @param string $id
* @param array $parameters
*
* @return Result Result object
*/
public function captureCharge(string $id, array $parameters = []): Result
{
return $this->post("charges/$id/capture", $parameters);
}
}

View File

@@ -1,48 +0,0 @@
<?php
declare(strict_types=1);
namespace GhostZero\BitinflowAccounts\Traits;
use Carbon\CarbonInterface;
use GhostZero\BitinflowAccounts\ApiOperations\Get;
use GhostZero\BitinflowAccounts\ApiOperations\Post;
use GhostZero\BitinflowAccounts\Result;
/**
* @author René Preuß <rene@preuss.io>
*/
trait DocumentsTrait
{
use Get, Post;
/**
* Create a Documents object
*
* @param array $parameters
*
* @return Result
*/
public function createDocument(array $parameters): Result
{
return $this->post('documents', $parameters);
}
/**
* Create a Documents download url
*
* @param string $identifier
* @param CarbonInterface|null $expiresAt
*
* @return Result
*/
public function createDocumentDownloadUrl(string $identifier, ?CarbonInterface $expiresAt = null): Result
{
return $this->post("documents/$identifier/download-url", [
'expires_at' => $expiresAt
? $expiresAt->toDateTimeString()
: now()->addHour()->toDateTimeString(),
]);
}
}

View File

@@ -0,0 +1,196 @@
<?php
namespace GhostZero\BitinflowAccounts\Traits;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\RequestOptions;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Log;
use RuntimeException;
/**
* @property string access_token todo: can we get this from HasBitinflowTokens ?
* @property PendingRequest $paymentsGatewayUser
*/
trait HasBitinflowPaymentsWallet
{
protected ?object $paymentsUser = null;
/**
* Create a new payment gateway request.
*
* @param string $method
* @param string $url
* @param array $attributes
* @return mixed
* @throws GuzzleException
*/
private function paymentsGatewayRequest(string $method, string $url, array $attributes = []): mixed
{
$client = new Client([
'base_uri' => config('bitinflow-accounts.payments.base_url'),
]);
$response = $client->request($method, $url, [
RequestOptions::JSON => $attributes,
RequestOptions::HEADERS => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => sprintf('Bearer %s', $this->access_token),
],
]);
return json_decode($response->getBody());
}
/**
* Get user from payments gateway.
*
* @return object|null
* @throws GuzzleException
*/
public function getPaymentsUser(): ?object
{
if (is_null($this->paymentsUser)) {
$this->paymentsUser = $this->paymentsGatewayRequest('GET', 'user');
}
return $this->paymentsUser;
}
/**
* Check if user has an active wallet.
*
* @return bool
* @throws GuzzleException
*/
public function hasWallet(): bool
{
return $this->getPaymentsUser()->data->has_wallet;
}
public function getWalletSetupIntent(string $success_path = ''): string
{
return sprintf('%swallet?continue_url=%s', config('bitinflow-accounts.payments.dashboard_url'), url($success_path));
}
/**
* Get balance from user.
*
* @return float
* @throws GuzzleException
*/
public function getBalance(): float
{
return $this->getPaymentsUser()->data->balance;
}
/**
* Get vat from user.
*
* @return int|null
* @throws GuzzleException
*/
public function getVat(): ?int
{
return $this->getPaymentsUser()->data->taxation->vat;
}
/**
* Get vat from user.
*
* @return array|null
* @throws GuzzleException
*/
public function getSubscriptions(): ?array
{
$subscriptions = $this->getPaymentsUser()->data->subscriptions;
foreach ($subscriptions as $key => $subscription) {
if (!isset($subscription->payload->client_id) || $subscription->payload->client_id !== config('bitinflow-accounts.client_id')) {
unset($subscriptions[$key]);
}
}
return $subscriptions;
}
public function getSubscription($name = 'default'): ?object
{
foreach ($this->getSubscriptions() as $subscription) {
if (isset($subscription->payload->name) && $subscription->payload->name === $name) {
return $subscription;
}
}
return null;
}
public function hasSubscribed($name = 'default'): bool
{
$subscription = $this->getSubscription($name);
return $subscription && $subscription->status === 'settled' || $subscription && $subscription->resumeable;
}
/**
* Create a new subscription.
*
* @param array $attributes array which requires following attributes:
* name, description, period, price
* and following attributes are optional:
* vat, payload, ends_at, webhook_url, webhook_secret
* @param array $payload optional data that is stored in the subscription
* @param bool $checkout optional checkout it directly
* @return object the subscription object
* @throws GuzzleException
*/
public function createSubscription(string $name, array $attributes, array $payload = [], bool $checkout = false): object
{
$client = [
'name' => $name,
'client_id' => config('bitinflow-accounts.client_id')
];
$defaults = ['period' => 'monthly'];
$attributes = array_merge(array_merge($defaults, $attributes), ['payload' => array_merge($payload, $client), 'checkout' => $checkout]);
return $this->paymentsGatewayRequest('POST', 'subscriptions', $attributes)->data;
}
/**
* Checkout given subscription.
*
* @param string $id
* @return void
* @throws GuzzleException
*/
public function checkoutSubscription(string $id): void
{
$this->paymentsGatewayRequest('PUT', sprintf('subscriptions/%s/checkout', $id));
}
/**
* Revoke a running subscription.
*
* @param $id
* @return void
* @throws GuzzleException
*/
public function revokeSubscription($id): void
{
$this->paymentsGatewayRequest('PUT', sprintf('subscriptions/%s/revoke', $id));
}
/**
* Resume a running subscription.
*
* @param $id
* @return void
* @throws GuzzleException
*/
public function resumeSubscription($id): void
{
$this->paymentsGatewayRequest('PUT', sprintf('subscriptions/%s/resume', $id));
}
}

View File

@@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
namespace GhostZero\BitinflowAccounts\Traits;
use GhostZero\BitinflowAccounts\ApiOperations\Get;
use GhostZero\BitinflowAccounts\ApiOperations\Post;
use GhostZero\BitinflowAccounts\Result;
/**
* @author René Preuß <rene@preuss.io>
*/
trait PaymentIntentsTrait
{
use Get, Post;
/**
* Get a Payment Intent object
*
* @param string $id
*
* @return Result Result object
*/
public function getPaymentIntent(string $id): Result
{
return $this->get("payment-intents/$id");
}
/**
* Create a Payment Intent object
*
* @param array $parameters
*
* @return Result
*/
public function createPaymentIntent(array $parameters): Result
{
return $this->post('payment-intents', $parameters);
}
}