qpay-go

module
v1.1.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: MIT

README

qpay-go

Unofficial Go SDK for the QPay payment gateway. Supports QPay V1, QPay V2, and QPay Quick APIs.

Installation

go get github.com/techpartners-asia/qpay-go

Requires Go 1.23+


Packages

Package Description
qpay_v2 QPay V2 — recommended for new integrations
qpay_v1 QPay V1 — legacy support
qpay_quick QPay Quick — marketplace/sub-merchant API

Initialize
import qpay "github.com/techpartners-asia/qpay-go/qpay_v2"

client := qpay.New(
    "YOUR_USERNAME",                // QPay username (client_id)
    "YOUR_PASSWORD",                // QPay password (client_secret)
    "https://merchant.qpay.mn/v2", // Production endpoint
    "https://yourapp.com/callback", // Callback base URL
    "YOUR_INVOICE_CODE",            // Invoice code assigned by QPay
    "YOUR_MERCHANT_ID",             // Merchant ID
)

Sandbox endpoint: https://merchant-sandbox.qpay.mn/v2

Options

You can pass options to New() to customize behavior:

Option Description
WithSyncAuth() Block until auth completes (default: async background auth)
WithClient(c) Inject a custom resty.Client (e.g. for custom TLS, proxies, or logging)
// Sync auth — New() blocks until token is ready
client := qpay.New(
    "USERNAME", "PASSWORD", "ENDPOINT", "CALLBACK", "INVOICE_CODE", "MERCHANT_ID",
    qpay.WithSyncAuth(),
)

// Custom HTTP client
httpClient := resty.New().SetTimeout(15 * time.Second)

client := qpay.New(
    "USERNAME", "PASSWORD", "ENDPOINT", "CALLBACK", "INVOICE_CODE", "MERCHANT_ID",
    qpay.WithClient(httpClient),
)

Create Invoice
invoice, err := client.CreateInvoice(qpay.QPayCreateInvoiceInput{
    SenderInvoiceNo:  "INV-2024-001", // Your unique invoice/order number
    InvoiceDescription: "Order #1234",
    Amount:           10000,          // Amount in MNT (integer)
    CallbackParam: map[string]string{
        "order_id": "1234",
    },
    // Advanced B2B fields (optional)
    SenderBranchCode: "BRANCH_01",
    InvoiceDueDate:   "2024-12-31 23:59:59",
})
if err != nil {
    log.Fatal(err)
}

fmt.Println(invoice.InvoiceID)
fmt.Println(invoice.QrImage) // Base64 encoded QR image
fmt.Println(invoice.QrText)  // Raw QR text value
fmt.Println(invoice.Urls)    // Bank app deeplinks
Get Invoice
invoice, err := client.GetInvoice("INVOICE_ID")
if err != nil {
    log.Fatal(err)
}
fmt.Println(invoice.InvoiceStatus) // OPEN, CLOSED, CANCELLED
fmt.Println(invoice.TotalAmount)
Check Payment
result, err := client.CheckPayment("INVOICE_ID", 10, 1) // pageLimit, pageNumber
if err != nil {
    log.Fatal(err)
}

fmt.Println(result.Count)
fmt.Println(result.PaidAmount)

for _, row := range result.Rows {
    fmt.Println(row.PaymentID, row.PaymentStatus, row.PaymentAmount)
}

Payment statuses: NEW, PAID, FAILED, REFUNDED

Cancel Invoice
res, err := client.CancelInvoice("INVOICE_ID")
Cancel Payment
res, err := client.CancelPayment("INVOICE_ID", "PAYMENT_ID")
Refund Payment
res, err := client.RefundPayment("INVOICE_ID", "PAYMENT_ID")
Get Payment
payment, err := client.GetPayment("PAYMENT_ID")
Ebarimt 3.0

Use CreateEbarimtInvoice when the invoice itself must carry Ebarimt 3.0 tax data. QPay assigns a separate Ebarimt-enabled invoice code for this flow.

invoice, err := client.CreateEbarimtInvoice(qpay.QPayCreateEbarimtInvoiceInput{
    InvoiceCode:         "TEST_EB_INVOICE",
    SenderInvoiceNo:     "TEST_INVOICE_23",
    InvoiceReceiverCode: "23",
    SenderBranchCode:    "TEST_BRANCH",
    InvoiceDescription:  "Test invoice",
    CallbackURL:         "https://example.com/callback",
    TaxType:             qpay.QPayTaxTypeVAT, // "1" taxable, "2" no VAT, "3" exempt
    DistrictCode:        "0101",
    Lines: []*qpay.QPayEbarimtInvoiceLine{
        {
            TaxProductCode:     "",
            LineDescription:    "Улаан буудайн үр",
            LineQuantity:       "1.00",
            LineUnitPrice:      "1000.00",
            Note:               "TEST",
            ClassificationCode: "0111100",
            Taxes: []*qpay.QPayEbarimtTax{
                {
                    TaxCode:     qpay.QPayTaxCodeVAT,
                    Description: "НӨАТ",
                    Amount:      "89.2857",
                    Note:        "НӨАТ",
                },
                {
                    TaxCode:     qpay.QPayTaxCodeCity,
                    Description: "City tax",
                    Amount:      "17.8571",
                    Note:        "TEST",
                },
            },
        },
        {
            TaxProductCode:     "",
            LineDescription:    "Бусад төрлийн сорго будаа",
            LineQuantity:       "1.00",
            LineUnitPrice:      "1000.00",
            Note:               "TEST",
            ClassificationCode: "0114200",
            Taxes: []*qpay.QPayEbarimtTax{
                {
                    TaxCode:     qpay.QPayTaxCodeVAT,
                    Description: "НӨАТ",
                    Amount:      "90.91",
                    Note:        "НӨАТ",
                },
            },
        },
    },
})

For QPayTaxTypeNoVAT and QPayTaxTypeVATExempt, the SDK sends calculate_vat: false unless you explicitly override it.

When QPay calls your callback URL, return HTTP 200 with body SUCCESS, then call CheckPayment with the invoice ID. Do not cron-poll CheckPayment.

payment, err := client.CheckPayment(invoice.InvoiceID, 100, 1)

If you create Ebarimt after a payment is already paid:

barimt, err := client.CreateEbarimt(qpay.QPayEbarimtCreateInput{
    PaymentID:           "PAYMENT_ID",
    EbarimtReceiverType: qpay.QPayEbarimtReceiverCitizen, // or QPayEbarimtReceiverCompany
    EbarimtReceiver:     "88614450",                      // phone or company register
    DistrictCode:        "3505",
    ClassificationCode:  "0000010",
})

Cancel Ebarimt by payment ID:

barimt, err := client.CancelEbarimt("PAYMENT_ID")

Token Management

The SDK handles authentication automatically. Tokens are cached and refreshed before expiry — you do not need to manage tokens manually. All methods are safe for concurrent use.


QPay V1

import qpay "github.com/techpartners-asia/qpay-go/qpay_v1"

client := qpay.New(
    "CLIENT_ID",
    "CLIENT_SECRET",
    "https://sandbox.qpay.mn/v1", // endpoint
    "https://yourapp.com/callback",
    "MERCHANT_ID",
    "TEMPLATE_ID",
    "BRANCH_ID",
    "POS_ID",
)

// Create invoice
invoice, err := client.CreateInvoice(qpay.QPayInvoiceCreateRequest{
    BillNo:      "ORDER-001",
    Date:        "2024-01-01",
    Description: "Order payment",
    Amount:      10000,
})

// Get invoice
invoice, err := client.GetInvoice("INVOICE_ID")

// Check payment
payment, err := client.CheckPayment("PAYMENT_ID")

QPay Quick

QPay Quick is a marketplace API for platforms that onboard sub-merchants.

import qpay "github.com/techpartners-asia/qpay-go/qpay_quick"

client := qpay.New(
    "USERNAME",
    "PASSWORD",
    "https://quickpay.qpay.mn", // endpoint
    "https://yourapp.com/callback",
    "INVOICE_CODE",
    "TERMINAL_ID",
)

// Register a company merchant
company, err := client.CreateCompany(qpay.QpayCompanyCreateRequest{
    Name:       "Example LLC",
    RegisterNo: "1234567",
    Phone:      "99001122",
    Email:      "info@example.mn",
    City:       "Ulaanbaatar",
    District:   "Bayanzurkh",
    Address:    "1st khoroo",
    MCCcode:    "5999",
})

// Register a person merchant
person, err := client.CreatePerson(qpay.QpayPersonCreateRequest{
    RegisterNo: "УУ12345678",
    FirstName:  "Bat",
    LastName:   "Bold",
    Phone:      "99001122",
    Email:      "bat@example.mn",
    City:       "Ulaanbaatar",
})

// Get a merchant
merchant, err := client.GetMerchant("MERCHANT_ID")

// List merchants
merchants, err := client.ListMerchant(qpay.QpayOffset{
    PageNumber: 1,
    PageLimit:  20,
})

// Create invoice for a sub-merchant
invoice, err := client.CreateInvoice(qpay.QpayInvoiceRequest{
    MerchantID:  "MERCHANT_ID",
    Amount:      10000,
    Currency:    "MNT",
    Description: "Order payment",
    CallbackUrl: "https://yourapp.com/callback",
})

// Get invoice
invoice, err := client.GetInvoice("INVOICE_ID")

// Check payment
payment, err := client.CheckPayment("INVOICE_ID")
fmt.Println(payment.InvoiceStatus) // OPEN, PAID, CLOSED

Error Handling

All methods return a standard Go error. On HTTP errors, the error contains the raw response body from QPay.

invoice, err := client.CreateInvoice(input)
if err != nil {
    log.Printf("QPay error: %v", err)
    return
}

QPay API Reference


License

MIT

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL