• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Amazon Pay Checkout, java, V2 in coldfusion cfc - method not found

New Here ,
Jul 14, 2022 Jul 14, 2022

Copy link to clipboard

Copied

I am trying to implement Amazon Pay Checkout, V2 in coldfusion (ACF2016/windows) leveraging the provided JAVA code from Amazon's docs and Amazon's .jar file. (https://github.com/amzn/amazon-pay-api-sdk-java#readmeglobal)

I have written a cfc, meant to be used in the session. I instantiate the WebstoreClient object, set the Pay Configuration and generate the button code just fine. Click the button on the page, a window opens, log into sandbox, close the window and go to the second checkout page with a sessionid in the URL (keeping it simple) When the button is clicked, amazon creates your checkout session, and all the local methods are GET/POST/PATCH operations to amazon servers - simple enough. Not knowing java, but able to [usually] follow code, it sure looks like everything is there..

Here is where I am having trouble. I cannot getCheckoutSession(sessionid) The error I get is

The getCheckoutSession method was not found. Either there are no methods with the specified method name and argument types or the getCheckoutSession method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.

My first checkout page is like this, works fine.

<cfset session.amazonPayClient=createObject('component', 'cfc.amazon').init(dsn='xyz',env='dev')>
<cfoutput>#session.amazonPayClient.renderButton()#</cfoutput>

The second page has this and is where I get the error - method not found

<cfset session.amazonPayClient.getCheckoutSess(url.amazonCheckoutSessionId)>

This is how I am creating the object - it happens during init() of the cfc

<cffunction name="setClient" access="private" returntype="void" hint="this creates the client used to initialize the checkout" output="no">
        <cfset region=createObject("java", "com.amazon.pay.api.types.Region")>
        
        <cffile action="read" file="#variables.PEM_PATH#" variable="pem">
        <cfset variables.oPayConfiguration = createObject("java", "com.amazon.pay.api.PayConfiguration")
            .setPublicKeyId("#variables.amazonProperties.publicKeyID#")
            .setPrivateKey("#pem#")
            .setRegion(Region.NA)
            .setEnvironment(variables.Environment.SANDBOX)
        >
        
        <cfset variables.oClient=createObject("java", "com.amazon.pay.api.WebstoreClient").init(variables.oPayConfiguration)>
</cffunction>

These 2 work with the button signature - which I assume is used elsewhere (eventually)

<cffunction name="genButtonSignature" access="private" returntype="string" hint="this generates the button signature used to create the checkoutsession" output="no">
    <cfset signature = variables.oClient.generateButtonSignature(variables.amazonProperties.buttonPayload)>
    <cfreturn trim(signature)>
</cffunction>

<cffunction name="getButtonSignature" access="private" returntype="string" output="no">
    <cfreturn trim(variables.amazonProperties.buttonSignature)>
</cffunction>

This renders the button - works just fine

<cffunction name="renderButton" access="public" returntype="string" output="no">
    <cfset var buttonCode="">
    <cfsavecontent variable="buttonCode">
        <div id="AmazonPayButton"></div>
        <script src="<cfoutput>#variables.amazonProperties.payScript#</cfoutput>"></script>
        <script type="text/javascript" charset="utf-8">
              amazon.Pay.renderButton('#AmazonPayButton', {
                   // set checkout environment
                   merchantId: '<cfoutput>#variables.amazonProperties.merchantID#</cfoutput>',
                   publicKeyId: '<cfoutput>#variables.amazonProperties.publicKeyID#</cfoutput>',
                      ledgerCurrency: 'USD',         
                      // customize the buyer experience
                      checkoutLanguage: 'en_US',
                      productType: 'PayAndShip',
                      placement: 'Cart',
                      buttonColor: 'Gold',
                      createCheckoutSessionConfig: {                     
                          <cfoutput>payloadJSON:'#variables.amazonProperties.buttonPayload#',
                          signature:'#getButtonSignature()#'</cfoutput>
                      }   
                  });
             </script>
        </cfsavecontent>
        <cfreturn buttonCode>
    </cffunction>

And this is where it is failing. When using the Amazon ScratchPad , all it needs is the checkoutSessionId, so I am completely lost at this point.

<cffunction name="getCheckoutSess" access="public" returntype="any">
    <cfargument name="sessionID" type="string" required="true">
    <cfreturn variables.oClient.getCheckoutSession(checkoutSessionId=arguments.sessionID)>
</cffunction>

The method is there in the WebStoreClient

/**
     * The GetCheckoutSession operation is used to get checkout session details that contain
     * all session associated details.
     *
     * @param checkoutSessionId Checkout Session ID provided by Checkout v2 service
     * @param header Map&lt;String, String&gt; containining key-value pair of required headers (e.g., keys such as x-amz-pay-idempotency-key, x-amz-pay-authtoken)
     * @return The response from the GetCheckoutSession service API, as
     * returned by Amazon Pay.
     * @throws AmazonPayClientException When an error response is returned by Amazon Pay due to bad request or other issue
     */
    public AmazonPayResponse getCheckoutSession(final String checkoutSessionId, final Map<String, String> header) throws AmazonPayClientException {
        final URI checkoutSessionURI = Util.getServiceURI(payConfiguration, ServiceConstants.CHECKOUT_SESSIONS);
        final URI getCheckoutSessionURI = checkoutSessionURI.resolve(checkoutSessionURI.getPath() + "/" + checkoutSessionId);
        return callAPI(getCheckoutSessionURI, "GET", null, "", header);
    }

    /**
     * The GetCheckoutSession operation is used to get checkout session details that contain
     * all session associated details.
     *
     * @param checkoutSessionId Checkout Session ID provided by Checkout v2 service
     * @return The response from the GetCheckoutSession service API, as
     * returned by Amazon Pay.
     * @throws AmazonPayClientException When an error response is returned by Amazon Pay due to bad request or other issue
     */
    public AmazonPayResponse getCheckoutSession(final String checkoutSessionId) throws AmazonPayClientException {
        return getCheckoutSession(checkoutSessionId, null);
    }

I am really hoping that someone, after reading all this, can say, oh, that's simple, you don't understand something basic..

Views

172

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 20, 2022 Jul 20, 2022

Copy link to clipboard

Copied

Two things that may help:

1) If I remember correctly (and I could be wrong), I couldn't use named parameters in the past when calling Java functions.

 <cfreturn variables.oClient.getCheckoutSession(checkoutSessionId=arguments.sessionID)>

should probably be:

 <cfreturn variables.oClient.getCheckoutSession(arguments.sessionID)>

2) Try cfdumping the variables.oClient and make sure you see the expected function and parameters for getCheckoutSession. Sometimes that will provide insight into issues with Java functions.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 23, 2022 Jul 23, 2022

Copy link to clipboard

Copied

LATEST

I can spot a few potential problems:

  1. The validation for the URL variable is missing. You should add one. For example:
    <!--- the url test is a must; the length test is just my example of additional validation --->
    <cfif structKeyExists(url, "amazonCheckoutSessionId") and len(url.amazonCheckoutSessionId) eq 36>
       <cfset session.amazonPayClient.getCheckoutSess(url.amazonCheckoutSessionId)>
    <cfelse>
       <!--- do error handling --->
    </cfif>​


  2.  The following switch in the WebStoreClient from 1 to 2 arguments amounts to method overloading in Java. However, ColdFusion does not support overloading.
     public AmazonPayResponse getCheckoutSession(final String checkoutSessionId) throws AmazonPayClientException {
            return getCheckoutSession(checkoutSessionId, null);
        }​


  3.   The following method call has just one argument, expecting overloading to occur automatically.
     <cfreturn variables.oClient.getCheckoutSession(checkoutSessionId=arguments.sessionID)>​

    That is the likely cause of the error. As ColdFusion doesn't support overloading, the function should have two arguments. A possible solution might be to use javacast("null","") as the second argument. That is,
    <cfreturn variables.oClient.getCheckoutSession(arguments.sessionID, javacast("null",""))>​

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation