Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3004b382b |
2
.github/workflows/code_style.yml
vendored
2
.github/workflows/code_style.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Run PHP CS Fixer
|
||||
uses: docker://oskarstark/php-cs-fixer-ga
|
||||
|
||||
4
.github/workflows/psalm.yml
vendored
4
.github/workflows/psalm.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
php-versions: ['8.0']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
|
||||
@ -27,7 +27,7 @@ jobs:
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,4 +3,5 @@
|
||||
.php-cs-fixer.cache
|
||||
*.cache
|
||||
composer.lock
|
||||
/tests/.env
|
||||
/tests/.env
|
||||
/.claude/
|
||||
@ -81,6 +81,32 @@ try {
|
||||
$basicPlanId = $basicPlan->getId();
|
||||
$premiumPlanId = $premiumPlan->getId();
|
||||
|
||||
// 2b. Update the offering
|
||||
echo "2b. Updating the offering...\n";
|
||||
$updatedOffering = $client->updateOffering(
|
||||
$storeId,
|
||||
$offeringId,
|
||||
'Premium SaaS App v2',
|
||||
'https://example.com/success-v2',
|
||||
['category' => 'saas', 'region' => 'eu', 'version' => '2.0']
|
||||
);
|
||||
echo "Offering updated: " . $updatedOffering->getAppName() . "\n\n";
|
||||
|
||||
// 2c. Update a plan
|
||||
echo "2c. Updating the basic plan...\n";
|
||||
$updatedPlan = $client->updateOfferingPlan(
|
||||
$storeId,
|
||||
$offeringId,
|
||||
$basicPlanId,
|
||||
'Updated basic monthly subscription',
|
||||
'USD',
|
||||
7,
|
||||
'Basic Plan v2',
|
||||
null,
|
||||
'2.99'
|
||||
);
|
||||
echo "Plan updated: " . $updatedPlan->getName() . " - " . $updatedPlan->getPrice() . " " . $updatedPlan->getCurrency() . "\n\n";
|
||||
|
||||
// 3. Get all offerings for the store
|
||||
echo "3. Getting all offerings for the store...\n";
|
||||
$offerings = $client->getOfferings($storeId);
|
||||
@ -171,6 +197,19 @@ try {
|
||||
echo "Status after suspension: " . ($suspendedSubscriber->isActive() ? 'Active' : 'Suspended') . "\n";
|
||||
echo "Suspension reason: " . ($suspendedSubscriber->getSuspensionReason() ?? 'N/A') . "\n\n";
|
||||
|
||||
// Update subscriber dates
|
||||
echo "9b. Updating subscriber dates...\n";
|
||||
$updatedSubscriber = $client->updateSubscriberDates(
|
||||
$storeId,
|
||||
$offeringId,
|
||||
$customerSelector,
|
||||
null,
|
||||
time() + (30 * 24 * 60 * 60) // 30 days from now
|
||||
);
|
||||
echo "Subscriber expiration updated\n";
|
||||
echo "Scheduled plan: " . ($updatedSubscriber->getScheduledPlan() ? $updatedSubscriber->getScheduledPlan()->getName() : 'None') . "\n";
|
||||
echo "Scheduled plan activates at: " . ($updatedSubscriber->getScheduledPlanActivatesAt() ? date('Y-m-d H:i:s', $updatedSubscriber->getScheduledPlanActivatesAt()) : 'N/A') . "\n\n";
|
||||
|
||||
// Unsuspend subscriber
|
||||
echo "10. Unsuspending subscriber...\n";
|
||||
$client->unsuspendSubscriber($storeId, $offeringId, $customerSelector);
|
||||
@ -182,6 +221,11 @@ try {
|
||||
echo "Suspension reason: " . ($reactivatedSubscriber->getSuspensionReason() ?? 'N/A') . "\n\n";
|
||||
}
|
||||
|
||||
// Delete subscriber
|
||||
echo "11. Deleting subscriber...\n";
|
||||
$client->deleteSubscriber($storeId, $offeringId, $customerSelector);
|
||||
echo "Subscriber deleted successfully!\n\n";
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
echo "Error in subscriber management: " . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
@ -79,6 +79,37 @@ class Subscriptions extends AbstractClient
|
||||
}
|
||||
}
|
||||
|
||||
public function updateOffering(
|
||||
string $storeId,
|
||||
string $offeringId,
|
||||
?string $appName = null,
|
||||
?string $successRedirectUrl = null,
|
||||
?array $metadata = null,
|
||||
?array $features = null
|
||||
): Offering {
|
||||
$url = $this->getApiUrl() . 'stores/' . urlencode($storeId) . '/offerings/' . urlencode($offeringId);
|
||||
$headers = $this->getRequestHeaders();
|
||||
$method = 'PUT';
|
||||
|
||||
$body = json_encode(
|
||||
[
|
||||
'appName' => $appName,
|
||||
'successRedirectUrl' => $successRedirectUrl,
|
||||
'metadata' => $metadata,
|
||||
'features' => $features
|
||||
],
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
|
||||
$response = $this->getHttpClient()->request($method, $url, $headers, $body);
|
||||
|
||||
if ($response->getStatus() === 200) {
|
||||
return new Offering(json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR));
|
||||
} else {
|
||||
throw $this->getExceptionByStatusCode($method, $url, $response);
|
||||
}
|
||||
}
|
||||
|
||||
// Plan endpoints
|
||||
|
||||
public function createOfferingPlan(
|
||||
@ -140,6 +171,52 @@ class Subscriptions extends AbstractClient
|
||||
}
|
||||
}
|
||||
|
||||
public function updateOfferingPlan(
|
||||
string $storeId,
|
||||
string $offeringId,
|
||||
string $planId,
|
||||
?string $description = null,
|
||||
?string $currency = null,
|
||||
?int $gracePeriodDays = null,
|
||||
?string $name = null,
|
||||
?bool $optimisticActivation = null,
|
||||
?string $price = null,
|
||||
?bool $renewable = null,
|
||||
?int $trialDays = null,
|
||||
?array $metadata = null,
|
||||
?string $recurringType = null,
|
||||
?array $features = null
|
||||
): OfferingPlan {
|
||||
$url = $this->getApiUrl() . 'stores/' . urlencode($storeId) . '/offerings/' . urlencode($offeringId) . '/plans/' . urlencode($planId);
|
||||
$headers = $this->getRequestHeaders();
|
||||
$method = 'PUT';
|
||||
|
||||
$body = json_encode(
|
||||
[
|
||||
'description' => $description,
|
||||
'currency' => $currency,
|
||||
'gracePeriodDays' => $gracePeriodDays,
|
||||
'name' => $name,
|
||||
'optimisticActivation' => $optimisticActivation,
|
||||
'price' => $price,
|
||||
'renewable' => $renewable,
|
||||
'trialDays' => $trialDays,
|
||||
'metadata' => $metadata,
|
||||
'recurringType' => $recurringType,
|
||||
'features' => $features
|
||||
],
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
|
||||
$response = $this->getHttpClient()->request($method, $url, $headers, $body);
|
||||
|
||||
if ($response->getStatus() === 200) {
|
||||
return new OfferingPlan(json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR));
|
||||
} else {
|
||||
throw $this->getExceptionByStatusCode($method, $url, $response);
|
||||
}
|
||||
}
|
||||
|
||||
// Subscriber endpoints
|
||||
|
||||
public function getSubscriber(string $storeId, string $offeringId, string $customerSelector): Subscriber
|
||||
@ -156,6 +233,46 @@ class Subscriptions extends AbstractClient
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteSubscriber(string $storeId, string $offeringId, string $customerSelector): void
|
||||
{
|
||||
$url = $this->getApiUrl() . 'stores/' . urlencode($storeId) . '/offerings/' . urlencode($offeringId) . '/subscribers/' . urlencode($customerSelector);
|
||||
$headers = $this->getRequestHeaders();
|
||||
$method = 'DELETE';
|
||||
$response = $this->getHttpClient()->request($method, $url, $headers);
|
||||
|
||||
if ($response->getStatus() !== 204) {
|
||||
throw $this->getExceptionByStatusCode($method, $url, $response);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateSubscriberDates(
|
||||
string $storeId,
|
||||
string $offeringId,
|
||||
string $customerSelector,
|
||||
?int $startDate = null,
|
||||
?int $expirationDate = null
|
||||
): Subscriber {
|
||||
$url = $this->getApiUrl() . 'stores/' . urlencode($storeId) . '/offerings/' . urlencode($offeringId) . '/subscribers/' . urlencode($customerSelector) . '/dates';
|
||||
$headers = $this->getRequestHeaders();
|
||||
$method = 'PUT';
|
||||
|
||||
$body = json_encode(
|
||||
[
|
||||
'startDate' => $startDate,
|
||||
'expirationDate' => $expirationDate
|
||||
],
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
|
||||
$response = $this->getHttpClient()->request($method, $url, $headers, $body);
|
||||
|
||||
if ($response->getStatus() === 200) {
|
||||
return new Subscriber(json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR));
|
||||
} else {
|
||||
throw $this->getExceptionByStatusCode($method, $url, $response);
|
||||
}
|
||||
}
|
||||
|
||||
public function suspendSubscriber(string $storeId, string $offeringId, string $customerSelector, string $reason): Subscriber
|
||||
{
|
||||
$url = $this->getApiUrl() . 'stores/' . urlencode($storeId) . '/offerings/' . urlencode($offeringId) . '/subscribers/' . urlencode($customerSelector) . '/suspend';
|
||||
|
||||
@ -76,6 +76,16 @@ class Subscriber extends AbstractResult
|
||||
return isset($this->getData()['nextPlan']) ? new OfferingPlan($this->getData()['nextPlan']) : null;
|
||||
}
|
||||
|
||||
public function getScheduledPlan(): ?OfferingPlan
|
||||
{
|
||||
return isset($this->getData()['scheduledPlan']) ? new OfferingPlan($this->getData()['scheduledPlan']) : null;
|
||||
}
|
||||
|
||||
public function getScheduledPlanActivatesAt(): ?int
|
||||
{
|
||||
return $this->getData()['scheduledPlanActivatesAt'] ?? null;
|
||||
}
|
||||
|
||||
public function getPhase(): string
|
||||
{
|
||||
return $this->getData()['phase'];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user