[{"data":1,"prerenderedAt":930},["ShallowReactive",2],{"/docs/base/jobs-base/server-exports/billing":3,"/docs/base/jobs-base/server-exports/billing-surround":916,"/docs/base/jobs-base/server-exports/billing-implemented-suggestions":929},{"id":4,"title":5,"body":6,"description":905,"extension":906,"head":907,"implementedSuggestions":907,"meta":908,"navigation":909,"path":911,"schemaOrg":907,"seo":912,"sitemap":913,"stem":914,"__hash__":915},"docs/1.docs/base/2.jobs-base/4.server-exports/5.billing.md","Sky Billing",{"type":7,"value":8,"toc":895},"minimark",[9,18,38,43,98,104,107,126,130,140,222,233,236,240,249,252,554,564,569,615,641,647,651,702,706,808,848,859,866,870,877,891],[10,11,12,13,17],"p",{},"Sky Billing is the default billing provider in Sky Base. It stores invoices in ",[14,15,16],"code",{},"sky_jobs_base"," and records society income after a payment has actually reached the society account. External billing providers remain optional through the Sky Base billing setting.",[10,19,20,21,24,25,29,30,33,34,37],{},"Players view their invoices with ",[14,22,23],{},"/billing",". Staff use ",[26,27,28],"strong",{},"File Explorer → Billing"," or their job's billing action in the radial menu. Configure the command, optional key binding and payment rules under ",[26,31,32],{},"Jobs Base → Administration → Billing"," in ",[14,35,36],{},"/jobconfig",".",[39,40,42],"h2",{"id":41},"payment-rules","Payment rules",[44,45,46,59],"table",{},[47,48,49],"thead",{},[50,51,52,56],"tr",{},[53,54,55],"th",{},"Mode",[53,57,58],{},"Behaviour",[60,61,62,75,86],"tbody",{},[50,63,64,72],{},[65,66,67,68,71],"td",{},"On-site (",[14,69,70],{},"onsite",")",[65,73,74],{},"An online issuer presents a payment request. Player recipients must be nearby, in the same routing bucket. Unpaid requests expire after 120 seconds by default.",[50,76,77,83],{},[65,78,79,80,71],{},"Pay Later (",[14,81,82],{},"later",[65,84,85],{},"The invoice is payable until and after its stored deadline. The default payment term is seven days.",[50,87,88,95],{},[65,89,90,91,94],{},"Immediate (",[14,92,93],{},"immediate",", trusted server exports only)",[65,96,97],{},"Record the invoice and attempt collection immediately, for example for an automatic speed-camera fine. Manual invoice forms cannot request a forced debit.",[10,99,100,103],{},[26,101,102],{},"Automatic overdue payment is enabled by default."," Disable it to leave overdue Pay Later invoices open for manual payment. Insufficient funds leave an invoice open; automatic collection retries later. Offline player invoices wait until the character is online because the current bank adapter cannot safely debit offline accounts. Society accounts can be collected without an online manager.",[10,105,106],{},"Changing the payment term affects new invoices only. Expired on-site requests and older invoices without a deadline are not automatically collected. Explicit external providers retain their own payment rules and capabilities.",[10,108,109,110,113,114,117,118,121,122,125],{},"Immediate invoices collect independently of the automatic overdue-payment setting. Offline recipients or insufficient funds can leave them unpaid for a later attempt. ",[14,111,112],{},"CreateInvoice"," returning ",[14,115,116],{},"success = true"," confirms creation; inspect ",[14,119,120],{},"data.status"," and ",[14,123,124],{},"paymentError"," to determine whether the immediate payment succeeded.",[39,127,129],{"id":128},"employee-shares","Employee shares",[10,131,132,133,136,137,139],{},"Under ",[26,134,135],{},"Jobs Base → Administration → Billing → Employee shares by job",", approve a percentage for each eligible job. No job receives a share by default. With ",[14,138,36],{}," disabled, the equivalent configuration is:",[141,142,147],"pre",{"className":143,"code":144,"language":145,"meta":146,"style":146},"language-lua shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","employeeShares = {\n    police = 10,    -- A paid $500 fine gives the officer $50 and the society $450.\n    sheriff = 5,    -- A paid $500 fine gives the deputy $25 and the society $475.\n    ambulance = 10, -- A paid $200 treatment invoice gives the medic $20 and the society $180.\n},\n","lua","",[14,148,149,165,184,200,216],{"__ignoreMap":146},[150,151,154,158,162],"span",{"class":152,"line":153},"line",1,[150,155,157],{"class":156},"sTEyZ","employeeShares ",[150,159,161],{"class":160},"sMK4o","=",[150,163,164],{"class":156}," {\n",[150,166,168,171,173,177,180],{"class":152,"line":167},2,[150,169,170],{"class":156},"    police ",[150,172,161],{"class":160},[150,174,176],{"class":175},"sbssI"," 10",[150,178,179],{"class":156},",    ",[150,181,183],{"class":182},"sHwdD","-- A paid $500 fine gives the officer $50 and the society $450.\n",[150,185,187,190,192,195,197],{"class":152,"line":186},3,[150,188,189],{"class":156},"    sheriff ",[150,191,161],{"class":160},[150,193,194],{"class":175}," 5",[150,196,179],{"class":156},[150,198,199],{"class":182},"-- A paid $500 fine gives the deputy $25 and the society $475.\n",[150,201,203,206,208,210,213],{"class":152,"line":202},4,[150,204,205],{"class":156},"    ambulance ",[150,207,161],{"class":160},[150,209,176],{"class":175},[150,211,212],{"class":156},", ",[150,214,215],{"class":182},"-- A paid $200 treatment invoice gives the medic $20 and the society $180.\n",[150,217,219],{"class":152,"line":218},5,[150,220,221],{"class":156},"},\n",[10,223,224,225,228,229,232],{},"Only ",[26,226,227],{},"society → player"," invoices in bank/cash currencies with society deposits enabled qualify. The real issuing employee must belong to the issuing job and differ from the recipient. Integrations identify that employee with ",[14,230,231],{},"createdBy = { source = issuer_source }",". Society-to-society invoices, private player invoices and automatic invoices with only a system name receive no employee share.",[10,234,235],{},"The percentage is stored when the invoice is issued. Only confirmed payments earn a share; partial payments use the cumulative paid amount, rounded down to whole currency units. The society receives the remainder and its income history records that net amount. The employee receives their share in the bank. If they are offline, it is saved and paid after their next login. Changing the configured percentage affects new invoices only.",[39,237,239],{"id":238},"create-an-invoice","Create an invoice",[10,241,242,243,246,247,37],{},"These are ",[26,244,245],{},"server exports",". Your resource must validate its prices, permissions and recipient identifiers. Do not forward unvalidated client input to ",[14,248,112],{},[10,250,251],{},"This speed-camera example needs no issuer source ID and also accepts an offline recipient:",[141,253,255],{"className":143,"code":254,"language":145,"meta":146,"style":146},"local result = exports[\"sky_jobs_base\"]:CreateInvoice({\n    from = { type = \"society\", job = \"police\" },\n    to = {\n        type = \"player\",\n        identifier = character_identifier,\n        name = character_name,\n    },\n    createdBy = { name = \"Speed camera - Elgin Avenue\" },\n    amount = 450,\n    reason = \"Exceeding the speed limit\",\n    paymentMode = \"later\",\n    sourceType = \"speed_camera\",\n    reference = \"my_speedcams:\" .. tostring(detection_id),\n})\n\nif not result.success then\n    print((\"[my_speedcams] Invoice failed: %s\"):format(result.error))\nend\n",[14,256,257,287,322,331,348,358,369,375,397,410,427,443,460,484,490,497,517,548],{"__ignoreMap":146},[150,258,259,262,265,267,270,273,276,278,281,284],{"class":152,"line":153},[150,260,261],{"class":160},"local",[150,263,264],{"class":156}," result ",[150,266,161],{"class":160},[150,268,269],{"class":156}," exports[",[150,271,272],{"class":160},"\"",[150,274,16],{"class":275},"sfazB",[150,277,272],{"class":160},[150,279,280],{"class":156},"]:",[150,282,112],{"class":283},"s2Zo4",[150,285,286],{"class":156},"({\n",[150,288,289,292,294,297,299,302,305,307,310,312,314,317,320],{"class":152,"line":167},[150,290,291],{"class":156},"    from ",[150,293,161],{"class":160},[150,295,296],{"class":156}," { type ",[150,298,161],{"class":160},[150,300,301],{"class":160}," \"",[150,303,304],{"class":275},"society",[150,306,272],{"class":160},[150,308,309],{"class":156},", job ",[150,311,161],{"class":160},[150,313,301],{"class":160},[150,315,316],{"class":275},"police",[150,318,319],{"class":160},"\" ",[150,321,221],{"class":156},[150,323,324,327,329],{"class":152,"line":186},[150,325,326],{"class":156},"    to ",[150,328,161],{"class":160},[150,330,164],{"class":156},[150,332,333,336,338,340,343,345],{"class":152,"line":202},[150,334,335],{"class":156},"        type ",[150,337,161],{"class":160},[150,339,301],{"class":160},[150,341,342],{"class":275},"player",[150,344,272],{"class":160},[150,346,347],{"class":156},",\n",[150,349,350,353,355],{"class":152,"line":218},[150,351,352],{"class":156},"        identifier ",[150,354,161],{"class":160},[150,356,357],{"class":156}," character_identifier,\n",[150,359,361,364,366],{"class":152,"line":360},6,[150,362,363],{"class":156},"        name ",[150,365,161],{"class":160},[150,367,368],{"class":156}," character_name,\n",[150,370,372],{"class":152,"line":371},7,[150,373,374],{"class":156},"    },\n",[150,376,378,381,383,386,388,390,393,395],{"class":152,"line":377},8,[150,379,380],{"class":156},"    createdBy ",[150,382,161],{"class":160},[150,384,385],{"class":156}," { name ",[150,387,161],{"class":160},[150,389,301],{"class":160},[150,391,392],{"class":275},"Speed camera - Elgin Avenue",[150,394,319],{"class":160},[150,396,221],{"class":156},[150,398,400,403,405,408],{"class":152,"line":399},9,[150,401,402],{"class":156},"    amount ",[150,404,161],{"class":160},[150,406,407],{"class":175}," 450",[150,409,347],{"class":156},[150,411,413,416,418,420,423,425],{"class":152,"line":412},10,[150,414,415],{"class":156},"    reason ",[150,417,161],{"class":160},[150,419,301],{"class":160},[150,421,422],{"class":275},"Exceeding the speed limit",[150,424,272],{"class":160},[150,426,347],{"class":156},[150,428,430,433,435,437,439,441],{"class":152,"line":429},11,[150,431,432],{"class":156},"    paymentMode ",[150,434,161],{"class":160},[150,436,301],{"class":160},[150,438,82],{"class":275},[150,440,272],{"class":160},[150,442,347],{"class":156},[150,444,446,449,451,453,456,458],{"class":152,"line":445},12,[150,447,448],{"class":156},"    sourceType ",[150,450,161],{"class":160},[150,452,301],{"class":160},[150,454,455],{"class":275},"speed_camera",[150,457,272],{"class":160},[150,459,347],{"class":156},[150,461,463,466,468,470,473,475,478,481],{"class":152,"line":462},13,[150,464,465],{"class":156},"    reference ",[150,467,161],{"class":160},[150,469,301],{"class":160},[150,471,472],{"class":275},"my_speedcams:",[150,474,319],{"class":160},[150,476,477],{"class":160},"..",[150,479,480],{"class":283}," tostring",[150,482,483],{"class":156},"(detection_id),\n",[150,485,487],{"class":152,"line":486},14,[150,488,489],{"class":156},"})\n",[150,491,493],{"class":152,"line":492},15,[150,494,496],{"emptyLinePlaceholder":495},true,"\n",[150,498,500,504,507,510,514],{"class":152,"line":499},16,[150,501,503],{"class":502},"s7zQu","if",[150,505,506],{"class":160}," not",[150,508,509],{"class":156}," result.",[150,511,513],{"class":512},"sBMFI","success",[150,515,516],{"class":502}," then\n",[150,518,520,523,526,528,531,533,536,539,542,545],{"class":152,"line":519},17,[150,521,522],{"class":283},"    print",[150,524,525],{"class":156},"((",[150,527,272],{"class":160},[150,529,530],{"class":275},"[my_speedcams] Invoice failed: %s",[150,532,272],{"class":160},[150,534,535],{"class":156},"):",[150,537,538],{"class":283},"format",[150,540,541],{"class":156},"(result.",[150,543,544],{"class":512},"error",[150,546,547],{"class":156},"))\n",[150,549,551],{"class":152,"line":550},18,[150,552,553],{"class":502},"end\n",[10,555,556,557,560,561,37],{},"Use a unique, stable ",[14,558,559],{},"reference"," for each event. Repeating the same invoice request returns the existing invoice; changing its parties, amount, reason, currency, account or payment mode returns ",[14,562,563],{},"reference_conflict",[565,566,568],"h3",{"id":567},"parties","Parties",[44,570,571,581],{},[47,572,573],{},[50,574,575,578],{},[53,576,577],{},"Party",[53,579,580],{},"Value",[60,582,583,594,604],{},[50,584,585,588],{},[65,586,587],{},"Online player",[65,589,590,593],{},[14,591,592],{},"{ type = \"player\", source = player_source }"," — the server resolves the character and name.",[50,595,596,599],{},[65,597,598],{},"Offline player",[65,600,601],{},[14,602,603],{},"{ type = \"player\", identifier = character_identifier, name = character_name }",[50,605,606,609],{},[65,607,608],{},"Society or business",[65,610,611,614],{},[14,612,613],{},"{ type = \"society\", job = \"police\" }"," — use the registered job key.",[10,616,617,618,212,620,121,623,626,627,630,631,634,635,121,638,37],{},"Supported combinations include ",[26,619,227],{},[26,621,622],{},"society → society",[26,624,625],{},"player → society",". ",[14,628,629],{},"from"," receives the payment and ",[14,632,633],{},"to"," owes it. For example, DOJ invoices a business by setting ",[14,636,637],{},"from.job = \"doj\"",[14,639,640],{},"to = { type = \"society\", job = \"mechanic\" }",[10,642,643,644,37],{},"A private player beneficiary must be online when payment settles. Otherwise the invoice stays open with ",[14,645,646],{},"beneficiary_offline",[565,648,650],{"id":649},"optional-fields","Optional fields",[652,653,654,665,671,688,694],"ul",{},[655,656,657,660,661,664],"li",{},[14,658,659],{},"currency",": invoice currency; defaults to the configured currency (",[14,662,663],{},"bank"," by default).",[655,666,667,670],{},[14,668,669],{},"depositToSociety",": whether a successful payment credits the issuing society; enabled by default.",[655,672,673,676,677,679,680,682,683,685,686,37],{},[14,674,675],{},"paymentMode",": ",[14,678,82],{}," by default; ",[14,681,70],{}," requires ",[14,684,231],{},". Trusted automatic integrations may use ",[14,687,93],{},[655,689,690,693],{},[14,691,692],{},"paymentTermDays",": a trusted override greater than zero and no more than 365 days.",[655,695,696,699,700,37],{},[14,697,698],{},"sourceType",": your integration name, such as ",[14,701,455],{},[39,703,705],{"id":704},"read-pay-and-cancel","Read, pay and cancel",[44,707,708,718],{},[47,709,710],{},[50,711,712,715],{},[53,713,714],{},"Export",[53,716,717],{},"Result and access",[60,719,720,736,746,763,773,786],{},[50,721,722,727],{},[65,723,724],{},[14,725,726],{},"CreateInvoice(request)",[65,728,729,732,733,37],{},[14,730,731],{},"{ success = true, data = invoice }"," or ",[14,734,735],{},"{ success = false, error = code }",[50,737,738,743],{},[65,739,740],{},[14,741,742],{},"GetInvoice(id)",[65,744,745],{},"The same response shape; trusted server read.",[50,747,748,753],{},[65,749,750],{},[14,751,752],{},"PayInvoice(source, id, options?)",[65,754,755,756,759,760,762],{},"Requires the matching player or an authorized society manager. Trusted options support partial ",[14,757,758],{},"amount"," and bank/cash ",[14,761,659],{}," for monetary invoices.",[50,764,765,770],{},[65,766,767],{},[14,768,769],{},"CancelInvoice(id)",[65,771,772],{},"Cancels an unpaid open invoice. Your calling resource must authorize cancellation.",[50,774,775,780],{},[65,776,777],{},[14,778,779],{},"GetCitizenInvoices(identifier, page?, limit?)",[65,781,782,785],{},[14,783,784],{},"{ success = true, data = { invoices, page, hasMore } }","; trusted server read.",[50,787,788,793],{},[65,789,790],{},[14,791,792],{},"GetBillingAccess(source)",[65,794,795,796,212,799,212,802,121,805,37],{},"Returns ",[14,797,798],{},"canViewJob",[14,800,801],{},"canIssue",[14,803,804],{},"canCancel",[14,806,807],{},"canPayJob",[10,809,810,811,212,814,212,816,212,818,212,821,212,823,212,826,212,829,212,832,121,834,837,838,212,841,121,844,847],{},"Invoice data includes ",[14,812,813],{},"number",[14,815,629],{},[14,817,633],{},[14,819,820],{},"createdBy",[14,822,758],{},[14,824,825],{},"amountPaid",[14,827,828],{},"balanceDue",[14,830,831],{},"status",[14,833,675],{},[14,835,836],{},"dueAt"," (Unix milliseconds).\n",[14,839,840],{},"employeeSharePercent",[14,842,843],{},"employeeShareEarned",[14,845,846],{},"employeeSharePaid"," report the saved allocation and confirmed employee payout.",[10,849,850,851,854,855,858],{},"Listen to the server event ",[14,852,853],{},"sky_jobs_base:billing:changed"," for an invoice's updated public data. Only a confirmed payment is income; issuing an invoice is not a deposit. An uncertain account-provider result keeps the invoice in ",[14,856,857],{},"processing"," for reconciliation. Do not manually reset it and retry, since money may already have moved.",[10,860,861,862,865],{},"The client export ",[14,863,864],{},"exports[\"sky_jobs_base\"]:OpenBilling(invoiceId)"," opens personal billing. The invoice ID is optional, and reads always check the current recipient's access.",[39,867,869],{"id":868},"existing-job-billing","Existing job billing",[10,871,872,873,876],{},"Police, Ambulance and Fire reach the selected provider through their ",[14,874,875],{},"framework"," billing mode. Existing saved mode overrides remain in effect. Mechanic service orders keep their own invoice and fulfilment flow; do not create a second collectible invoice for the same order.",[10,878,879,880,883,884,732,887,890],{},"Existing integrations may continue using ",[14,881,882],{},"Sky.Functions.SendBill",". With the Sky provider, its optional eighth argument accepts ",[14,885,886],{},"{ paymentMode = \"onsite\" }",[14,888,889],{},"{ paymentMode = \"later\" }",". External providers are not given capabilities they do not support, and their existing invoices are not automatically imported into Sky Billing.",[892,893,894],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":146,"searchDepth":153,"depth":167,"links":896},[897,898,899,903,904],{"id":41,"depth":167,"text":42},{"id":128,"depth":167,"text":129},{"id":238,"depth":167,"text":239,"children":900},[901,902],{"id":567,"depth":186,"text":568},{"id":649,"depth":186,"text":650},{"id":704,"depth":167,"text":705},{"id":868,"depth":167,"text":869},"Create player and society invoices, including automated invoices without an online issuer.","md",null,{},{"icon":910},"i-lucide-receipt","/docs/base/jobs-base/server-exports/billing",{"title":5,"description":905},{"loc":911},"1.docs/base/2.jobs-base/4.server-exports/5.billing","zID6xM4oXQqs0q3eXqX4AcWcHZ1FEdDrTuDP9A9p_Ww",[917,923],{"title":918,"path":919,"stem":920,"description":921,"icon":922,"children":-1},"Vehicle Registry","/docs/base/jobs-base/server-exports/vehicle-registry","1.docs/base/2.jobs-base/4.server-exports/4.vehicle-registry","Read technical inspection and vehicle registration status, access signed records, and receive committed vehicle certificate events.","i-lucide-file-check-2",{"title":924,"path":925,"stem":926,"children":-1,"description":927,"icon":928},"Client Events","/docs/base/jobs-base/client-events","1.docs/base/2.jobs-base/5.client-events","Client-side events provided by sky_jobs_base that other resources can listen to.","i-lucide-radio",[],1790723341395]