Need Help Using python-quickbooks library and Quickbooks Accounting API
<p>I'm trying to implement the Quickbooks API for Python, to generate invoices based on transactions, and send them to my quickbooks account. I'm using <a href="https://github.com/sidecars/python-quickbooks" rel="nofollow">this</a> python library for accessing the API, which is currently in version 0.5.1 and is available on PyPI. I'm having trouble connecting my application to Quickbooks Online.</p>

<p>I have created a developer account on Quickbooks, and have access to my app token, consumer key, and consumer secret. The guide on the library's github page, confuses me because, under "Connecting your application to Quickbooks Online", steps 1 and 2 seem related but somewhat independent of each other; mainly because of the re-initialization of the client variable. </p>

<p>Am I supposed to have multiple Quickbook objects named client, but re-initializing it throughout my code? </p>

<p>My code looks like this: </p>

<pre><code>def create_invoice():
    consumer_key = 'MY-CONSUMER-KEY'
    consumer_secret = 'MY-CONSUMER-SECRET'

    client = QuickBooks(
        sandbox=True,
        consumer_key=consumer_key,
        consumer_secret=consumer_secret,
        callback_url='https://sandbox-quickbooks.api.intuit.com',
    )

    authorize_url = client.get_authorize_url()
    request_token = client.request_token
    request_token_secret = client.request_token_secret

    client = QuickBooks(
        sandbox=True,
        consumer_key=consumer_key,
        consumer_secret=consumer_secret
    )

    client.authorize_url = authorize_url
    client.request_token = request_token
    client.request_token_secret = request_token_secret
    client.set_up_service()

    client.get_access_tokens(request.vars.oauth_verifier)

    realm_id = request.vars.realmId
    access_token = client.access_token
    access_token_secret = client.access_token_secret

    client = QuickBooks(
        sandbox=True,
        consumer_key=consumer_key,
        consumer_secret=consumer_secret,
        access_token=access_token,
        access_token_secret=access_token_secret,
        company_id=realm_id
    )

    invoice = Invoice()
    line = SalesItemLine()
    line.LineNum = 1
    line.Description = "description"
    line.Amount = 100
    line.SalesItemLineDetail = SalesItemLineDetail()
    item = Item.all(max_results=1, qb=client)[0]

    line.SalesItemLineDetail.ItemRef = item.to_ref()
    invoice.Line.append(line)

    customer = Customer.all(max_results=1, qb=client)[0]
    invoice.CustomerRef = customer.to_ref()

    invoice.CustomerMemo = CustomerMemo()
    invoice.CustomerMemo.value = "Customer Memo"
    invoice.save(qb=client)
</code></pre>

<p>With this code I get the error: </p>

<pre><code>KeyError: 'Decoder failed to handle oauth_token with data as returned by provider. A different decoder may be needed. Provider returned: oauth_problem=parameter_absent&amp;oauth_parameters_absent=oauth_verifier'
</code></pre>

<p>Because I'm getting the error something has to be wrong, but I'm confused where to go now.</p>

<p>I found the answer to my problem. After reading this <a href="http://stackoverflow.com/questions/16078366/reuse-oauth1-authorization-tokens-with-rauth">thread</a>, where they had the same error, I got a better sense of what the library was doing; mainly the flow that was going on behind the scenes. I ultimately found it was the callback url that I had supplied was wrong. Choose a callback url that points back to where you are running above code. I also chose to store most of my variables in a database so I can easily access them for future use. My code now looks like this:</p>

<pre><code>def create_invoice():
    consumer_key = 'MY-CONSUMER-KEY'
    consumer_secret = 'MY-CONSUMER-SECRET'
    rows = db(db.quickbooks_info).select()
    p = [dict(realm_id=r.realm_id, access_token=r.access_token, access_token_secret=r.access_token_secret, consumer_key=r.consumer_key,
          consumer_secret=r.consumer_secret, authorize_url=r.authorize_url, request_token=r.request_token, request_token_secret=r.request_token_secret)
         for r in rows]
    if len(p) == 0:
        client = QuickBooks(
            sandbox=True,
            consumer_key=consumer_key,
            consumer_secret=consumer_secret,
            callback_url='http://127.0.0.1:8800/SNotes/default/create_invoice'
        )
        authorize_url = client.get_authorize_url()
        request_token = client.request_token
        request_token_secret = client.request_token_secret

        db.quickbooks_info.update_or_insert((db.quickbooks_info.consumer_key == consumer_key),
                                            consumer_key=consumer_key,
                                            consumer_secret=consumer_secret,
                                            authorize_url=authorize_url,
                                            request_token=request_token,
                                            request_token_secret=request_token_secret
                                        )
    else:
        if p[0]['access_token'] == None and p[0]['access_token_secret'] == None and p[0]['realm_id'] == None:
            client = QuickBooks(
                sandbox=True,
                consumer_key=p[0]['consumer_key'],
                consumer_secret=p[0]['consumer_secret']
            )

            client.authorize_url = p[0]['authorize_url']
            client.request_token = p[0]['request_token']
            client.request_token_secret = p[0]['request_token_secret']
            client.set_up_service()
            client.get_access_tokens(request.get_vars['oauth_verifier'])

            realm_id = request.vars.realmId
            access_token = client.access_token
            access_token_secret = client.access_token_secret
            db.quickbooks_info.update_or_insert((db.quickbooks_info.consumer_key == p[0]['consumer_key']),
                                                access_token=access_token,
                                                access_token_secret=access_token_secret,
                                                realm_id=realm_id
                                            )
        else:
            client = QuickBooks(
                sandbox=True,
                consumer_key=p[0]['consumer_key'],
                consumer_secret=p[0]['consumer_secret'],
                access_token=p[0]['access_token'],
                access_token_secret=p[0]['access_token_secret'],
                company_id=p[0]['realm_id']
            )

            invoice = Invoice()

            line = SalesItemLine()
            line.LineNum = 1
            line.Description = "test"
            line.Amount = 6969
            line.SalesItemLineDetail = SalesItemLineDetail()
            item = Item.all(max_results=1, qb=client)[0]

            line.SalesItemLineDetail.ItemRef = item.to_ref()
            invoice.Line.append(line)

            customer = Customer.all(max_results=1, qb=client)[0]
            invoice.CustomerRef = customer.to_ref()

            invoice.CustomerMemo = CustomerMemo()
            invoice.CustomerMemo.value = "Customer Memo"
            invoice.save(qb=client)
</code></pre>

python web2py quickbooks-online