Search code examples
phpoauth-2.0quickbooks-onlinepurchase-order

Quickbooks PHP SDK purchase orders missing param error


I'm trying to create purchase orders using Quickbooks PHP SDK and keep getting an invalid/missing param error or possibly wrong ID.

My parameters are based off of the Quickbooks API Explorer. Under the Purchase Order's 'Create' demo, there's an option to generate some default json/xml. I thought this would give me the minimum required params.

So in my code, I have created a Purchase Order array with these Params and made up values. But can't figure out what is wrong or missing.

The few samples of PHP QuickBooks SDK Purchase orders I've seen are using Oauth 1.0, so playing with them was not worth my time since My APP uses Oauth 2.0

ERROR

The Status code is: 400 The Helper message is: Invalid auth/bad request strong text(got a 400, expected HTTP/1.1 20X or a redirect) The Response message is: Invalid Reference IdInvalid Reference Id : Something you're trying to use has been made inactive. Check the fields with accounts, customers, items, vendors or employees.

SAMPLE JSON from QUICKBOOKS API Explorer (data from App sandbox)

{
    "Line": [{
        "Id": "1",
        "Amount": 25.0,
        "DetailType": "ItemBasedExpenseLineDetail",
        "ItemBasedExpenseLineDetail": {
            "CustomerRef": {
                "value": "3",
                "name": "Cool Cars"
            },
            "BillableStatus": "NotBillable",
            "ItemRef": {
                "value": "38",
                "name": "Garden Supplies"
            },
            "UnitPrice": 25,
            "Qty": 1,
            "TaxCodeRef": {
                "value": "NON"
            }
        }
    }],
    "VendorRef": {
        "value": "41",
        "name": "Hicks Hardware"
    },
    "APAccountRef": {
        "value": "33",
        "name": "Accounts Payable (A/P)"
    },
    "TotalAmt": 25.0
}

Quickbooks.php (only the important parts)

$purchaseOrder = PurchaseOrder::create([
      "Line" =>[
              [
                  "Id" =>"0",
                  "Amount" => 25.0,
                  "DetailType" => "ItemBasedExpenseLineDetail",
                  "ItemBasedExpenseLineDetail"=>
                  [
                      "CustomerRef"=>
                      [
                          "value"=>"3",
                          "name"=>"Cool Cars"
                      ],
                      "BillableStatus"=> "NotBillable",
                      "ItemRef"=>
                      [
                        "value"=> "38",
                        "name"=> "Garden Supplies"
                      ],
                      "UnitPrice"=> "25",
                      "Qty"=>"1",
                       "TaxCodeRef"=>
                      [
                        "value"=> "NON",
                      ]

                  ]
              ]
          ],
          "VendorRef"=>
          [
              "value"=>"41",
          "name"=>"Hicks Hardware"

          ],
          "APAccountRef"=>
          [
              "value"=>"33",
          "name"=>"Accounts Payable (A/P)"

          ],
          "TotalAmt"=> 25.0
    ]);



    $resultingpurchaseOrder = $dataService->Add($purchaseOrder);
    $error = $dataService->getLastError();
    if ($error != null) {
        echo "The Status code is: " . $error->getHttpStatusCode() . "\n";
        echo "The Helper message is: " . $error->getOAuthHelperError() . "\n";
        echo "The Response message is: " . $error->getResponseBody() . "\n";
    } else {
        var_dump($resultingpurchaseOrder);
    }

Solution

  • It took a while to figure out, but here's what I did in order to create a successful sample Purchase Order in my sandbox.

    Tip to find good sample Json/XML to base PO parameters off of

    • Go to you APP's API Explorer and select Purchase Orders https://developer.intuit.com/v2/apiexplorer?apiname=V3QBO#?id=PurchaseOrder
    • Find the 'Query' explorer at the bottom of the page.
    • enter select * from PurchaseOrder in the query field.
    • much of the returned xml/json can be used for your PO paramaters
    • I removed several things including the ID (which I believe is auto generated by QB)
    • See my final code sample below as a reference for which parameters were or were not needed.

    This is just a sample to test out creating PO's that worked for me, posted in case it helps anyone else.

    Sample Create Purchase Order

     $dataService = DataService::Configure(array(
             'auth_mode' => 'oauth2',
               'ClientID' => "",
               'ClientSecret' => "",
               'accessTokenKey' => "",
               'refreshTokenKey' => '',
               'QBORealmID' => "",
               'baseUrl' => "https://sandbox-quickbooks.api.intuit.com"
      ));
    
      $OAuth2LoginHelper = $dataService->getOAuth2LoginHelper();
      $accessToken = $OAuth2LoginHelper->refreshToken();
      $error = $OAuth2LoginHelper->getLastError();
      if ($error != null) {
          echo "The Status code is: " . $error->getHttpStatusCode() . "\n";
          echo "The Helper message is: " . $error->getOAuthHelperError() . "\n";
          echo "The Response message is: " . $error->getResponseBody() . "\n";
          return;
      }
      $dataService->updateOAuth2Token($accessToken);
    
      $dataService->setLogLocation("/home/lindsay/Desktop/log");
    $purchaseOrder = PurchaseOrder::create([
      "ShipAddr" => [
          "Id"=> "96",
          "Line1"=> "Sandbox Company_US_1",
          "Line2"=> "123 Sierra Way",
          "Line3"=> "San Pablo, CA  87999"
        ],
      "Line" =>[
              [
                  "Id" =>"1",
                  "Description" => "This is the purchasing description.",
                  "Amount" => 5.0,
                  "DetailType" => "ItemBasedExpenseLineDetail",
                  "ItemBasedExpenseLineDetail"=>
                  [
                      "CustomerRef"=>
                      [
                          "value"=>"4",
                          "name"=>"Diego Rodriguez"
                      ],
                      "BillableStatus"=> "NotBillable",
                      "ItemRef"=>
                      [
                        "value"=> "19",
                        "name"=> "T-Shirt"
                      ],
                      "UnitPrice"=> "5",
                      "Qty"=>"1",
                       "TaxCodeRef"=>
                      [
                        "value"=> "NON",
                      ]
    
                  ]
              ]
          ],
          "VendorRef"=>
          [
              "value"=>"56",
          "name"=>"Bob's Burger Joint"
    
          ],
          "APAccountRef"=>
          [
              "value"=>"33",
          "name"=>"Accounts Payable (A/P)"
    
          ],
          "TotalAmt"=> 5.0,
          "Memo" => "vendor message test!"
    
    ]);
    
    
    
    $resultingpurchaseOrder = $dataService->Add($purchaseOrder);
    $error = $dataService->getLastError();
    if ($error != null) {
        echo "The Status code is: " . $error->getHttpStatusCode() . "\n";
        echo "The Helper message is: " . $error->getOAuthHelperError() . "\n";
        echo "The Response message is: " . $error->getResponseBody() . "\n";
    } else {
        var_dump($resultingpurchaseOrder);
    }