QuickBooks
QuickBooks Online (Intuit) — Accounting API v3, OAuth 2.0
The difference between 60 hours of work and 8 weeks of calendar time is not anyone's laziness: it is Intuit's review. According to Intuit's documentation, the technical review takes on average about 20 days from when it starts, and that timeline depends on their schedule, on how many problems they find, and on how fast you fix them. If they reject your assessment questionnaire, the clock starts over. You can have everything working perfectly in sandbox in two weeks and still wait another month to touch real data.
Two pieces of advice that save weeks: first, submit the assessment questionnaire as soon as you have the connector running in sandbox, not at the end. It is the task with the longest delay and it can run in parallel while you finish the rest. Second, do not promise the owner a launch date until Intuit approves. Promise a date for "ready and tested in sandbox", because that one does depend on you.
And add, on top of all this, between 1 and 3 hours per month of permanent maintenance: checking that token renewal has not broken down, renewing the TLS certificate, and reconciling payments that got stuck.
Who does it
The owner alone canNOT do this. The implementation partner is needed, no way around it.
Split it up like this:
THE OWNER (or whoever holds the administrator role in QuickBooks): creates the Intuit developer account in the business's name, makes the authorization click that connects the company (nobody else can do it for them), and provides the privacy policy and end user license agreement URLs that Intuit requires for the production keys.
THE ACCOUNTANT: defines just ONE thing, but it is the most important of all: which accounting account the payment gets deposited against and whether the payment goes into "Undeposited Funds" or straight to the bank. If this is decided wrong, every payment generates manual work for life. The accountant does NOT touch the developer portal.
THE IMPLEMENTER / PROGRAMMER: everything else. And that is the biggest part. QuickBooks Online has no way to receive a webhook from ROKI or to record a payment on its own. You have to build a connector service, host it, keep it running with public HTTPS, and have it renew tokens every day forever. This is not a configuration: it is software someone has to operate indefinitely.
Put bluntly: if there is nobody who can keep a server running, this integration does not hold up. Do not start it.
What has to exist before you start
Where: Gear icon (top right) > "Account and settings" (in the Spanish interface, "Cuenta y configuración") > the "Billing & subscription" / "Facturación y suscripción" tab
Without a live subscription there is no company and therefore no realmId, which is the identifier the API uses to know which company to write to. You also need to check the regional edition: QuickBooks Online is not officially sold in Honduras, and the company's base currency is set when it is created and canNOT be changed later. Find this out BEFORE promising anything, not after.
Where: Gear icon > "Manage users" / "Administrar usuarios"
Only an administrator can authorize a third-party application. A user with a limited role will see the connection screen and it will fail without a clear message as to why. Do not lose half an hour on that.
Where: Gear icon > "Account and settings" > "Sales" / "Ventas" > "Sales form content" section > "Custom transaction numbers", set to ON
ROKI's external_reference ("FAC-001") has to match the invoice's DocNumber in QuickBooks. If QuickBooks numbers on its own and you do not control that field, there is no way to match the payment to the invoice and the whole integration loses its point.
Where: Gear icon > "Chart of accounts" / "Plan de cuentas"
In the Payment object this is DepositToAccountRef. If you do not send it, QuickBooks deposits the payment into "Undeposited Funds" ("Fondos no depositados") and someone has to build the deposit by hand, payment by payment. Have the accountant choose it and put it in writing before any programming.
Where: Side menu "Sales" / "Ventas" > "Customers" / "Clientes"
The Payment object requires CustomerRef. You cannot record a payment against a customer that does not exist. If you sell to occasional end consumers, define a generic customer and always use that one.
Where: Gear icon > "Account and settings" > "Advanced" / "Avanzado" > "Currency" / "Moneda" section > "Multicurrency"
ROKI sends amounts in lempiras in decimal units. If the company has a different base currency, you need CurrencyRef and ExchangeRate on every Payment. Watch out: turning on multicurrency in QuickBooks Online is IRREVERSIBLE. Do not turn it on just to try it.
Where: https://developer.intuit.com > "Sign up" / "Sign in"
It is the account that owns the application and the production keys. If the consultant creates it with their personal email, the day they leave, the business loses control of its own integration. Use something like sistemas@tucomercio.com with the password held by the owner.
Where: Outside QuickBooks: it is infrastructure belonging to the business or the implementer
This is the requirement people discover late, and it hurts. You need: port 443/TCP open for inbound traffic from the internet, a valid TLS certificate issued by a public certificate authority (self-signed does NOT work, neither for Intuit nor as the destination for ROKI's webhook), your own domain name, and outbound internet access over 443 to quickbooks.api.intuit.com, oauth.platform.intuit.com and aura.roki.systems. The store where you keep the tokens must be encrypted and have file permissions restricted to the service user (no 0644, and no leaving them in a repository).
The steps
- 1. Create the developer account and the application in the Intuit portal
Go to https://developer.intuit.com and sign up. Then you create the app from the developer dashboard and choose the "QuickBooks Online and Payments" platform.
Honest warning: Intuit has redesigned and renamed this portal several times in recent years, and its documentation pages are built with JavaScript, so the exact label of every button cannot always be verified. The names that do appear in Intuit's documentation and official support are "My Hub", the "Keys & OAuth" section under "Development" and under "Production" in the sidebar, and the "Keys and credentials" screen. If the button on your screen is called something else, look for the section that shows "Client ID" and "Client Secret": that is the one.
From the start the app is in development mode, with development keys. That is normal, and that is what you will work with for the first few weeks.
- 2. Request the com.intuit.quickbooks.accounting scope and understand that there is no smaller one
When configuring the app you have to enable the accounting data source (Accounting). That is the com.intuit.quickbooks.accounting scope, and it is the only one you need for this integration: it is the one that lets you read invoices and create the Payment object.
Here is something you have to tell the owner in plain words: that scope canNOT be narrowed. According to Intuit's list of scopes, there is no read-only permission, none limited to invoices, none limited to payments. com.intuit.quickbooks.accounting gives read and write access to the company's entire accounting: customers, vendors, journal entries, accounts, everything. The principle of "least privilege" cannot be applied here on Intuit's side, because Intuit does not offer it. The only real control is who has the Client Secret and the tokens on your server.
The com.intuit.quickbooks.payment scope is a different product (Intuit's payment gateway) and you do not need it: ROKI is the one collecting the payment.
- 3. Add the Redirect URI
In your app's "Keys and credentials" section, under "Redirect URIs", you click "Add URI", paste your connector's address, and save with "Save". If you do not save, it does not stick: it is a classic mistake.
Example: https://conector.tucomercio.com/qbo/callback
Three rules Intuit does not forgive:
- It has to be HTTPS. localhost with http is not accepted in production.
- It has to match, character by character, the one you send in the authorization request. One extra trailing slash and it throws "redirect_uri query parameter value is invalid" at you.
- Development and Production have SEPARATE lists of Redirect URIs. Adding the development one does not work for production. You can have up to 25 per app. - 4. Create the sandbox company and test there first
From your developer account you go to "My Hub" > "Sandboxes" and click "Add" (or "Add a sandbox company"), choosing for example QuickBooks Online Plus.
The sandbox is a fake QuickBooks company, with toy data, so you can break things without fear. There you test with the development keys and against the sandbox base URL.
Base addresses (confirmed in Intuit's documentation):
- Sandbox: https://sandbox-quickbooks.api.intuit.com
- Production: https://quickbooks.api.intuit.comThe difference between sandbox and production is exactly that: a different base URL, a different Client ID/Client Secret pair, a different list of Redirect URIs, and data that is not real. The OAuth flow is identical and uses the SAME authorization and token endpoints in both cases.
What the sandbox does NOT test for you: the sandbox is a US company in dollars. If your real company operates in another currency, the entire conversion path remains untested. Keep that in mind.
- 5. The OAuth 2.0 flow: the owner's click and where the realmId comes from
This is the central part and the most misunderstood one. Nobody types a QuickBooks username and password into your system. What happens is this:
STEP A — your connector sends the QuickBooks administrator to this address (endpoint confirmed in Intuit's OpenID discovery document, https://developer.api.intuit.com/.well-known/openid_configuration):
https://appcenter.intuit.com/connect/oauth2?client_id=TU_CLIENT_ID&response_type=code&scope=com.intuit.quickbooks.accounting&redirect_uri=https://conector.tucomercio.com/qbo/callback&state=un_valor_aleatorio
STEP B — the owner sees an Intuit screen, chooses the company, and presses the connect button. That is the only moment a person is involved.
STEP C — Intuit returns them to your Redirect URI with three things in the address:
?code=AB11...&state=un_valor_aleatorio&realmId=9130350000000000That realmId is the company's identifier. It is what makes everything work and you have to store it together with the tokens. It goes inside every API call: /v3/company/{realmId}/... . It is not a secret piece of data, but without it you cannot write anywhere. And it is PER COMPANY: if the same consultant connects five businesses, that is five realmId values with five sets of tokens. Do not hardcode it.
STEP D — your connector exchanges that code for tokens against the token endpoint (also confirmed in the discovery document):
POST https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer
Authorization: Basic <client_id:client_secret in base64>
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=AB11...&redirect_uri=https://conector.tucomercio.com/qbo/callbackAnd you receive access_token, refresh_token and their expiration times.
To revoke the connection, the endpoint is https://developer.api.intuit.com/v2/oauth2/tokens/revoke.
- 6. Storing and renewing the tokens: this is where most integrations break
Read this twice, because it is the number one cause of a QuickBooks integration "stopping on its own" after a few months.
- The access token lasts 1 hour. Nothing more.
- The refresh token lasts up to 100 days.
- BUT the refresh token ROTATES: every time you renew, Intuit may return a new refresh token to you, and in practice it does so about once a day. When it returns a new one, the previous one is dead.Operating rule: ALWAYS store the last refresh token they returned to you, overwriting the previous one, in the same transaction. If your system holds on to an old one, the next renewal gives you invalid_grant, the connection goes down, and the only way out is for the owner to do the authorization click again by hand.
And the other ugly scenario: if the business takes a vacation and the connector does not call the API for more than 100 days, the refresh token expires and the connection goes down all the same. A healthy connector renews on its own even when there are no sales.
Add an alert to the connector: if renewal fails, it should notify someone by email or WhatsApp the same day. Otherwise, they find out when there are already thirty unrecorded payments.
- 7. Create the payment in ROKI and send the link to the customer
When an invoice that will be collected through ROKI is issued in QuickBooks, your connector calls ROKI:
POST https://aura.roki.systems/api/connect/v1/payments
Authorization: Bearer sk_live_... (use sk_test_... while you test against the sandbox)
Content-Type: application/json{
"amount": 1500.00,
"external_reference": "FAC-001",
"name": "Factura 001"
}The amount goes in decimal units, in lempiras. NEVER in cents: 1500.00 is one thousand five hundred lempiras, not fifteen lempiras. This is convenient because it matches how QuickBooks handles TotalAmt, which is also decimal. There is no cent conversion anywhere in this integration, and that is how it should be.
The external_reference has to be the exact DocNumber of the invoice in QuickBooks. It is the thread that will tie the two ends together later on.
ROKI responds 201 with { id, checkout_url, transaction_id: null }. Store ROKI's id together with the QuickBooks invoice's internal Id in a table of your own: you are going to need it.
You send the checkout_url to the customer by email or WhatsApp, or you set it as a payment link. That link is what the customer opens to pay.
- 8. Receive ROKI's webhook at the connector (not in QuickBooks)
When the customer pays, ROKI sends a signed notification to a public HTTPS URL. That URL is YOUR connector's, for example https://conector.tucomercio.com/roki/webhook. QuickBooks plays no part in this step: see the point about webhooks further down.
Validate the signature before believing anything. The ROKI-Signature header carries t=<unix>,v1=<hmac_sha256_hex>. You take the timestamp, append a period, append the RAW BODY exactly as it arrived (without parsing it, without reordering it, without reformatting it), compute HMAC-SHA256 with your secret, and compare. Compare with a constant-time function, not a plain ==. And reject anything with a timestamp older than a few minutes, so nobody can replay an old notification to you.
If the event is payment.approved, the payment was credited and only then do you proceed.
Respond quickly with 200 and do the heavy lifting in the background. A webhook that takes too long gets retried, and a badly handled retry duplicates the payment in your books.
- 9. Find the invoice's internal Id (the step almost everyone skips)
Here lies the most costly technical trap in the whole integration, and it is worth understanding even if you do not program.
In QuickBooks, an invoice has TWO numbers:
- the DocNumber, which is "FAC-001", the number the customer sees and the one you chose;
- the Id, which is an internal QuickBooks number like "249", which you do not choose and the customer never sees.To record the payment, QuickBooks requires the internal Id. It does not accept the DocNumber. And ROKI gives you back the external_reference, which is the DocNumber. So there is a mandatory translation step:
GET https://quickbooks.api.intuit.com/v3/company/{realmId}/query?query=select Id, Balance, TotalAmt, CustomerRef from Invoice where DocNumber = 'FAC-001'
Authorization: Bearer <access_token>
Accept: application/jsonFrom there you get the Id, the CustomerRef, and the outstanding Balance.
Pay attention to this: the QuickBooks query parser sometimes confuses values with hyphens and treats them as dates. A DocNumber like "FAC-001" is right in the risk zone. Test it with your real numbering format before calling the integration done. If it gives you trouble, change the numbering format (for example, without hyphens) while there is still time.
A safer alternative if you can: store the QuickBooks internal Id in your own table when you create the payment in ROKI (step 7), so in this step you query nothing, you just read your table. It is faster and does not depend on Intuit's parser.
- 10. Record the payment against the invoice: the Payment object with Line and LinkedTxn
Now, the accounting entry itself. In QuickBooks a payment is a Payment object that has a total and a list of lines, and each line says which document it applies to via LinkedTxn. That is the whole logic: the LinkedTxn is the rope that ties the payment to the invoice.
POST https://quickbooks.api.intuit.com/v3/company/{realmId}/payment?minorversion=<pin a version and leave it pinned>
Authorization: Bearer <access_token>
Content-Type: application/json
Accept: application/json{
"CustomerRef": { "value": "69" },
"TotalAmt": 1500.00,
"TxnDate": "2026-08-16",
"PaymentRefNum": "ROKI-9f3a2",
"PrivateNote": "ROKI Connect payment, reference FAC-001",
"DepositToAccountRef": { "value": "35" },
"Line": [
{
"Amount": 1500.00,
"LinkedTxn": [
{ "TxnId": "249", "TxnType": "Invoice" }
]
}
]
}Field by field, in plain English:
- CustomerRef: the customer. Required, and it has to be the SAME customer as on the invoice.
- TotalAmt: the total collected, decimal. The 1500.00 that came from ROKI.
- TxnDate: the date the entry is booked under. Use the date the payment was credited, not the issue date.
- PaymentRefNum: put ROKI's payment identifier here. It is your audit trail for when the accountant asks where that money came from.
- PrivateNote: internal note. Leave the external_reference written there. It costs nothing and saves hours.
- DepositToAccountRef: the account the accountant defined. If you omit it, it goes to "Undeposited Funds" and someone has to deposit it by hand.
- Line[].Amount: how much of this payment applies to THAT invoice.
- Line[].LinkedTxn[].TxnId: the invoice's INTERNAL Id (the "249" from the previous step, not "FAC-001").
- Line[].LinkedTxn[].TxnType: the word "Invoice".If a single payment settles several invoices, you add more elements to the Line array, one per invoice, and the sum of the Amount values has to equal TotalAmt.
Before sending this, check that a Payment with that same PaymentRefNum does not already exist. If the webhook arrives twice and you create two payments, the invoice ends up paid double and you leave the accountant a problem.
- 11. Confirm that the invoice was settled
Do not take a 200 at face value. Query the invoice again and look at the Balance field:
GET https://quickbooks.api.intuit.com/v3/company/{realmId}/invoice/249
If Balance ended up at 0, the invoice is settled. If it ended up at anything other than 0, there was a partial payment or something went wrong, and that has to be recorded in your log and, if you can, trigger an alert.
The invoice will also show you a LinkedTxn array pointing to the Payment: it is the same link seen from the other side. It is useful for auditing.
Store in your log, for every operation: ROKI's id, the external_reference, the realmId, the invoice's Id, the Id of the Payment created, and the date. The day there is an argument about money, that table is your entire defense.
- 12. The fallback for when the webhook does not arrive
Webhooks get lost. The internet goes down, the server restarts, a certificate expires. Assume it from the design stage, not as a patch.
Leave a scheduled task that runs every 15 or 30 minutes, takes all the payments you created in ROKI that are still unrecorded in QuickBooks, and queries:
GET https://aura.roki.systems/api/connect/v1/payments/{id}
Authorization: Bearer sk_live_...If the status is approved and there is no Payment in QuickBooks, you record it with the same procedure as step 10. The "does this payment already exist?" check is what keeps the webhook and this task from creating the payment twice.
This is not optional. Without this fallback, sooner or later there is a customer who paid and an invoice that shows as unpaid in the books.
- 13. Going to production: real keys and Intuit's review
When everything works in sandbox, you request the production keys in your app's "Production" > "Keys & OAuth" section. Intuit does not hand them over just for asking. First it requires, at a minimum:
- Completing the app profile.
- A privacy policy URL and an end user license agreement URL (End User License Agreement). They have to be addresses that actually load. If the app is only for the business's internal use, Intuit support has indicated that a placeholder URL is enough, but if you are going to offer it to third parties you need real documents.
- Adding the production Redirect URI, which is a separate list from the development one.
- Completing the app assessment questionnaire. This is mandatory for EVERY app that touches production data, including private ones that are never published in the App Store. Refusing to complete it can end with Intuit cutting off your production access.What that questionnaire asks you, so it does not catch you off guard: where the application is hosted, how often you run vulnerability scans, whether you use a security monitoring system (SIEM), what your network security looks like, whether you require multi-factor authentication, how you encrypt data in transit and at rest, how you handle authentication and authorization, and whether you have ISO 27001 certification or a SOC 2 audit.
Here comes the uncomfortable part, and I would rather tell you now: a small consultant with a shared VPS does not have good answers for half of those questions. Passing is not impossible, but it is not a formality. Prepare it ahead of time.
And the timelines: according to Intuit's documentation, the technical review takes on average about 20 days from when it starts, and that timeline depends on the review schedule, on how many problems they find, and on how fast you fix them. If they reject you, the clock starts over. Intuit also reviews apps once a year, or more often if it feels like it: this is not a permit you obtain once and are done with.
Do not give the owner a launch date until Intuit approves.
How the webhook arrives
QuickBooks Online canNOT receive ROKI's webhook. Not with custom development, not by paying more. It does not exist.
It is important to understand why, because the word "webhook" appears in Intuit's documentation and confuses everybody:
QuickBooks Online DOES have webhooks, but they go in the opposite direction. They are notifications that Intuit SENDS OUTWARD, to a URL of yours, when something changes inside QuickBooks (an invoice was created, a customer was modified). They are outbound. QuickBooks exposes no address where a third party like ROKI can knock on the door and say "I collected 1500 lempiras". As a closed cloud system, QuickBooks only accepts writes through its OAuth-authenticated API, never through an anonymous incoming notification.
So, the alternative, which is also the only possible architecture:
THE CONNECTOR IN THE MIDDLE. You need your own service, hosted by the business or by the implementer, with a public HTTPS address. That service:
- Receives ROKI's webhook at, for example, https://conector.tucomercio.com/roki/webhook
- Validates the ROKI-Signature signature (HMAC-SHA256 over timestamp + "." + raw body)
- Responds 200 right away
- Translates the external_reference "FAC-001" into the invoice's internal Id in QuickBooks
- Calls the QuickBooks API with the current access token and creates the Payment object with its Line/LinkedTxn
- Logs everything in its log
What that connector needs, concretely: port 443/TCP open for inbound traffic from the internet, a TLS certificate issued by a public certificate authority (self-signed does not work: ROKI will not deliver the notification to it), your own domain, and outbound access over 443 to quickbooks.api.intuit.com and oauth.platform.intuit.com. No port 80, no bare IP, no homemade tunnels like ngrok for production.
One detail that works in your favor: since QuickBooks Online is a cloud service, your connector can live anywhere with internet. It does not have to be in the business's office, there is no need to open ports on the business's router or expose the internal network. You can put the connector on a VPS and be done. This is the only real advantage QuickBooks Online has over an ERP installed in the office, and it is not a small one.
Now, what nobody tells you: that connector is software that has to be kept running forever. It renews tokens every day, the certificate expires every 90 days, the VPS goes down. If nobody looks after it, the integration dies silently and the business finds out when the accountant closes the month. Define who operates it BEFORE starting, and put it in writing.
And QuickBooks' own webhooks? For this integration you do not need them. They would only be useful if you wanted ROKI to find out when someone issues a new invoice in QuickBooks, to generate the payment automatically. That is a later improvement, not part of the initial rollout. The section where they are configured is inside the app in the developer portal, but I could not confirm the exact label of that tab in the official documentation, so I am not going to make it up for you.
What breaks
The LinkedTxn.TxnId is the invoice's INTERNAL Id ("249"), not the number the customer sees ("FAC-001"). ROKI's external_reference is the DocNumber. You must translate between them, no way around it, either with a prior query or by storing the internal Id in your own table from the moment you create the payment. If you send the DocNumber where the Id goes, the payment fails or, worse, gets applied to a different invoice.
The QuickBooks query parser sometimes confuses values with hyphens and treats them as dates. A DocNumber like "FAC-001" is in the risk zone. Test your real numbering format early; if it fails, change the format while there is still time, not after issuing a thousand invoices.
The refresh token rotates almost every day. Each renewal can return a new one to you and kills the previous one. If your system keeps the old one, the connection goes down with invalid_grant and the owner has to authorize again by hand. Always store the latest one, in the same transaction, no exceptions.
If the connector does not call the API for more than 100 days, the refresh token expires anyway and the connection dies. A seasonal business that closes for three months comes back to a disconnected system. Renew even when there is no activity.
The access token lasts 1 hour. If your code caches it without checking the expiration, everything works fine for the first hour of every deployment and then starts failing on and off. It is a mistake that gets diagnosed very late because it looks intermittent.
If you omit DepositToAccountRef, the payment lands in "Undeposited Funds" and someone has to build the deposit by hand, one by one, forever. Have the accountant decide this BEFORE any programming, not when there are already 200 payments piled up.
A QuickBooks Online company's base currency is set when the company is created and can never be changed. And turning on multicurrency is IRREVERSIBLE. If the company is not in lempiras, every Payment needs CurrencyRef and ExchangeRate. Check the regional edition and the company's currency BEFORE promising deadlines: QuickBooks Online is not officially sold in Honduras and this can knock down the entire project in the first week.
The sandbox is a US company in dollars. Everything working in sandbox does not prove that the currency path works in the real company. Set aside budget to test that separately.
The com.intuit.quickbooks.accounting scope is all or nothing: it gives read and write over the entire accounting. There is no read-only permission and none limited to invoices. Tell the owner at the kickoff meeting, not when it shows up in the contract. The only real control over that access is who guards the Client Secret and the tokens.
The realmId is per company. An implementer with several clients manages several realmId values with several sets of tokens. If you hardcode it, the second client writes into the first one's books. It sounds absurd until it happens.
If the webhook arrives twice (and it will) and you do not control duplicates, you create two Payment objects and the invoice ends up overpaid. Always check whether a payment with that PaymentRefNum already exists before creating another. The same care applies to the fallback task, which can step on the webhook.
The app assessment questionnaire is mandatory to touch production data, even if the app is private and never published. It asks about hosting, encryption in transit and at rest, multi-factor authentication, vulnerability scanning, SIEM, and ISO 27001 or SOC 2 certification. A small consultant with a shared VPS does not have good answers for half of it. Prepare it weeks in advance.
The Development and Production Redirect URIs are SEPARATE lists. Adding it in development does not enable it in production, and the error Intuit returns is not clear. It must also match character by character: one extra trailing slash and it does not go through.
Pin the minorversion parameter in your API calls. If you do not pin it, Intuit can move the default behavior and your integration changes by itself on some random Tuesday without anyone having touched anything.
Intuit applies rate limits per company and per app. I did not verify the current number, so I am not going to make it up for you: check it in the documentation before designing processes that fire many calls in a row, and program retries with increasing backoff on a 429.
Intuit reviews approved apps once a year, or more often if it wants to. Approval is not permanent. Someone has to take charge of answering those reviews or the business loses production access without useful warning.
The developer.intuit.com documentation is built with JavaScript and several pages cannot be read with automated tools, on top of the portal having been redesigned and renamed several times. That is why some exact button labels may differ from what you see on screen. When that happens, go by function (look for the screen that shows "Client ID" and "Client Secret") and not by the literal name.
What we could not confirm
Every menu name and port on this page was checked against the platform's official documentation. These 7 points could not be confirmed, and are flagged rather than presented as facts:
- The path "Gear icon > Account and settings > Billing & subscription tab" for viewing the subscription/regional edition - different name. The "Billing & Subscription" tab exists, but it NO LONGER hangs off "Account and settings". The current official path is: Settings (gear) > "Subscriptions and billing" > "Billing & Subscription" tab.
- The path "Side menu Sales / Ventas > Customers / Clientes" for creating the Customer - different name. The current official documentation (Intuit Platform / new menu) documents: "All apps" > "Customer Hub" > "Customers & leads" > "New customer". The "Sales > Customers" pair corresponds to the previous
- "The sandbox is a US company in dollars" (step 4, section on what the sandbox does NOT test) - does not exist. That restriction does not exist as stated. When creating a sandbox with "QuickBooks Online Plus" there is a "Country" dropdown and sandbox companies are region-specific ("you can't change this later o
- When creating the app you choose the "QuickBooks Online and Payments" platform - unverifiable. I could not confirm that exact label in official documentation: developer.intuit.com is built with JavaScript and returns truncated content. Third-party sources documenting the current portal show "My
- The "Keys and credentials" screen where the Redirect URIs are added - different name. It exists, but the label varies by source and portal version: Intuit's official error message says "listed in the Redirect URIs section on your app's Keys tab" ("Keys tab"), and other portal pages cal
- With multicurrency, CurrencyRef and ExchangeRate are needed on every Payment - unverifiable. CurrencyRef is confirmed as an optional attribute of the Payment when the company has multicurrency enabled. ExchangeRate on the Payment entity specifically I could NOT confirm: the developer.intuit.c
- "QuickBooks Online is not officially sold in Honduras" - unverifiable. I could not confirm or refute the Honduras case with an official country list. What is on record is that Intuit offers a "QuickBooks Online Global" version for countries without a localized edition an
Sources
- https://developer.api.intuit.com/.well-known/openid_configuration (leído directo, JSON crudo: confirma authori
- https://developer.api.intuit.com/.well-known/openid_sandbox_configuration (leído directo, JSON crudo: confirma
- https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/oauth-2.0
- https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/set-redirect-uri
- https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/faq
- https://developer.intuit.com/app/developer/qbo/docs/learn/scopes
- https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/payment
- https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/invoice
- https://developer.intuit.com/app/developer/qbo/docs/workflows/manage-linked-transactions
- https://developer.intuit.com/app/developer/qbo/docs/learn/explore-the-quickbooks-online-api/data-queries
- https://developer.intuit.com/app/developer/qbo/docs/develop/sandboxes
- https://developer.intuit.com/app/developer/qbo/docs/develop/sandboxes/sandbox-faqs
