## pos : object Point of Sale, transaction, and payment-related functionality. **Kind**: global namespace * [pos](#pos) : object * [.ReceiptItem](#pos.ReceiptItem) * [new ReceiptItem(id, label, text, priceEach, quantity, cost, taxrate, taxableAmount)](#new_pos.ReceiptItem_new) * [.ReceiptPayment](#pos.ReceiptPayment) * [new ReceiptPayment(amount, type, text)](#new_pos.ReceiptPayment_new) * [.addReceiptItem(item)](#pos.addReceiptItem) * [.addReceiptPayment(payment)](#pos.addReceiptPayment) * [.addOnscreenPaymentLog(msg)](#pos.addOnscreenPaymentLog) * [.getReceiptID()](#pos.getReceiptID) ⇒ string * [.onReceiptChange(f)](#pos.onReceiptChange) * ~~[.onTransactionFinished(f)](#pos.onTransactionFinished)~~ * [.registerCardProcessor(f)](#pos.registerCardProcessor) * [.registerCryptoProcessor(f)](#pos.registerCryptoProcessor) * [.getShippingSalesTax()](#pos.getShippingSalesTax) ⇒ Object ### pos.ReceiptItem **Kind**: static class of [pos](#pos) **Properties** | Name | Type | Default | Description | | --- | --- | --- | --- | | merch | boolean | false | True if merchandise, false if shipping. | | barcode | string | | Item barcode, or tracking number if `merch = false`. | | qty | number | 1 | Item quantity. | | retailPrice | number | | The calculated retail/markup price for a shipment, regardless of actual sale price. If unset, defaults to priceEach * qty. | | taxRate | number | 0 | Tax rate | | toAddress | Address | | Shipping destination address. | | fromAddress | Address | | Shipping return address. | | carrier | string | | Shipping carrier. | | service | string | | Shipping service. | | category | string | | Merchandise/item category. | | electronicReturnReceipt | boolean | false | If true, the customer's receipt will have instructions on retrieveing the return receipt from USPS. | | mailboxDays | number | 0 | Number of days this item adds to a mailbox's expiration date. | | mailboxMonths | number | 0 | Number of months this item adds to a mailbox's expiration date. | | mailboxNumber | string | | Mailbox number to apply `mailboxDays` or `mailboxMonths` to after checkout. | | setCertifiedInfo() | function | | Set Certified Mail receipt data. `setCertifiedInfo(trackingNumber, certfee, extrafees, postage, date, location, toaddress)` | | toJSON() | function | | Get the item as an object suitable for JSON encoding. | | fromJSON(json) | static\_function | | Returns a ReceiptItem created from the object returned by `item.toJSON()`. | #### new ReceiptItem(id, label, text, priceEach, quantity, cost, taxrate, taxableAmount) A class representing a sale item in the current transaction. | Param | Type | Default | Description | | --- | --- | --- | --- | | id | string | | Unique ID number for this item (UPC code, inventory number, etc). Used to deduplicate and merge line items on the receipt. Unique items (like shipping labels) should be a unique/random ID. | | label | string | | One-line item information. | | text | string | | Extra multi-line item information. | | priceEach | number | | Sale price per unit. | | quantity | number | | Number of units. | | cost | number | | Cost per unit. Used for automatic expense tracking. | | taxrate | number | 0.0 | Examples: 0 (for 0%), 0.05 (for 5%), etc | | taxableAmount | string | | The part of the sale price that's taxable. "" for default (all), "markup" for only taxing profit. | ### pos.ReceiptPayment **Kind**: static class of [pos](#pos) **Properties** | Name | Type | Description | | --- | --- | --- | | label | string | (readonly) The human-readable string of the payment type. | | id | string | Automatically-generated unique ID for this payment. | | toJSON() | function | Get the payment as an object suitable for JSON encoding. | | fromJSON(json) | static\_function | Returns a ReceiptPayment created from the object returned by `payment.toJSON()`. | #### new ReceiptPayment(amount, type, text) A class representing a payment entry for the current transaction. | Param | Type | Description | | --- | --- | --- | | amount | number | amount paid | | type | string | payment type | | text | string | extra data (credit card info, etc) | ### pos.addReceiptItem(item) Add an item (shipment, merchandise, etc) to the current transaction. **Kind**: static method of [pos](#pos) | Param | Type | | --- | --- | | item | ReceiptItem | ### pos.addReceiptPayment(payment) Add a payment to the current transaction/receipt. **Kind**: static method of [pos](#pos) | Param | Type | | --- | --- | | payment | ReceiptPayment | ### pos.addOnscreenPaymentLog(msg) Append a line of text to the onscreen log displayed during credit card processing. Not shown in kiosk mode. **Kind**: static method of [pos](#pos) | Param | Type | Description | | --- | --- | --- | | msg | string | Line of text to add to the log. | ### pos.getReceiptID() ⇒ string Get the unique alphanumeric ID for the current transaction/receipt. This is the same code printed on receipts and used in digital receipt URLs. **Kind**: static method of [pos](#pos) ### pos.onReceiptChange(f) Specify a function to be called whenever the transaction data/receipt is changed. It is passed a single argument, a Receipt object containing the entire transaction so far. **Kind**: static method of [pos](#pos) | Param | Type | | --- | --- | | f | function | ### ~~pos.onTransactionFinished(f)~~ ***Deprecated*** The supplied function will be called when a transaction is finished. It is passed a single argument, a Receipt object containing the entire transaction. Recommended to listen for the `transactionFinished` event instead. **Kind**: static method of [pos](#pos) | Param | Type | | --- | --- | | f | function | ### pos.registerCardProcessor(f) Register as a card payment processor. **Kind**: static method of [pos](#pos) | Param | Type | Description | | --- | --- | --- | | f | Object | Payment processor functions | **Example** ```js global.apis.pos.registerCardProcessor({ name: "Demo Card Processor", // Shown in PostalPoint settings menu init: async function () { // This will run after PostalPoint launches // and before any payments are processed. // In some situations it might run multiple times in a session. }, checkout: async function ({amount, capture = true}) { // Charge a credit card using a card reader device. // amount is in pennies (or the equivalent base unit in the local currency). // Add a payment to the receipt with the total amount paid, card details, etc. global.apis.pos.addReceiptPayment( new global.apis.pos.ReceiptPayment( global.apis.i18n.currencyMinorToMajor(amount), "card", // Payment type. Accepted values are card, ach, crypto, cash, // check, account, and free. Other types will be displayed as-is. "Demo Card\nCardholder Name, etc\nMore info for receipt" // Additional text for receipt ) ); // Must return boolean false if the payment failed. // Otherwise it will be assumed it succeeded. // If an error is encountered, handle it and return false. // It's recommended to display a short "payment failed" error // message via global.apis.alert, and outputting more details // via global.apis.pos.addOnscreenPaymentLog. // If capture is false, perform an authorization but don't capture, // and return a value you can use to identify the authorization later // and complete it. The value will be passed back to finishPayment, below. // This is used mainly for the self-serve kiosk mode, in case the label fails // to be purchased/generated by the carrier. }, cancelCheckout: function () { // The user has requested the card transaction be canceled before it completes. // Reset the terminal to its resting state, clear its screen, etc. }, finishPayment: async function ({checkoutResponse}) { // Finish a payment that was authorized but not captured // because checkout() was called with capture = false. // If payment was already captured and added // to the receipt, just return true. global.apis.pos.addReceiptPayment( new global.apis.pos.ReceiptPayment( global.apis.i18n.currencyMinorToMajor(amount), "card", "Demo Card\nCardholder Name, etc\nMore info for receipt" ) ); }, updateCartDisplay: function (receipt) { // Show transaction data on the card reader display. // This function is called when the "cart" or total changes. // `receipt` is a receipt object, see docs for details. }, checkoutSavedMethod: async function ({customerID, paymentMethodID, amount}) { // Same as checkout() except using a payment method already on file. // customerID and paymentMethodID are provided by getSavedPaymentMethods below. // Must return true upon success. // If the payment is not successful, and you didn't throw an Error to show the user, // then `return false` instead and it'll appear that the user's action to start the payment did nothing. return true; }, saveCardForOfflineUse: async function ({statusCallback, customerUUID, name, company, street1, street2, city, state, zip, country, email, phone}) { // Use the card reader to capture an in-person card and save it for offline use. // Provided details are the customer's info, which might be empty strings except for the customerUUID. // Saved card details must be tied to the customerUUID, as that's how saved cards are looked up. // statusCallback(string, boolean) updates the progress message on the cashier's screen. // If the boolean is true, the progress message is replaced with a confirmation message. statusCallback("Saving card details...", false); return true; // Card saved to customer // If an error occurred, you can throw it and the error // message will be displayed to the cashier. // Alternatively, return boolean false and display the error // yourself with global.apis.alert(message, title) or something. }, cancelSaveCardForOfflineUse: function () { // Cancel the process running in saveCardForOfflineUse() at the user/cashier's request. }, getSavedPaymentMethods: async function ({customerUUID}) { // Return all saved payment methods tied to the provided customer UUID. return [{ customer: "", // Passed to checkoutSavedMethod as customerID customer_uuid: customerUUID, id: "", // Passed to checkoutSavedMethod as paymentMethodID type: "card", // Payment type. Accepted values are card, ach, crypto, cash, check, account, and free. label: "Visa debit x1234 (exp. 12/29)", // Label for payment method label_short: "Visa debit x1234" // Abbreviated label for payment method }]; }, deleteSavedPaymentMethod: async function ({customerUUID, customerID, paymentMethodID}) { // Delete the payment method identified by paymentMethodID // and tied to the PostalPoint customerUUID and the card processor customerID. // If unable to delete, throw an error and the error message // will be displayed to the cashier. } }); ``` ### pos.registerCryptoProcessor(f) Register as a cryptocurrency payment processor. **Kind**: static method of [pos](#pos) | Param | Type | Description | | --- | --- | --- | | f | Object | Payment processor functions | **Example** ```js global.apis.pos.registerCryptoProcessor({ name: "Demo Crypto", // Shown in PostalPoint settings menu init: async function () { // This is run after PostalPoint starts, // and before any other crypto functions are called. }, checkout: async function ({amount}) { // Run the checkout process. // amount is the amount of fiat currency to collect, // in pennies (or the local equivalent). // If an error is encountered during processing, // display an error message in a dialog and return boolean false. // If this function returns anything except false or undefined, // and doesn't throw an error, // it is assumed the payment was successful. // Adds a line of text visible to the cashier global.apis.pos.addOnscreenPaymentLog("Getting crypto payment..."); // Display a web page (i.e. with a payment QR code) // to the customer on the customer-facing display. global.apis.ui.setCustomerScreen("", "html"); global.apis.ui.setCustomerScreen("https://postalpoint.app", "raw"); // Poll the status of the crypto transaction var paymentComplete = false; do { await global.apis.util.delay(1000); paymentComplete = true; } while (paymentComplete != true); global.apis.pos.addReceiptPayment( new global.apis.pos.ReceiptPayment( global.apis.i18n.currencyMinorToMajor(amount), "crypto", // Payment type. "Bitcoin\n0.00001234 BTC" // Additional text for receipt ) ); global.apis.pos.addOnscreenPaymentLog("Payment successful!"); global.apis.ui.clearCustomerScreen(); }, cancelCheckout: function () { // The user requested to cancel the payment. // Reset things accordingly. global.apis.ui.clearCustomerScreen(); }, isConfigured: function () { // Is this plugin properly setup // and able to process payments? // If not, return false. // This determines if the crypto payment method button will be shown. return true; } }); ``` ### pos.getShippingSalesTax() ⇒ Object Get the sales tax percentage to charge on a shipping service ReceiptItem. **Kind**: static method of [pos](#pos) **Returns**: Object - `{type: "", percent: 0.15}` `type` is an empty string for taxing the entire price, or "markup" for only adding tax to the markup amount. `percent` is the tax percentage. A value of 0.15 means a 15% tax.