Acumatica支付插件开发:如何获取发票/销售订单编号
Hey there! Let's figure out how to pull those invoice or sales order numbers into your CardConnect payment plugin for Acumatica. Since you're only accessing the PMT document type and payment number right now, we need to trace the payment back to the documents it's applied to. Here's a step-by-step approach with working code snippets:
First, we need to link the payment to the specific invoices or sales orders it's paying off. Every payment in Acumatica has associated PMTran records that track which documents it applies to. You can fetch these using the payment's document type and reference number:
public override bool DoTransaction(PX.CCProcessing.CCProcessingContext processingContext) { // Fetch the current payment record from the processing context PMRegister payment = processingContext.GetCurrentPayment() as PMRegister; if (payment == null) return base.DoTransaction(processingContext); PXGraph graph = PXGraph.CreateInstance<PXGraph>(); // Get all application lines for this payment IEnumerable<PMTran> paymentApplications = PXSelect<PMTran, Where<PMTran.paymentDocType, Equal<Required<PMTran.paymentDocType>>, And<PMTran.paymentRefNbr, Equal<Required<PMTran.paymentRefNbr>>>>> .Select(graph, payment.DocType, payment.RefNbr);
Each PMTran record has a RefNoteID field that points directly to the underlying document (like an ARInvoice or SOOrder). We can use this ID to pull the document's reference number:
foreach (PMTran tran in paymentApplications) { if (tran.RefNoteID == null) continue; // First check for AR Invoices (most common scenario for payments) ARInvoice invoice = PXSelect<ARInvoice, Where<ARInvoice.noteID, Equal<Required<ARInvoice.noteID>>>> .Select(graph, tran.RefNoteID); if (invoice != null) { string invoiceNumber = invoice.RefNbr; // Pass this invoice number to your payment gateway // Example: gatewayRequest.MerchantReference = invoiceNumber; continue; } // If no invoice found, check for Sales Orders (for scenarios where payments are applied directly to SOs) SOOrder salesOrder = PXSelect<SOOrder, Where<SOOrder.noteID, Equal<Required<SOOrder.noteID>>>> .Select(graph, tran.RefNoteID); if (salesOrder != null) { string salesOrderNumber = salesOrder.OrderNbr; // Pass this sales order number to your payment gateway // Example: gatewayRequest.MerchantReference = salesOrderNumber; } } // Rest of your existing transaction logic... return base.DoTransaction(processingContext); }
If a single payment applies to multiple invoices, you might want to concatenate all related numbers (depending on your payment gateway's support):
List<string> relatedDocumentNumbers = new List<string>(); foreach (PMTran tran in paymentApplications) { ARInvoice invoice = PXSelect<ARInvoice, Where<ARInvoice.noteID, Equal<Required<ARInvoice.noteID>>>> .Select(graph, tran.RefNoteID); if (invoice != null) { relatedDocumentNumbers.Add($"INV-{invoice.RefNbr}"); } } // Combine into a single string for the gateway string combinedReference = string.Join(", ", relatedDocumentNumbers); // gatewayRequest.MerchantReference = combinedReference;
- Always check for
nullvalues when fetching records to avoid runtime errors. - Payments typically apply directly to AR Invoices, not sales orders—sales orders are usually linked to invoices, so you might need to trace from the invoice to the sales order if that's what you need (use
ARInvoice.OrderNbrfor that).
内容的提问来源于stack exchange,提问作者Shawn

