Issue creating or retrieving Customer Payment Method with Acumatica Rest API - acumatica

Update:--- Code provided which fixes an issue on the graph which was preventing the API from allowing me to create.
public class CustomerPaymentMethodMaint_Extension:PXGraphExtension<CustomerPaymentMethodMaint>
{
#region Event Handlers
protected virtual void CustomerPaymentMethodDetail_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected del)
{
if (del != null)
{
del(cache, e);
}
if (Base.IsContractBasedAPI)
{
CustomerPaymentMethodDetail row = (CustomerPaymentMethodDetail)e.Row;
PXDefaultAttribute.SetPersistingCheck<CustomerPaymentMethodDetail.value>(cache, row, PXPersistingCheck.Nothing);
}
}
#endregion
}
For the life of me, I cannot figure out what Acumatica is expecting me to send to it to either retrieve or create a customer payment method using the Rest API. It would be greatly appreciated if you could point me in the right direction. The examples we are given are very basic and don't seem to cover any scenarios such as this.
I would assume it would be retrieved using the standard "Retrieval of a Record by Key Fields" as described in the help section.
I have tried using all of the below url structures and it either gives me an "Operation is not valud due to the current state of the object" error, or "More than one entity satisfies the condition".
/entity/Default/6.00.001/CustomerPaymentMethod/{BAccountID}/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{AcctCD}/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{BAccountID}
/entity/Default/6.00.001/CustomerPaymentMethod/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{AcctCD}
While trying to create a payment method I tried using a "PUT" to the CustomerPaymentMethod endpoint with the following json Body (I also tried using the soap friendly names of these fields instead of the label thats in the UI "CCDNUM","CVV","EXPDATE","NAMEONCC"). The error I get returned to me is that "Value" cannot be empty.
{
"CustomerID" : { value: "0000467" },
"PaymentMethod" : { value: "CC" },
"CustomerPaymentMethodDetail" : [
{
"Description" : { value : "Card Number" },
"Value" : { value : "4111111111111111" },
},
{
"Description" : { value : "Expiration Date" },
"Value" : { value : "102020" },
},
{
"Description" : { value : "Name on the Card" },
"Value" : { value : "Test API" },
}
]
}

The following works for me on a project where I'm using APS (American Payment Solutions) as the Processing Center.
Use GET to retreive a collection of Customer Payment Methods for a specific customer:
/entity/Default/6.00.001/CustomerPaymentMethod/?$filter=CustomerID+eq+'000000'
Use GET to return a single Customer Payment Method by ID: (You can find the ID from a record returned by the call above.)
/entity/Default/6.00.001/CustomerPaymentMethod/guid-from-record?$expand=Details
I don't think it's possible to create a Customer Payment Method using a brand new card with the Acumatica API. I think you'll first have to create the payment record using your processing center's API. (APS in my case, but I assume Authorize.net works in a similar fashion.) Then, once the payment record exists at the processor, you can add the Customer Payment Record in Acumatica using a PUT to populate the Payment Profile ID, which is a reference to the tokenized card. From there, you can use the GET calls above to return what you need in order to auth/capture a Sales Order.
I'm working through this now and I'll update my comment once I've learned more.

For me the following worked
/entity/Default/{version}/CustomerPaymentMethod/{customerID}/{customerPaymentMethodId}
Now to get the customerPaymentMethodId this can be done via the customer endpoint when expanding PaymentInstructions.
However unfortunately PaymentInstructions only returns the default payment method for the customer.

Related

Create a new item in a SharePoint list

I try to create a new list item, in general work fine, buy I have trouble with Person field.
On my list, I have two columns:
Employee -> Person type - it's for employee
EmployeeId -> Text field - it's like Employee ID from ex. AAD
EmployeeSuperior -> Person type - it's for employee superior
I need to create new item with filled only the Employee I got errors.
If request body is like:
{
"fields": {
"EmployeeLookupId": "6"
}
}
A new item is created by field EmployeeId is filled, but Employee is empty.
If request body is like:
{
"fields": {
"EmployeeLookupId": 6
}
}
I get error:
"message": "General exception while processing",
If request body is like:
{
"fields": {
"EmployeeSuperiorLookupId": "6"
}
}
A new item is created by field EmployeeSuperior correctly.
I think the EmployeeId field is confusing for MS Graph. But I cannot remove it, but I want to use MS Graph for adding new items.
Has anyone how write good request body?
I tried a few combinations of request body, on new list with the same fields but with new names. For my tests I'm usingĀ  Graph Explorer, no test in other ways.

Generate itemId when batchUpdating with Forms API

Please what are the constraints in generating an itemId. I generate unique itemId for each item in the form, but the API keeps telling me invalid ID.
https://developers.google.com/forms/api/reference/rest/v1/forms#Item
Please I need help with this
{
"includeFormInResponse": false,
"requests": [
{
"createItem": {
"item": {
"itemId": "4e637fjc",
"description": "First Name",
"questionItem": {
"question": {
"textQuestion": {
"paragraph": false
},
"required": true
}
}
},
"location": {
"index": 0
}
}
},
{
"createItem": {
"item": {
"itemId": "njyf3izr",
"description": "Middle Name",
"questionItem": {
"question": {
"textQuestion": {
"paragraph": false
},
"required": true
}
}
},
"location": {
"index": 1
}
}
},
}
]
When I had tested Google Forms API before, unless I'm mistaken, I had thought that the rule of item ID might be required to be 00000000 to 7fffffff as the hex value. By the way, for example, 0 is used as 00000000.
When I saw your showing request body, you are trying to use 4e637fjc and njyf3izr as the item ID. In the case of these values, the values are not hex values. I thought that by this, an error like Invalid ID occurred.
But, I think that actually, this is not published in the official document. So, I would like to tell this.
Added:
About your following reply,
Do you mean something like this, with Javascript. crypto.randomBytes(256).toString('hex').slice(0, 8)
From your tag, when you want to use Google Apps Script or Node.js, how about the following sample script? Unfortunately, Google Apps Script cannot directly use "crypto". So, I proposed the following sample script.
Sample script:
const res = Math.floor(Math.random() * parseInt("7FFFFFFF", 16)).toString(16).padStart(8, "0");
console.log(res);
In this sample script, the values of 00000000 to 7fffffff are randomly returned.
Missing documentation
I am afraid that since the Forms API is very new there is no documentation about the specific format the ID should have.
I have done a couple of tests with the API and the only thing I was able to figure out is that the ID needs an 8-character-long string to work, otherwise it would not work or would fill out the blank spaces with zeros.
When doing the testing I was also able to find out that sometimes the API would take a specific pattern of letters and numbers, but when changing the numbers and letters it stops working for no reason.
This seems like missing clarification from the documentation, and I would strongly recommend sending feedback about this problem on the API method page. You can do so by clicking the following option at the top right corner of the documentation:
Google tends to check that feedback a lot when talking about missing information. In addition to all that you can also fill out a report in Google's issue tracker so that they investigate the inconsistencies when using the batchUpdate method to update the ID.
References:
Forms Item
Method: forms.batchUpdate

How to use Angular/Typescript to Access Nested Array from HTTP data?

I am sending JSON from a NodeJS API to an Angular app to be displayed as part of an Angular component. The returned data is simple Mongo id and name string. The data is present in debugger and Postman like so:
{ "httpAllNames": [
{
"_id": "5d5c54315be61d26c0b2afb8",
"campaignTitle": "Make America Zombie Free Again"
},
{
"_id": "5d5c54735be61d26c0b2afba",
"campaignTitle": "Zmobie Free 2"
},
{
"_id": "5d5d3fb280dead0604fe6f8c",
"campaignTitle": "Universal Basic Income For All"
},
{
"_id": "5d5eeaee3278d24b10093988",
"campaignTitle": "Remove All Zombies from the US"
} ]}
I pass the data from my Campaign Service to the component without any trouble. The code in question for accessing it within the browseCampaigns.component is as follows:
browsingCampaignNames: httpAllNames[];
campaignCountDisplayed: number = 0;
onLoadCampaigns() {
this.browsCampServ.fetchCampaignsForBrowsing().subscribe(camps => {
this.browsingCampaignNames = camps;
});
this.campaignCountDisplayed = this.browsingCampaignNames.length;
}
What I'm expecting is to have an array of as many items as are within the httpAllNames object, however, Angular is treating that as a single array, with the desired array nested within.
I guess what I'm trying to do is 'unwrap' the outer layer so that my browsingCampaignNames property is able to access it.
I've tried adjusting the output of the API by removing the status code and unwrapping it from a generic httpResponse object. I've also tried this.browsingCampaignNames = camps[0]; and this.browsingCampaignNames = camps['httpAllNames']; as though to try to access the data by index, even though those methods are 'hacky.'
Thank you in advance.

Cannot change workitem's parent through the azure devops api

I'm trying to programatically change a workitem's parent using the azure devops api but it's not working as expected.
I tried using update link endpoint and also remove link endpoint but none of them seem to be the correct one given that there is no way I can get a relation ID for the parent-child relationship to use in the request path.
The "relation ID" to send in path: is just the index of the relation being changed or removed in the WorkItemRelation[] on the Work Item being PATCHed.
Use the $expand=Relations argument in the query string of the GET operation for the work item whose parentage you want to change (Get Work Item).
https://dev.azure.com/{YOUR_ORG}/{YOUR_PROJ}/_apis/wit/workitems/{Child_ID}?$expand=Relations&api-version=5.0-preview.2
note: I'm not exactly sure, but I think the {YOUR_PROJ} value can be omitted.
With the resulting workitem object, get the index of the relation where the relation type is Hierarchy-Reverse, and use this as the leaf of the "path": "/relations/{index}" property sent in the PATCH body with op: "remove".
Get response (abbreviated):
{
"rel": "System.LinkTypes.Hierarchy-Reverse",
"url": "https://dev.azure.com/{YOUR_ORG}/_apis/wit/workItems/{Parent_ID}",
"attributes": {
"isLocked": false
}
}
Patch request (body):
[
{
"op": "test",
"path": "/rev",
"value": 1
},
{
"op": "remove",
"path": "/relations/0"
}
]
The examples in the documentation tend to perform a test on the revision of the work item before executing the remove or add operation. This isn't necessary, but it's probably a good idea.

Saving a Person or Group field using REST

Does anyone know how to save a Person field using REST?
I have tried the following and it works:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonFieldId" : 1
}
But this only works if you know the ID. I don't have that! How can I get it? I have the key which is i.0#w|domain\userName.
I tried the following and it doesnt work either:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonField" : { "__metadata": { "type": "SP.Data.UserInfoItem" }, "Name": "i.0#w|domain\userName" }
}
Any ideas?? Thanks!
I haven't done this with a Person field, but I did do something similar with a managed metadata field. I basically had to pass in additional information as an object to create the value in the field.
See if passing in the ID of the user along with the name works. I'm about to try this myself as I have the same need.
{
"MyPersonField": { "Name": "i.0#w|domain\userName", "ID": 1 }
}
EDIT: Ok, updating this field is easier than I thought. I was able to perform the update by simply passing in the ID of the user to the Id field:
{
"MyPersonFieldId": 1
}
This means the user should already be in the site collection, so if the user doesn't exist the request will fail.
Use the below code to get Current User ID to save user under People and group column. People column name is Requestor. But to save user we have to specify column name as RequestorId
var userid = _spPageContextInfo.userId; // To get current user ID
var itemProperties={'Title':vTitle,'RequestorId':userid};
The thing is that User information is a lookup field thereby MyPersonField does not exist on your SharePoint list if you use an OData endpoint, I really don't know how to save data but same problem happened to me when I tried to read a user.
for example {server}/{api}/list/getbytitle('mylist')/items does not return MyPersonField instead return MyPersonFieldId.
But if we use:
{server}/{api}/list/getbytitle('mylist')/items/?$select=*,MyPersonField/Name&$expand=MyPersonField
We are able to work with MyPersonField lookup values.

Resources