Skip to content

Commit

Permalink
feat: Add support for saved payment methods (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgrayston-paddle authored Nov 18, 2024
1 parent f3be3d4 commit df53ce8
Show file tree
Hide file tree
Showing 32 changed files with 1,298 additions and 5 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx&utm_medium=paddle-php-sdk) for information about changes to the Paddle Billing platform, the Paddle API, and other developer tools.

## [Unreleased]

### Added

- Support for saved payment methods, see [related changelog](https://developer.paddle.com/changelog/2024/saved-payment-methods?utm_source=dx&utm_medium=paddle-php-sdk)
- `Client->paymentMethods->list()`
- `Client->paymentMethods->get()`
- `Client->paymentMethods->delete()`
- `Client->customers->generateAuthToken()`

## [1.4.0] - 2024-10-17

### Added
Expand Down
33 changes: 33 additions & 0 deletions examples/customer_auth_token.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

use Paddle\SDK\Exceptions\ApiError;
use Paddle\SDK\Exceptions\SdkExceptions\MalformedResponse;

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

$environment = Paddle\SDK\Environment::tryFrom(getenv('PADDLE_ENVIRONMENT') ?: '') ?? Paddle\SDK\Environment::SANDBOX;
$apiKey = getenv('PADDLE_API_KEY') ?: null;
$customerId = getenv('PADDLE_CUSTOMER_ID') ?: null;

if (is_null($apiKey)) {
echo "You must provide the PADDLE_API_KEY in the environment:\n";
echo "PADDLE_API_KEY=your-key php examples/basic_usage.php\n";
exit(1);
}

$paddle = new Paddle\SDK\Client($apiKey, options: new Paddle\SDK\Options($environment));

// ┌───
// │ Create Customer Auth Token │
// └────────────────────────────┘
try {
$authToken = $paddle->customers->generateAuthToken($customerId);
} catch (ApiError|MalformedResponse $e) {
var_dump($e);
exit;
}

echo sprintf("Created Customer Auth Token: %s\n", $authToken->customerAuthToken);
echo sprintf(" - Expires At: %s\n", $authToken->expiresAt->format(DATE_RFC3339_EXTENDED));
97 changes: 97 additions & 0 deletions examples/payment_methods.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

declare(strict_types=1);

use Paddle\SDK\Exceptions\ApiError;
use Paddle\SDK\Exceptions\SdkExceptions\MalformedResponse;
use Paddle\SDK\Resources\PaymentMethods\Operations\ListPaymentMethods;
use Paddle\SDK\Resources\Shared\Operations\List\Pager;

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

$environment = Paddle\SDK\Environment::tryFrom(getenv('PADDLE_ENVIRONMENT') ?: '') ?? Paddle\SDK\Environment::SANDBOX;
$apiKey = getenv('PADDLE_API_KEY') ?: null;
$customerId = getenv('PADDLE_CUSTOMER_ID') ?: null;
$paymentMethodId = getenv('PADDLE_PAYMENT_METHOD_ID') ?: null;

if (is_null($apiKey)) {
echo "You must provide the PADDLE_API_KEY in the environment:\n";
echo "PADDLE_API_KEY=your-key php examples/basic_usage.php\n";
exit(1);
}

$paddle = new Paddle\SDK\Client($apiKey, options: new Paddle\SDK\Options($environment));

// ┌───
// │ List Payment Methods │
// └──────────────────────┘
try {
$paymentMethods = $paddle->paymentMethods->list(
$customerId,
new ListPaymentMethods(
pager: new Pager(perPage: 10),
),
);
} catch (ApiError|MalformedResponse $e) {
var_dump($e);
exit;
}

echo "List Payment Methods\n";

foreach ($paymentMethods as $paymentMethod) {
echo sprintf("- %s:\n", $paymentMethod->id);
echo sprintf(" - Type: %s\n", $paymentMethod->type->getValue());

if ($paymentMethod->card) {
echo sprintf(" - Card Type: %s\n", $paymentMethod->card->type->getValue());
echo sprintf(" - Card Holder Name: %s\n", $paymentMethod->card->cardholderName);
echo sprintf(" - Card Last 4 Digits: %s\n", $paymentMethod->card->last4);
echo sprintf(" - Card Expiry Year: %d\n", $paymentMethod->card->expiryYear);
echo sprintf(" - Card Expiry Month: %d\n", $paymentMethod->card->expiryMonth);
}

if ($paymentMethod->paypal) {
echo sprintf(" - PayPal Reference: %s\n", $paymentMethod->paypal->reference);
echo sprintf(" - PayPal Email: %s\n", $paymentMethod->paypal->email);
}
}

// ┌───
// │ Get Payment Method |
// └────────────────────┘
try {
$paymentMethod = $paddle->paymentMethods->get($customerId, $paymentMethodId);
} catch (ApiError|MalformedResponse $e) {
var_dump($e);
exit;
}

echo sprintf("Get Payment Method: %s\n", $paymentMethod->id);
echo sprintf(" - Type: %s\n", $paymentMethod->type->getValue());

if ($paymentMethod->card) {
echo sprintf(" - Card Type: %s\n", $paymentMethod->card->type->getValue());
echo sprintf(" - Card Holder Name: %s\n", $paymentMethod->card->cardholderName);
echo sprintf(" - Card Last 4 Digits: %s\n", $paymentMethod->card->last4);
echo sprintf(" - Card Expiry Year: %d\n", $paymentMethod->card->expiryYear);
echo sprintf(" - Card Expiry Month: %d\n", $paymentMethod->card->expiryMonth);
}

if ($paymentMethod->paypal) {
echo sprintf(" - PayPal Reference: %s\n", $paymentMethod->paypal->reference);
echo sprintf(" - PayPal Email: %s\n", $paymentMethod->paypal->email);
}

// ┌───
// │ Delete Payment Method |
// └───────────────────────┘
try {
$paddle->paymentMethods->delete($customerId, $paymentMethodId);
} catch (ApiError|MalformedResponse $e) {
var_dump($e);
exit;
}

echo sprintf("Deleted Payment Method: %s\n", $paymentMethodId);
echo sprintf(" - Type: %s\n", $paymentMethod->type->getValue());
5 changes: 4 additions & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use Paddle\SDK\Resources\NotificationLogs\NotificationLogsClient;
use Paddle\SDK\Resources\Notifications\NotificationsClient;
use Paddle\SDK\Resources\NotificationSettings\NotificationSettingsClient;
use Paddle\SDK\Resources\PaymentMethods\PaymentMethodsClient;
use Paddle\SDK\Resources\Prices\PricesClient;
use Paddle\SDK\Resources\PricingPreviews\PricingPreviewsClient;
use Paddle\SDK\Resources\Products\ProductsClient;
Expand Down Expand Up @@ -75,6 +76,7 @@ class Client
public readonly EventTypesClient $eventTypes;
public readonly EventsClient $events;
public readonly PricingPreviewsClient $pricingPreviews;
public readonly PaymentMethodsClient $paymentMethods;
public readonly NotificationSettingsClient $notificationSettings;
public readonly NotificationsClient $notifications;
public readonly NotificationLogsClient $notificationLogs;
Expand Down Expand Up @@ -122,6 +124,7 @@ public function __construct(
$this->eventTypes = new EventTypesClient($this);
$this->events = new EventsClient($this);
$this->pricingPreviews = new PricingPreviewsClient($this);
$this->paymentMethods = new PaymentMethodsClient($this);
$this->notificationSettings = new NotificationSettingsClient($this);
$this->notifications = new NotificationsClient($this);
$this->notificationLogs = new NotificationLogsClient($this);
Expand Down Expand Up @@ -153,7 +156,7 @@ public function patchRaw(string|UriInterface $uri, array|\JsonSerializable $payl
return $this->requestRaw('PATCH', $uri, $payload);
}

public function postRaw(string|UriInterface $uri, array|\JsonSerializable $payload = [], array|HasParameters $parameters = []): ResponseInterface
public function postRaw(string|UriInterface $uri, array|\JsonSerializable|null $payload = [], array|HasParameters $parameters = []): ResponseInterface
{
if ($parameters) {
$parameters = $parameters instanceof HasParameters ? $parameters->getParameters() : $parameters;
Expand Down
30 changes: 30 additions & 0 deletions src/Entities/Collections/PaymentMethodCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/**
* |------
* | ! Generated code !
* | Altering this code will result in changes being overwritten |
* |-------------------------------------------------------------|.
*/

namespace Paddle\SDK\Entities\Collections;

use Paddle\SDK\Entities\PaymentMethod;

class PaymentMethodCollection extends Collection
{
public static function from(array $itemsData, Paginator|null $paginator = null): self
{
return new self(
array_map(fn (array $item): PaymentMethod => PaymentMethod::from($item), $itemsData),
$paginator,
);
}

public function current(): PaymentMethod
{
return parent::current();
}
}
32 changes: 32 additions & 0 deletions src/Entities/CustomerAuthToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

/**
* |------
* | ! Generated code !
* | Altering this code will result in changes being overwritten |
* |-------------------------------------------------------------|.
*/

namespace Paddle\SDK\Entities;

use Paddle\SDK\Notifications\Entities\DateTime;
use Paddle\SDK\Notifications\Entities\Entity;

class CustomerAuthToken implements Entity
{
private function __construct(
public string $customerAuthToken,
public \DateTimeInterface $expiresAt,
) {
}

public static function from(array $data): self
{
return new self(
customerAuthToken: $data['customer_auth_token'],
expiresAt: DateTime::from($data['expires_at']),
);
}
}
48 changes: 48 additions & 0 deletions src/Entities/PaymentMethod.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

/**
* |------
* | ! Generated code !
* | Altering this code will result in changes being overwritten |
* |-------------------------------------------------------------|.
*/

namespace Paddle\SDK\Entities;

use Paddle\SDK\Entities\Shared\Card;
use Paddle\SDK\Entities\Shared\Paypal;
use Paddle\SDK\Entities\Shared\SavedPaymentMethodOrigin;
use Paddle\SDK\Entities\Shared\SavedPaymentMethodType;

class PaymentMethod implements Entity
{
private function __construct(
public string $id,
public string $customerId,
public string $addressId,
public SavedPaymentMethodType $type,
public Card|null $card,
public Paypal|null $paypal,
public SavedPaymentMethodOrigin $origin,
public \DateTimeInterface $savedAt,
public \DateTimeInterface $updatedAt,
) {
}

public static function from(array $data): self
{
return new self(
id: $data['id'],
customerId: $data['customer_id'],
addressId: $data['address_id'],
type: SavedPaymentMethodType::from($data['type']),
card: isset($data['card']) ? Card::from($data['card']) : null,
paypal: isset($data['paypal']) ? Paypal::from($data['paypal']) : null,
origin: SavedPaymentMethodOrigin::from($data['origin']),
savedAt: DateTime::from($data['saved_at']),
updatedAt: DateTime::from($data['updated_at']),
);
}
}
29 changes: 29 additions & 0 deletions src/Entities/Shared/Paypal.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

/**
* |------
* | ! Generated code !
* | Altering this code will result in changes being overwritten |
* |-------------------------------------------------------------|.
*/

namespace Paddle\SDK\Entities\Shared;

class Paypal
{
private function __construct(
public string $email,
public string $reference,
) {
}

public static function from(array $data): self
{
return new self(
$data['email'],
$data['reference'],
);
}
}
24 changes: 24 additions & 0 deletions src/Entities/Shared/SavedPaymentMethodOrigin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

/**
* |------
* | ! Generated code !
* | Altering this code will result in changes being overwritten |
* |-------------------------------------------------------------|.
*/

namespace Paddle\SDK\Entities\Shared;

use Paddle\SDK\PaddleEnum;

/**
* @method static SavedPaymentMethodOrigin SavedDuringPurchase()
* @method static SavedPaymentMethodOrigin Subscription()
*/
final class SavedPaymentMethodOrigin extends PaddleEnum
{
private const SavedDuringPurchase = 'saved_during_purchase';
private const Subscription = 'subscription';
}
30 changes: 30 additions & 0 deletions src/Entities/Shared/SavedPaymentMethodType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/**
* |------
* | ! Generated code !
* | Altering this code will result in changes being overwritten |
* |-------------------------------------------------------------|.
*/

namespace Paddle\SDK\Entities\Shared;

use Paddle\SDK\PaddleEnum;

/**
* @method static SavedPaymentMethodType Alipay()
* @method static SavedPaymentMethodType ApplePay()
* @method static SavedPaymentMethodType Card()
* @method static SavedPaymentMethodType GooglePay()
* @method static SavedPaymentMethodType Paypal()
*/
final class SavedPaymentMethodType extends PaddleEnum
{
private const Alipay = 'alipay';
private const ApplePay = 'apple_pay';
private const Card = 'card';
private const GooglePay = 'google_pay';
private const Paypal = 'paypal';
}
Loading

0 comments on commit df53ce8

Please sign in to comment.