Quickbooks Online API - 提供发票 ID 后付款 'Unapplied'
Quickbooks Online API - Payment 'Unapplied' when Invoice ID provided
我已经成功地使用 C# .NET SDK 创建了付款,但是当我签入 QBO 时它一直显示为 'unapplied'。
我正在提供发票 ID 并尝试遵循他们的开发人员 API 文档,但我已经做了这么长时间,也许我遗漏了什么?
以下代码创建付款但不'receive'发票付款,是否有我遗漏或需要做的事情才能将两者链接在一起?
Payment payment = new Payment
{
ProcessPayment = false,
CustomerRef = new ReferenceType { name = customer.DisplayName, Value = customer.Id },
CurrencyRef = new ReferenceType { type = "Currency", Value = "CAD" },
TotalAmt = amount,
TotalAmtSpecified = true
};
if (method == PaymentTypes.Cash)
{
var paymentType = paymentMethods.FirstOrDefault(o => o.Id == "1");
if (paymentType != null)
{
payment.PaymentMethodRef = new ReferenceType()
{name = paymentType.Name, Value = paymentType.Id};
}
}
if (method == PaymentTypes.DebitCard)
{
var paymentType = paymentMethods.FirstOrDefault(o => o.Id == "9");
if (paymentType != null)
{
payment.PaymentMethodRef = new ReferenceType()
{ name = paymentType.Name, Value = paymentType.Id };
}
}
if (method == PaymentTypes.CreditCard)
{
var paymentType = paymentMethods.FirstOrDefault(o => o.Id == "8");
if (paymentType != null)
{
payment.PaymentMethodRef = new ReferenceType()
{ name = paymentType.Name, Value = paymentType.Id };
}
}
List<LinkedTxn> linkedTxns = new List<LinkedTxn>
{
new LinkedTxn()
{
TxnId = invoice.Id,
TxnType = TxnTypeEnum.Invoice.ToString()
},
};
foreach (Line line in invoice.Line)
{
//line.Amount = amount;
//line.AmountSpecified = true;
line.Received = amount;
line.ReceivedSpecified = true;
line.DetailType = LineDetailTypeEnum.PaymentLineDetail;
line.DetailTypeSpecified = true;
line.LinkedTxn = linkedTxns.ToArray();
}
payment.DepositToAccountRef = new ReferenceType() { Value = "5" };
payment.Line = invoice.Line;
payment.PaymentRefNum = reference;
DataService dataService = new DataService(serviceContext);
dataService.Add<Payment>(payment);
这是不是的答案。但是,要添加到评论中的内容太多了。我希望这将是一个有用的起点(如果没有,我稍后会删除它)。
首先,我建议重构您的代码并参数化您的变量。这样做您应该能够单独执行可重复的测试。
当您执行 dataService.Add<Payment>(payment)
时,存储响应对象,因为它可能提供有关如何处理请求的线索。或者,如果这是抑制错误消息,您可能想尝试使用 Postman 发送 HTTP 请求。这可能有助于确定哪些参数丢失/不正确。
避免创建部分分配的对象,这样可以更轻松地阅读 7 找出需要分配的属性。
此外,如果您查看 完整更新付款 部分 https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/payment
json 有效载荷有一个额外的 Line,属性 TxnType 设置为 CreditMemo.我假设您需要添加类似 ReceivePayment 或 CreditCardPayment?
的内容
要重构您的代码,请考虑:
// TODO - Set variables for testing purposes.
// This can be added as params to a method.
decimal amount = 100;
string reference = "";
string invoiceId = ""; // invoice.Id
string customerDisplayName = ""; //customer.DisplayName
string customerId = ""; //customer.Id
string paymentName = "Cash"; // paymentType.Name
string paymentId = "1"; // paymentType.Id
List<Line> lines = new List<Line>(); // invoice.Line
if(lines.Count() == 0)
{
// TODO: You might want to check there are lines?
throw new ArgumentException("No invoice.");
}
Line[] invoiceLines = lines.Select(m => new Line()
{
AnyIntuitObject = m.AnyIntuitObject,
Amount = m.Amount,
AmountSpecified = m.AmountSpecified,
CustomField = m.CustomField,
Id = m.Id,
LineNum = m.LineNum,
Description = m.Description,
DetailType = LineDetailTypeEnum.PaymentLineDetail, //m.DetailType,
DetailTypeSpecified = true, //m.DetailTypeSpecified,
LinkedTxn = new List<LinkedTxn>
{
new LinkedTxn()
{
TxnId = invoiceId,
TxnType = TxnTypeEnum.Invoice.ToString() // TODO: Should this be ReceivePayment?
},
}.ToArray(), //m.LinkedTxn,
LineEx = m.LineEx,
Received = amount, //m.Received,
ReceivedSpecified = true // m.ReceivedSpecified
}).ToArray();
Payment payment = new Payment
{
ProcessPayment = false,
CustomerRef = new ReferenceType { name = customerDisplayName, Value = customerId },
CurrencyRef = new ReferenceType { type = "Currency", Value = "CAD" },
TotalAmt = amount,
TotalAmtSpecified = true,
DepositToAccountRef = new ReferenceType() { Value = "5" },
Line = invoiceLines, // Variable is for debugging purposes - it should be inline or call a method.
PaymentRefNum = reference,
PaymentMethodRef = new ReferenceType()
{
name = paymentName,
Value = paymentId,
}
};
DataService dataService = new DataService(serviceContext);
Payment results = dataService.Add<Payment>(payment);
var json = JsonConvert.SerializeObject(results);
Console.Write(json); // TODO - Use break point/ or write response somewhere for clues.
我已经成功地使用 C# .NET SDK 创建了付款,但是当我签入 QBO 时它一直显示为 'unapplied'。
我正在提供发票 ID 并尝试遵循他们的开发人员 API 文档,但我已经做了这么长时间,也许我遗漏了什么?
以下代码创建付款但不'receive'发票付款,是否有我遗漏或需要做的事情才能将两者链接在一起?
Payment payment = new Payment
{
ProcessPayment = false,
CustomerRef = new ReferenceType { name = customer.DisplayName, Value = customer.Id },
CurrencyRef = new ReferenceType { type = "Currency", Value = "CAD" },
TotalAmt = amount,
TotalAmtSpecified = true
};
if (method == PaymentTypes.Cash)
{
var paymentType = paymentMethods.FirstOrDefault(o => o.Id == "1");
if (paymentType != null)
{
payment.PaymentMethodRef = new ReferenceType()
{name = paymentType.Name, Value = paymentType.Id};
}
}
if (method == PaymentTypes.DebitCard)
{
var paymentType = paymentMethods.FirstOrDefault(o => o.Id == "9");
if (paymentType != null)
{
payment.PaymentMethodRef = new ReferenceType()
{ name = paymentType.Name, Value = paymentType.Id };
}
}
if (method == PaymentTypes.CreditCard)
{
var paymentType = paymentMethods.FirstOrDefault(o => o.Id == "8");
if (paymentType != null)
{
payment.PaymentMethodRef = new ReferenceType()
{ name = paymentType.Name, Value = paymentType.Id };
}
}
List<LinkedTxn> linkedTxns = new List<LinkedTxn>
{
new LinkedTxn()
{
TxnId = invoice.Id,
TxnType = TxnTypeEnum.Invoice.ToString()
},
};
foreach (Line line in invoice.Line)
{
//line.Amount = amount;
//line.AmountSpecified = true;
line.Received = amount;
line.ReceivedSpecified = true;
line.DetailType = LineDetailTypeEnum.PaymentLineDetail;
line.DetailTypeSpecified = true;
line.LinkedTxn = linkedTxns.ToArray();
}
payment.DepositToAccountRef = new ReferenceType() { Value = "5" };
payment.Line = invoice.Line;
payment.PaymentRefNum = reference;
DataService dataService = new DataService(serviceContext);
dataService.Add<Payment>(payment);
这是不是的答案。但是,要添加到评论中的内容太多了。我希望这将是一个有用的起点(如果没有,我稍后会删除它)。
首先,我建议重构您的代码并参数化您的变量。这样做您应该能够单独执行可重复的测试。
当您执行 dataService.Add<Payment>(payment)
时,存储响应对象,因为它可能提供有关如何处理请求的线索。或者,如果这是抑制错误消息,您可能想尝试使用 Postman 发送 HTTP 请求。这可能有助于确定哪些参数丢失/不正确。
避免创建部分分配的对象,这样可以更轻松地阅读 7 找出需要分配的属性。
此外,如果您查看 完整更新付款 部分 https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/payment json 有效载荷有一个额外的 Line,属性 TxnType 设置为 CreditMemo.我假设您需要添加类似 ReceivePayment 或 CreditCardPayment?
的内容要重构您的代码,请考虑:
// TODO - Set variables for testing purposes.
// This can be added as params to a method.
decimal amount = 100;
string reference = "";
string invoiceId = ""; // invoice.Id
string customerDisplayName = ""; //customer.DisplayName
string customerId = ""; //customer.Id
string paymentName = "Cash"; // paymentType.Name
string paymentId = "1"; // paymentType.Id
List<Line> lines = new List<Line>(); // invoice.Line
if(lines.Count() == 0)
{
// TODO: You might want to check there are lines?
throw new ArgumentException("No invoice.");
}
Line[] invoiceLines = lines.Select(m => new Line()
{
AnyIntuitObject = m.AnyIntuitObject,
Amount = m.Amount,
AmountSpecified = m.AmountSpecified,
CustomField = m.CustomField,
Id = m.Id,
LineNum = m.LineNum,
Description = m.Description,
DetailType = LineDetailTypeEnum.PaymentLineDetail, //m.DetailType,
DetailTypeSpecified = true, //m.DetailTypeSpecified,
LinkedTxn = new List<LinkedTxn>
{
new LinkedTxn()
{
TxnId = invoiceId,
TxnType = TxnTypeEnum.Invoice.ToString() // TODO: Should this be ReceivePayment?
},
}.ToArray(), //m.LinkedTxn,
LineEx = m.LineEx,
Received = amount, //m.Received,
ReceivedSpecified = true // m.ReceivedSpecified
}).ToArray();
Payment payment = new Payment
{
ProcessPayment = false,
CustomerRef = new ReferenceType { name = customerDisplayName, Value = customerId },
CurrencyRef = new ReferenceType { type = "Currency", Value = "CAD" },
TotalAmt = amount,
TotalAmtSpecified = true,
DepositToAccountRef = new ReferenceType() { Value = "5" },
Line = invoiceLines, // Variable is for debugging purposes - it should be inline or call a method.
PaymentRefNum = reference,
PaymentMethodRef = new ReferenceType()
{
name = paymentName,
Value = paymentId,
}
};
DataService dataService = new DataService(serviceContext);
Payment results = dataService.Add<Payment>(payment);
var json = JsonConvert.SerializeObject(results);
Console.Write(json); // TODO - Use break point/ or write response somewhere for clues.