• Resolved hollymcr

    (@hollymcr)


    For no apparent reason, having previously worked fine, I was unable to receive WooCommerce payments via Square.

    Payment attempts just failed with no useful message, but with logging enabled, I found the cause, see below.

    The idempotency_key that was failing was 50 chars long. Looking at the Square API info 128 chars should be accepted, but changing my order numbering scheme to bring it below 45 solved it.

    Failed: 77c03b5942fa2784e3304b45a4a164d5:XXXXX-ORDER-1234 (50 chars)
    Worked: 77c03b5942fa2784e3304b45a4a164d5:XXXXX-1234 (44 chars)

    However looking through the logs I see that if another failure occurs (eg wrong card details) any retries have a suffix added (eg 77c03b5942fa2784e3304b45a4a164d5:XXXXX-1234-2) which will take it over the 45 char limit again.

    There must be a better way to fix this, suggestions?

    (Note for anyone changing their order number text: the numeric part will reset to (eg) 1000) when you do, so consider changing the order starting number as well.)

    09-03-2020 @ 14:59:26 - Response
    code: 400
    message:
    headers: Array
    (
        [0] => HTTP/1.1 400 Bad Request
        [Date] => Thu, 03 Sep 2020 13:59:25 GMT
        [Frame-Options] => DENY
        [X-Frame-Options] => DENY
        [X-Content-Type-Options] => nosniff
        [X-Xss-Protection] => 1; mode=block
        [Content-Type] => application/json
        [Square-Version] => 2019-08-14
        [Squareup--Connect--V2--Common--Versionmetadata-Bin] => CgoyMDE5LTA4LTE0
        [Content-Length] => 157
        [Strict-Transport-Security] => max-age=631152000; includeSubDomains; preload
    )
    body: Array
    (
        [errors] => Array
            (
                [0] => stdClass Object
                    (
                        [code] => VALUE_TOO_LONG
                        [detail] => Field must not be greater than 45 length
                        [field] => idempotency_key
                        [category] => INVALID_REQUEST_ERROR
                    )
    
            )
    
    )
Viewing 7 replies - 1 through 7 (of 7 total)
  • Plugin Contributor mattdallan

    (@mattdallan)

    Hi @hollymcr,

    > The idempotency_key that was failing was 50 chars long. Looking at the Square API info 128 chars should be accepted

    Thanks for bring this to our attention! Can you please share a link to the Square API docs that mention 128 characters?

    Here’s a link to the Square API library we use in our extension and is says the idempotency_key has to be MAX 45 characters (screenshot: https://d.pr/i/mD8UTF)

    In our Square extension we set the idempotency key on payment requests to have the value: {32-char-hash} + : + Order number + - + number of failed attempts.

    With a 45 character limit, that leaves 12 characters after the {hash}: for the order ID and number of failed attempts, which I believe will only become a problem after the order ID gets larger than 999,999,999.

    In the examples you shared, you had XXXXX-ORDER-1234 in the Failed case: 77c03b5942fa2784e3304b45a4a164d5:XXXXX-ORDER-1234.

    What is adding the XXXXX-ORDER- to the idempotency key value??
    Do you have some other plugin that customises the value returned by get_order_number to include the xxxx-order- at the front?

    Thanks for reporting this.

    Thread Starter hollymcr

    (@hollymcr)

    OK, I hadn’t realised I was using an order number plugin – it’s been there since I started using Woo – but I have this installed:
    woo-custom-and-sequential-order-number.

    (I have no idea what order numbers look like by default any more!)

    As to the API docs: looking again I can’t see a specific figure documented and did find at least one place where 45 was mentioned just now, but here’s a reference to it being 192 (I can’t now find 128)

    Clearly the problem I have is a clash between two extensions but as far as I can tell neither are doing anything wrong. Not sure what a sensible solution would be…

    Thread Starter hollymcr

    (@hollymcr)

    Question: You say idemopotency_key is set to {hash}:{order number}-{attempts}, but what is {hash} generated from?

    From a glance at the code, {hash} seems to be based on the site URL, so should stay the same for all my site transactions. But is there any reason for it to be so?

    Thought: What would be the implication of having idemopotency_key set to md5(“$site:$order_number”) so that, regardless of order number structure, the result was always 32 chars? You could then set idempotency_key to {hash}-{attempts} and (for any reasonable number of attempts!) always remain below 45 chars. That would make it compatible with any plugin which changed the order number structure.

    I can see an advantage of the current structure when looking at the logs but as far as I can see the actual order number is always present within the data structure that contains the idempotency_key.

    Or maybe a better fix: if idempotency_key ever exceeds 45 chars, do something to make force it under 45 chars, eg (untested):

    public function get_idempotency_key( $key_input = '' ) {
    
        if ( '' === $key_input ) {
            $key_input = uniqid( '', false );
        }
    
        $hash_source = get_option( 'siteurl' );
        if ( strlen( $key_input ) > 12 ) {
            // As things stand, idempotency_key will exceed 45 chars
            // Therefore include $key_input in the md5 hash (to ensure uniqueness)
            // and shorten $key_input to make everything fit
            $hash_source .= ':' . $key_input;
            $key_input = substr( $key_input, -12 );
        }
        return apply_filters( 'wc_square_idempotency_key', md5( $hash_source ) . ':' . $key_input );
    }

    That should result in no changes to idempotency_key for sites where it already works, but fix any that don’t because of a long order number. (Can you see any problems with it?)

    Still don’t understand why it used to work then stopped though, as I have always had this order number structure. Maybe something was letting >45 char idempotency_key values work, then started to enforce the limit?

    Plugin Support Elvira K. a11n

    (@treibalen)

    Hi there @hollymcr,

    Thanks for getting back to us!

    The issue has already been reported to our developers and they’re working on a permanent fix so idemopotency_key value stays under 45 symbols even with customer order numbers.

    Meanwhile, please use add the following code snippet to your site and check if the issue is resolved now:

    function custom_square_idempotency_key( $key ) {
    
        if ( strlen( $key ) > 45 ) {
            $hash_split = explode( ':', $string );
            $short_hash = substr( $hash_split[0], 0, 10 );
    
            $key = $short_hash . substr( $string, strlen( $hash_split[0] ) );
        }
    
        return $key;
    }
    add_filter( 'wc_square_idempotency_key', 'custom_square_idempotency_key', 10, 1);

    Still don’t understand why it used to work then stopped though, as I have always had this order number structure.

    Since Square 2.2.0 we upgraded from the Transactions API to the Payments API which is having this limitation.

    Enjoy the rest of your day and stay safe!

    Plugin Support Elvira K. a11n

    (@treibalen)

    Hi there @hollymcr,

    I wanted to let you know that the error you were seeing has been fixed in Square 2.2.1 so you don’t need a code snippet anymore.

    Please let us know if you’re still seeing issues after an update!

    Cheers!

    Plugin Support AW a11n

    (@slash1andy)

    Automattic Happiness Engineer

    Hey there!

    We haven’t heard back from you in a while, so I’m going to mark this as resolved – if you have any further questions, you can start a new thread.

    Thread Starter hollymcr

    (@hollymcr)

    Sorry for not getting back to you, for some reason I didn’t see the email notifications of updates.

    I agree that this is likely resolved now but in the meantime I had changed my order number structure to ensure it never exceeded the character limit so it no longer affects me and the fix won’t therefore affect me either.

    This is a busy time for my store but when things get quiet I’ll return to a custom order format that challenges the character limit and report back if there are issues. But having looked at the code I’m confident your fix is fine.

    Many thanks for your investigation and fix for this.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘VALUE_TOO_LONG for idemopotency_key’ is closed to new replies.