-
Notifications
You must be signed in to change notification settings - Fork 43
Implement Subscriptions #364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
alexstewartja
wants to merge
7
commits into
bitpay:9.3.x
Choose a base branch
from
alexstewartja:subscriptions
base: 9.3.x
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
299fe76
Implement Subscriptions
alexstewartja 9962c88
Implement Subscriptions
alexstewartja 52252e6
Merge remote-tracking branch 'origin/subscriptions' into subscriptions
alexstewartja 24fb49c
Fix PHP CodeSniffer action failure
alexstewartja 808e3f9
Fix PHP CodeSniffer errors/warnings
alexstewartja 77fa8e6
Added `SettlementStatus` convenience constants
alexstewartja 399e0d4
Fix PHP CodeSniffer warnings
alexstewartja File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
use BitPaySDK\Client\RateClient; | ||
use BitPaySDK\Client\RefundClient; | ||
use BitPaySDK\Client\SettlementClient; | ||
use BitPaySDK\Client\SubscriptionClient; | ||
use BitPaySDK\Client\TokenClient; | ||
use BitPaySDK\Client\WalletClient; | ||
use BitPaySDK\Exceptions\BitPayApiException; | ||
|
@@ -36,6 +37,7 @@ | |
use BitPaySDK\Model\Rate\Rate; | ||
use BitPaySDK\Model\Rate\Rates; | ||
use BitPaySDK\Model\Settlement\Settlement; | ||
use BitPaySDK\Model\Subscription\Subscription; | ||
use BitPaySDK\Model\Wallet\Wallet; | ||
use BitPaySDK\Util\RESTcli\RESTcli; | ||
use Exception; | ||
|
@@ -576,7 +578,7 @@ public function getBill(string $billId, string $facade = Facade::MERCHANT, bool | |
* | ||
* @see https://developer.bitpay.com/reference/retrieve-bills-by-status Retrieve Bills by Status | ||
* | ||
* @param string|null The status to filter the bills. | ||
* @param $status string|null The status to filter the bills. | ||
* @return Bill[] | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
|
@@ -625,6 +627,75 @@ public function deliverBill(string $billId, string $billToken, bool $signRequest | |
return $billClient->deliver($billId, $billToken, $signRequest); | ||
} | ||
|
||
/** | ||
* Create a BitPay Subscription. | ||
* | ||
* @see https://developer.bitpay.com/reference/create-a-subscription Create a Subscription | ||
* | ||
* @param Subscription $subscription A Subscription object with request parameters defined. | ||
* @return Subscription Created Subscription object | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function createSubscription(Subscription $subscription): Subscription | ||
{ | ||
$subscriptionClient = $this->getSubscriptionClient(); | ||
|
||
return $subscriptionClient->create($subscription); | ||
} | ||
|
||
/** | ||
* Retrieve a BitPay subscription by its ID. | ||
* | ||
* @see https://developer.bitpay.com/reference/retrieve-a-subscription Retrieve a Subscription | ||
* | ||
* @param $subscriptionId string The ID of the subscription to retrieve. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
* @return Subscription | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function getSubscription(string $subscriptionId): Subscription | ||
{ | ||
$subscriptionClient = $this->getSubscriptionClient(); | ||
|
||
return $subscriptionClient->get($subscriptionId); | ||
} | ||
|
||
/** | ||
* Retrieve a collection of BitPay subscriptions. | ||
* | ||
* @see https://developer.bitpay.com/reference/retrieve-subscriptions-by-status Retrieve Subscriptions by Status | ||
* | ||
* @param $status string|null The status on which to filter the subscriptions. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorrect order of type and var name |
||
* @return Subscription[] Filtered list of Subscription objects | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function getSubscriptions(?string $status = null): array | ||
{ | ||
$subscriptionClient = $this->getSubscriptionClient(); | ||
|
||
return $subscriptionClient->getSubscriptions($status); | ||
} | ||
|
||
/** | ||
* Update a BitPay Subscription. | ||
* | ||
* @see https://developer.bitpay.com/reference/update-a-subscription Update a Subscription | ||
* | ||
* @param Subscription $subscription A Subscription object with the parameters to update defined. | ||
* @param string $subscriptionId The ID of the Subscription to update. | ||
* @return Subscription Updated Subscription object | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function updateSubscription(Subscription $subscription, string $subscriptionId): Subscription | ||
{ | ||
$subscriptionClient = $this->getSubscriptionClient(); | ||
|
||
return $subscriptionClient->update($subscription, $subscriptionId); | ||
} | ||
|
||
/** | ||
* Retrieve the exchange rate table maintained by BitPay. | ||
* @see https://bitpay.com/bitcoin-exchange-rates | ||
|
@@ -1113,6 +1184,16 @@ protected function getBillClient(): BillClient | |
return BillClient::getInstance($this->tokenCache, $this->restCli); | ||
} | ||
|
||
/** | ||
* Gets subscription client | ||
* | ||
* @return SubscriptionClient the subscription client | ||
*/ | ||
protected function getSubscriptionClient(): SubscriptionClient | ||
{ | ||
return SubscriptionClient::getInstance($this->tokenCache, $this->restCli); | ||
} | ||
|
||
/** | ||
* Gets rate client | ||
* | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
<?php | ||
|
||
/** | ||
* Copyright (c) 2025 BitPay | ||
**/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace BitPaySDK\Client; | ||
|
||
use BitPaySDK\Exceptions\BitPayApiException; | ||
use BitPaySDK\Exceptions\BitPayExceptionProvider; | ||
use BitPaySDK\Exceptions\BitPayGenericException; | ||
use BitPaySDK\Model\Subscription\Subscription; | ||
use BitPaySDK\Model\Facade; | ||
use BitPaySDK\Tokens; | ||
use BitPaySDK\Util\JsonMapperFactory; | ||
use BitPaySDK\Util\RESTcli\RESTcli; | ||
use Exception; | ||
|
||
/** | ||
* Handles interactions with the subscriptions endpoints. | ||
* | ||
* @package BitPaySDK\Client | ||
* @author BitPay Integrations <[email protected]> | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT | ||
*/ | ||
class SubscriptionClient | ||
{ | ||
private static ?self $instance = null; | ||
private Tokens $tokenCache; | ||
private RESTcli $restCli; | ||
|
||
private function __construct(Tokens $tokenCache, RESTcli $restCli) | ||
{ | ||
$this->tokenCache = $tokenCache; | ||
$this->restCli = $restCli; | ||
} | ||
|
||
/** | ||
* Factory method for Subscription Client. | ||
* | ||
* @param Tokens $tokenCache | ||
* @param RESTcli $restCli | ||
* @return static | ||
*/ | ||
public static function getInstance(Tokens $tokenCache, RESTcli $restCli): self | ||
{ | ||
if (!self::$instance) { | ||
self::$instance = new self($tokenCache, $restCli); | ||
} | ||
|
||
return self::$instance; | ||
} | ||
|
||
/** | ||
* Create a BitPay Subscription. | ||
* | ||
* @param Subscription $subscription A Subscription object with request parameters defined. | ||
* @return Subscription Created Subscription object | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function create(Subscription $subscription): Subscription | ||
{ | ||
$subscription->setToken($this->tokenCache->getTokenByFacade(Facade::MERCHANT)); | ||
|
||
$responseJson = $this->restCli->post("subscriptions", $subscription->toArray()); | ||
|
||
try { | ||
return $this->mapJsonToSubscriptionClass($responseJson); | ||
} catch (Exception $e) { | ||
BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); | ||
} | ||
} | ||
|
||
/** | ||
* Retrieve a BitPay subscription by its resource ID. | ||
* | ||
* @param $subscriptionId string The id of the subscription to retrieve. | ||
* @return Subscription Retrieved Subscription object | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function get(string $subscriptionId): Subscription | ||
{ | ||
$params = []; | ||
$params["token"] = $this->tokenCache->getTokenByFacade(Facade::MERCHANT); | ||
|
||
$responseJson = $this->restCli->get("subscriptions/" . $subscriptionId, $params); | ||
|
||
try { | ||
return $this->mapJsonToSubscriptionClass($responseJson); | ||
} catch (Exception $e) { | ||
BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); | ||
} | ||
} | ||
|
||
/** | ||
* Retrieve a collection of BitPay subscriptions. | ||
* | ||
* @param string|null $status The status to filter the subscriptions. | ||
* @return Subscription[] Filtered list of Subscription objects | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function getSubscriptions(?string $status = null): array | ||
{ | ||
$params = []; | ||
$params["token"] = $this->tokenCache->getTokenByFacade(Facade::MERCHANT); | ||
if ($status) { | ||
$params["status"] = $status; | ||
} | ||
|
||
$responseJson = $this->restCli->get("subscriptions", $params); | ||
|
||
try { | ||
$mapper = JsonMapperFactory::create(); | ||
return $mapper->mapArray( | ||
json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), | ||
[], | ||
Subscription::class | ||
); | ||
} catch (Exception $e) { | ||
BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); | ||
} | ||
} | ||
|
||
/** | ||
* Update a BitPay Subscription. | ||
* | ||
* @param Subscription $subscription A Subscription object with the parameters to update defined. | ||
* @param string $subscriptionId The ID of the Subscription to update. | ||
* @return Subscription Updated Subscription object | ||
* @throws BitPayApiException | ||
* @throws BitPayGenericException | ||
*/ | ||
public function update(Subscription $subscription, string $subscriptionId): Subscription | ||
{ | ||
$subscriptionToken = $this->get($subscription->getId())->getToken(); | ||
$subscription->setToken($subscriptionToken); | ||
|
||
$responseJson = $this->restCli->update("subscriptions/" . $subscriptionId, $subscription->toArray()); | ||
|
||
try { | ||
$mapper = JsonMapperFactory::create(); | ||
|
||
return $mapper->map( | ||
json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), | ||
$subscription | ||
); | ||
} catch (Exception $e) { | ||
BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); | ||
} | ||
} | ||
|
||
/** | ||
* @param string|null $responseJson | ||
* @return Subscription | ||
* @throws \JsonException | ||
* @throws \JsonMapper_Exception | ||
*/ | ||
private function mapJsonToSubscriptionClass(?string $responseJson): Subscription | ||
{ | ||
$mapper = JsonMapperFactory::create(); | ||
|
||
return $mapper->map( | ||
json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), | ||
new Subscription() | ||
); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
/** | ||
* Copyright (c) 2025 BitPay | ||
**/ | ||
|
||
/** | ||
* @author BitPay Integrations <[email protected]> | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT | ||
*/ | ||
|
||
namespace BitPaySDK\Model\Settlement; | ||
|
||
/** | ||
* Status of the settlement. | ||
* Possible statuses are "new", "processing", "rejected" and "completed". | ||
* | ||
* @package BitPaySDK\Model\Settlement | ||
* @author BitPay Integrations <[email protected]> | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT | ||
* @see https://developer.bitpay.com/reference/settlements Settlements | ||
*/ | ||
interface SettlementStatus | ||
{ | ||
public const NEW = "new"; | ||
public const PROCESSING = "processing"; | ||
public const REJECTED = "rejected"; | ||
public const COMPLETED = "completed"; | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name should be after the type.