Adding Customer attributes

I had to make a new account here because your system wasn’t sending out emails when it was supposed to.

Here’s my real issue. I reached the point where the test customer has already accepted a hold on his credit card for 7 days and your system won’t allow me to connect a new order to the payment since the payment state is approved.

What I’m trying to do is after receiving payment, I want to be able to insert somewhere all the customer names and emails that the buyer made purchases for.

So I tried creating custom attributes as follows…

First the definition…

curl https://connect.squareupsandbox.com/v2/customers/custom-attribute-definitions \
  -X POST \
  -H 'Square-Version: 2024-07-17' \
  -H 'Authorization: Bearer EAAAlx9JezVirPKdRae5GUAFquTz05526ec7gJq3ZLyXeRFF7kscnJYB4_AiEVz3' \
  -H 'Content-Type: application/json' \
  -d '{
    "custom_attribute_definition": {
      "description": "some kind of string for a customer",
      "key": "mystringkey",
      "name": "its a string",
      "schema": {
        "$ref": "https://developer-production-s.squarecdn.com/schemas/v1/common.json#squareup.common.String"
      },
      "visibility": "VISIBILITY_READ_ONLY"
    },
    "idempotency_key": "3ece97cc-94ba-4aeb-8002-0c9a584727e1"
  }'

That succeeds. So at this point I’m, guessing I use “mystringkey” to set values.

Now assuming one customer made a purchase for 2 customers in one order, I want to make a one-time massive update to avoid a too many requests error (HTTP response code 429) should hundreds of customers make purchases.

Say this customer ordered for Jackie Chan and John Smith. What I do is send the first name, last name and email as one string comma-separated.

So I tried the following request:

curl https://connect.squareupsandbox.com/v2/customers/custom-attributes/bulk-upsert \
  -X POST \
  -H 'Square-Version: 2024-07-17' \
  -H 'Authorization: Bearer EAAAlx9JezVirPKdRae5GUAFquTz05526ec7gJq3ZLyXeRFF7kscnJYB4_AiEVz3' \
  -H 'Content-Type: application/json' \
  -d '{
    "values": {
      "mystringkey": {
        "custom_attribute": {
          "key": "recipient1",
          "value": "john,smith,[email protected]"
        },
        "customer_id": "SSRGKPX6CHN9BY7W41Y7MX35FM",
        "idempotency_key": "feae3079-003d-4a95-b7e5-f79592650894"
      },
      "mystringkey": {
        "custom_attribute": {
          "key": "recipient2",
          "value": "jackie,chan,[email protected]"
        },
        "customer_id": "SSRGKPX6CHN9BY7W41Y7MX35FM",
        "idempotency_key": "feae3079-003d-4a95-b7e5-f79592650895"
      }
    }
  }'

And I get this error:

{"values":{"mystringkey":{"errors":[{"code":"BAD_REQUEST","detail":"No matching definition found for value","field":"key","category":"INVALID_REQUEST_ERROR"}]}}}

Then I try:

curl https://connect.squareupsandbox.com/v2/customers/custom-attributes/bulk-upsert \
  -X POST \
  -H 'Square-Version: 2024-07-17' \
  -H 'Authorization: Bearer EAAAlx9JezVirPKdRae5GUAFquTz05526ec7gJq3ZLyXeRFF7kscnJYB4_AiEVz3' \
  -H 'Content-Type: application/json' \
  -d '{
    "values": {
      "recipient1": {
        "custom_attribute": {
          "key": "mystringkey",
          "value": "john,smith,[email protected]"
        },
        "customer_id": "SSRGKPX6CHN9BY7W41Y7MX35FM",
        "idempotency_key": "feae3079-003d-4a95-b7e5-f79592650894"
      },
      "recipient2": {
        "custom_attribute": {
          "key": "mystringkey",
          "value": "jackie,chan,[email protected]"
        },
        "customer_id": "SSRGKPX6CHN9BY7W41Y7MX35FM",
        "idempotency_key": "feae3079-003d-4a95-b7e5-f79592650895"
      }
    }
  }'

and I get:

{"values":{"recipient1":{"errors":[{"code":"CONFLICT","detail":"Attempted to create a record with key\u003dmystringkey, parent_resource_id\u003dSSRGKPX6CHN9BY7W41Y7MX35FM when one already exists in the database. This indicates a race condition where the same value was created multiple times in a short time period.","field":"key","category":"INVALID_REQUEST_ERROR"}]},"recipient2":{"customer_id":"SSRGKPX6CHN9BY7W41Y7MX35FM","custom_attribute":{"key":"mystringkey","version":1,"updated_at":"2024-07-22T00:22:52.035Z","value":"jackie,chan,[email protected]","created_at":"2024-07-22T00:22:52.035Z","visibility":"VISIBILITY_READ_ONLY"}}}}

But I read in the error (if I can translate it):

“Attempted to create a record with key “mystringkey”, parent_resource_id SSRGKPX6CHN9BY7W41Y7MX35FM when one already exists in the database. This indicates a race condition where the same value was created multiple times in a short time period.”

However I’m trying to set two different values and it seems its accepting one but not the other, and I don’t want to make an HTTP request for each value I want to send.

I grabbed the customer ID from the Square API explorer because I gave it my valid sandbox key for testing.

How do I fix this so the bulk upsert works and I can have multiple values assigned for a customer?

And I wouldn’t have this issue if the note field in the customers API would accept an array of strings instead of one string with a character limit.

The square bracket idea in the code didnt work.

But it seems that the only way I could pull it off is to make multiple definitions and use one definition per value.

So if I had a customer buy for say 20 people, then I’d have to make 20 calls in advance to square to make 20 definitions then set values to match each definition.

So something like this would work after creating 2 string definitions with string key string123 and string1234

And yes I just used x y and z and me as samples for customer ID and idempotency key and bearer.

I didn’t think it’d be this much of a challenge to upload an array of strings per customer.

curl https://connect.squareupsandbox.com/v2/customers/custom-attributes/bulk-upsert \
  -X POST \
  -H 'Square-Version: 2024-07-17' \
  -H 'Authorization: Bearer me \
  -H 'Content-Type: application/json' \
  -d '{
    "values": {
	"i1":{
        "custom_attribute": {"key": "string123","value": "abcd"},
        "customer_id": "x",
        "idempotency_key": "y"
      },
	"i2":{
        "custom_attribute": {"key": "string1234","value": "efgh"},
        "customer_id": "x",
        "idempotency_key": "z"
      }
    }
  }'

Hello, @osd3

you’re on the right track with using the bulk-upsert endpoint to handle multiple custom attributes for a customer. Here are a few tips to ensure it works smoothly:

Ensure Unique Idempotency Keys:
Each request within the values map should have a unique idempotency_key to avoid conflicts.
Correct Authorization Header:
Make sure the Authorization header is correctly formatted:
-H ‘Authorization: Bearer YOUR_ACCESS_TOKEN’

Proper JSON Formatting:
Ensure your JSON payload is correctly formatted. Here’s a refined version of your cURL command:
curl https:// connect .squareupsandbox.com/v2/customers/custom-attributes/bulk-upsert
-X POST
-H ‘Square-Version: 2024-07-17’
-H ‘Authorization: Bearer YOUR_ACCESS_TOKEN’
-H ‘Content-Type: application/json’
-d ‘{
“values”: {
“i1”: {
“custom_attribute”: {“key”: “string123”, “value”: “abcd”},
“customer_id”: “x”,
“idempotency_key”: “y”
},
“i2”: {
“custom_attribute”: {“key”: “string1234”, “value”: “efgh”},
“customer_id”: “x”,
“idempotency_key”: “z”
}
}
}’
Check API Limits:
The bulk-upsert endpoint supports up to 25 individual upsert requests per call. Ensure you are within this limit.
Debugging:
If you encounter errors, check the response for detailed error messages. This can help identify issues with specific requests.

I hope this info is helpful to you.

Best Regard,
Gregory Chavez

The issue seems to be related to how you’re assigning multiple custom attributes under the same key (mystringkey) in the bulk upsert request. Each key must be unique for the custom attributes you want to add. Instead of trying to use the same key with different values, consider creating separate custom attribute definitions for each recipient (e.g., recipient1, recipient2). This way, you avoid key conflicts and can successfully store multiple values for the same customer. If the note field allowed arrays, this wouldn’t be necessary, but for now, separate keys are the way to go.

[quote=“osd3, post:1, topic:17923”] compass mobile
I had to make a new account here because your system wasn’t sending out emails when it was supposed to.

Here’s my real issue. I reached the point where the test customer has already accepted a hold on his credit card for 7 days and your system won’t allow me to connect a new order to the payment since the payment state is approved.

What I’m trying to do is after receiving payment, I want to be able to insert somewhere all the customer names and emails that the buyer made purchases for.
[/quote]

Thanks for sharing the answer. It helps me a lot.

…the test customer has already accepted a hold on his credit card for 7 days and your system won’t allow me to connect a new order to the payment since the payment state is approved.

This is to be expected with Delay Capture. The only way to move forward with the original order and payment in delay capture is to cancel or completed the payment - overview.


What I’m trying to do is after receiving payment, I want to be able to insert somewhere all the customer names and emails that the buyer made purchases for.

Most of the order and payment object details cannot get updated once they’ve been paid for, or in this delay captured state.

In this case, I’m not sure that delay capture is the right way to implement for what you’re trying to do. Maybe you should just save the card on file instead, then you can update the unpaid order at will until you create the payment.