-->

How Do I Create a Sales Order with Payment Setting

2019-04-16 12:26发布

问题:

I am trying to create a sales order using the Acumatica Web Service API. I have been able to pass all the required fields except the Payment Settings. Our installation uses the Authorize.NET (PX.CCProcessing.AuthorizeNetTokenizedProcessing) add-in. Is it possible to interact with the Authorize.NET add-in through the API by creating a new payment method and authorizing payment so that the employees can work the order from within Acumatica and capture the payment there.

Below is the code I am using to create my sales order. I am not sure the structure to use in order to activate the "Create New Payment Profile ID" action through the API itself. Through the GUI, it opens a popup window that copies the card to Authorize.Net and saves a Payment Profile ID record within Acumatica.


        SO301000Content SO301000 = context.SO301000GetSchema();
        context.SO301000Clear();
        SO301000Content[] SO30100content = context.SO301000Submit
        (
            new Command[]
            {
                //add header info
                new Value { Value = "SO", LinkedCommand = SO301000.OrderSummary.OrderType },
                new Value { Value = "<NEW>", LinkedCommand = SO301000.OrderSummary.OrderNbr },
                new Value { Value = "999999", LinkedCommand = SO301000.OrderSummary.Customer  },

                //add line items
                SO301000.DocumentDetails.ServiceCommands.NewRow,
                new Value { Value = "SS1121", LinkedCommand = SO301000.DocumentDetails.InventoryID },
                new Value { Value = "2", LinkedCommand = SO301000.DocumentDetails.Quantity },
                SO301000.DocumentDetails.ServiceCommands.NewRow,
                new Value { Value = "SS1122", LinkedCommand = SO301000.DocumentDetails.InventoryID },
                new Value { Value = "2", LinkedCommand = SO301000.DocumentDetails.Quantity },
                SO301000.DocumentDetails.ServiceCommands.NewRow,
                new Value { Value = "SS1123", LinkedCommand = SO301000.DocumentDetails.InventoryID },
                new Value { Value = "2", LinkedCommand = SO301000.DocumentDetails.Quantity },

                //add shipping information
                new Value { Value = "True", LinkedCommand = SO301000.ShippingSettingsShipToInfoOverrideContact.OverrideContact },
                new Value { Value = "DEMO CHURCH SHIP", LinkedCommand = SO301000.ShippingSettingsShipToInfoOverrideContact.BusinessName },
                new Value { Value = "True", LinkedCommand = SO301000.ShippingSettingsShipToInfo.OverrideAddress },
                new Value { Value = "123 TEST STREET", LinkedCommand = SO301000.ShippingSettingsShipToInfo.AddressLine1 },
                new Value { Value = "BUFORD", LinkedCommand = SO301000.ShippingSettingsShipToInfo.City },
                new Value { Value = "GA", LinkedCommand = SO301000.ShippingSettingsShipToInfo.State },
                new Value { Value = "30519", LinkedCommand = SO301000.ShippingSettingsShipToInfo.PostalCode },
                new Value { Value = "FREESHIP", LinkedCommand = SO301000.ShippingSettingsShippingInformation.ShipVia },

                //add totals
                new Value { Value = "10.00", LinkedCommand = SO301000.Totals.PremiumFreight },
                new Value { Value = "94.0000", LinkedCommand = SO301000.Totals.PackageWeight },

                //add payment

                SO301000.Actions.Save,
                SO301000.OrderSummary.OrderNbr
            }
        );

New Code Error - I am now able to insert the customer payment record but receive an error when trying to insert that card into an existing sales order.

Here is my code:

        SO301000Content SO301000 = context.SO301000GetSchema();
        context.SO301000Clear();
        SO301000Content[] SO30100content = context.SO301000Submit
        (
            new Command[]
                {
                    //add header info
                    new Value { Value = "SO", LinkedCommand = SO301000.OrderSummary.OrderType },
                    new Value { Value = "000129", LinkedCommand = SO301000.OrderSummary.OrderNbr },
                    //add payment
                    new Value { Value = "VISA", LinkedCommand = SO301000.PaymentSettings.PaymentMethod },
                    new Value { Value = "VISA:****-****-****-7261", LinkedCommand = SO301000.PaymentSettings.CardAccountNo },

                    SO301000.Actions.Save
                }
        );

If anybody has any ideas, I would greatly appreciate it. Thanks.

回答1:

You can't use the "Create New Payment Profile ID", because it relies on an actual user in the web browser (we simply show the Authorize.net new profile page in an IFRAME). We do this to limit the exposure of the application to PCI Compliance, and this way no credit card number or sensitive information ever touches the Acumatica server. You should add the payment profile directly through the Authorize.net CIM site or CIM APIs, and pass the profile ID to Acumatica.

Unfortunately you can't pass the customer profile ID directly to the order, only the payment profile value is accepted as input, so you'll first need to add the entry using the Customer Payment Methods screen API.

        AR303010Content AR301000 = context.AR303010GetSchema();
        context.AR303010Clear();
        AR303010Content[] AR303010content = context.AR303010Submit(
            new Command[]
            {
                new Value { Value = "999999", LinkedCommand = AR301000.PaymentMethodSelection.Customer },
                new Value { Value = "VISATOK", LinkedCommand = AR301000.PaymentMethodSelection.PaymentMethod },
                new Value { Value = "AUTHTOK", LinkedCommand = AR301000.PaymentMethodSelection.ProcCenterID },
                new Value { Value = "102000", LinkedCommand = AR301000.PaymentMethodSelection.CashAccount },
                new Value { Value = "23640304", LinkedCommand = AR301000.PaymentMethodSelection.CustomerProfileID },
                new Value { Value = "27187006",  FieldName = "Value", ObjectName = "ccpIdDet"}, //Payment Profile ID, going directly to internal ccpIdDet view to bypass validation error when using AR301000.PaymentMethodDetails.Value
                AR301000.Actions.Save,
                AR301000.PaymentMethodSelection.CardAccountNo
            });

        string cardAccountNo = AR303010content[0].PaymentMethodSelection.CardAccountNo.Value;

Then when you create the sales order, you just need to specify which card to be used, as returned by AR301000 after the creation process:

         //add payment
         new Value { Value = "VISATOK", LinkedCommand = SO301000.PaymentSettings.PaymentMethod },
         new Value { Value = cardAccountNo, LinkedCommand = SO301000.PaymentSettings.CardAccountNoCardAccountNo }, //Use card account number returned earlier, like "VISATOK:****-****-****-1111"


回答2:

Below is the sample showing how to set Card Number in Sales Orders through Screen-Based API:

Content orderSchema = context.GetSchema();

orderSchema.PaymentSettings.CardAccountNo.FieldName += "!Descr";

var commands = new Command[]
{
   new Value
   {
       Value = "SO",
       LinkedCommand = orderSchema.OrderSummary.OrderType,
       Commit = true
   },
   orderSchema.Actions.Insert,

   new Value
   {
       Value = "ABARTENDE",
       LinkedCommand = orderSchema.OrderSummary.Customer,
       Commit = true
   },

   new Value
   {
       Value = "VISA",
       LinkedCommand = orderSchema.PaymentSettings.PaymentMethod
   },
   new Value
   {
       Value = "VISA:****-****-****-7630",
       LinkedCommand = orderSchema.PaymentSettings.CardAccountNo,
       Commit = true
   },    

   orderSchema.Actions.Save
};
context.Submit(commands);

This pattern is necessary for every selector with TextField property set in Aspx.



标签: acumatica