Quick Sale – OptoSoft API
The counter-billing workflow: build a cart in a temporary session, look up items by barcode or autocomplete, check live stock, then commit the sale, invoice and receipt in a single call.
28 endpoints in this module. Every request needs a JWT bearer token — see Authentication.
Quick Sale
Quick Sale is OptoSoft’s counter-billing workflow — the fastest path from a customer walking in to a printed invoice and receipt. It is the largest module in the API at 28 endpoints, and it powers both the OptoSoft web POS and the free Android mobile POS app.
The model is a server-side cart. You open a session, add line items to a temporary order one at a time, adjust quantities and discounts, then commit the whole thing in a single call that creates the sales order, the invoice and the receipt together.
The workflow
- Generate a
sessionIDon your side (a GUID is fine). - Find items by barcode with
getItemDetailFromCode, or by autocomplete. - Add each one with
saveSalesOrderTemp. - Read the running cart back with
GetSalesOrderTempto get live totals and tax. - Adjust or remove lines as needed.
- Commit with
SaveSale.
The session ID is yours to manage. OptoSoft keys the temporary cart on
whatever string you supply. Use a fresh unique value per transaction, and always call
deleteSalesOrderTempBySession if the customer walks
away, or abandoned carts will accumulate.
Response shapes are confirmed for only 4 of these 28 endpoints — Commit sale, Raise invoice for existing order, Record payment and Get receipt detail, which show an Example response block. The request contracts on this page are taken from the live OpenAPI specification and are accurate, but for the cart and dropdown helpers the response fields are not yet published. Parse them defensively and tell us if you need a specific one documented.
Cart session
POST /api/quickSale/saveSalesOrderTemp
Bearer tokenAdds one line item to the temporary cart. Call it once per product. For a spectacle lens, the optical powers travel on the line itself — that is how a single order can carry different powers for each pair.
Most-used fields
| Field | Type | Required | Description |
|---|---|---|---|
| sessionID | string | Required | Your cart session key. |
| itemID | string | Required | Encrypted item ID from a lookup call. |
| inventoryID | string | Optional | Specific stock unit, when tracking serialised inventory. |
| qty | double | Required | Quantity. |
| mrp | double | Optional | Printed MRP. |
| price | double | Required | Selling price per unit before discount. |
| discountRate | double | Optional | Percentage discount. |
| discountAmount | double | Optional | Flat discount. Use one or the other, not both. |
| sgstRate | double | Optional | SGST percentage for intra-state sales. |
| cgstRate | double | Optional | CGST percentage for intra-state sales. |
| igstRate | double | Optional | IGST percentage for inter-state sales. |
| jobCharges | double | Optional | Lens fitting or lab charges on this line. |
| pairNo | string | Optional | Groups lines into pairs, so one order can hold two complete spectacles. |
| spectacleLensType | int32 | Optional | Lens type for a spectacle-lens line. |
| spherical | string | Optional | SPH power for this lens. |
| cylinder | string | Optional | CYL power. |
| axis | string | Optional | Axis in degrees. |
| addition | string | Optional | ADD power for bifocal or progressive. |
| pd | string | Optional | Pupillary distance. |
| lensFittingHeight | double | Optional | Fitting height for progressive lenses. |
| lensTotalHeight | double | Optional | Total lens height. |
About the other fields (48 total)
| Group | Fields |
|---|---|
| Computed totals | totalMRP, totalPrice, taxableAmount, sgstAmount, cgstAmount, igstAmount, totalAmount |
| Service tax | serviceTaxId, serviceTaxRate, serviceTaxAmount |
| Optical detail | near, vision, vn |
| Audit | createdBy, createdDate, createdIP |
| Linkage | id, salesOrderID, isOrdered |
Leave the computed total and tax-amount fields unset. OptoSoft calculates them
from qty,
price, the discount and the GST rates.
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/saveSalesOrderTemp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sessionID": "3f9c1a52-7b40-4e6d-9a11-0d2c8e5b7f31",
"itemID": "ENCRYPTED_ITEM_ID",
"qty": 1,
"mrp": 4500,
"price": 4500,
"discountRate": 10,
"sgstRate": 6,
"cgstRate": 6,
"pairNo": "1"
}'
POST /api/quickSale/GetSalesOrderTemp
Bearer tokenReads the current cart back with live totals. Extra charges are supplied here rather than stored on the cart, so the same session can be re-totalled under different charge assumptions.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Required | Your cart session key. Note the lower-case d here, unlike sessionID elsewhere. |
| jobCharges | double | Optional | Order-level fitting or lab charges. |
| shippingCharges | double | Optional | Delivery charges. |
| otherCharges | double | Optional | Any other charge line. |
| serviceTax | double | Optional | Service tax rate on charges. |
| isCompositionScheme | boolean | Optional | Set true if the store is registered under the GST composition scheme (no tax shown on the bill). |
| isCustomerStateNotSameAsCompanyState | boolean | Optional | Drives IGST instead of CGST + SGST. |
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/GetSalesOrderTemp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "3f9c1a52-7b40-4e6d-9a11-0d2c8e5b7f31",
"jobCharges": 150,
"isCompositionScheme": false,
"isCustomerStateNotSameAsCompanyState": false
}'
POST /api/quickSale/update-sales-order-temp-values
Bearer tokenEdits one cart line in place — the quantity, price or discount stepper on a POS screen. Tax and totals are recalculated for you.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Encrypted temporary-line ID from GetSalesOrderTemp. |
| qty | double | Required | New quantity. |
| price | double | Required | New unit price. |
| discountRate | double | Optional | New percentage discount. |
| discountAmount | double | Optional | New flat discount. |
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/update-sales-order-temp-values \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "ENCRYPTED_TEMP_LINE_ID",
"qty": 2,
"price": 4500,
"discountRate": 15
}'
POST /api/quickSale/delete-salesorder-temp
Bearer tokenRemoves a single line, or a whole pair, from the cart.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| sessionID | string | Required | Cart session key. |
| salesOrderTempId | string | Optional | Encrypted line ID to remove. |
| pairNo | string | Optional | Remove every line in this pair instead of a single line. |
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/delete-salesorder-temp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sessionID": "3f9c1a52-7b40-4e6d-9a11-0d2c8e5b7f31",
"salesOrderTempId": "ENCRYPTED_TEMP_LINE_ID"
}'
POST /api/quickSale/deleteSalesOrderTempBySession
Bearer tokenAbandons the whole cart. Call this whenever a transaction is cancelled, and on start-up for any session your client did not finish.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| sessionID | string | Required | Cart session key to clear. |
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/deleteSalesOrderTempBySession \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "sessionID": "3f9c1a52-7b40-4e6d-9a11-0d2c8e5b7f31" }'
Item lookup and stock
GET /api/quickSale/getItemDetailFromCode
Bearer tokenResolves a barcode or item code into a full item record with price and tax rates. This is the barcode-scanner endpoint — the fastest way to add a frame or accessory to the cart.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| code | string | Required | Barcode or item code, exactly as scanned. |
Example request
curl "https://api.opto-soft.com/api/quickSale/getItemDetailFromCode?code=8901234567890" \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/quickSale/getExactItemStock
Bearer tokenReturns the live on-hand quantity for one item. Call it before committing a sale to avoid overselling a frame that is down to its last piece.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| itemId | int64 | Required | Numeric item ID, not the encrypted string. |
Example request
curl "https://api.opto-soft.com/api/quickSale/getExactItemStock?itemId=88214" \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/quickSale/GetFrameSunGlassForAutoComplete
Bearer tokenType-ahead search across frames and sunglasses. Use it when the barcode is unreadable or the customer is browsing by brand or model.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| term | string | Required | Partial brand, model or code. Send at least 2 characters. |
| yearId | int64 | Required | Financial year to search stock within. |
Example request
curl "https://api.opto-soft.com/api/quickSale/GetFrameSunGlassForAutoComplete?term=rayban&yearId=9" \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/quickSale/GetSpectacleLensForAutoComplete
Bearer tokenType-ahead search across spectacle lenses. Unlike the frame search, this takes no year parameter.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| term | string | Required | Partial lens name, coating or index. |
Example request
curl "https://api.opto-soft.com/api/quickSale/GetSpectacleLensForAutoComplete?term=progressive" \
-H "Authorization: Bearer YOUR_TOKEN"
POST /api/quickSale/search-contact-lens
Bearer token
Searches contact lenses. This one is a POST
with a JSON body rather than a query string, unlike the two autocomplete endpoints
above.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| term | string | Required | Partial brand, power or modality. |
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/search-contact-lens \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "term": "acuvue" }'
GET /api/quickSale/get-item-type-id
Bearer tokenResolves an item type by its numeric ID — used to decide which cart section (frame, lens, contact lens, accessory) a scanned item belongs in.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | int32 | Required | Numeric item-type ID. |
Example request
curl "https://api.opto-soft.com/api/quickSale/get-item-type-id?id=3" \
-H "Authorization: Bearer YOUR_TOKEN"
Committing the sale
POST /api/quickSale/SaveSale
Bearer tokenThe commit call. Converts the temporary cart into a real transaction — sales order, invoice, receipt, stock movement and any lab purchase order — in one atomic operation.
The body is the composite OMFastWizardModel,
the same object used by
/api/Invoice/save-invoice-data.
Its top-level structure is documented on the Invoices page.
Key fields
| Field | Type | Description |
|---|---|---|
| sessionID | string | The cart session to convert. This is what links the call to the lines you added. |
| customerModel | object | The customer. Can create a new one inline during the sale. |
| salesorderModel | object | Order-level values: dates, delivery mode, charges, remarks. |
| receiptModel | object | Payment taken at the counter. Omit to leave the order fully unpaid. |
| eyeInfoModel | object | The prescription being dispensed. |
| eyecheckupRecallModel | object | Schedules the next eye-test recall for WhatsApp or SMS follow-up. |
| purchaseOrderModel | object | Lab order raised for lens surfacing and fitting. |
| orderDate | date-time | Transaction date. |
| expectedDate | date-time | Promised delivery date. |
| supplierID | string | Encrypted supplier ID for the lab job. |
| fitterID | string | Encrypted fitter ID. |
| priorityID | string | Encrypted job-priority ID. |
| userId | int64 | Operator recording the sale. |
Do not retry blindly on a timeout. This call creates financial
documents. If it times out, query
POST /api/Orders/search for the session’s
customer and date range to check whether the order was in fact created before
re-sending.
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/SaveSale \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @sale.json
Example response — 200 OK
{
"success": true,
"message": "Sale saved successfully.",
"data": {
"CustomerID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"SalesOrderID": "Q2ZQdGhSZVhBaVlXTnpaWFF4TWk0d01B",
"ReceiptID": "Q2ZQdGhSZVhBaVlXTnpaWFF5TWk0d01B",
"ReceiptNo": "REC-2024-0321",
"InvoiceID": "Q2ZQdGhSZVhBaVlXTnpaWFF6TWk0d01B",
"InvoiceNo": "INV-2024-1042",
"IsInvoiceGenerated": true
}
}
POST /api/quickSale/SaveInvoiceOnly
Bearer tokenRaises an invoice against an order that already exists, without recreating the order. This is the delivery-day call: the customer collects their spectacles and the tax invoice is generated.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| salesOrderID | string | Required | Encrypted sales order ID to invoice. |
| customerID | string | Required | Encrypted customer ID. |
| sessionID | string | Optional | Cart session, if the invoice was assembled through one. |
| invoiceDate | date-time | Required | Invoice date. Determines the GST return period. |
| isCompositionScheme | boolean | Optional | Set true for composition-scheme stores. |
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/SaveInvoiceOnly \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"salesOrderID": "ENCRYPTED_SALES_ORDER_ID",
"customerID": "ENCRYPTED_CUSTOMER_ID",
"invoiceDate": "2026-07-29T00:00:00",
"isCompositionScheme": false
}'
Example response — 200 OK
{
"success": true,
"invoiceId": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"invoiceNo": "INV-2024-1043"
}
POST /api/quickSale/SaveReceipt
Bearer tokenRecords a payment. Use it for an advance at order time, for the balance on delivery, or for a standalone payment not tied to an invoice.
The model is large (164 fields) because it doubles as the print payload — it carries branch letterhead, terms and totals for the printed receipt as well as the payment itself. In practice you set a small subset.
Most-used fields
| Field | Type | Required | Description |
|---|---|---|---|
| salesOrderID | string | Required | Encrypted order the payment applies to. |
| receiptAmount | double | Required | Amount being taken now. |
| receiptTypeId | int64 | Required | Payment method. Values from GET /api/quickSale/Fetch-Receipt-Type. |
| yearId | string | Required | Encrypted financial-year ID. |
| branchId | int64 | Required | Numeric branch ID. |
| receiptId | string | Optional | Encrypted receipt ID. Omit to create a new receipt. |
| referenceNo | string | Optional | Cheque number, UPI reference or card transaction ID. |
| salesOrderNo | string | Optional | Order number, printed on the receipt. |
| netAmount | double | Optional | Order net amount, for the printed summary. |
| statusId | int32 | Optional | Receipt status, for example cleared or pending. |
| taxNotApplicable | boolean | Optional | Set true for non-GST transactions, including most sales outside India. |
| isForeigner | boolean | Optional | Marks an overseas customer. |
| receiptPrintFormat | int32 | Optional | Which receipt template to render. |
About the other fields (164 total)
| Group | Purpose |
|---|---|
| Branch letterhead | branchName, branchAddress, branchCity, branchEmail, branchMobile and similar — printed header. Populate from get-branch-details. |
| Tax totals | totalTaxableAmount, totalSGST, totalCGST, totalIGST, rounding, totalDiscount — computed by OptoSoft. |
| Print layout | receiptName, intrenalReceiptName, isExternalReceiptFormat, signature, termsAndConditions. |
| Repair jobs | repairingID, repairingNO — only for repair receipts. |
| Line detail | Item-level arrays mirroring the order, used to render the receipt body. |
Example request
curl -X POST https://api.opto-soft.com/api/quickSale/SaveReceipt \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"salesOrderID": "ENCRYPTED_SALES_ORDER_ID",
"yearId": "ENCRYPTED_YEAR_ID",
"branchId": 24,
"receiptTypeId": 2,
"receiptAmount": 3000,
"referenceNo": "UPI-402291837",
"salesOrderNo": "SO/2026/001842"
}'
Example response — 200 OK
{
"success": true,
"receiptId": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"receiptNo": "REC-2024-0322",
"invoiceGenerated": false,
"invoiceId": null,
"invoiceNo": null
}
Receipt helpers
GET /api/quickSale/Fetch-Receipt-Type
Bearer token
Lists the configured payment methods — cash, card, UPI, cheque, credit note and
so on. Fetch once at start-up and cache; the IDs feed
receiptTypeId on SaveReceipt.
Example request
curl https://api.opto-soft.com/api/quickSale/Fetch-Receipt-Type \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/quickSale/GetReceiptDetails
Bearer tokenReturns the full detail of one receipt, in the shape needed to reprint it.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| customerId | int64 | Required | Numeric customer ID. |
| receiptId | int64 | Required | Numeric receipt ID. |
| salesOrderId | int64 | Required | Numeric sales order ID. |
Example request
curl "https://api.opto-soft.com/api/quickSale/GetReceiptDetails?customerId=30188&receiptId=77120&salesOrderId=104822" \
-H "Authorization: Bearer YOUR_TOKEN"
Example response — 200 OK
{
"ReceiptId": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"ReceiptNo": "REC-2024-0321",
"ReceiptType": "Advance",
"SalesOrderNo": "SO-2024-0568",
"CustomerName": "Rajesh Sharma",
"CustomerMobile": "9876543210",
"Date": "2024-01-16T00:00:00",
"Amount": 3000.00,
"PaymentMode": "Cash",
"Status": "Active",
"StatusID": 1,
"Remarks": null
}
GET /api/quickSale/get-credit-notes
Bearer tokenLists unredeemed credit notes held by a customer — from returns, cancellations or goodwill adjustments — so they can be applied against a new sale.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| customerId | int64 | Required | Numeric customer ID. |
Example request
curl "https://api.opto-soft.com/api/quickSale/get-credit-notes?customerId=30188" \
-H "Authorization: Bearer YOUR_TOKEN"
Dropdowns and pickers
Eight small lookup endpoints populate the pickers on a POS screen. All are cheap, all are cacheable, and none change during a trading day — fetch them once at start-up.
GET /api/quickSale/get-doctors-dropdown
Bearer tokenReferring doctors, in picker form. The fuller doctor master with addresses lives in Customers & Prescriptions.
Query parameters
None.
GET /api/quickSale/get-fitters-dropdown
Bearer token
Staff who fit lenses into frames. Feeds fitterID
on SaveSale.
Query parameters
None.
GET /api/quickSale/get-suppliers-dropdown
Bearer token
Labs and suppliers used for lens surfacing. Feeds
supplierID on the purchase order raised with a
sale.
Query parameters
None.
GET /api/quickSale/get-priority-dropdown
Bearer token
Job priorities — normal, urgent, same-day. Feeds
priorityID and drives the promised delivery
date.
Query parameters
None.
GET /api/quickSale/getGenders
Bearer token
Gender options with their encrypted IDs, for
genderID on customer upsert.
Query parameters
None.
GET /api/quickSale/getSources
Bearer tokenCustomer acquisition sources — walk-in, referral, online, campaign. Paged, unusually for a lookup.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| page | int32 | Optional | 1-based page index. |
| pageSize | int32 | Optional | Rows per page. |
Example request
curl "https://api.opto-soft.com/api/quickSale/getSources?page=1&pageSize=100" \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/quickSale/getMemberships
Bearer token
Loyalty and membership schemes, with their encrypted IDs. Paged like
getSources.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| page | int32 | Optional | 1-based page index. |
| pageSize | int32 | Optional | Rows per page. |
Example request
curl "https://api.opto-soft.com/api/quickSale/getMemberships?page=1&pageSize=50" \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/quickSale/allCard
Bearer token
Lists the card types configured for card payments, for the picker shown when
receiptTypeId is a card method.
Query parameters
None.
Branch and app
GET /api/quickSale/get-branch-details
Bearer token
Returns the branch profile for the token’s scope — name, address, GSTIN,
phone and email. Use it to populate the letterhead fields on
SaveReceipt and on printed documents.
Query parameters
None. Scope comes from the bearer token.
Example request
curl https://api.opto-soft.com/api/quickSale/get-branch-details \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/quickSale/get-branch-logo/{branchId}/{fileName}
Bearer tokenStreams the branch logo image for printed receipts and invoices. Returns image bytes, not JSON.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| branchId | int64 | Required | Numeric branch ID. |
| fileName | string | Required | Logo file name, as returned by get-branch-details. |
Example request
curl https://api.opto-soft.com/api/quickSale/get-branch-logo/24/logo.png \
-H "Authorization: Bearer YOUR_TOKEN" \
-o logo.png
GET /api/quickSale/app-version
No token requiredReturns the minimum supported client version. The OptoSoft Android POS app calls this on launch to decide whether to prompt for an update. Worth calling from your own client too, as a forward-compatibility signal.
Query parameters
None.
Example request
curl https://api.opto-soft.com/api/quickSale/app-version \
-H "Authorization: Bearer YOUR_TOKEN"