Integração via Mercado Pago para websites
Este modelo permite oferecer Apple Pay no seu site sem gerenciar certificados de pagamento nem descriptografar tokens no seu servidor. Você pode integrar via SDK, usando o SDK de JavaScript do Mercado Pago no frontend para exibir o botão Apple Pay, ou via API, implementando o fluxo no seu backend. Em ambos os casos, o Mercado Pago faz a validação com a Apple e devolve um token pronto para criar o pagamento.
sequenceDiagram
participant C as Comprador
participant V as Site (frontend)
participant MP as Mercado Pago
participant A as Apple
V->>MP: Inicializar Apple Pay
MP->>A: Validar comércio e domínio
A-->>V: Botão Apple Pay disponível
C->>V: Clique em Apple Pay
V->>A: Solicitação de pagamento (Touch ID/Face ID)
A-->>MP: Token do Apple Pay
MP-->>V: Token do Mercado Pago (callback)
V->>V: Enviar token ao backend
V->>MP: Criar pagamento (token + dados)
MP-->>V: Resposta do pagamento
Nesta integração você utiliza o SDK de JavaScript do Mercado Pago no frontend para exibir o botão Apple Pay. O Mercado Pago valida a sessão com a Apple e devolve um token pronto para criar o pagamento no seu backend. Siga os passos a seguir para integrar.
Tendo obtido e configurado os certificados obrigatórios do Apple Developer, inclua o SDK MercadoPago.js na sua página:
<script src="https://sdk.mercadopago.com/js/v2"></script>
Em seguida, inicialize a biblioteca com seu Public Key de testesChave pública da aplicação criada no Mercado Pago, usada no frontend. Você pode acessá-la em Suas integrações > Detalhes da aplicação > Testes > Credenciais de teste.:
javascript
const mp = new MercadoPago('YOUR_PUBLIC_KEY'); const quickCheckoutBuilder = mp.quickCheckout();
- Configure os dados do pagamento e da sessão Apple Pay no seu frontend. A seguir, você pode ver um exemplo de configuração e a descrição dos parâmetros necessários para isso.
const renderApplePayBrick = async (quickCheckoutBuilder) => {
const settings = {
checkoutTypes: ['applePay'],
applePay: {
paymentRequest: {
countryCode: 'BR',
currencyCode: 'BRL',
merchantCapabilities: ['supports3DS'],
supportedNetworks: ['visa', 'masterCard'],
total: {
label: 'Meu produto',
amount: '10.00'
}
},
sessionRequest: {
id: 'PUBLIC_HASH_DE_MERCADO_PAGO',
merchantIdentifier: 'merchant.seu-identificador',
domainName: 'seu-dominio.com',
displayName: 'Minha loja',
initiative: 'web',
initiativeContext: 'seu-dominio.com'
},
customization: {
locale: 'pt-BR'
},
callbacks: {
onReady: async () => {
console.log('Apple Pay pronto');
},
onTokenGenerated: async (token, bin, paymentMethodId) => {
// Envie token, bin e paymentMethodId ao seu backend para criar o pagamento
const response = await fetch('/seu-endpoint/pagar', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token, bin, paymentMethodId })
});
const result = await response.json();
// Redirecionar ou exibir resultado conforme result
},
onCancel: async () => {
console.log('Pagamento cancelado');
},
onError: async (error) => {
console.error('Erro Apple Pay:', error);
}
}
}
};
window.applePayBrickController = await quickCheckoutBuilder.create(
'payment-container',
settings
);
};
renderApplePayBrick(quickCheckoutBuilder);
| Parâmetro | Descrição |
paymentRequest.merchantCapabilities | Capacidades do comercio para o pagamento. Deve incluir obrigatoriamente supports3DS para habilitar a autenticação 3D Secure nas transações com Apple Pay. |
paymentRequest.supportedNetworks | Redes de pagamento aceitas no checkout. Só são suportadas as bandeiras visa e/ou masterCard. |
sessionRequest.id | Hash público que o Mercado Pago entrega após configurar e enviar os certificados no Portal Apple Developer. Identifica a sua sessão Apple Pay perante o Mercado Pago. |
sessionRequest.merchantIdentifier | Identificador único do seu negócio no Apple Pay. Corresponde ao Merchant ID que você criou e configurou no Portal Apple Developer. |
sessionRequest.domainName | Domínio do site onde o botão Apple Pay é exibido. Deve coincidir com o domínio verificado no Portal Apple Developer e onde o arquivo de verificação está publicado em .well-known. |
sessionRequest.displayName | Nome comercial exibido ao usuário durante o fluxo de pagamento Apple Pay, por exemplo na tela de autorização do Touch ID ou Face ID. |
sessionRequest.initiativeContext | Contexto da iniciativa de pagamento na web. Deve ter o mesmo valor que domainName para que a sessão Apple Pay seja validada corretamente. |
- Depois de criar as configurações, defina no seu HTML o contêiner em que o botão Apple Pay será exibido e insira o código a seguir.
html
<div id="payment-container" class="payment-container"></div>
O resultado da exibição do componente deve ser semelhante ao da imagem a seguir.

Personalização visual do botão
Você pode personalizar o estilo do botão, o tipo de texto e o idioma no objeto customization da sua configuração:
javascript
customization: { buttonStyle: 'black', // 'black' | 'white' | 'white-outline' buttonType: 'pay', // 'pay' | 'buy' | 'check-out' | 'plain' | etc. locale: 'pt-BR' // O valor padrão é o idioma e a região configurados atualmente no navegador }
| Opção | Descrição |
buttonStyle | Estilo do botão. Os valores podem ser: black, white ou white-outline. |
buttonType | Tipo de botão exibido. Os valores podem ser: pay, buy, check-out, plain, entre outros. |
locale | Código de idioma. Os valores podem ser: es-ES, pt-BR, en-US, entre outros. |
Quando o comprador autoriza o pagamento com Apple Pay, o callback onTokenGenerated entrega no seu frontend o token, o bin e o paymentMethodId.
Envie esses valores no pagamento ao Mercado Pago por meio dos nossos SDKs. Utilize sua Access Token de testesChave privada da aplicação criada no Mercado Pago, utilizada no backend. Você pode acessá-la em Suas integrações > Detalhes da aplicação > Testes > Credenciais de teste..
<?php
use MercadoPago\Client\Payment\PaymentClient;
use MercadoPago\Client\Common\RequestOptions;
use MercadoPago\MercadoPagoConfig;
MercadoPagoConfig::setAccessToken("YOUR_ACCESS_TOKEN");
$client = new PaymentClient();
$request_options = new RequestOptions();
$request_options->setCustomHeaders(["X-Idempotency-Key: <SOME_UNIQUE_VALUE>"]);
$payment = $client->create([
"transaction_amount" => (float) $_POST['<TRANSACTION_AMOUNT>'],
"token" => $_POST['<TOKEN>'],
"description" => $_POST['<DESCRIPTION>'],
"installments" => $_POST['<INSTALLMENTS>'],
"payment_method_id" => $_POST['<PAYMENT_METHOD_ID>'],
"issuer_id" => $_POST['<ISSUER>'],
"payer" => [
"email" => $_POST['<EMAIL>'],
"identification" => [
"type" => $_POST['<IDENTIFICATION_TYPE>'],
"number" => $_POST['<NUMBER>']
]
]
], $request_options);
echo implode($payment);
?>
import { MercadoPagoConfig, Payment } from '@src/index';
const client = new MercadoPagoConfig({ accessToken: '<ACCESS_TOKEN>', options: { timeout: 5000 } });
const payment = new Payment(client);
payment
.create({
body: {
transaction_amount: 100,
token: '<TOKEN>',
description: '<DESCRIPTION>',
installments: 1,
payment_method_id: '<PAYMENT_METHOD_ID>',
issuer_id: 310,
payer: {
email: '<EMAIL>',
identification: {
number: '12345678909',
type: 'CPF',
},
},
},
}).then(console.log).catch(console.log);
Map<String, String> customHeaders = new HashMap<>();
customHeaders.put("x-idempotency-key", <SOME_UNIQUE_VALUE>);
MPRequestOptions requestOptions = MPRequestOptions.builder()
.customHeaders(customHeaders)
.build();
MercadoPagoConfig.setAccessToken("YOUR_ACCESS_TOKEN");
PaymentClient client = new PaymentClient();
PaymentCreateRequest paymentCreateRequest =
PaymentCreateRequest.builder()
.transactionAmount(request.getTransactionAmount())
.token(request.getToken())
.description(request.getDescription())
.installments(request.getInstallments())
.paymentMethodId(request.getPaymentMethodId())
.payer(
PaymentPayerRequest.builder()
.email(request.getPayer().getEmail())
.firstName(request.getPayer().getFirstName())
.identification(
IdentificationRequest.builder()
.type(request.getPayer().getIdentification().getType())
.number(request.getPayer().getIdentification().getNumber())
.build())
.build())
.build();
client.create(paymentCreateRequest, requestOptions);
require 'mercadopago'
sdk = Mercadopago::SDK.new('YOUR_ACCESS_TOKEN')
custom_headers = {
'x-idempotency-key': '<SOME_UNIQUE_VALUE>'
}
custom_request_options = Mercadopago::RequestOptions.new(custom_headers: custom_headers)
payment_data = {
transaction_amount: params[:transactionAmount].to_f,
token: params[:token],
description: params[:description],
installments: params[:installments].to_i,
payment_method_id: params[:paymentMethodId],
payer: {
email: params[:cardholderEmail],
identification: {
type: params[:identificationType],
number: params[:identificationNumber]
},
first_name: params[:cardholderName]
}
}
payment_response = sdk.payment.create(payment_data, custom_request_options)
payment = payment_response[:response]
puts payment
using System;
using MercadoPago.Client.Common;
using MercadoPago.Client.Payment;
using MercadoPago.Config;
using MercadoPago.Resource.Payment;
MercadoPagoConfig.AccessToken = "YOUR_ACCESS_TOKEN";
var requestOptions = new RequestOptions();
requestOptions.CustomHeaders.Add("x-idempotency-key", "<SOME_UNIQUE_VALUE>");
var paymentRequest = new PaymentCreateRequest
{
TransactionAmount = decimal.Parse(Request["transactionAmount"]),
Token = Request["token"],
Description = Request["description"],
Installments = int.Parse(Request["installments"]),
PaymentMethodId = Request["paymentMethodId"],
Payer = new PaymentPayerRequest
{
Email = Request["cardholderEmail"],
Identification = new IdentificationRequest
{
Type = Request["identificationType"],
Number = Request["identificationNumber"],
},
FirstName = Request["cardholderName"]
},
};
var client = new PaymentClient();
Payment payment = await client.CreateAsync(paymentRequest, requestOptions);
Console.WriteLine(payment.Status);
import mercadopago
sdk = mercadopago.SDK("ACCESS_TOKEN")
request_options = mercadopago.config.RequestOptions()
request_options.custom_headers = {
'x-idempotency-key': '<SOME_UNIQUE_VALUE>'
}
payment_data = {
"transaction_amount": float(request.POST.get("transaction_amount")),
"token": request.POST.get("token"),
"description": request.POST.get("description"),
"installments": int(request.POST.get("installments")),
"payment_method_id": request.POST.get("payment_method_id"),
"payer": {
"email": request.POST.get("cardholderEmail"),
"identification": {
"type": request.POST.get("identificationType"),
"number": request.POST.get("identificationNumber")
},
"first_name": request.POST.get("cardholderName")
}
}
payment_response = sdk.payment().create(payment_data, request_options)
payment = payment_response["response"]
print(payment)
| Elemento | Descrição | Obrigatoriedade |
Authorization | Header com seu Access Token de testeChave privada da aplicação criada no Mercado Pago e que é utilizada no backend. Você pode acessá-la através de Suas integrações > Dados da integração > Testes > Credenciais de teste.. | Obrigatório |
X-Idempotency-Key | Valor único por solicitação (por exemplo, UUID v4) para evitar pagamentos duplicados. | Obrigatório |
token | Card token recebido no callback onTokenGenerated. | Obrigatório |
payment_method_id | Identificador do meio de pagamento: visa ou master. | Obrigatório |
transaction_amount | Valor da transação. | Obrigatório |
installments | Quantidade de parcelas. | Obrigatório |
payer | Dados do comprador. | Obrigatório |
description | Descrição do pagamento. | Obrigatório |
issuer_id | ID do emissor do cartão. | Opcional |
A API devolve uma resposta com estrutura semelhante ao exemplo a seguir:
json
{ "status": "approved", "status_detail": "accredited", "id": 3055677, "date_approved": "2019-02-23T00:01:10.000-04:00", "payer": { ... }, "payment_method_id": "visa", "payment_type_id": "credit_card", "refunds": [], ... }
Você pode simular diferentes cenários de pagamento em ambiente de testes usando a propriedade testStatus na configuração do Apple Pay. Ela só tem efeito quando você usa uma Public Key de testesChave pública da aplicação criada no Mercado Pago, usada no frontend. Você pode acessá-la em Suas integrações > Detalhes da aplicação > Testes > Credenciais de teste..
testStatus é opcional e deve ser usada apenas para testes. Em produção, não inclua esta configuração.- Adicione a propriedade
testStatusdentro deapplePayna sua configuração. Use os diferentes valores possíveis detalhados na tabela para simular cenários de pagamento.
javascript
const settings = { checkoutTypes: ['applePay'], applePay: { paymentRequest: { /* ... */ }, sessionRequest: { /* ... */ }, callbacks: { /* ... */ }, testStatus: 'APRO' // Opcional: apenas para testes } };
Valor testStatus | Cenário de pagamento |
APRO | Pagamento aprovado |
OTHE | Rejeitado por erro geral |
CONT | Pendente de pagamento |
CALL | Rejeitado com validação para autorizar |
FUND | Rejeitado por valor insuficiente |
SECU | Rejeitado por código de segurança inválido |
EXPI | Rejeitado por data de vencimento |
FORM | Rejeitado por erro de formulário |
CARD | Rejeitado por falta de card_number |
INST | Rejeitado por parcelas inválidas |
DUPL | Rejeitado por pagamento duplicado |
LOCK | Rejeitado por cartão desabilitado |
CTNA | Rejeitado por tipo de cartão não permitido |
ATTE | Rejeitado por tentativas excedidas do PIN |
BLAC | Rejeitado por estar na lista negra |
UNSU | Não suportado |
TEST | Usado para aplicar regra de valores |
