├── index.html
├── logs
├── ipns
│ └── index.html
└── webhooks
│ └── index.html
├── README.md
├── .env.example
├── .gitignore
├── src
├── PlanIdStorage.php
├── TokenCache.php
├── Logger.php
├── bootstrap.php
├── Endpoints.php
├── DirectoryList.php
├── services
│ ├── FileBasedPlanIdStorage.php
│ ├── FileBasedTokenCache.php
│ └── FileBasedLogger.php
├── SubscriptionCreator.php
├── OrderCreator.php
├── Authenticator.php
├── ProductCreator.php
├── PlanCreator.php
└── ApiFactory.php
├── public
├── donate.php
├── ipns.php
├── events.php
├── ipn.php
├── confirmation.php
├── create-products.php
├── list-ipns.php
├── list-webhooks.php
├── membership.php
├── index.php
└── create-plans.php
├── docker-compose.yml
├── composer.json
├── phpunit.xml.dist
└── tests
├── AuthenticatorTest.php
├── PlanCreatorTest.php
├── OrderCreatorTest.php
├── ProductCreatorTest.php
├── ApiTest.php
└── SubscriptionCreatorTest.php
/index.html:
--------------------------------------------------------------------------------
1 | alsndasjkdmnklasjn
--------------------------------------------------------------------------------
/logs/ipns/index.html:
--------------------------------------------------------------------------------
1 | G'way outta that!
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Fundraising-paypal-api-test
2 |
--------------------------------------------------------------------------------
/logs/webhooks/index.html:
--------------------------------------------------------------------------------
1 | G'way outta that!
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | CLIENT_ID=
2 | SECRET=
3 | BASE_URL=http://localhost:8008
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 | .env
3 | composer.lock
4 | .phpunit.result.cache
5 | token.json
6 | plans.json
7 | logs/webhooks/*
8 | logs/ipns/*
9 | !logs/webhooks/index.html
10 | !logs/ipns/index.html
--------------------------------------------------------------------------------
/src/PlanIdStorage.php:
--------------------------------------------------------------------------------
1 | newAuthenticator();
12 | $orderCreator = $factory->newOrderCreator();
13 | $url = $orderCreator->createOrderUrl( $authenticator->getToken() );
14 |
15 | header( 'Location: ' . $url );
16 |
--------------------------------------------------------------------------------
/src/bootstrap.php:
--------------------------------------------------------------------------------
1 | safeLoad();
12 |
13 | return new ApiFactory( [
14 | 'client_id' => $_ENV['CLIENT_ID'],
15 | 'secret' => $_ENV['SECRET'],
16 | 'base_url' => $_ENV['BASE_URL']
17 | ] );
18 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 |
3 | services:
4 | web:
5 | image: nginx:latest
6 | ports:
7 | - "8008:80"
8 | volumes:
9 | - ./build/web/conf.d:/etc/nginx/conf.d
10 | - ./:/usr/src/app
11 | depends_on:
12 | - app
13 |
14 | app:
15 | image: php:8.1-fpm
16 | volumes:
17 | - ./:/usr/src/app
18 | working_dir: /usr/src/app/public
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "vlucas/phpdotenv": "^5.4",
4 | "guzzlehttp/guzzle": "^7.4"
5 | },
6 | "require-dev": {
7 | "phpunit/phpunit": "^9.5"
8 | },
9 | "autoload": {
10 | "psr-4": {
11 | "WMDE\\ApiTestKit\\": "src/"
12 | }
13 | },
14 | "autoload-dev": {
15 | "psr-4": {
16 | "WMDE\\ApiTestKit\\Tests\\": "tests/"
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/ipns.php:
--------------------------------------------------------------------------------
1 | newIPNLogger();
12 |
13 | try {
14 | $logger->storeLog( strval( ( new \DateTimeImmutable() )->getTimestamp() ), $_POST );
15 | } catch ( \Exception $e ) {
16 | // Don't do anything
17 | }
18 |
19 | echo 'OK';
20 | exit();
21 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | src
6 |
7 |
8 |
9 |
10 | tests
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tests/AuthenticatorTest.php:
--------------------------------------------------------------------------------
1 | factory->newAuthenticator();
14 |
15 | $token = $authenticator->getToken();
16 |
17 | $this->assertIsString( $token );
18 | $this->assertNotEmpty( $token );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/public/events.php:
--------------------------------------------------------------------------------
1 | newWebhookLogger();
12 |
13 | try {
14 | $body = file_get_contents( 'php://input' );
15 | $data = json_decode( $body, true );
16 | $logger->storeLog( $data['resource']['id'], $data );
17 | } catch ( \Exception $e ) {
18 | // Don't do anything
19 | }
20 |
21 | echo 'OK';
22 | exit();
23 |
--------------------------------------------------------------------------------
/tests/PlanCreatorTest.php:
--------------------------------------------------------------------------------
1 | factory->newAuthenticator();
11 | $planCreator = $this->factory->newPlanCreator();
12 |
13 | $planId = $planCreator->createPlan( $authenticator->getToken() );
14 |
15 | $this->assertIsString( $planId );
16 | $this->assertStringStartsWith( 'P-', $planId );
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Endpoints.php:
--------------------------------------------------------------------------------
1 | factory->newAuthenticator();
11 | $orderCreator = $this->factory->newOrderCreator();
12 |
13 | $url = $orderCreator->createOrderUrl( $authenticator->getToken() );
14 |
15 | $this->assertIsString( $url );
16 | $this->assertStringStartsWith( 'https://', $url );
17 | $this->assertStringNotContainsString( 'api-m', $url );
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/tests/ProductCreatorTest.php:
--------------------------------------------------------------------------------
1 | markTestSkipped();
16 |
17 | $authenticator = $this->factory->newAuthenticator();
18 | $productCreator = $this->factory->newProductCreator();
19 |
20 | $data = $productCreator->createProduct( $authenticator->getToken() );
21 |
22 | print_r( $data );
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/tests/ApiTest.php:
--------------------------------------------------------------------------------
1 | factory === null ) {
17 | $dotenv = Dotenv::createImmutable( __DIR__ . '/../' );
18 | $dotenv->safeLoad();
19 |
20 | $this->factory = new ApiFactory( [
21 | 'client_id' => $_ENV['CLIENT_ID'],
22 | 'secret' => $_ENV['SECRET'],
23 | 'base_url' => $_ENV['BASE_URL']
24 | ] );
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/DirectoryList.php:
--------------------------------------------------------------------------------
1 | directoryPath = $directoryPath;
13 | }
14 |
15 | public function getFiles(): array {
16 | $fileList = [];
17 |
18 | if ( $handle = opendir( $this->directoryPath ) ) {
19 | while ( false !== ( $file = readdir( $handle ) ) ) {
20 | if ( !str_contains( $file, 'json' ) ) {
21 | continue;
22 | }
23 |
24 | $fileList[] = $file;
25 | }
26 | closedir( $handle );
27 | }
28 |
29 | return $fileList;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/public/ipn.php:
--------------------------------------------------------------------------------
1 | newIPNLogger();
12 |
13 | $data = $logger->getLog( filter_var( $_GET['timestamp'], FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
14 |
15 | ?>
16 |
17 |
18 |
19 | PayPal API Test
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | No IPN has been logged yet, try reloading.
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/public/confirmation.php:
--------------------------------------------------------------------------------
1 | newWebhookLogger();
12 |
13 | $data = $logger->getLog( filter_var( $_GET['id'], FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
14 |
15 | ?>
16 |
17 |
18 |
19 | PayPal API Test
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | No Webhook has been logged yet, try reloading.
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/public/create-products.php:
--------------------------------------------------------------------------------
1 | newAuthenticator()->getToken();
12 | $productCreator = $factory->newProductCreator();
13 |
14 | $products = [
15 | 'MEMBERSHIP' => 'Membership to Wikimedia Deutschland',
16 | 'DONATION' => 'Donation to Wikimedia Deutschland'
17 | ];
18 |
19 | $results = [];
20 | foreach ( $products as $productId => $name ) {
21 | $results[] = $productCreator->createProduct( $token, [
22 | 'id' => $productId,
23 | 'name' => $name
24 | ] );
25 | }
26 |
27 | echo '';
28 | print_r( $results );
29 | echo '
';
30 |
--------------------------------------------------------------------------------
/tests/SubscriptionCreatorTest.php:
--------------------------------------------------------------------------------
1 | factory->newAuthenticator();
11 | $planCreator = $this->factory->newPlanCreator();
12 | $subscriptionCreator = $this->factory->newSubscriptionCreator();
13 |
14 | $token = $authenticator->getToken();
15 | $planId = $planCreator->createPlan( $token );
16 | $url = $subscriptionCreator->createSubscription( $token, $planId );
17 |
18 | $this->assertIsString( $url );
19 | $this->assertStringStartsWith( 'https://', $url );
20 | $this->assertStringNotContainsString( 'api-m', $url );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/public/list-ipns.php:
--------------------------------------------------------------------------------
1 | newIpnDirectoryList();
12 |
13 | $data = $directoryList->getFiles();
14 |
15 | ?>
16 |
17 |
18 |
19 | PayPal API Test
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 | No IPNS have been logged yet, try reloading.
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/public/list-webhooks.php:
--------------------------------------------------------------------------------
1 | newWebhookDirectoryList();
12 |
13 | $data = $directoryList->getFiles();
14 |
15 | ?>
16 |
17 |
18 |
19 | PayPal API Test
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 | No Webhooks have been logged yet, try reloading.
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/public/membership.php:
--------------------------------------------------------------------------------
1 | newAuthenticator();
12 | $subscriptionCreator = $factory->newSubscriptionCreator();
13 | $plans = $factory->newPlanIdStorage()->getPlanIds();
14 |
15 | $plan = $_GET['plan'];
16 | $amount = $_GET['amount'];
17 |
18 | $url = $subscriptionCreator->createSubscription( $authenticator->getToken(), $plans[$plan], [
19 | 'plan' => [
20 | 'billing_cycles' => [
21 | [
22 | 'sequence' => 1,
23 | 'pricing_scheme' => [
24 | 'fixed_price' => [
25 | 'currency_code' => 'EUR',
26 | 'value' => $amount
27 | ]
28 | ]
29 | ]
30 | ]
31 | ]
32 | ] );
33 |
34 | header( 'Location: ' . $url );
--------------------------------------------------------------------------------
/src/services/FileBasedPlanIdStorage.php:
--------------------------------------------------------------------------------
1 | filename = $filename;
15 | }
16 |
17 | public function getPlanIds(): array {
18 | if ( !file_exists( $this->filename ) ) {
19 | return [];
20 | }
21 |
22 | try {
23 | $json = file_get_contents( $this->filename );
24 | $data = json_decode( $json, true );
25 | }
26 | catch ( \Exception $e ) {
27 | return [];
28 | }
29 |
30 | return $data;
31 | }
32 |
33 | public function savePlanIds( array $planIds ): void {
34 | file_put_contents( $this->filename, json_encode( $planIds ) );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PayPal API Test
4 |
5 |
6 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/services/FileBasedTokenCache.php:
--------------------------------------------------------------------------------
1 | filename = $filename;
15 | }
16 |
17 | public function getToken(): ?string {
18 | if ( !file_exists( $this->filename ) ) {
19 | return null;
20 | }
21 |
22 | try {
23 | $json = file_get_contents( $this->filename );
24 | $data = json_decode( $json, true );
25 | } catch ( \Exception $e ) {
26 | return null;
27 | }
28 |
29 | if ( ( new \DateTimeImmutable() )->getTimestamp() > $data['expiry'] ) {
30 | return null;
31 | }
32 |
33 | return $data['token'];
34 | }
35 |
36 | public function storeToken( string $token, int $expiry ): void {
37 | $data = json_encode( [
38 | 'token' => $token,
39 | 'expiry' => ( new \DateTimeImmutable() )->getTimestamp() + $expiry,
40 | ] );
41 |
42 | file_put_contents( $this->filename, $data );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/services/FileBasedLogger.php:
--------------------------------------------------------------------------------
1 | basePath = $basePath;
15 | }
16 |
17 | public function getLog( string $filename ): ?array {
18 | if ( !file_exists( $this->filePath( $filename ) ) ) {
19 | return null;
20 | }
21 |
22 | try {
23 | $json = file_get_contents( $this->filePath( $filename ) );
24 | $data = json_decode( $json, true );
25 | } catch ( \Exception $e ) {
26 | return null;
27 | }
28 |
29 | return $data;
30 | }
31 |
32 | public function storeLog( string $filename, array $data ): void {
33 | $filename = $this->filePath( $filename );
34 |
35 | if ( file_exists( $filename ) ) {
36 | return;
37 | }
38 |
39 | file_put_contents( $filename, json_encode( $data ) );
40 | }
41 |
42 | private function filePath( string $filename ): string {
43 | return "{$this->basePath}/{$filename}.json";
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/SubscriptionCreator.php:
--------------------------------------------------------------------------------
1 | client = $client;
17 | $this->endpoint = $endpoint;
18 | $this->baseUrl = $baseUrl;
19 | }
20 |
21 | public function createSubscription( string $token, string $planId, array $data = [] ): string {
22 | $response = $this->client->request( 'POST', $this->endpoint, [
23 | 'headers' => [
24 | 'Authorization' => "Bearer {$token}"
25 | ],
26 | 'http_errors' => false,
27 | 'json' => array_replace_recursive( [
28 | 'plan_id' => $planId,
29 | 'start_time' => (new \DateTimeImmutable( '+1 month' ))->format( 'Y-m-d\TH:i:s\Z' ),
30 | 'custom_id' => uniqid( 'MEMBERSHIP-' )
31 | ], $data )
32 | ] );
33 |
34 | $data = json_decode( $response->getBody()->getContents(), true );
35 |
36 | return $data['links'][0]['href'] . '?return=' . $this->baseUrl . '/confirmation.php?id=' . $data['id'];
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/OrderCreator.php:
--------------------------------------------------------------------------------
1 | client = $client;
17 | $this->endpoint = $endpoint;
18 | $this->baseUrl = $baseUrl;
19 | }
20 |
21 | public function createOrderUrl( string $token, array $data = [] ): string {
22 | $response = $this->client->request( 'POST', $this->endpoint, [
23 | 'headers' => [
24 | 'Authorization' => "Bearer {$token}"
25 | ],
26 | 'json' => array_merge( [
27 | 'intent' => 'CAPTURE',
28 | 'status' => 'CREATED',
29 | 'purchase_units' => [
30 | [
31 | 'reference_id' => uniqid( 'DONATION-' ),
32 | 'amount' => [
33 | 'currency_code' => 'EUR',
34 | 'value' => '1000'
35 | ]
36 | ]
37 | ],
38 | 'return_url' => $this->baseUrl . '/confirmation.php?id=' . $data['id']
39 | ], $data )
40 | ] );
41 |
42 | $data = json_decode( $response->getBody()->getContents(), true );
43 |
44 | return $data['links'][1]['href'];
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Authenticator.php:
--------------------------------------------------------------------------------
1 | tokenCache = $tokenCache;
19 | $this->client = $client;
20 | $this->authEndpoint = $apiEndpoint;
21 | $this->clientId = $clientId;
22 | $this->secret = $secret;
23 | }
24 |
25 | public function getToken(): string {
26 | $token = $this->tokenCache->getToken();
27 |
28 | if ( $token !== null ) {
29 | return $token;
30 | }
31 |
32 | $response = $this->client->request( 'POST', $this->authEndpoint, [
33 | 'auth' => [ $this->clientId, $this->secret ],
34 | 'form_params' => [
35 | 'grant_type' => 'client_credentials',
36 | ]
37 | ] );
38 |
39 | $data = json_decode( $response->getBody()->getContents(), true );
40 |
41 | $this->tokenCache->storeToken( $data['access_token'], $data['expires_in'] );
42 |
43 | return $data['access_token'];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/ProductCreator.php:
--------------------------------------------------------------------------------
1 | client = $client;
20 | $this->endpoint = $endpoint;
21 | }
22 |
23 | public function createProduct( string $token, array $data = [] ): array {
24 | $response = $this->client->request( 'POST', $this->endpoint, [
25 | 'headers' => [
26 | 'Authorization' => "Bearer {$token}"
27 | ],
28 | 'http_errors' => false,
29 | 'json' => array_merge( [
30 | 'id' => 'MEMBERSHIP',
31 | 'type' => 'SERVICE',
32 | 'name' => 'Membership to Wikimedia Deutschland',
33 | 'description' => 'Ihre Spende für freies Wissen',
34 | 'category' => 'NONPROFIT',
35 | 'image_url' => 'https://spenden.wikimedia.de/skins/laika/images/logo-horizontal-wikimedia.svg',
36 | 'home_url' => 'https://spenden.wikimedia.de'
37 | ], $data )
38 | ] );
39 |
40 | return json_decode( $response->getBody()->getContents(), true );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/PlanCreator.php:
--------------------------------------------------------------------------------
1 | client = $client;
20 | $this->endpoint = $endpoint;
21 | }
22 |
23 | public function createPlan( string $token, array $data = [] ): ?string {
24 | $response = $this->client->request( 'POST', $this->endpoint, [
25 | 'headers' => [
26 | 'Authorization' => "Bearer {$token}"
27 | ],
28 | 'http_errors' => false,
29 | 'json' => array_replace_recursive( [
30 | 'product_id' => 'MEMBERSHIP',
31 | 'name' => 'Membership to Wikimedia Deutschland',
32 | 'billing_cycles' => [
33 | [
34 | 'frequency' => [
35 | 'interval_unit' => 'MONTH',
36 | 'interval_count' => 1
37 | ],
38 | 'tenure_type' => 'REGULAR',
39 | 'sequence' => 1,
40 | 'total_cycles' => 0,
41 | 'pricing_scheme' => [
42 | 'fixed_price' => [
43 | 'value' => 1,
44 | 'currency_code' => 'EUR'
45 | ]
46 | ]
47 | ]
48 | ],
49 | 'payment_preferences' => [
50 | 'auto_bill_outstanding' => true,
51 | 'payment_failure_threshold' => 3
52 | ]
53 | ], $data )
54 | ] );
55 |
56 | $data = json_decode( $response->getBody()->getContents(), true );
57 |
58 | return $data['id'] ?? null;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/public/create-plans.php:
--------------------------------------------------------------------------------
1 | newAuthenticator()->getToken();
12 | $planCreator = $factory->newPlanCreator();
13 | $planIdStorage = $factory->newPlanIdStorage();
14 |
15 | $plans = [
16 | 'membership-daily' => [
17 | 'product_id' => 'MEMBERSHIP',
18 | 'name' => 'Daily Membership to Wikimedia Deutschland',
19 | 'billing_cycles' => [
20 | [
21 | 'frequency' => [
22 | 'interval_unit' => 'DAY',
23 | 'interval_count' => 1
24 | ],
25 | ],
26 | ]
27 | ],
28 | 'membership-monthly' => [
29 | 'product_id' => 'MEMBERSHIP',
30 | 'name' => 'Monthly Membership to Wikimedia Deutschland',
31 | 'billing_cycles' => [
32 | [
33 | 'frequency' => [
34 | 'interval_unit' => 'MONTH',
35 | 'interval_count' => 1
36 | ],
37 | ],
38 | ]
39 | ],
40 | 'membership-quarterly' => [
41 | 'product_id' => 'MEMBERSHIP',
42 | 'name' => 'Quarterly Membership to Wikimedia Deutschland',
43 | 'billing_cycles' => [
44 | [
45 | 'frequency' => [
46 | 'interval_unit' => 'MONTH',
47 | 'interval_count' => 3
48 | ],
49 | ],
50 | ]
51 | ],
52 | 'membership-twice-yearly' => [
53 | 'product_id' => 'MEMBERSHIP',
54 | 'name' => 'Twice Yearly Membership to Wikimedia Deutschland',
55 | 'billing_cycles' => [
56 | [
57 | 'frequency' => [
58 | 'interval_unit' => 'MONTH',
59 | 'interval_count' => 6
60 | ],
61 | ],
62 | ]
63 | ],
64 | 'membership-yearly' => [
65 | 'product_id' => 'MEMBERSHIP',
66 | 'name' => 'Yearly Membership to Wikimedia Deutschland',
67 | 'billing_cycles' => [
68 | [
69 | 'frequency' => [
70 | 'interval_unit' => 'YEAR',
71 | 'interval_count' => 1
72 | ],
73 | ],
74 | ]
75 | ]
76 | ];
77 |
78 | $planIds = $planIdStorage->getPlanIds();
79 |
80 | foreach ( $plans as $planName => $data ) {
81 | if ( isset( $planIds[$planName] ) ) {
82 | continue;
83 | }
84 |
85 | $planId = $planCreator->createPlan( $token, $data );
86 | if ( $planId ) {
87 | $planIds[$planName] = $planId;
88 | }
89 | }
90 |
91 | $planIdStorage->savePlanIds( $planIds );
92 |
93 | echo '';
94 | print_r( $planIds );
95 | echo '
';
96 |
--------------------------------------------------------------------------------
/src/ApiFactory.php:
--------------------------------------------------------------------------------
1 | config = $config;
28 | }
29 |
30 | private function getClient(): Client {
31 | if ( $this->client === null ) {
32 | $this->client = new Client();
33 | }
34 |
35 | return $this->client;
36 | }
37 |
38 | public function newAuthenticator(): Authenticator {
39 | return new Authenticator(
40 | new FileBasedTokenCache( __DIR__ . '/../token.json' ),
41 | $this->getClient(),
42 | Endpoints::AUTH,
43 | $this->config['client_id'],
44 | $this->config['secret']
45 | );
46 | }
47 |
48 | public function newOrderCreator(): OrderCreator {
49 | return new OrderCreator(
50 | $this->getClient(),
51 | Endpoints::ORDERS,
52 | $this->config['base_url']
53 | );
54 | }
55 |
56 | public function newPlanCreator(): PlanCreator {
57 | return new PlanCreator(
58 | $this->getClient(),
59 | Endpoints::PLANS
60 | );
61 | }
62 |
63 | public function newProductCreator(): ProductCreator {
64 | return new ProductCreator(
65 | $this->getClient(),
66 | Endpoints::PRODUCTS
67 | );
68 | }
69 |
70 | public function newSubscriptionCreator(): SubscriptionCreator {
71 | return new SubscriptionCreator(
72 | $this->getClient(),
73 | Endpoints::SUBSCRIPTIONS,
74 | $this->config['base_url']
75 | );
76 | }
77 |
78 | public function newWebhookLogger(): Logger {
79 | return new FileBasedLogger( self::WEBHOOK_LOG_DIRECTORY );
80 | }
81 |
82 | public function newIPNLogger(): Logger {
83 | return new FileBasedLogger( self::IPN_LOG_DIRECTORY );
84 | }
85 |
86 | public function newPlanIdStorage(): PlanIdStorage {
87 | return new FileBasedPlanIdStorage( __DIR__ . '/../plans.json' );
88 | }
89 |
90 | public function newIpnDirectoryList(): DirectoryList {
91 | return new DirectoryList( self::IPN_LOG_DIRECTORY );
92 | }
93 |
94 | public function newWebhookDirectoryList(): DirectoryList {
95 | return new DirectoryList( self::WEBHOOK_LOG_DIRECTORY );
96 | }
97 | }
98 |
--------------------------------------------------------------------------------