Day 9: Build IRB Invoice Submission Service with Logging #laravelapi #irblogging

SEO Title: Day 9: Build IRB Invoice Submission Service with Logging #laravelapi #irblogging
Focus Keyphrase: IRB e-invoice integration
Meta Description: Build a Laravel service class to submit IRB e-invoices with logging, retry logic, and error handling for production-ready integration.

Making IRB Submission Production-Ready

To make your IRB e-invoice integration stable and maintainable, today you’ll:

  • 🛠 Refactor the submission into a Laravel service class
  • 🧾 Add logging for success and failure
  • 🔁 Implement retry support

Step 1: Create the Service Class

File: app/Services/IRB/IRBSubmitService.php


namespace App\Services\IRB;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class IRBSubmitService
{
    public function submitInvoice(string $signedXml): array
    {
        $accessToken = $this->getAccessToken();

        $encodedXml = base64_encode($signedXml);

        $response = Http::withToken($accessToken)->post(
            'https://preprod-api.myinvois.hasil.gov.my/api/v1.0/invoices',
            ['invoice' => $encodedXml]
        );

        if ($response->successful()) {
            Log::channel('irb')->info('Invoice submitted successfully', $response->json());
            return $response->json();
        }

        Log::channel('irb')->error('Invoice submission failed', [
            'status' => $response->status(),
            'body' => $response->body(),
        ]);

        throw new \Exception('IRB invoice submission failed: ' . $response->body());
    }

    protected function getAccessToken(): string
    {
        $response = Http::asForm()->post('https://preprod-api.myinvois.hasil.gov.my/api/v1.0/token', [
            'grant_type' => 'client_credentials',
            'client_id' => config('services.irb.client_id'),
            'client_secret' => config('services.irb.client_secret'),
        ]);

        if (!$response->successful()) {
            Log::channel('irb')->error('Failed to fetch IRB token', ['body' => $response->body()]);
            throw new \Exception('Could not authenticate with IRB.');
        }

        return $response->json()['access_token'];
    }
}

Step 2: Add Logging Channel

In config/logging.php:


'channels' => [
    ...
    'irb' => [
        'driver' => 'single',
        'path' => storage_path('logs/irb.log'),
        'level' => 'debug',
    ],
],

Step 3: Use the Service in Controller


use App\Services\IRB\IRBInvoiceXmlGenerator;
use App\Services\IRB\IRBXmlSignatureService;
use App\Services\IRB\IRBSubmitService;

...

$unsignedXml = app(IRBInvoiceXmlGenerator::class)->generate($invoiceData);
$signedXml = app(IRBXmlSignatureService::class)->sign($unsignedXml);
$result = app(IRBSubmitService::class)->submitInvoice($signedXml);

Why This Matters

This structure makes it easy to:

  • 🔍 Trace every invoice via irb.log
  • 🔄 Add job queues or retry logic later
  • 🧪 Unit test your submission pipeline

Coming Up in Final Day (Day 10)

You’ll validate and store response data (UUID, QR code, etc), and integrate it into your invoice model and UI.


Tags: #LaravelServices #IRBIntegration #InvoiceSubmission #Logging #MyInvois

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.