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

Svea Laravel Package

nordkit/svea

Modern PHP SDK for Svea Checkout, Payment Admin, webhook subscriptions and inbound webhook verification. Fluent API with typed value objects, retries, idempotency, async task polling, and a robust testing fake. Includes first-class Laravel integration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require nordkit/svea
    

    For Laravel, publish the config:

    php artisan vendor:publish --tag=svea-config
    
  2. Configure .env:

    SVEA_MERCHANT_ID=your_merchant_id
    SVEA_SHARED_SECRET=your_shared_secret
    SVEA_ENVIRONMENT=test
    SVEA_WEBHOOK_SECRET=your_webhook_secret
    
  3. First Use Case: Create a checkout order in a Laravel controller:

    use Svea\Laravel\Svea;
    
    public function createCheckout()
    {
        $order = Svea::checkout()->create(new CheckoutOrder(
            currency: 'SEK',
            countryCode: 'SE',
            locale: 'sv-SE',
            clientOrderNumber: 'ORD-001',
            merchantSettings: new MerchantSettings(
                pushUri: route('webhooks.svea'),
                termsUri: route('terms'),
                confirmationUri: route('checkout.confirmation'),
                checkoutUri: route('checkout'),
            ),
            cart: new Cart([new OrderRow(quantity: 100, unitPrice: 29900, vatPercent: 2500, sku: 'TSHIRT-BLK-M', name: 'T-Shirt Black M')])
        ));
    
        return response()->json(['snippet' => $order->snippet()]);
    }
    

Implementation Patterns

Workflows

  1. Checkout Flow:

    • Create order → Embed snippet → Handle webhook callbacks.
    // Create order
    $order = Svea::checkout()->create(...);
    
    // Embed snippet in view
    return view('checkout', ['snippet' => $order->snippet()]);
    
    // Handle webhook (Laravel)
    public function handleWebhook(Request $request)
    {
        $event = Svea::webhook()->verify($request);
        // Process event
    }
    
  2. Admin Operations:

    • Deliver payments, cancel orders, or credit refunds.
    Svea::admin()->order('12345678')->deliver();
    Svea::admin()->order('12345678')->cancel();
    
  3. Subscriptions:

    • Register for webhook events via CLI or code.
    Svea::subscriptions()->add(
        callbackUrl: route('webhooks.svea.subscription'),
        events: ['CheckoutOrder.Created', 'CheckoutOrder.Delivered']
    );
    

Integration Tips

  • Laravel Facade: Use Svea::checkout(), Svea::admin(), or Svea::subscriptions() for concise syntax.
  • Fluent API: Chain methods for readability:
    Svea::admin()->order('12345678')
        ->withIdempotencyKey('unique-key')
        ->deliver();
    
  • Webhook Verification: Use Svea::webhook()->verify($request) in your webhook endpoint.
  • Testing: Leverage Svea::fake() for isolated tests:
    Svea::fake()->assertCheckoutWasCreated(function (CheckoutOrder $order) {
        $order->currency('SEK');
    });
    

Gotchas and Tips

Pitfalls

  1. Minor-Unit Convention:

    • Forgetting to use minor units (e.g., 29900 for 299.00 SEK instead of 299) causes API failures.
    • Fix: Use helper methods like Svea\Money::minor(299) or Svea\Money::percent(25) for vatPercent.
  2. Webhook Signature Mismatch:

    • Incorrect SVEA_WEBHOOK_SECRET in .env throws SignatureVerificationException.
    • Fix: Verify the secret matches Svea’s dashboard and restart Laravel.
  3. Idempotency Keys:

    • Reusing keys for non-idempotent operations (e.g., deliver()) may cause duplicate payments.
    • Fix: Use unique keys for each operation or omit them for one-off actions.
  4. Async Task Polling:

    • HTTP 202 responses require polling. Use Svea::admin()->task('task-id')->poll() to check status.

Debugging

  • Enable Wiretap: Log all HTTP requests/responses for debugging:
    $this->app->singleton(SveaClient::class, fn () => new SveaClient(
        config: config('svea'),
        handlerStack: HandlerStack::create()->push(WiretapMiddleware::make(app(Wiretap::class)))
    ));
    
  • Check Exceptions: SveaApiException provides detailed error info (status code, body). Log or display:
    try {
        Svea::admin()->order('12345678')->deliver();
    } catch (SveaApiException $e) {
        Log::error('Svea error: ' . $e->getMessage());
    }
    

Tips

  1. Conditional Logic: Use when() for branching logic:

    Svea::admin()->order('12345678')
        ->when($isPartial, fn ($req) => $req->deliver(rows: $rowIds))
        ->unless($isCancelled, fn ($req) => $req->cancel());
    
  2. Retry Configuration: Enable retries for transient failures:

    Svea::admin()->withRetries(3)->order('12345678')->deliver();
    
  3. Testing:

    • Use Svea::fake() to mock responses:
      Svea::fake()->checkout()->shouldCreate(fn () => new CheckoutOrderResponse('12345678'));
      
    • Assert interactions:
      Svea::fake()->assertCheckoutWasCreated();
      
  4. Environment Overrides: Point to local mock servers during development:

    SVEA_CHECKOUT_URL=http://localhost:8000/checkout
    SVEA_ADMIN_URL=http://localhost:8000/admin
    
  5. Subscription Management:

    • Use Artisan commands for CLI management:
      php artisan svea:subscription:add --events=CheckoutOrder.Created
      
    • Verify subscriptions after URL changes:
      php artisan svea:subscription:verify {id}
      
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.
iio/libmergepdf
redaxo/project
zatona-eg/zatona-eg-api
patrickbussmann/oauth2-apple
3brs/enterprise-security-bundle
ardenexal/fhir-models
ardenexal/fhir-validation
dpfx/laravel-livewire-wizards
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
crudly/encrypted
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony