URL-адрес запроса Quickbooks v3 возвращает ошибку

Первый - мой вопрос:

При доступе к API Quickbooks v3 (как было навязано мне Intuit в эти выходные) я пытаюсь получить доступ к записям журнала (но следующая проблема сохраняется при любом другом запросе), и я пытаюсь использовать предписанный запрос? query=SELECT * FROM JournalEntry (что?).

https://qb.sbfinance.intuit.com/v3/company/<id>/query?query=SELECT * FROM JournalEntry

Я получаю в результате:

{"Fault":{"Error":[{"Message":"message=Exception authenticating OAuth; errorCode=003200; statusCode=401","code":"3200"}],"type":"AUTHENTICATION"},"requestId":"6f5e5f14af7d4867ad0d8f639ade7d04","time":"2013-11-12T16:10:44.724Z"}

Что, да, говорит мне, что произошла ошибка аутентификации. Однако, когда я получаю доступ к URL-адресу, который не включает этот нелепый синтаксис запроса, все работает нормально:

https://qb.sbfinance.intuit.com/v3/company/<id>/journalentry/<id>

У меня была аналогичная ошибка при доступе к v2 API, и это было плохое форматирование с моей стороны, но я не вижу, что не так с моим запросом.

И поскольку мой код для генерации токенов аутентификации и т. д. идентичен для обоих типов запросов, я сомневаюсь, что проблема связана с тем, как я аутентифицируюсь. Точно так же «исключение» говорит мне, что что-то идет не так, что API не идентифицирует. Вероятно, неправильное форматирование URL-адреса.

Я попытался заменить пробелы URL-адреса запроса как на «+», так и на «% 20», что возвращает ту же ошибку.

Я использую питон и рут. Код отлично работает для v2 (но он был объявлен устаревшим на выходных без предупреждения, и теперь он больше не документирован).

В качестве бонуса и потому, что, по-видимому, это основной способ общения Intuit со своими клиентами: я шокирован тем, что у Intuit больше нет частных билетов в службу поддержки, доступных на их веб-сайте, и что они полагаются на среду сообщества, такую ​​​​как SO, для обеспечения поддержки. Меньшее, что они могли сделать, это обеспечить собственную поддержку. Особенно, если мы платим за использование API. Это абсолютно шокирует.

Кроме того, API возвращает противоречивые ответы (один и тот же запрос вернет ошибку или действительный результат, в зависимости от... вообще никаких изменений). Ошибка, о которой я сообщил через их заявки в службу поддержки, и они должным образом проигнорировали.

О, и документация говорит использовать

https://quickbooks.api.intuit.com/v3/v3/company/companyID/query?query=selectStmt

в то время как API Explorer использует:

https://qb.sbfinance.intuit.com/v3/company/<id>/query?query=SELECT * FROM JournalEntry

Кто-нибудь знает, какой из них я должен на самом деле использовать?

Изменить

Для ответа, который не работает, заголовки моих запросов:

{
    'Content-Length': u'62',
    'Accept-Encoding': 'gzip,
    deflate,
    compress',
    'accept': 'application/json',
    'User-Agent': 'python-requests/1.2.3CPython/2.7.5Darwin/13.0.0',
    'Content-Type': 'application/x-www-form-urlencoded',
    'authorization': 'OAuthrealm="<companyId>",
    oauth_nonce="3ad98c5f71bc9f102cc31ac9815cb6d08994454e",
    oauth_timestamp="1384280420",
    oauth_consumer_key="<consumerKey>",
    oauth_signature_method="HMAC-SHA1",
    oauth_version="1.0",
    oauth_token="<oauthToken>",
    oauth_signature="<oauthSignature"'
}

Мой адрес:

https://quickbooks.api.intuit.com/v3/company/<id>/query?query=SELECT+*+FROM+JournalEntry&

И мои заголовки ответов:

{'content-length': '227', 'server': 'Apache/2.2.22 (Unix)', 'connection': 'close', 'date': 'Tue, 12 Nov 2013 18:20:20 GMT', 'content-type': 'application/json;charset=ISO-8859-1', 'www-authenticate': 'OAuth oauth_problem="signature_invalid"'}

Моя функция хеширования подписи верна. Это стандартная функция, используемая Rauth, и она работает подходит для более стандартных вызовов API (в которых нет пробелов или запросов выбора SQL).


person NotSimon    schedule 12.11.2013    source источник


Ответы (4)


  1. Передайте URL-адрес своему HTTP-вызову без кодирования:

    URL = https://quickbooks.api.intuit.com/v3/company/123456789/query?query="Выберите * от клиента"

  2. Но чтобы построить подпись, отделить параметры от URL, а затем закодировать отдельно, вы должны получить:

    "GET" + "&" + URLEncode(https://quickbooks.api.intuit.com/v3/company/123456789/query) + "&" + URLEncode(query=Select%20%2A%20from%20Customer), где Select%20%2A%20from%20Customer — кодировка Select * from Customer

Обратите внимание, что SQL кодируется второй раз при создании подписи.

И вуаля! Я потратил на это неделю, я знаю, о чем говорю.

(обозначения взяты из языка VBA, поэтому замените по мере необходимости)

person Basile    schedule 10.07.2017

Оказывается, настоящая проблема заключается в том, что документация Quickbooks неверна на момент написания этой статьи (14.11.2013).

В документации говорится, что URL-адрес запроса ожидает запрос GET, что не так. Это работает при отправке оператора SELECT как части тела запроса POST.

Подробнее см. здесь: https://intuitpartnerplatform.lc.intuit.com/questions/786661-python-script-to-integrate-with-quickbook

person NotSimon    schedule 14.11.2013
comment
Не могли бы вы немного уточнить? Какой URL вы используете для отправки POST? И должно ли тело содержать только запрос на выборку? У меня тоже не работает. Я пробовал GET и POST. - person Bruno Buccolo; 10.12.2013
comment
Привет, @BrunoBuccolo, я добавил ссылку на свой ответ на форумах QB. Надеюсь, поможет! - person NotSimon; 11.12.2013
comment
Спасибо @Simon, у меня возникла проблема с Ruby URI.encode, который не кодировал запрос, как ожидалось. Но я заставил его работать, как описано здесь: системная ошибка, когда я запрашиваю элемент"> stackoverflow.com/questions/20503835/ - person Bruno Buccolo; 11.12.2013
comment
Я думаю, что Бруно прав; Документация QBO верна, и настоящая проблема здесь заключается в кодировке. Переключение на запрос POST работает, поскольку позволяет избежать проблемы с кодировкой, но технически это должен быть запрос GET. - person Ian Dunn; 09.02.2016
comment
Кроме того, в моем случае причина, по которой API вернуло ошибку аутентификации, а не неожиданную внутреннюю ошибку, которую он обычно возвращает из-за отсутствия кодировки, заключалась в том, что я обновил кодировку параметров в самом URL-адресе, но не в копии, которая использовался для создания подписи OAuth в заголовке Authorization. - person Ian Dunn; 10.02.2016

Я пробовал этот вызов API, используя Java devkit.

JournalEntry je = GenerateQuery.createQueryEntity(JournalEntry.class);
String jeQuery = select($(je)).generate();
System.out.println("Query - " + jeQuery);
QueryResult JournalEntryRes = service.executeQuery(jeQuery);

Request URI : https://quickbooks.api.intuit.com/v3/company/688779980/query?query=SELECT+*+FROM+JournalEntry&

XML ответа

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2013-11-12T09:50:39.836-08:00">
    <QueryResponse startPosition="1" maxResults="1" totalCount="1">
        <JournalEntry domain="QBO" sparse="false">
            <Id>22734</Id>
            <SyncToken>0</SyncToken>
            <MetaData>
                <CreateTime>2013-10-15T08:42:12-07:00</CreateTime>
                <LastUpdatedTime>2013-10-15T08:42:12-07:00</LastUpdatedTime>
            </MetaData>
            <TxnDate>2013-10-15</TxnDate>
            <Line>
                <Id>0</Id>
                <Amount>100.00</Amount>
                <DetailType>JournalEntryLineDetail</DetailType>
                <JournalEntryLineDetail>
                    <PostingType>Debit</PostingType>
                    <AccountRef name="Advertising">9</AccountRef>
                </JournalEntryLineDetail>
            </Line>
            <Line>
                <Id>1</Id>
                <Amount>100.00</Amount>
                <DetailType>JournalEntryLineDetail</DetailType>
                <JournalEntryLineDetail>
                    <PostingType>Credit</PostingType>
                    <AccountRef name="Advertising">9</AccountRef>
                </JournalEntryLineDetail>
            </Line>
            <Adjustment>false</Adjustment>
        </JournalEntry>
    </QueryResponse>
</IntuitResponse>

Вы также можете попробовать этот вызов из V3 QBO ApiExplorer.

Запрос — SELECT * FROM JournalEntry

Спасибо

person Manas Mukherjee    schedule 12.11.2013
comment
Привет, Манас, к сожалению, я не использую Java Dev Kit, так как это не вариант для программы, которую я разрабатываю. Запрос работает нормально и всегда работал из APIExplorer (который использует другой URL-адрес, как я указал в вопросе), и с использованием строки, которую вы показали в моем коде, это не так. Я мог бы показать вам свой код, но я не решаюсь делать это в публичном месте. - person NotSimon; 12.11.2013
comment
Я добавил некоторые подробности о заголовках моих запросов и ответов. - person NotSimon; 12.11.2013

вам нужно кодировать запрос, но не весь URL

https://quickbooks.api.intuit.com/v3/company/123456789/query?query=" & URLEncode("Выберите * от клиента")

см. образец, объясненный здесь:

https://developer.intuit.com/docs/0100_quickbooks_online/0300_references/0000_programming_guide/0050_data_queries

person Basile    schedule 28.06.2017
comment
Этот вопрос был задан почти 4 года назад, и ваш ответ не добавляет ничего нового к ответам, на самом деле это совсем другая проблема, о которой вы говорите. Проблема заключалась в способе отправки данных на страницу. - person GrumpyCrouton; 28.06.2017
comment
Нет, это та же проблема: передача параметра запроса sql в URL-адресе - person Basile; 10.07.2017
comment
@GrumpyCrouton да, Бэзил прав. Хотя ответ, предоставленный ими здесь, немного лучше: stackoverflow.com/a/45017283/154392 - person NotSimon; 10.07.2017