# MD for: https://www.mercadopago.com.co/developers/pt/docs/checkout-api-orders/saved-cards.md \# Save cards Save buyer data in your store to speed up future purchases. This configuration allows you to \*\*reuse payment data previously tokenized by the Mercado Pago API\*\*, avoiding the resending of sensitive information in each transaction. It reduces input errors, simplifies the authorization flow and allows the reuse of cards already validated in previous transactions, which tends to avoid rejections due to data inconsistency and increase payment approval rates. Below you'll find the documentation to implement and manage saved cards in your integration. :::::AccordionComponent{title="Create customer and card"} Create the customer and card through the :TagComponent{tag="API" text="Create customer" href="/developers/en/reference/online-payments/checkout-api/customers/create-customer/post"} and :TagComponent{tag="API" text="Save card" href="/developers/en/reference/online-payments/checkout-api/cards/save-card/post"} APIs. To do this, you must use your :toolTipComponent\[Production Access Token\]{content="Private key of the application created in Mercado Pago, used in the backend for production operations. You can access it in Your integrations > Integration data > Production credentials."}. To do so, follow these steps. 1\. Send a \*\*POST\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers" href="/developers/en/reference/online-payments/checkout-api/customers/create-customer/post"} to create the customer. \`\`\`curl curl -X POST \\ 'https://api.mercadopago.com/v1/customers'\\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer ' \\ -d '{ "email": "test@testuser.com", "first\_name": "Jhon", "last\_name": "Doe", "phone": { "area\_code": "55", "number": "991234567" }, "identification": { "type": "CPF", "number": "12345678900" }, "default\_address": "Home", "address": { "id": "123123", "zip\_code": "01234567", "street\_name": "Rua Exemplo", "street\_number": 123, "city": {} }, "date\_registered": "2021-10-20T11:37:30.000-04:00", "description": "Description del user", "default\_card": "None" }' \`\`\` | Field | Description | Required | | :---- | :---- | :---- | | \`email\` | Email address of the customer. If you use test users, the email must follow the format \`test\_payer\_\[0-9\]{1,10}@testuser.com\`. | Required | | \`first\_name\` | Customer's first name. | Optional | | \`last\_name\` | Customer's last name. | Optional | | \`phone\` | Object containing the customer's phone information. | Optional | | \`phone.area\_code\` | Phone area code. | Optional | | \`phone.number\` | Phone number without area code. | Optional | | \`identification\` | Object containing the customer's identification information. | Optional | | \`identification.type\` | Type of identification document (e.g., CPF, DNI, CNPJ). | Optional | | \`identification.number\` | Identification document number. | Optional | | \`default\_address\` | Name of the customer's default address. | Optional | | \`address\` | Object containing the customer's address information. | Optional | | \`address.id\` | Address identifier. | Optional | | \`address.zip\_code\` | Address postal code. | Optional | | \`address.street\_name\` | Street name. | Optional | | \`address.street\_number\` | Address number. | Optional | | \`address.city\` | Object containing the city information. | Optional | | \`date\_registered\` | Customer registration date in ISO 8601 format. | Optional | | \`description\` | Additional customer description. | Optional | | \`default\_card\` | Default card identifier. Can be \`"None"\` if there is no default card. | Optional | 2\. Send a \*\*POST\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/{id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/save-card/post"} with the \*\*Customer ID\*\* (\`customer\_id\`) in the path to perform the association, and the card \`token\` in the \_body\_ of the request. \`\`\`curl curl -X POST \\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer ' \\ 'https://api.mercadopago.com/v1/customers/CUSTOMER\_ID/cards' \\ -d '{"token": "9b2d63e00d66a8c721607214cedaecda"}' \`\`\` | Field | Description | Required | | :---- | :---- | :---- | | \`token\` | \*Token\* generated that securely represents the card's sensitive data. | Required | After successful creation, objects are identified with these prefixes: | Prefix | Description | Example | | :---- | :---- | :---- | | \`customer\` | Customer prefix. | \`custID+xyz123\` | | \`card\` | Card prefix. | \`card\_abc456\` | > For complete details on fields and methods, see the API references: \[Create customer\](https://www.mercadopago.com.co/developers/en/reference/online-payments/checkout-api/customers/create-customer/post) and \[Save card\](https://www.mercadopago.com.co/developers/en/reference/online-payments/checkout-api/cards/save-card/post). The response will return the following result: \`\`\`json { "id": "123456789-jxOV430go9fx2e", "email": "test\_payer@testuser.com", ... "default\_card": "1490022319978", "default\_address": null, "cards": \[{ "id": "1490022319978", "expiration\_month": 12, "expiration\_year": 2020, "first\_six\_digits": "415231", "last\_four\_digits": "0001", ... }\], "addresses": \[\], "live\_mode": false } \`\`\` > WARNING > > If the request response returns an \`invalid parameter\` error with HTTP code 400, check the \`payment\_method\_id\` parameter and make sure the value has been inserted correctly. In addition, when using test users, the customer email must follow the format \`test\_payer\_\[0-9\]{1,10}@testuser.com\`. ::::: :::::AccordionComponent{title="Update customer"} Update any customer information, such as address, card, or email. You can perform this operation using the Mercado Pago API. Send a \*\*PUT\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/{id}" href="/developers/en/reference/online-payments/checkout-api/customers/update-customer/put"} with the \*\*Customer ID\*\* (\`customer\_id\`) in the path and the \*\*attributes to modify\*\* in the \_body\_ of the request. > NOTE > > If you don't have the \`customer\_id\`, send a \*\*GET\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/search" href="/developers/en/reference/online-payments/checkout-api/customers/search-customer/get"} to get the information. Also, the \`email\` field can only be updated if the customer does not yet have an email address associated with their account. \`\`\`curl curl -X PUT \\ 'https://api.mercadopago.com/v1/customers/{id}' \\ -H 'Authorization: Bearer ' \\ -d '{ "email": "test@testuser.com", "first\_name": "john", "last\_name": "wagner", "address": { "zip\_code": "52", "street\_name": "Av. das Nações Unidas", "street\_number": "2" }, "phone": { "area\_code": "11", "number": "001234567" }, "identification": { "type": "CPF", "number": "12341234" }, "description": "Customer information" }' \`\`\` The endpoint accepts modification of \*\*all attributes described in the table below\*\*. | Attribute | Description | | :---- | :---- | | \`address\` | Customer address. | | \`default\_address\` | ID of the customer's default address for shipping. | | \`default\_card\` | ID of the customer's default card for making payments. | | \`description\` | Additional information or notes about the customer. | | \`email\` | Customer email address. Can only be updated if the customer does not yet have an email address associated with their account. | | \`first\_name\` | Customer first name. | | \`last\_name\` | Customer last name. | | \`phone\` | Customer phone number. | | \`identification\` | Customer identification document type and number. | The response will return the following result: \`\`\`json { "id": "xxxxxxxxxxxxxxxxxxxxx", "email": "test@testuser.com", "first\_name": "john", "last\_name": "wagner", "phone": { "area\_code": "11", "number": "001234567" }, "identification": { "type": "CPF", "number": "12341234" }, "address": { "zip\_code": "52", "street\_name": "Av. das Nações Unidas", "street\_number": 2 }, "description": "Customer information", "date\_created": "2021-05-25T15:36:23.541Z", "metadata": {}, "cards": \[ {} \], "addresses": \[ {} \] } \`\`\` > WARNING > > If the \`customer\_id\` parameter is not sent, the response will return the error \`"message": "missing customer id"\`. ::::: :::::AccordionComponent{title="Search customer"} Get specific customer data, such as ID, address, or registration date, through the Customer API. You can perform this operation using the Mercado Pago API. Send a \*\*GET\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/search" href="/developers/en/reference/online-payments/checkout-api/customers/search-customer/get"} specifying the \*\*customer email\*\* as a \*\*query parameter\*\*. \`\`\`curl curl -X GET \\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer ' \\ 'https://api.mercadopago.com/v1/customers/search?email=test@testuser.com' \`\`\` The response will show this result: \`\`\`json { "paging": { "limit": 10, "offset": 0, "total": 1 }, "results": \[ { "address": { "id": null, "street\_name": null, "street\_number": null, "zip\_code": null }, "addresses": \[\], "cards": \[ { ... } \], "date\_created": "2017-05-05T00:00:00.000-04:00", "date\_last\_updated": "2017-05-05T09:23:25.021-04:00", "date\_registered": null, "default\_address": null, "default\_card": "1493990563105", "description": null, "email": "test\_payer@testuser.com", "first\_name": null, "id": "123456789-jxOV430go9fx2e", "identification": { "number": null, "type": null }, "last\_name": null, "live\_mode": false, "metadata": {}, "phone": { "area\_code": null, "number": null } } \] } \`\`\` ::::: :::::AccordionComponent{title="Add new cards to a customer"} Associate additional cards with a registered customer. You can perform this operation using the Mercado Pago API. Send a \*\*POST\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/{customer\_id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/save-card/post"} with the \*\*Customer ID\*\* (\`customer\_id\`) in the path and \*\*card data\*\* in the body of the request. > NOTE > > If you need to delete a card before adding a new one, send a \*\*DELETE\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/{customer\_id}/cards/{id}" href="/developers/en/reference/online-payments/checkout-api/cards/delete-card/delete"} with the Customer ID (\`customer\_id\`) and Card ID (\`id\`). The last card saved automatically becomes the \`DefaultCard\`. \`\`\`curl curl -X POST \\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer ' \\ 'https://api.mercadopago.com/v1/customers/CUSTOMER\_ID/cards' \\ -d '{"token": "9b2d63e00d66a8c721607214cedaecda"}' \`\`\` The response will return the following result: \`\`\`json { "id": "1493990563105", "expiration\_month": 12, "expiration\_year": 2020, "first\_six\_digits": "503175", "last\_four\_digits": "0604", "payment\_method": { "id": "master", "name": "master", "payment\_type\_id": "credit\_card", "thumbnail": "http://img.mlstatic.com/org-img/MP3/API/logos/master.gif", "secure\_thumbnail": "https://www.mercadopago.com/org-img/MP3/API/logos/master.gif" }, "security\_code": { "length": 3, "card\_location": "back" }, "issuer": { "id": 3, "name": "Mastercard" }, "cardholder": { "name": "Card holdername", "identification": { "number": "12345678", "type": "DNI" } }, "date\_created": "2017-05-05T09:22:30.893-04:00", "date\_last\_updated": "2017-05-05T09:22:30.893-04:00", "customer\_id": "255276729-yLOTNHQjpDWw1X", "user\_id": "255276729", "live\_mode": false } \`\`\` ::::: :::::AccordionComponent{title="List cards"} Query all cards associated with a customer. You can perform this operation using the Mercado Pago API. Send a \*\*GET\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/{customer\_id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/get-customer-cards/get"} with the \*\*Customer ID\*\* (\`customer\_id\`) in its path. \`\`\`curl curl -X GET \\ -H 'Authorization: Bearer ' \\ 'https://api.mercadopago.com/v1/customers/CUSTOMER\_ID/cards' \\ \`\`\` The response will be an array with all saved card objects for the customer. \`\`\`json \[{ "id": "1490022319978", "expiration\_month": 12, "expiration\_year": 2020, "first\_six\_digits": "415231", "last\_four\_digits": "0001", ... }\] \`\`\` ::::: :::::AccordionComponent{title="Receive payments with saved cards"} For a customer to make a payment with saved cards, you must capture the \*\*security code (CVV)\*\* of the card again, since Mercado Pago does not store this data for security reasons. You can perform this operation using the Mercado Pago API. ### 1\. Show list of saved cards Show the buyer the list of saved cards so they can choose the desired option. Send a \*\*GET\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/{customer\_id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/get-customer-cards/get"} with the \*\*Customer ID\*\* (\`customer\_id\`) in its path. \`\`\`curl curl -X GET \\ -H 'Authorization: Bearer ' \\ 'https://api.mercadopago.com/v1/customers/CUSTOMER\_ID/cards' \\ \`\`\` ### 2\. Create payment form After showing the saved cards to the buyer, proceed with creating the payment form. This stage allows the buyer to see where they must include the security code (CVV) of the selected card. To perform it, implement the code below directly in your project. \`\`\`html Send \`\`\` ### 3\. Capture security code and create token After showing the saved cards and creating the payment form, the next step is to capture the verification code (CVV) of the card and generate the security token. To do this, you must create a \*token\* by submitting the form with the \*\*card ID\*\* selected by the customer and the \*\*security code (CVV)\*\* using the Javascript code below. \`\`\`javascript const formElement = document.getElementById('form-checkout'); formElement.addEventListener('submit', e => createCardToken(e)); const createCardToken = async (event) => { try { const tokenElement = document.getElementById('token'); if (!tokenElement.value) { event.preventDefault(); const token = await mp.fields.createCardToken({ cardId: document.getElementById('form-checkout\_\_cardId').value }); tokenElement.value = token.id; console.log(tokenElement); } } catch (e) { console.error('error creating card token: ', e) } } \`\`\` ### 4\. Create the payment Once you have obtained the card security \*token\* in the previous stage, the final step is to \*\*create the payment\*\* with the corresponding value. Send a \*\*POST\*\* request to the endpoint :TagComponent{tag="API" text="/v1/orders" href="/developers/en/reference/orders/online-payments/create/post"} including the \`payer.customer\_id\` and \`payment\_method.token\` in the request body, sending the following data. \`\`\`curl curl --request POST \\ --url https://api.mercadopago.com/v1/orders \\ --header 'Content-Type: application/json' \\ --data '{ "type": "online", "external\_reference": "ext\_ref\_1234", "total\_amount": "50.00", "payer": { "customer\_id": "{{CUSTOMER\_ID}}" }, "transactions": { "payments": \[ { "amount": "50.00", "payment\_method": { "id": "{{PAYMENT\_METHOD\_ID}}", "type": "{{PAYMENT\_METHOD\_TYPE}}", "token": "{{CARD\_TOKEN}}", "installments": 1 } } \] } }' \`\`\` | Field | Description | |---|:---:| | \`type\` | Order type. | | \`external\_reference\` | External reference to identify the order. | | \`total\_amount\` | Total order amount. | | \`payer.customer\_id\` | ID of the customer who owns the saved card. | | \`transactions.payments.amount\` | Payment amount associated with the order. | | \`transactions.payments.payment\_method.id\` | Payment method ID. | | \`transactions.payments.payment\_method.type\` | Payment method type. | | \`transactions.payments.payment\_method.token\` | Card token that replaces sensitive data and CVV. | | \`transactions.payments.payment\_method.installments\` | Number of installments for the payment. | ::::: :::::AccordionComponent{title="Delete card"} Perform the deletion of a specific card associated with a saved customer, ensuring data is updated. The operation is available via the Mercado Pago API or through the available SDKs. Send a \*\*DELETE\*\* request to the endpoint :TagComponent{tag="API" text="/v1/customers/{customer\_id}/cards/{id}" href="/developers/en/reference/online-payments/checkout-api/cards/delete-card/delete"} with the \*\*Customer ID\*\* (\`customer\_id\`) and \*\*Card ID\*\* (\`id\`) as path parameters. \`\`\`curl curl -X DELETE \\ 'https://api.mercadopago.com/v1/customers/12123adfasdf123u4u/cards/12123adfasdf123u4u'\\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer ' \\ \`\`\` The response will return this result: \`\`\`json { "id": "8987269652", "expiration\_month": 7, "expiration\_year": 2023, "first\_six\_digits": "503143", "last\_four\_digits": "6351", "payment\_method": { "id": "master", "name": "Mastercard", "payment\_type\_id": "credit\_card", "thumbnail": "http://img.mlstatic.com/org-img/MP3/API/logos/master.gif", "secure\_thumbnail": "https://www.mercadopago.com/org-img/MP3/API/logos/master.gif" }, "security\_code": { "length": 3, "card\_location": "back" }, "issuer": { "id": 24, "name": "Mastercard" }, "cardholder": { "name": "APRO", "identification": { "number": "01234567890", "type": "CPF" } }, "date\_created": "2021-03-16T16:08:21.000-04:00", "date\_last\_updated": "2021-03-16T16:14:40.962-04:00", "customer\_id": "470183340-cpunOI7UsIHlHr", "user\_id": "470183340", "live\_mode": true } \`\`\`