CreateCard INVALID_CARD_DATA with Ecuador-issued international Visa after successful payment

Hello Square Developer Team,

I’m experiencing a consistent issue specifically when trying to save an international Visa credit card issued in Ecuador as a Card on File.

The important point is that Square successfully processes and captures the payment with this Ecuador-issued card, but CreateCard fails immediately afterward.

I’m following the documented flow:

Web Payments SDK → CreatePayment → payment_id → CreateCard

The Web Payments SDK tokenization and payment are successful:

  • Card country: Ecuador (EC)

  • Card type: Visa Credit

  • Payment status: COMPLETED

  • Card details status: CAPTURED

  • Entry method: KEYED

  • CVV status: CVV_ACCEPTED

  • AVS status: AVS_NOT_CHECKED

  • Risk level: NORMAL

After the successful payment, I immediately call:

CreateCard(source_id = payment_id, card.customer_id = customer_id)

However, CreateCard returns:

category: INVALID_REQUEST_ERROR
code: INVALID_CARD_DATA
detail: Invalid card data.
field: source_id

Example Payment ID:

PdFdgwzKEgQRqrVIWXCPSiTvAtBZY

Customer ID:

XN7A5KX09KMWZM98ZT6PPZ9ZKW

Location ID:

42863CWXB158P

I have tested the same Ecuador-issued card both with the Ecuador billing postal code included and with the postal code completely omitted. The payment succeeds in both cases, but CreateCard still fails.

I also previously tested the alternative flow using a Web Payments SDK token with STORE and calling CreateCard directly. Cards issued in Ecuador also failed at the CreateCard step.

So the consistent behavior I’m seeing is:

Ecuador-issued Visa → Payment succeeds → CreateCard fails

Could you please clarify:

  1. Is using a successful payment_id as the source_id for CreateCard still the correct and supported method?

  2. Are there any known restrictions or additional requirements for creating Cards on File from international cards issued in Ecuador?

  3. Since CreateCard performs a $0 verification, can you check whether the $0 verification for the Payment ID above was actually submitted to the Visa network / Ecuadorian card issuer?

  4. If it reached the issuer, was the verification declined? Is there an internal issuer/network response code behind the INVALID_CARD_DATA error?

  5. Could the AVS_NOT_CHECKED result be relevant when attempting to store an Ecuador-issued card?

The card itself is valid and Square successfully captures the payment. The problem occurs specifically when attempting to create the Card on File.

Thank you.

This is the payment:

{
“payment”: {
“id”: “PdFdgwzKEgQRqrVIWXCPSiTvAtBZY”,
“created_at”: “2026-09-18T03:58:12.747Z”,
“updated_at”: “2026-09-18T03:58:13.502Z”,
“amount_money”: {
“amount”: 658,
“currency”: “USD”
},
“status”: “COMPLETED”,
“delay_duration”: “PT168H”,
“source_type”: “CARD”,
“card_details”: {
“status”: “CAPTURED”,
“card”: {
“card_brand”: “VISA”,
“last_4”: “[redacted]”,
“exp_month”: 7,
“exp_year”: 2030,
“fingerprint”: “[redacted]”,
“card_type”: “CREDIT”,
“prepaid_type”: “NOT_PREPAID”,
“bin”: “[redacted]”,
“payment_account_reference”: “[redacted]”
},
“entry_method”: “KEYED”,
“cvv_status”: “CVV_ACCEPTED”,
“avs_status”: “AVS_NOT_CHECKED”,
“auth_result_code”: “114266”,
“statement_description”: “SQ *CARS4GO CAR RENTAL I”,
“card_payment_timeline”: {
“authorized_at”: “2026-09-18T03:58:13.051Z”,
“captured_at”: “2026-09-18T03:58:13.502Z”
}
},
“location_id”: “42863CWXB158P”,
“order_id”: “QMWpXD6PSHFM6afCOFqRqWQ8mDWZY”,
“risk_evaluation”: {
“created_at”: “2026-09-18T03:58:13.362Z”,
“risk_level”: “NORMAL”
},
“buyer_email_address”: “[redacted]”,
“billing_address”: {
“address_line_1”: “[redacted]”,
“locality”: “[redacted]”,
“country”: “EC”,
“first_name”: “[redacted]”,
“last_name”: “[redacted]”
},
“note”: “Cars4Go Payment from link”,
“customer_id”: “XN7A5KX09KMWZM98ZT6PPZ9ZKW”,
“total_money”: {
“amount”: 658,
“currency”: “USD”
},
“approved_money”: {
“amount”: 658,
“currency”: “USD”
},
“receipt_number”: “PdFd”,
“receipt_url”: " [redacted] ",
“delay_action”: “CANCEL”,
“delayed_until”: “2026-09-25T03:58:12.747Z”,
“application_details”: {
“square_product”: “ECOMMERCE_API”,
“application_id”: “sq0idp-6B4qzJJ9-Pj8dbsoihZsYQ”
},
“version_token”: “DRNaLHsv0O6AtBD5wH3P1m5Hw29JBUyo3JyU8JzzA6F6o”
}
}

this is the card request:

{
“idempotency_key”: “savecard_6aacb6d5c8bd70.41884493”,
“source_id”: “[redacted]”,
“card”: {
“cardholder_name”: “[redacted]”,
“customer_id”: “XN7A5KX09KMWZM98ZT6PPZ9ZKW”
}
}

this is the card response:

{
“errors”: [
{
“category”: “INVALID_REQUEST_ERROR”,
“code”: “INVALID_CARD_DATA”,
“detail”: “Invalid card data.”,
“field”: “source_id”
}
]
}

Thank you.

Thanks for sharing the details. I was able to confirm that the payment was approved and captured successfully, and the following CreateCard request returned INVALID_CARD_DATA for source_id.

Using a successful payment_id as the source_id for CreateCard is a supported flow. However, a card being accepted for a payment does not always mean it can be saved as a Card on File. INVALID_CARD_DATA is a generic error for the storage step, and the API does not return a more specific underlying reason.

I’m not aware of any Ecuador-specific API restriction from this request, and AVS_NOT_CHECKED by itself would not explain the result. I also cannot confirm through whether a separate verification was sent to the issuer or provide an issuer/network response for the failed save attempt.

One thing to double-check in the Web Payments SDK flow:

For keyed card-not-present payments, pass verificationDetails into card.tokenize() so the token includes any required 3DS authentication. The amount and currency in verificationDetails must match the CreatePayment request. In this specific payment, 3DS was completed successfully, so it does not appear to be the reason this CreateCard call failed. It is still worth including for future payment or direct-store attempts.

Since you are seeing the same result with both the payment-ID and direct-store flows, your overall integration approach looks correct. The next best test is another eligible card, or checking with the issuer about Card-on-File/credential-storage support.

Hello Square Developer Support,

Att: zacstlouis.

We are investigating a reproducible issue when attempting to store certain international Visa cards on file using the Square Web Payments SDK and Cards API.

We have isolated the issue and tested both the legacy buyer-verification flow and the current Web Payments SDK STORE tokenization flow.

Our merchant is located in the United States. The affected card is a Visa credit card issued in Ecuador.

Current isolated test

We created a completely separate test containing no payment operation.

There is no CreatePayment call and no charge to the customer.

The test follows this flow:

  1. Initialize the Web Payments SDK card object.

  2. Call card.tokenize(verificationDetails) with:

{
    intent: "STORE",
    billingContact: {
        // cardholder billing information
        countryCode: "EC",
        // address, city, state, name, email and phone supplied
    },
    customerInitiated: true,
    sellerKeyedIn: false
}

  1. Tokenization succeeds.

  2. No 3DS challenge is presented to the cardholder.

  3. The resulting payment token is sent as source_id to CreateCard.

  4. CreateCard is rejected with:

{
  "errors": [
    {
      "category": "PAYMENT_METHOD_ERROR",
      "code": "CARD_DECLINED_VERIFICATION_REQUIRED",
      "detail": "Card declined. A verification is required to process this payment."
    }
  ]
}

This is the behavior we would like Square to investigate.

According to the Web Payments SDK documentation, when verificationDetails are supplied to card.tokenize(), Square automatically determines whether authentication is required during tokenization and displays an authentication challenge if one is needed.

In our test, tokenization succeeds without presenting a challenge, but the immediately following CreateCard operation determines that verification is required.

Same result with legacy verification flow

We also reproduced the issue using the older explicit STORE verification flow:

TOKENIZE_STORE_RETURNED
status: OK
card_brand: VISA
card_type: CREDIT
country: EC
postal_code_present: false
intent: STORE

VERIFY_BUYER_STORE_RETURNED
status: OK
intent: STORE
user_challenged: false

CUSTOMER_LOOKUP_RESULT
status: SUCCESS

CREATE_CARD_REQUEST
source_token_present: true
verification_token_present: true
customer_id_present: true
country: EC

CREATE_CARD
result: FAILED

Square then returned:

{
  "category": "PAYMENT_METHOD_ERROR",
  "code": "CARD_DECLINED_VERIFICATION_REQUIRED",
  "detail": "Card declined. A verification is required to process this payment."
}

Therefore, in the legacy test:

  • verifyBuyer(STORE) returned successfully.

  • A verification token was generated.

  • No challenge was presented (user_challenged: false).

  • The verification token was supplied to CreateCard.

  • CreateCard nevertheless returned CARD_DECLINED_VERIFICATION_REQUIRED.

Important comparison with another Ecuador-issued Visa

We have successfully stored another Ecuador-issued Visa card through Square.

In that successful case, the cardholder was presented with 3DS authentication/verification codes, completed the authentication, and the card was successfully stored on file.

Therefore, this does not appear to be a general inability to store Ecuador-issued Visa cards.

The relevant difference we are observing is:

Successful Ecuador Visa:

3DS challenge presented
→ Cardholder completes verification
→ CreateCard succeeds


Affected Ecuador Visa:

STORE tokenization/verification succeeds
→ No 3DS challenge is presented
→ CreateCard returns
  CARD_DECLINED_VERIFICATION_REQUIRED

Additional troubleshooting already performed

We previously investigated the billing postal code.

For the affected Ecuador Visa, we tested without sending a postal code. The Web Payments SDK successfully tokenizes the card, and our application now allows the request to reach Square’s CreateCard endpoint.

The current CARD_DECLINED_VERIFICATION_REQUIRED response is therefore the actual response received from Square’s Cards API, not an application-side billing-address validation error.

We also confirmed:

Card brand: VISA
Card type: CREDIT
Prepaid: NOT_PREPAID
Country: EC
STORE tokenization: SUCCESS
Buyer verification: SUCCESS in legacy test
user_challenged: false
Customer lookup: SUCCESS
CreateCard request reaches Square: YES
CreateCard result: CARD_DECLINED_VERIFICATION_REQUIRED

Question for Square Engineering

Could you please investigate why Web Payments SDK STORE tokenization does not trigger a 3DS challenge for this card when the immediately following CreateCard request determines that additional verification is required?

Specifically, we would like to understand:

  1. Why does card.tokenize() with intent: "STORE" return a successful token without presenting a 3DS challenge, while CreateCard subsequently returns CARD_DECLINED_VERIFICATION_REQUIRED?

  2. Is the issuer requesting step-up authentication during the $0 card verification performed by CreateCard?

  3. If so, how should our Web Payments SDK integration trigger or satisfy that additional authentication requirement before calling CreateCard?

  4. Is there any additional information from the tokenization or Cards API response that we should capture to diagnose why the authentication remains frictionless during tokenization?

  5. Since another Ecuador-issued Visa successfully triggers 3DS and can be stored, could this behavior be specific to the issuer/card authentication configuration rather than our integration?

We can provide the relevant Square request IDs, customer ID, timestamps, application ID, location ID, and additional API logs privately if needed.

For security reasons, we have intentionally omitted the full PAN, CVV, payment tokens, verification tokens, and card-on-file IDs from this report.

Thank you.

Could you please DM me the following for the test that returned CreateCard result: CARD_DECLINED_VERIFICATION_REQUIRED

  1. Square request id (found in the response header)
  2. application id
  3. customer id
  4. timestamp + timezone

Could you also verify if both Ecuador-issued Visas are issued by the same or different banks?

Hello, sure how can i do that?

Can you please tell me where do I have to find the Squere request ID? Thank you.

FRANK CEDENO

It may be difficult to get the request id post mortem, a timestamp is sufficient and if you have an idempotency key that helps even more!

Hello, I already send you all info by DM, if you haven’t received let me know

Thank you for the extra info. I was able to confirm you are doing everything right on your side. Unfortunately square doesn’t expose the specific reason the card was declined for storing.

Your implementation is passing the relevant fields, including verification_token, so there is no additional client-side parameter we can recommend to force a 3DS challenge. Whether a challenge occurs is determined by Square and the card issuer/network during the authentication flow.

I’ll pass this info along internally and see if I can get a more specific understanding of the issue.

Were you able to confirm with the other card that worked that they are issued by the same bank?

I would also recommend contacting the issuing bank if it is your own card because the decline is occurring on their end.

the banks are

visa 6792 Produbanco

Amex Guayaquil Bank

visa 5974 Pichincha bank

It would be worthwhile to contact the bank having the problem and have them verify why they declined without offering SCA or 3DS.

I don’t think this is the issue, but it might be worth testing on the latest version of the sdk.

Hello,

Following your recommendation, we updated our isolated diagnostic environment to the latest Square PHP SDK and performed a new production test using the current Web Payments SDK verification flow.

I am attaching the complete log for TEST #13.

Environment:

  • Square PHP SDK: 47.0.0.20260916
  • PHP: 8.4.25
  • Environment: Production
  • Web Payments SDK: Production
  • Card: Ecuador-issued Visa Credit ending in 6792
  • Issuer: Produbanco
  • Country: Ecuador (EC)

For this test we used the modern STORE flow:

card.tokenize({
    intent: "STORE",
    billingContact: {
        givenName: "...",
        addressLines: ["..."],
        city: "QUITO",
        state: "pichincha",
        countryCode: "EC"
    },
    customerInitiated: true,
    sellerKeyedIn: false
});

We intentionally did not use the deprecated payments.verifyBuyer() flow.

We also did not send a postal code for Ecuador.

The tokenization completed successfully:

status: OK
card: VISA CREDIT
last4: 6792

The resulting cnon: token was then passed directly to CreateCard using Square PHP SDK 47.

CreateCard returned HTTP 402:

category: PAYMENT_METHOD_ERROR
code: CARD_DECLINED_VERIFICATION_REQUIRED

Card declined. A verification is required to process this payment.

This is particularly important because we have now reproduced the same underlying problem using both verification methods:

Previous test:
card.tokenize() → payments.verifyBuyer(intent: STORE) → verification token successfully returned → CreateCard → CARD_DECLINED_VERIFICATION_REQUIRED

TEST #13:
card.tokenize({ intent: "STORE", customerInitiated: true, sellerKeyedIn: false, ... }) → tokenization successful → CreateCard → CARD_DECLINED_VERIFICATION_REQUIRED

We have also successfully created Cards on File in the same SDK 47 production diagnostic environment with a U.S.-issued card, so the SDK 47 environment, production credentials, location, and CreateCard implementation have been validated independently.

Our main question is:

When Card.tokenize() successfully completes using intent: "STORE" with the modern verification details, but the subsequent CreateCard still returns CARD_DECLINED_VERIFICATION_REQUIRED, what additional verification is Square expecting?

Since the modern flow performs buyer verification during Card.tokenize() and there is no separate verification_token to provide to CreateCard, we would appreciate clarification on what is occurring between the successful STORE tokenization and the CreateCard rejection.

Also, can you confirm whether Square can determine internally if:

  1. A 3DS/SCA challenge was requested or attempted for this STORE operation.
  2. The issuer/network declined or prevented the Card-on-File verification.
  3. Square received any issuer/network response explaining why additional verification was required after the STORE tokenization had already succeeded.
  4. There is any additional diagnostic information or request identifier you can retrieve from the attached timestamps and log.

The complete TEST #13 log is attached, including the tokenization request/response and the CreateCard response.

Thank you,

Log: I will send you the log by DM

Thank you for providing the latest log. We traced this attempt internally.

Square did initiate a 3DS authentication for the affected card. The card issuer’s authentication server rejected the frictionless authentication and did not offer an interactive challenge. Because the authentication was rejected, CreateCard returned CARD_DECLINED_VERIFICATION_REQUIRED.

The OK response from Card.tokenize() means the Web Payments SDK successfully created a secure token containing the authentication result. It does not guarantee that the issuer approved the authentication. The Cards API evaluates that embedded result when CreateCard is called.

Your integration is using the supported modern flow, and there is no additional verification_token or client-side parameter to send. Square also cannot force the issuer to offer a challenge instead of rejecting the authentication. We have both confirmed that a different card succeeds in the same environment, which further indicates that this is specific to the affected card and its issuer.

The cardholder should contact Produbanco and ask why its 3DS authentication was rejected for card-on-file storage, or use another card.

Thank you very much for taking the time to investigate this issue internally and for providing such a detailed explanation. We truly appreciate the time and effort your team has dedicated to helping us understand what is happening.

Your explanation clarified the apparent contradiction we were seeing between successful tokenization and the subsequent CARD_DECLINED_VERIFICATION_REQUIRED response.

I also wanted to share an additional result from our testing with a different Ecuador-issued card, because I believe it may be useful information.

We tested an American Express card issued in Ecuador by Banco Guayaquil.

During our original test with the previous integration/version, Square initiated the 3DS process, but instead of presenting the cardholder with the normal authentication challenge, the browser ended on a white screen displaying the raw 3DS/ACS error response. Among the information displayed was:

errorCode: 403
errorComponent: A
errorDescription: Transient system failure
errorDetail: Transient system failure
errorMessageType: RReq
messageVersion: 2.2.0

After updating our isolated test environment to Square PHP SDK 47 / PHP 8.4 and changing the Web Payments implementation to the current modern STORE flow using:

card.tokenize({
    intent: "STORE",
    customerInitiated: true,
    sellerKeyedIn: false,
    billingContact: ...
})

we tested the same American Express card again.

This time the behavior was different and much better: the 3DS process successfully presented the cardholder with the normal interactive challenge screen requesting the authentication code.

Unfortunately, we could not complete that challenge at that moment because the cardholder was not available to provide the code. We plan to repeat and complete that test when the cardholder is available.

This is interesting to us because we now have two different behaviors with Ecuador-issued cards using the current implementation:

  • American Express / Banco Guayaquil: Square successfully reached an interactive 3DS challenge.
  • Visa / Produbanco: Square initiated 3DS, but as your internal trace confirmed, the issuer’s authentication server rejected the frictionless authentication and did not offer an interactive challenge.

Based on your findings, our next step will be to prepare a technical report for Produbanco. We will explain that Square confirmed through its internal trace that the 3DS authentication was initiated correctly, but Produbanco’s authentication server rejected the frictionless authentication without offering the cardholder an interactive challenge.

This is important for us beyond this individual card. Produbanco is a major Ecuadorian issuer, so our concern is that other Cars4Go customers using Produbanco cards could encounter the same Card-on-File authentication behavior.

We will ask Produbanco to investigate their 3DS authentication side and determine why this Card-on-File authentication is being rejected rather than allowing the cardholder to complete an interactive challenge.

Thank you again for your time, patience, and especially for tracing the affected attempt internally. Your findings have allowed us to stop looking for an additional parameter or integration issue on our side and move the investigation to the appropriate next point: the issuing bank.

Best regards,

This is our internal log for Amex, the first is our fisrt intent , we type a incorrect code witch is the second log

============================================================================

TEST #14 - INICIO
2026-09-28 20:12:58.819 EDT
{
“php_web_runtime”: “8.4.25”,
“sdk”: “47.0.0.20260916”,
“environment”: “production”,
“application_id”: “sq0idp-6B4qzJJ9-Pj8dbsoihZsYQ”,
“location_id”: “42863CWXB158P”
}

[2026-09-28 20:12:58.896 EDT] TEST #14 [0] TEST INITIALIZED IN BROWSER
{
“environment”: “production”,
“application_id”: “sq0idp-6B4qzJJ9-Pj8dbsoihZsYQ”,
“location_id”: “42863CWXB158P”,
“user_agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36”,
“page_url”: “Square SDK 47 Diagnostic”
}
[2026-09-28 20:14:58.418 EDT] TEST #13 [1] TOKENIZE MODERN STORE - REQUEST
{
“environment”: “production”,
“customer_id”: “SNCNZMYJ0VMANZQ8WMPVEFFKN8”,
“cardholder_name”: “josue vazquez”,
“verification_details”: {
“intent”: “STORE”,
“billingContact”: {
“givenName”: “josue vazquez”,
“addressLines”: [
“granda centeno y gregorio vadilla”
],
“city”: “QUITO”,
“state”: “pichincha”,
“countryCode”: “EC”
},
“customerInitiated”: true,
“sellerKeyedIn”: false
}
}

============================================================================

TEST #15 - INICIO
2026-09-28 20:17:58.624 EDT
{
“php_web_runtime”: “8.4.25”,
“sdk”: “47.0.0.20260916”,
“environment”: “production”,
“application_id”: “sq0idp-6B4qzJJ9-Pj8dbsoihZsYQ”,
“location_id”: “42863CWXB158P”
}

[2026-09-28 20:17:58.717 EDT] TEST #15 [0] TEST INITIALIZED IN BROWSER
{
“environment”: “production”,
“application_id”: “sq0idp-6B4qzJJ9-Pj8dbsoihZsYQ”,
“location_id”: “42863CWXB158P”,
“user_agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0”,
“page_url”: “Square SDK 47 Diagnostic”

Feel free to post again if you get feedback on the produbanco side!