问题
My payments are not showing up in QuickBooks.
I can successfully create and update Customers. I can also successfully create and update Invoices. I cannot create Payments. But here's the thing, when I execute the Update command on my Payment object I do get a proper Id and Domain (NG) passed back. I've checked the Sync log file (IntuitSyncManagerLogger.log) after running a Sync but it has no error messages. Everything looks ok, there just is no payment associated with the invoice in QuickBooks.
I believe I'm setting all of the required fields but I'm not sure about two of them.
1) The PaymentLine has a field named TxnId. I'm setting it to be the Id and Domain of the InvoiceHeader, but am not sure if this is correct.
2) There is another required field (per the documentation) but I'm leaving it blank as I don't know what to populate it with. It's the DiscountAccountId field. I don't want a discount associated with the invoice.
Here is my code...
SqlConnection connection = new SqlConnection(m_connectionString);
connection.Open();
SqlCommand cmd = new SqlCommand("dbo.Intuit_GetPayment", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@glmvSyncId", SqlDbType.Int).Value = glmvSyncId;
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
Intuit.Ipp.Data.Qbd.PaymentHeader paymentHeader = new Intuit.Ipp.Data.Qbd.PaymentHeader();
paymentHeader.ARAccountId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = Intuit.Ipp.Data.Qbd.idDomainEnum.QB,
Value = "37"
};
paymentHeader.ARAccountName = "Accounts Receivable";
paymentHeader.DepositToAccountId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = Intuit.Ipp.Data.Qbd.idDomainEnum.QB,
Value = "35"
};
paymentHeader.DepositToAccountName = "Undeposited Funds";
paymentHeader.CustomerId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = (rdr["cust_iddomain"].ToString() == "QB" ? Intuit.Ipp.Data.Qbd.idDomainEnum.QB : Intuit.Ipp.Data.Qbd.idDomainEnum.NG),
Value = rdr["cust_idvalue"].ToString()
}; // cust_iddomain and cust_idvalue are from the Customer
paymentHeader.DocNumber = rdr["invoicekey"].ToString();
paymentHeader.TxnDate = DateTime.Now;
List<Intuit.Ipp.Data.Qbd.PaymentLine> listLine = new List<Intuit.Ipp.Data.Qbd.PaymentLine>();
var paymentLine = new Intuit.Ipp.Data.Qbd.PaymentLine();
paymentLine.Amount = Convert.ToDecimal(rdr["amount"]);
paymentLine.TxnId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = (rdr["invc_iddomain"].ToString() == "QB" ? Intuit.Ipp.Data.Qbd.idDomainEnum.QB : Intuit.Ipp.Data.Qbd.idDomainEnum.NG),
Value = rdr["invc_idvalue"].ToString()
}; // invc_iddomain and invc_idvalue are from the InvoiceHeader
listLine.Add(paymentLine);
Intuit.Ipp.Data.Qbd.Payment syncPayment = new Intuit.Ipp.Data.Qbd.Payment();
syncPayment.Header = paymentHeader;
syncPayment.Line = listLine.ToArray();
connection.Close();
Intuit.Ipp.Data.Qbd.Payment resultPayment = new Intuit.Ipp.Data.Qbd.Payment();
resultPayment = commonService.Add(syncPayment);
I suspect the problem is with TxnId.
All I'm doing is creating a Customer, then creating an Invoice for the Customer, then creating a Payment for the Invoice. Am I missing a object someplace?
Any and all help is greatly appreciated.
回答1:
The Payment is likely going into an error state after sync. You can check by executing a PaymentQuery and setting ErroredObjectsOnly=true.
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0100_Calling_Data_Services/0015_Retrieving_Objects#Objects_in_Error_State
If the entity is in error state, you can query for the specific reason using the Status API:
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0600_Object_Reference/SyncStatus
SyncStatusRequest syncStatusRequest = new SyncStatusRequest();
syncStatusRequest.ErroredObjectsOnly = true;
syncStatusRequest.NgIdSet = new NgIdSet[] { new NgIdSet { NgId = <<EnterYourNgIdHere>>, NgObjectType = objectName.Payment } };
SyncStatusResponse[] response = dataServices.GetSyncStatus(syncStatusRequest);
If the payment is in error state, you can delete the entity from the cloud since it was never synced with QuickBooks:
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0100_Calling_Data_Services/Deleting_an_Object
If a successful sync did occur with the entity at least once, but then an Update pushed it into error state, you will need to do a Revert:
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0100_Calling_Data_Services/Reverting_an_Object
You can also try doing an Update directly on the entity in error state once you know the reason from the Status API, but it is not documented so it may not work.
回答2:
Adding the following lines of code seems to have fixed the problem. The Payment is now being recorded in QuickBooks.
paymentHeader.TotalAmt = Convert.ToDecimal(rdr["amount"]);
paymentHeader.TotalAmtSpecified = true;
来源:https://stackoverflow.com/questions/14863355/payment-not-being-created