Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Payone Sdk Stream Client Laravel Package

andrepayone/payone-sdk-stream-client

PSR-18 stream-based HTTP client for the PAYONE Payment Integration SDK. Lightweight implementation to send requests to PAYONE APIs using PHP streams, suitable as a drop-in client for the php-payone-sdk.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require andrepayone/payone-sdk-stream-client
    

    Ensure php-payone-sdk is also installed (this package extends it).

  2. First Use Case: Basic Payment Request

    use Andrepayone\PayoneSdk\StreamClient;
    use Psr\Http\Message\RequestFactoryInterface;
    use Psr\Http\Client\ClientInterface;
    
    // Initialize with HTTP client and request factory (e.g., Guzzle)
    $client = new StreamClient(
        new \GuzzleHttp\Client(),
        new \GuzzleHttp\Psr7\RequestFactory(),
        new \GuzzleHttp\Psr7\UriFactory(),
        new \GuzzleHttp\Psr7\StreamFactory()
    );
    
    // Configure PAYONE SDK (see php-payone-sdk docs)
    $payone = new \Cakasim\PayoneSdk\Payone($client, [
        'username' => 'your_username',
        'password' => 'your_password',
        'endpoint' => 'https://api.payone.com',
    ]);
    
    // Execute a payment request
    $response = $payone->payment->create([
        'amount' => 1000, // 10.00 EUR
        'currency' => 'EUR',
        'transaction_id' => 'txn_123',
    ]);
    
  3. Key Files to Review


Implementation Patterns

Workflows

  1. PSR-18 Integration

    • Request/Response Handling:
      $request = $client->createRequest('POST', '/api/v1/payment');
      $request = $request->withBody(
          $streamFactory->createStream(json_encode($paymentData))
      );
      $response = $client->sendRequest($request);
      
    • Streaming Large Payloads: Use StreamFactory to handle file uploads (e.g., 3D-Secure data) without memory overload:
      $stream = fopen('large_file.pdf', 'r');
      $request = $request->withBody($streamFactory->createStreamFromResource($stream));
      
  2. Error Handling

    • Wrap SDK calls in try-catch for PayoneException:
      try {
          $response = $payone->payment->create($data);
      } catch (\Cakasim\PayoneSdk\Exception\PayoneException $e) {
          \Log::error('PAYONE Error:', ['code' => $e->getCode(), 'message' => $e->getMessage()]);
          throw new \RuntimeException('Payment failed', 0, $e);
      }
      
  3. Configuration

    • Dynamic Endpoints: Override the default endpoint via constructor:
      $client = new StreamClient($httpClient, $requestFactory, $uriFactory, $streamFactory, [
          'endpoint' => 'https://test.payone.com', // Sandbox
      ]);
      
    • Custom Headers: Attach headers via middleware or modify requests directly:
      $request = $request->withHeader('X-Custom-Header', 'value');
      
  4. Testing

    • Mocking: Use Psr\Http\Message\StreamInterface mocks (e.g., GuzzleHttp\Psr7\Stream) for unit tests:
      $mockStream = new \GuzzleHttp\Psr7\Stream(fopen('data://text/plain;base64,...', 'r'));
      $request = $request->withBody($mockStream);
      

Gotchas and Tips

Pitfalls

  1. Stream Resource Management

    • Unclosed Streams: Ensure streams are closed after use (e.g., file uploads) to avoid resource leaks:
      $stream = fopen('file.pdf', 'r');
      try {
          $request = $request->withBody($streamFactory->createStreamFromResource($stream));
          $response = $client->sendRequest($request);
      } finally {
          fclose($stream);
      }
      
    • Memory Leaks: Large streams (e.g., >10MB) may cause timeouts or crashes. Use chunked transfers if supported.
  2. PSR-18 Compliance

    • Immutable Requests: PSR-18 requires immutable requests. Avoid modifying the original request object:
      // Wrong: $request->setHeader(...); // Mutates!
      // Right: $request = $request->withHeader(...);
      
  3. Endpoint Configuration

    • Hardcoded Endpoints: The SDK defaults to production. Always override in development:
      $payone->setEndpoint('https://test.payone.com'); // Critical for sandbox testing!
      
  4. Error Codes

    • PAYONE-Specific Codes: Handle 400 (Bad Request) and 402 (Payment Failed) separately:
      if ($e->getCode() === 402) {
          // Retry or notify merchant
      }
      

Tips

  1. Logging

    • Log raw requests/responses for debugging:
      \Log::debug('PAYONE Request', [
          'method' => $request->getMethod(),
          'uri' => (string) $request->getUri(),
          'body' => $request->getBody()->getContents(),
      ]);
      
  2. Retry Logic

    • Implement exponential backoff for transient failures (e.g., 503 Service Unavailable):
      use Symfony\Component\Retry\Retry;
      
      $retry = new Retry(3, 100); // 3 retries, 100ms delay
      $response = $retry->retry(fn() => $client->sendRequest($request));
      
  3. Performance

    • Connection Pooling: Reuse the ClientInterface (e.g., Guzzle) across requests to leverage HTTP/2 and connection reuse:
      $httpClient = new \GuzzleHttp\Client(['http_version' => '2.0']);
      $streamClient = new StreamClient($httpClient, ...);
      
  4. Extending Functionality

    • Custom Middleware: Add middleware to the HTTP client for logging, auth, or metrics:
      $httpClient = new \GuzzleHttp\Client([
          'middleware' => [
              new \GuzzleHttp\Middleware(),
              new class implements \GuzzleHttp\Promise\PromiseInterface {
                  // Custom logic
              },
          ],
      ]);
      
  5. Debugging

    • Enable Guzzle Debug: For Guzzle-based clients, enable debug to inspect traffic:
      $httpClient = new \GuzzleHttp\Client([
          'handler' => \GuzzleHttp\HandlerStack::create(
              \GuzzleHttp\Middleware::tap(function ($request, $options) {
                  \Log::debug('Request:', ['request' => $request]);
              })
          ),
      ]);
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony