Java SDK com.squareup.square.models.Payment gave different customer id between toString() and json serialization

Dear Team,

The background of this topic is related to below topic:

When we did troubleshooting for the topic mentioned in above post, we noticed for the success payment (around UTC 2023-12-03 02:42, payment id: RaBQUtmSBdniWwGICMN17U3Rr2XZY), the response com.squareup.square.models.Payment gave different customer id between toString() and json serialization

The payment flow in our application is as below for the success payment :

  1. create a customer in square
  2. add a card to the customer in square
  3. make a card on file payment with customer id and card id through java sdk
  4. log out the success payment from square (com.squareup.square.models.Payment, toString())
  5. serialize the same success payment from square (com.squareup.square.models.Payment, as json string through jackson) and save into DB
  6. delete card and customer in square (for information security purpose)

above 3. ~ 6. are done in the same API call to our application, which means they are in the same java thread in our application

at Step 4. , we got customer id Z156PTX2XWGEX0ARY6567JET4G from toString() method, which is the same one created at Step 1, it’s logged out to our log file, but can’t be found in square now, as it’s deleted already at Step6.

at Step 5. , we got a different customer id DPC8WF163FJVC026M8NYZBCKNG from jackson serialization; as confirmed in our log file, i believe it’s not created by our application, but it can be found in square, square API shows this customer as “INSTANT_PROFILE”.

we are confused why jackson serialization gave a different customer id, any advice is appreciated.

Thanks.

Hello! :wave:

If I’m following correctly, Steps 1-3 and 6 are where you’re making requests to Square’s APIs, and 4-5 are just handling the response and logging/storing?

I’m not sure why you would get different values when logging the response as a string versus when serializing it. Once a response is sent from Square and received by your application, there will only be one value set for Customer ID. Is it possible that there is a caching issue causing your app to serialize a different object?

As an aside, I did want to mention that you can use the Payments API without having to create a customer and card on file every time! Cards on file are intended to be used for recurring payments. If you’re doing single payments and deleting the Card and Customer in Square afterwards every time, it may be easier to just make payments without creating those objects.

@josh-square

thanks for help on looking into this topic,

If I’m following correctly, Steps 1-3 and 6 are where you’re making requests to Square’s APIs, and 4-5 are just handling the response and logging/storing?

yes, your are right

Once a response is sent from Square and received by your application, there will only be one value set for Customer ID. Is it possible that there is a caching issue causing your app to serialize a different object?

agree, customerID has no reason to change once the payment response sent from square;
but it doesn’t look like a caching issue to serialize a different object, as toString() and serialization got the same payment ID;

while looking into square java sdk com.squareup.square.models.Payment, i noticed below comment, it looks an instant profile is created and it’s what we got at Step 5, but it looks still not make sense, as we deleted customer at Step 6. which is after Step 5. where we got the customer ID of instant profile, and if we were attempting to get the customer ID of the instant profile, we would need to retrieve the payment info from square again after Step6…
we will do more investigation to see whether we can find any further clue.

/**
 * Getter for CustomerId.
 * The ID of the customer associated with the payment. If the ID is not provided in the
 * `CreatePayment` request that was used to create the `Payment`, Square may use information in
 * the request (such as the billing and shipping address, email address, and payment source) to
 * identify a matching customer profile in the Customer Directory. If found, the profile ID is
 * used. If a profile is not found, the API attempts to create an [instant
 * profile](https://developer.squareup.com/docs/customers-api/what-it-does#instant-profiles). If
 * the API cannot create an instant profile (either because the seller has disabled it or the
 * seller's region prevents creating it), this field remains unset. Note that this process is
 * asynchronous and it may take some time before a customer ID is added to the payment.
 * @return Returns the String
 */
@JsonGetter("customer_id")
@JsonInclude(JsonInclude.Include.NON_NULL)
public String getCustomerId() {
    return customerId;
}

If you’re doing single payments and deleting the Card and Customer in Square afterwards every time, it may be easier to just make payments without creating those objects.

thanks for advice, yes, we are aware of that. In our application the design is that customer can choose whether to save his info or not, our application is hard to know that beforehand, so above Step 1. ~ 6. is in the case that customer chose not to save his info = )

I took a look at the logs an it looks like an auto merge took place which is why the customer_id changed. The auto merge event took place 50 minutes after the customer was created. However the first two payments failed because of generic declines from the bank. :slightly_smiling_face:

@Bryan-Square

thanks for help on this topic,
but may i know what’s the “auto merge”?

When we feel confident that we know there are duplicate profiles within a customer directory we will merge the profiles. When a merge happens the customer is still retrievable with the old customer_id but we will return the new profile with the new ID. :slightly_smiling_face: