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

Midtrans Php Laravel Package

midtrans/midtrans-php

Official Midtrans PHP wrapper for Core API and Snap (including Snap-bi). Composer-ready library to create transactions, get Snap tokens, handle notifications, and process payments in sandbox or production. Configure via Midtrans\Config and start integrating quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Install the package:

    composer require midtrans/midtrans-php
    composer dump-autoload
    
  2. Configure environment variables (.env):

    MIDTRANS_SERVER_KEY=your_server_key_here
    MIDTRANS_IS_PRODUCTION=false
    MIDTRANS_CLIENT_KEY=your_client_key_here  # Only needed for Snap
    
  3. Initialize in a service provider (e.g., AppServiceProvider):

    use Midtrans\Config;
    
    public function boot()
    {
        Config::$serverKey = env('MIDTRANS_SERVER_KEY');
        Config::$isProduction = env('MIDTRANS_IS_PRODUCTION', false);
        Config::$is3ds = true; // Enable 3DS for credit cards
    }
    
  4. First use case: Create a Snap token (for frontend integration):

    use Midtrans\Snap;
    
    $params = [
        'transaction_details' => [
            'order_id' => 'ORDER-' . uniqid(),
            'gross_amount' => 10000, // 10,000 IDR
        ],
        'customer_details' => [
            'first_name' => 'John',
            'email' => 'customer@example.com',
        ],
    ];
    
    $snapToken = Snap::getSnapToken($params);
    return view('checkout', compact('snapToken'));
    

Implementation Patterns

1. Snap Integration (Recommended for Most Use Cases)

Workflow:

  1. Backend (Laravel Controller):

    • Generate a Snap token with transaction details.
    • Pass the token to the frontend.
  2. Frontend (JavaScript):

    • Load Midtrans Snap.js with your clientKey.
    • Trigger payment with the token.
    snap.pay(snapToken, {
        onSuccess: (result) => {
            // Handle success (e.g., redirect to order confirmation)
            window.location.href = '/order/confirm?transaction=' + result.transaction_id;
        },
        onError: (error) => {
            // Log error or show user-friendly message
            console.error('Payment error:', error);
        }
    });
    
  3. Notification Handling:

    • Set up a Laravel route (e.g., /midtrans-notification) to handle webhooks.
    • Update your database based on transaction_status and fraud_status.
    Route::post('/midtrans-notification', [PaymentController::class, 'handleNotification']);
    
    public function handleNotification()
    {
        $notif = new \Midtrans\Notification();
        $orderId = $notif->order_id;
        $status = $notif->transaction_status;
        $fraud = $notif->fraud_status;
    
        // Update order status in DB
        Order::where('midtrans_order_id', $orderId)
             ->update(['status' => $status]);
    
        return response()->json(['status' => 'success']);
    }
    

2. Core API (VT-Direct) for Custom Frontends

Workflow:

  1. Frontend:

    • Use Midtrans Core API to tokenize cards (e.g., via Midtrans 3DS SDK).
    • Send token_id to your backend.
  2. Backend:

    • Charge the transaction with the token_id.
    $transactionData = [
        'payment_type' => 'credit_card',
        'credit_card' => [
            'token_id' => $request->token_id,
            'authentication' => true,
        ],
        'transaction_details' => [
            'order_id' => 'ORDER-' . uniqid(),
            'gross_amount' => 10000,
        ],
    ];
    
    $response = \Midtrans\CoreApi::charge($transactionData);
    
    if ($response->transaction_status === 'capture') {
        // Success: Update order status
    } elseif ($response->transaction_status === 'challenge') {
        // Redirect to 3DS page (handle via frontend)
        return redirect($response->redirect_url);
    }
    

3. Snap Redirect (Legacy or Simple Redirects)

Workflow:

  1. Generate redirect URL:

    $params = [
        'transaction_details' => [
            'order_id' => 'ORDER-' . uniqid(),
            'gross_amount' => 10000,
        ],
    ];
    
    $paymentUrl = Snap::createTransaction($params)->redirect_url;
    return redirect($paymentUrl);
    
  2. Handle notification (same as Snap).


4. Transaction Management

Common Operations:

  • Check status:

    $status = \Midtrans\Transaction::status('ORDER-123');
    
  • Approve/Reject challenge:

    \Midtrans\Transaction::approve('ORDER-123'); // For fraud challenges
    
  • Cancel/Refund:

    \Midtrans\Transaction::cancel('ORDER-123'); // For pending/capture transactions
    \Midtrans\Transaction::refund('ORDER-123', ['amount' => 5000, 'reason' => 'Refund']);
    

Gotchas and Tips

1. Configuration Pitfalls

  • Server Key vs. Client Key:

    • serverKey is for backend API calls (e.g., charging, notifications).
    • clientKey is for frontend Snap.js (never expose this in client-side code in production).
    • Tip: Use Laravel's .env to manage keys securely.
  • Production Mode:

    • Set Config::$isProduction = true only in production. Sandbox mode (false) is for testing.
    • Gotcha: Forgetting to switch to production can cause real transactions to fail silently.
  • Notification URLs:

    • Always test your notification endpoint locally using Midtrans Sandbox.
    • Tip: Use Config::$overrideNotifUrl for testing without changing Midtrans Dashboard settings.

2. Snap-Specific Issues

  • Token Expiry:

    • Snap tokens expire after 5 minutes. Regenerate if the user takes too long.
    • Tip: Show a "Pay Now" button prominently to reduce abandonment.
  • 3DS Authentication:

    • If transaction_status === 'challenge', the user must complete 3DS verification.
    • Gotcha: The redirect_url in the response must be handled via frontend (e.g., window.location.href).
    • Tip: Use Midtrans' 3DS SDK for seamless integration.
  • Fraud Status:

    • fraud_status === 'challenge' means manual review is needed. Use Transaction::approve() to resolve.
    • Tip: Log all challenge transactions for review.

3. Core API Quirks

  • Tokenization:

    • token_id is single-use. Regenerate if the transaction fails.
    • Gotcha: Storing token_id in the database is not recommended (security risk). Use save_token_id: true only for one-click payments.
  • Idempotency Keys:

    • Always set Config::$paymentIdempotencyKey for retries to avoid duplicate charges.
    • Tip: Use a UUID or database-generated key tied to the order.
  • Error Handling:

    • Midtrans returns HTTP 200 even for errors. Always check $response->status_code and $response->status_message.
    • Example:
      if ($response->status_code !== '200') {
          throw new \Exception($response->status_message);
      }
      

4. Notification Handling

  • Validation:

    • Verify the signature_key in notifications to prevent spoofing.
    • Tip: Use Laravel middleware to validate signatures:
      public function handleNotification(Request $request)
      {
          $notif = new \Midtrans\Notification($request->all());
          if (!$notif->validateSignatureKey(env('MIDTRANS_SERVER_KEY'))) {
              abort(403, 'Invalid signature');
          }
          // Process notification
      }
      
  • Retry Logic:

    • Midtrans retries notifications 3 times with a 24-hour delay. Implement idempotent logic in your handler.
    • Tip: Use a database lock or order_id to avoid duplicate processing.
  • Testing Notifications:

    • Use Midtrans Sandbox to simulate capture, deny, and challenge statuses.
    • Gotcha: Sandbox notifications use a different serverKey (check Midtrans Dashboard).

5. Performance and Scalability

  • Rate Limits:
    • Midtrans API has rate limits. Cache Snap tokens and transaction statuses.
    • Tip: Use Laravel's cache for frequently checked
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.
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky