Skip to Content
SDKsRuby

Ruby SDK

Ruby client library for the QPay V2 API. Idiomatic Ruby interface with Struct-based request/response objects, automatic token management with mutex synchronization, and Faraday HTTP under the hood.

Gem Version GitHub

Requirements: Ruby 3.0+, Faraday ~> 2.0

Installation

Add to your Gemfile:

gem "qpay-sdk"

Then run:

bundle install

Or install directly:

gem install qpay-sdk

Configuration

Environment Variables

VariableDescription
QPAY_BASE_URLQPay API base URL (e.g., https://merchant.qpay.mn)
QPAY_USERNAMEQPay merchant username
QPAY_PASSWORDQPay merchant password
QPAY_INVOICE_CODEDefault invoice code
QPAY_CALLBACK_URLPayment callback URL
config = QPay::Config.from_env

Manual Configuration

config = QPay::Config.new( base_url: "https://merchant.qpay.mn", username: "YOUR_USERNAME", password: "YOUR_PASSWORD", invoice_code: "YOUR_INVOICE_CODE", callback_url: "https://yoursite.com/callback" )

Custom Faraday Connection

faraday = Faraday.new do |f| f.options.timeout = 60 f.adapter Faraday.default_adapter end client = QPay::Client.new(config: config, faraday: faraday)

Quick Start

require "qpay" config = QPay::Config.from_env client = QPay::Client.new(config: config) invoice = client.create_simple_invoice( QPay::CreateSimpleInvoiceRequest.new( invoice_code: config.invoice_code, sender_invoice_no: "ORDER-001", invoice_receiver_code: "terminal", invoice_description: "Payment for Order #001", amount: 10_000, callback_url: config.callback_url ) ) puts "Invoice ID: #{invoice.invoice_id}" puts "QR Image: #{invoice.qr_image}" puts "Short URL: #{invoice.qpay_short_url}" invoice.urls.each do |url| puts " #{url['name']}: #{url['link']}" end

Create Invoice

invoice = client.create_simple_invoice( QPay::CreateSimpleInvoiceRequest.new( invoice_code: "INV_CODE", sender_invoice_no: "ORDER-002", invoice_receiver_code: "terminal", invoice_description: "Quick payment", sender_branch_code: "BRANCH01", # optional amount: 5_000, callback_url: "https://yoursite.com/callback" ) )

Cancel an invoice:

client.cancel_invoice("invoice-id-here")

Check Payment

result = client.check_payment( QPay::PaymentCheckRequest.new( object_type: "INVOICE", obj_id: "INVOICE_ID", offset: QPay::Offset.new(page_number: 1, page_limit: 10) ) ) if result.count > 0 puts "Payment received! Paid: #{result.paid_amount}" result.rows.each do |row| puts " #{row.payment_id}: #{row.payment_status} (#{row.payment_amount} #{row.payment_currency})" end else puts "No payment yet" end

List Payments

payments = client.list_payments( QPay::PaymentListRequest.new( object_type: "INVOICE", obj_id: "INVOICE_ID", start_date: "2024-01-01", end_date: "2024-12-31", offset: QPay::Offset.new(page_number: 1, page_limit: 20) ) ) puts "Total: #{payments.count}" payments.rows.each do |item| puts " #{item.payment_id}: #{item.payment_amount} #{item.payment_currency} (#{item.payment_status})" end

Get details for a single payment:

detail = client.get_payment("payment-id-here") puts "Payment #{detail.payment_id}: #{detail.payment_status}"

Webhook Handling

QPay sends a POST request to your callback_url when a payment completes.

Rails

class QpayCallbacksController < ApplicationController skip_before_action :verify_authenticity_token def create payment_id = params[:payment_id] config = QPay::Config.from_env client = QPay::Client.new(config: config) result = client.check_payment( QPay::PaymentCheckRequest.new( object_type: "INVOICE", obj_id: payment_id, ) ) if result.count > 0 # Payment verified -- update your order status Rails.logger.info("Payment confirmed: #{payment_id} (#{result.paid_amount} MNT)") end render json: { status: "ok" } end end

Sinatra

require "sinatra" require "qpay" post "/api/qpay/callback" do body = JSON.parse(request.body.read) payment_id = body["payment_id"] config = QPay::Config.from_env client = QPay::Client.new(config: config) result = client.check_payment( QPay::PaymentCheckRequest.new( object_type: "INVOICE", obj_id: payment_id, ) ) if result.count > 0 # Payment verified end { status: "ok" }.to_json end

Error Handling

All API errors raise QPay::Error, which is a subclass of StandardError:

begin client.create_simple_invoice(request) rescue QPay::Error => e puts e.message # "qpay: INVOICE_LINE_REQUIRED - ..." puts e.status_code # 400 puts e.code # "INVOICE_LINE_REQUIRED" puts e.raw_body # Raw JSON response body end

Error Code Constants

rescue QPay::Error => e case e.code when QPay::AUTHENTICATION_FAILED # Re-authenticate when QPay::INVOICE_NOTFOUND # Handle missing invoice when QPay::INVOICE_PAID # Invoice already paid when QPay::PAYMENT_NOTFOUND # Handle missing payment when QPay::PAYMENT_ALREADY_CANCELED # Payment was already canceled when QPay::INVALID_AMOUNT # Amount out of range when QPay::PERMISSION_DENIED # Access denied end end

API Reference

MethodParametersReturnsDescription
get_tokenTokenResponseAuthenticate and get token pair
refresh_tokenTokenResponseRefresh access token
create_invoiceCreateInvoiceRequestInvoiceResponseCreate full invoice
create_simple_invoiceCreateSimpleInvoiceRequestInvoiceResponseCreate simple invoice
create_ebarimt_invoiceCreateEbarimtInvoiceRequestInvoiceResponseCreate invoice with tax info
cancel_invoiceinvoice_id (String)nilCancel an invoice
get_paymentpayment_id (String)PaymentDetailGet payment details
check_paymentPaymentCheckRequestPaymentCheckResponseCheck payment status
list_paymentsPaymentListRequestPaymentListResponseList payments
cancel_paymentpayment_id, request: (optional)nilCancel a payment
refund_paymentpayment_id, request: (optional)nilRefund a payment
create_ebarimtCreateEbarimtRequestEbarimtResponseCreate tax receipt
cancel_ebarimtpayment_id (String)EbarimtResponseCancel tax receipt
Last updated on