├── 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 | --------------------------------------------------------------------------------