# Louvin Payment Gateway API > Louvin is an Indonesian payment gateway API that allows you to accept digital payments (QRIS, GoPay, ShopeePay, Virtual Account) without requiring a business identity. ## Base URL https://api.louvin.dev ## Authentication All requests require an API key in the `x-api-key` header. API keys start with `lv_` and are obtained from the Louvin Dashboard. Headers: - Content-Type: application/json - x-api-key: lv_your_api_key ## SDK JavaScript SDK (no dependencies, works in browser and Node.js): - CDN: - ES Module: import { Louvin } from 'https://louvin.dev/sdk/louvin.js'; Usage: ```javascript const louvin = new Louvin('lv_your_api_key'); const result = await louvin.createPayment({ amount: 50000, payment_type: 'qris' }); ``` Shortcut methods: createQRIS(), createBNI(), createBRI(), createPermata(), createCIMB() Status polling: checkStatus(id), waitForPayment(id, options) ## Endpoints ### POST /create-transaction Create a new payment transaction. Request body (JSON): - amount (number, required): Payment amount in IDR. Minimum 1 for VA, minimum 1500 for QRIS. - payment_type (string, required): Payment method code (see Payment Types below). - customer_name (string, optional): Customer name. - customer_email (string, optional): Customer email. - description (string, optional): Transaction description. - reference (string, optional): Your unique reference/order ID. Auto-generated if empty. Response (201 Created): ```json { "success": true, "transaction": { "id": "uuid", "amount": 50750, "fee": 750, "net_amount": 50000, "status": "pending", "reference": "order-ref", "fee_on_customer": true, "created_at": "2026-03-09T10:30:00Z" }, "payment": { "order_id": "order-ref", "payment_type": "qris", "qr_string": "00020101021226...", "payment_number": "00020101021226...", "expired_at": "2026-03-09T10:45:00Z", "total_payment": 50750 } } ``` For Virtual Account, `payment` contains `va_number` and `bank` instead of `qr_string`. ### GET /check-status?id=TRANSACTION_ID Check payment status. Also supports POST with body `{"id": "..."}`. Response: ```json { "success": true, "transaction": { "id": "uuid", "status": "settled", "amount": 50750, "fee": 750, "net_amount": 50000, "reference": "order-ref", "created_at": "2026-03-09T10:30:00Z", "updated_at": "2026-03-09T10:35:00Z" } } ``` ## Payment Types | Code | Method | Fee | Response Field | |----------------|--------------------------|----------------|-----------------------------| | qris | QRIS | 0.7% + Rp 400 | qr_string | | gopay | GoPay | 0.7% + Rp 400 | qr_string, deeplink_url | | shopeepay | ShopeePay | 0.7% + Rp 400 | deeplink_url | | bni_va | BNI Virtual Account | Rp 6,500 flat | va_number, bank | | bri_va | BRI Virtual Account | Rp 6,500 flat | va_number, bank | | permata_va | Permata Virtual Account | Rp 6,500 flat | va_number, bank | | cimb_niaga_va | CIMB Niaga Virtual Account | Rp 6,500 flat | va_number, bank | ## Fees - QRIS / E-Wallet: 0.7% + Rp 400 per transaction - Virtual Account: Rp 6,500 flat per transaction - No monthly fees, no setup fees - If fee_on_customer is true (default), fee is added to customer total. Merchant receives full net_amount. ## Transaction Status Flow pending → settled (payment confirmed by gateway) pending → failed (payment failed, rejected, or expired) ## Webhooks If a project has a Webhook URL configured, Louvin sends HTTP POST on every status change. Webhook payload: ```json { "event": "payment.settled", "data": { "transaction_id": "uuid", "midtrans_transaction_id": "midtrans-uuid", "project_id": "project-uuid", "order_id": "order-ref", "amount": 50750, "fee": 750, "net_amount": 50000, "payment_type": "qris", "status": "settled", "customer_name": "John Doe", "customer_email": "john@example.com" } } ``` Event types: payment.settled, payment.failed, payment.pending Important: Always return HTTP 200 from your webhook endpoint. ## Error Codes | Status | Cause | Solution | |--------|--------------------------|---------------------------------------------------| | 400 | Invalid parameters | Check amount > 0, valid payment_type, QRIS min 1500 | | 401 | Invalid API key | Verify x-api-key header | | 404 | Transaction not found | Check transaction ID | | 500 | Server error | Retry or contact support | Error response format: ```json { "error": "Error message here", "details": "Optional additional info" } ``` ## Links - Website: https://louvin.dev - API Docs: https://louvin.dev/docs - SDK: https://louvin.dev/sdk/louvin.min.js