Solved

ICCHostedPaymentFormResponseParser

  • 13 October 2023
  • 30 replies
  • 394 views

Badge

Working on creating a Custom cc plug-in . However i cannot get the ICCHostedPaymentFormResponseParser to work . 

Does anyone have any ideas of how i can go about this?

icon

Best answer by Evgeny Afanasiev 19 October 2023, 15:44

View original

30 replies

Badge

When i submit the form i get : The 001982 payment has no active pre-authorized or captured transactions. To process the 001982 payment, open the Payments and Applications (AR302000) form.

 

when i post do window.postMessage nothings happens when i post to parent I get a CORS error..

Userlevel 3
Badge

Hi @Merch ,


The click on the Pay/Save on the Hosted Payment Form should invoke the following callback from within Hosted Payment Form:

window.parent.px_callback.paymentCallback('action=transactResponse&response=somestring

The somestring value will be delivered as an input in the Parse() method. Where you can take the whole response and and extract the TransactionId from it.


Here is a demo implementation of CC Plug-in: https://github.com/weihnachtswichtel/AcumaticaDemoHostedFormIntegration

Badge

@Evgeny Afanasiev 

 

Thank you very much for this !

After implementing this solution I am still getting Uncaught DOMException: Blocked a frame with origin "****.com" from accessing a cross-origin frame. The iframe calls to this origin with a subdomain appended.

Userlevel 3
Badge

Hi @Merch,

It looks like that the issue you’re describing is related to Same-origin policy for example when you’re trying to access an iframe with different origin using JavaScript. This is not really Acumatica specific, and most probably related to the code nested in the frame loaded in the PaymentConnector. There are two common scenarios we see in implementation of hosted form - it is either really a web page hosted by the gateway and when called it is loaded in the iframe. Or it is some js. libraries that allows you to build form on side in PCI-compliant way. Which is your case? Since there is not much information provided in the post, I would suggest to debug hosted form using browser developer tools, to find where exactly the issue is happening and act accordingly.

Badge

@Evgeny Afanasiev 

It is hosted on the payment gateway . If it is the not the Same-Origin Policy then how do you think I should resolve in that case?

The interesting part about this is that the error displays as two domains as the same domain with a different subdomain.

 

for example test.com and test.com/test1

Userlevel 3
Badge

Hi @Merch,

The error message you’ve posted stating that the issue is in accessing a cross-origin frame, so it should be related to Same-Origin Policy. In your example test1 is not a subdomain but a path, so test.com and test.com/test1 are same-origin as only path part is different, but host is the same.


My scientific guess, that the issue might be in the protocol. When you’re retrieving the url of the current Acumatica instance for a callback based on the scenario it might take http instead of https. If this is the case in GetDataForPaymentForm method, when getting PaymentConnector url for a callback, ensure that it is https using string.Replace().

 

Badge

This is very interesting. I set the URL as Https://…. . I should replace it with the same value? How would that ensure that it is HTTPS?

Badge

I dont think it is Https protocol because my iframe is on another domain so I think that is what is causing the error. Is there anyway to circumvent that?

Userlevel 3
Badge

Hi @Merch,

First about http/https:
I am still referring to your statement:

The interesting part about this is that the error displays as two domains as the same domain with a different subdomain.

for example test.com and test.com/test1

Since the origin issue is thrown when the host and origin are test.com in both cases, what could be an issue is either the protocol or port or both.
Not to be unfounded below is an example, when there is external http call from within the https frame:

because http://localhost and https://localhost are different origins. If this is fixed, and call is made using https, the request is working:


If to make a call from the frame to the another domain and call the paymentCallback function directly, CORS will arise:

So in my case above the issue would be CORSMissingAllowOrigin.
I did not see such issues in the case when the payment form is hosted at the gateway, as usually js-scripts loaded in the frame that enabling the secure communication.

If you are using a custom payment conntector, it might not be really needed in your case. Please use the build-in Frames/PaymentConnector.html (or review and reuse it’s code). Its contains the logic that passes the data from Iframe to parent.

If suggestions above not resolving the matter, please share the screenshots of the error from the browser developer tools - console and networking tabs, when the issue is raised.

Badge


I thought i should just include the url for the iframe which hosts the payment and then send back the response through the iframe form. Is this not the method to use? what would you suggest?

   

Badge

after i submit the form the page submits reloads and the i did a parent.postMessage or parent.window.px_callback().. i think i am missing a step here  

Badge

Also my form submit the page and then on the submitted page (same url) i try to post but i am not even seeing that portion on my browser debug tools .. 

Badge

I created an iframe from within the payment processor hosted window the iframe source is ***.acumatica.com/Frames/PaymentConnector.html. i then did iframe.contentWindow.PostMessage(action=transactResponse&response=somestring , ‘*’) . I got a simillar result in my dev tools to what you posted but the transaction is still not feeding through (the window for the hosted paymnet form is also not closing unless i X it out)

Userlevel 3
Badge

Hi @Merch,

Another idea.

Many gateways having some of the services and APIs behind the Geo Block, etc for security reasons. In the case of hosted form, the API request will be done from the browser of your machine (not from the place where the server is hosted). The server response for the blocked location might not contain “Access-Control-Allow-Origin” header. And that will look like a CORS issue, but root cause is elsewhere.
Below is an actual example of getting a CORS issue when vaulting card via Hosted Form that was caused be geo blocking:

So if you are not based in the area where the gateway usually operates (US?), try to use VPN tunnels, or RDP machine somewhere closer to that region. As a proof of concept, try to access the url location that fails just in the browser to see if you have any response. If the physical location is not an issue, please share some screenshots of browser console.

Badge

okay but at this point i am not seeing any errors- no cors or failed to load resource or anything like that! everything seems to be working but the SynchornizePayment graph is still not triggered. How can I send you screenshots because i do not want to submit them on  a public forum?

Userlevel 3
Badge

@Merch,

SynchornizePayment will be triggered after the payment callback is invoked from hosted form. By callback I mean window.parent.px_callback.paymentCallback() method. As for sharing, you can copy/paste pictures in PMs. Or use any service that allow sharing files by link.

Badge

   

Userlevel 3
Badge

@Merch ,

I think something is not right in the approach.

If the hosted form is really hosted in the processing center side, than IFrame should direct to this form. i.e. Url property of the HostedFormData object returned by GetDataForPaymentForm() method should be populated by the hosted form service, not the local frame. The url to the local frame passed to the processing center as a parameter for callback.

If you’re building the hosted form your own using js libs, then you can use in the Url the local custom frame that you’ve build.

It looks somehow mixed in your case. Also as mentioned before -iframePost.contentWindow.postMessage('action=transactResponse&response would not work.
When hosted form is open Acuamica is just waiting for the px_callback.paymentCallback() method to be called. It is hardcoded and compiled in PX.Web.dll, so nothing can be done about it.

Please note that in the native PaymentConnector this method in not called directly. Instead the listener is added and window.parent.parent.px_callback.paymentCallback(somedata) is called on message received.
This part is missing

Badge

If it is a nested IFrame meaning the acumatica order holds the payment form which hold the connector.html . Why wouldnt parent.parent.postMEssage achieve the same thing? Thats what I dont understand, doesnt that part communicate through frames which is the case here.

Badge

I created A frame how to i publish it to production ? ( i was able to publish to local)

Userlevel 3
Badge

Hi @Merch,

Yes, you’d need to pass the full url of the PaymentConnector.html to the HostedForm service, so it will render its own hosted form, and place the PaymentConnector in the nested IFrame. The communication between the processing center and hosted form will be performed directly, but when it will happened, nested iframe with PaymentConnector, will pass the result of the response to Acumatica. Obviously the full url to the connector should be generated dynamically, and since HttpContext.Current might not be available in some scenarios or depending on version, try to use build in helper method for it and check the GitHub link in first reply.

 

In case you are using build-in PaymentConnector.html you do not need to add it again. If you are build your own form, based on JS scripts, after you have if on the Dev instance, you can just add it as Files item in the customization project.

Badge

right but how do i add the file on the dev instance ? Also when i was trying to use build in methods to get the url , it was telling me that it wasnt available on this instance?

Userlevel 3
Badge

Hi @Merch,

For the development purposes in most cases you would require a locally installed instance of Acumatica, as implementing a code customization you would need a direct access to the file system. In order to have a file that has to be distributed, you just need to place it physically on on the local site where you would like it to be and add this as FILE item in the customization project.
If you do not have a local instance for development, it better to set one. Here is a quick guide: https://www.acumatica.com/blog/quick-start-acumatica-developer-guide/

Badge

I have a local ORG and i added the Frame , my question is going from there how do i get it into production?

Userlevel 3
Badge

Great, then you only need to add the file to the customization project like documented here:

https://help.acumatica.com/(W(5))/Help?ScreenId=ShowWiki&pageid=01a694bb-8e42-436c-89ad-2c42c040089a then export it from your dev instance and import and publish it on production instance.

Please note that even you are absolutely sure in your customization, it is recommended to have a staging environment, for testing at least the deployment process.

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved