Skip to Content
SDKsDart / Flutter

Dart / Flutter SDK

A Dart/Flutter client library for the QPay V2 API with automatic token management, strong typing, and comprehensive error handling. Works with both server-side Dart CLI apps and Flutter mobile/web apps.

pub.dev GitHub

Installation

Dart

dart pub add qpay

Flutter

flutter pub add qpay

Or add it manually to your pubspec.yaml:

dependencies: qpay: ^1.0.0

Configuration

Direct Configuration

import 'package:qpay/qpay.dart'; const config = QPayConfig( baseUrl: 'https://merchant.qpay.mn', username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD', invoiceCode: 'YOUR_INVOICE_CODE', callbackUrl: 'https://yourapp.com/callback', );

From Environment Variables

For server-side Dart applications:

final config = QPayConfig.fromEnvironment();
VariableDescription
QPAY_BASE_URLQPay API base URL
QPAY_USERNAMEQPay merchant username
QPAY_PASSWORDQPay merchant password
QPAY_INVOICE_CODEDefault invoice code
QPAY_CALLBACK_URLPayment callback URL

Custom HTTP Client

import 'package:http/http.dart' as http; final httpClient = http.Client(); final client = QPayClient(config, httpClient: httpClient);

Quick Start

import 'package:qpay/qpay.dart'; void main() async { final client = QPayClient(QPayConfig( baseUrl: 'https://merchant.qpay.mn', username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD', invoiceCode: 'YOUR_INVOICE_CODE', callbackUrl: 'https://yourapp.com/callback', )); try { final invoice = await client.createSimpleInvoice(CreateSimpleInvoiceRequest( invoiceCode: 'YOUR_INVOICE_CODE', senderInvoiceNo: 'INV-001', invoiceReceiverCode: 'terminal', invoiceDescription: 'Order #001', amount: 10000, callbackUrl: 'https://yourapp.com/callback', )); print('Invoice ID: ${invoice.invoiceId}'); print('QR Image: ${invoice.qrImage}'); print('Short URL: ${invoice.qPayShortUrl}'); for (final url in invoice.urls) { print(' ${url.name}: ${url.link}'); } } on QPayException catch (e) { print('QPay error: ${e.code} - ${e.message}'); } finally { client.close(); } }

Create Invoice

final invoice = await client.createSimpleInvoice(CreateSimpleInvoiceRequest( invoiceCode: 'YOUR_INVOICE_CODE', senderInvoiceNo: 'INV-002', invoiceReceiverCode: 'terminal', invoiceDescription: 'Coffee x2', amount: 12000, callbackUrl: 'https://yourapp.com/callback', )); print('Invoice ID: ${invoice.invoiceId}');

Cancel an invoice:

await client.cancelInvoice('invoice-id-here');

Check Payment

final result = await client.checkPayment(PaymentCheckRequest( objectType: 'INVOICE', objectId: invoice.invoiceId, )); if (result.count > 0) { print('Payment received! Paid: ${result.paidAmount} MNT'); for (final row in result.rows) { print(' ${row.paymentId}: ${row.paymentStatus} (${row.paymentAmount} ${row.paymentCurrency})'); } } else { print('No payment yet'); }

List Payments

final payments = await client.listPayments(PaymentListRequest( objectType: 'INVOICE', objectId: invoice.invoiceId, startDate: '2024-01-01', endDate: '2024-12-31', offset: Offset(pageNumber: 1, pageLimit: 20), )); print('Total: ${payments.count}'); for (final item in payments.rows) { print('${item.paymentId}: ${item.paymentAmount} ${item.paymentCurrency}'); }

Get details for a single payment:

final detail = await client.getPayment('payment-id-here'); print('Payment ${detail.paymentId}: ${detail.paymentStatus}');

Webhook Handling

QPay sends a POST request to your callbackUrl when a payment completes. In a Dart server (e.g., using shelf):

import 'dart:convert'; import 'package:shelf/shelf.dart'; import 'package:qpay/qpay.dart'; final config = QPayConfig.fromEnvironment(); final qpayClient = QPayClient(config); Future<Response> callbackHandler(Request request) async { final body = jsonDecode(await request.readAsString()); final paymentId = body['payment_id'] as String; final result = await qpayClient.checkPayment(PaymentCheckRequest( objectType: 'INVOICE', objectId: paymentId, )); if (result.count > 0) { // Payment verified -- update your order status print('Payment confirmed: $paymentId (${result.paidAmount} MNT)'); } return Response.ok(jsonEncode({'status': 'ok'})); }

Error Handling

try { await client.cancelInvoice('nonexistent-id'); } on QPayException catch (e) { print('Status: ${e.statusCode}'); // e.g., 404 print('Code: ${e.code}'); // e.g., "INVOICE_NOTFOUND" print('Message: ${e.message}'); print('Body: ${e.rawBody}'); if (e.code == QPayException.invoiceNotFound) { print('Invoice does not exist'); } else if (e.code == QPayException.invoicePaid) { print('Invoice has already been paid'); } else if (e.code == QPayException.authenticationFailed) { print('Authentication failed'); } }

Flutter Integration

Display QR Code

import 'dart:convert'; import 'package:flutter/material.dart'; Widget buildQrImage(InvoiceResponse invoice) { final bytes = base64Decode(invoice.qrImage); return Image.memory(bytes); }
import 'package:url_launcher/url_launcher.dart'; Future<void> openBankApp(Deeplink deeplink) async { final uri = Uri.parse(deeplink.link); if (await canLaunchUrl(uri)) { await launchUrl(uri); } }

Payment Polling

Future<bool> waitForPayment(QPayClient client, String invoiceId) async { for (var i = 0; i < 60; i++) { await Future.delayed(const Duration(seconds: 5)); final result = await client.checkPayment(PaymentCheckRequest( objectType: 'INVOICE', objectId: invoiceId, )); if (result.count > 0) { return true; // Payment received } } return false; // Timeout after 5 minutes }

API Reference

MethodDescriptionReturns
getToken()Authenticate and get a new token pairFuture<TokenResponse>
refreshToken()Refresh the current access tokenFuture<TokenResponse>
createInvoice(request)Create a full invoice with all optionsFuture<InvoiceResponse>
createSimpleInvoice(request)Create a simple invoiceFuture<InvoiceResponse>
createEbarimtInvoice(request)Create an invoice with ebarimtFuture<InvoiceResponse>
cancelInvoice(invoiceId)Cancel an existing invoiceFuture<void>
getPayment(paymentId)Get payment details by IDFuture<PaymentDetail>
checkPayment(request)Check if a payment has been madeFuture<PaymentCheckResponse>
listPayments(request)List payments with filtersFuture<PaymentListResponse>
cancelPayment(paymentId, request)Cancel a card paymentFuture<void>
refundPayment(paymentId, request)Refund a card paymentFuture<void>
createEbarimt(request)Create an electronic tax receiptFuture<EbarimtResponse>
cancelEbarimt(paymentId)Cancel an electronic tax receiptFuture<EbarimtResponse>
close()Close the underlying HTTP clientvoid
Last updated on