@tiendanube/checkout-payment-lib
v1.35.0
Published
- Toda lógica principal deve estar contida dentro de **LoadCheckoutPaymentContext** - ES5 válido (Pode ser compilado ou o que for, mas é importante ter em conta os browser que damos suporte e não utilizar métodos sem polyfills - inclusive abrimos algun
Downloads
1,313
Readme
Payment Lib
Required Implementations
- Toda lógica principal deve estar contida dentro de LoadCheckoutPaymentContext
- ES5 válido (Pode ser compilado ou o que for, mas é importante ter em conta os browser que damos suporte e não utilizar métodos sem polyfills - inclusive abrimos alguns métodos com polyfills para auxiliar no desenvolvimento)
LoadCheckoutPaymentContext
Este método é exposto em um contexto global através de window.LoadCheckoutPaymentContext, ele é responsável por efetuar o carregamento de todos Plugins dos partners.
Ele espera como parâmetro um método que conterá todo o código do Plugin que é esperado que seja executado dentro do Checkout React.Esse método recebe 2 argumentos como no exemplo a seguir:
LoadCheckoutPaymentContext(function (Checkout, PaymentMethods) {
// Your plugin implementation
}) O método LoadCheckoutPaymentContext recebe 2 parâmetros, que são:
Checkout - Contém os dados e métodos responsáveis por interagir com os componentes do checkout
PaymentMethods - Instâncias pré-definidas de como cada tipo de pagamento deve se comportar Cada um desses parâmetros é responsável por controlar como o checkout e seus componentes irá comportar, eles também permitem ao plugin execução de
Ajax Callsou por exemplo utilização de dados do carrinho comoLineItems. A seguir eles serão mais detalhados.
Checkout [argument]
O parâmetro de Checkout é repsonsável por todo comportamento e interação com o Checkout, e possui os seguintes objetos:
| Nome | Descrição | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | updateFields | Atualiza a exibição dos inputs opcionais do checkout. Lista de fields | | addPaymentOption | Adiciona o método criado ao checkout | | closeAlert | Fecha o alerta de erro no Checkout, caso este esteja aberto. | | setInstallments | Atualiza o array com as opções de parcelamento. Exemplo | | changePaymentBenefit | Altera o texto de benefício (desconto/parcelamento) exibido na opção de pagamento registrada por este script. Exemplo | | getData | Obtém os dados do carrinho (endereço, dados do form de pagamento, email, país, etc). Abaixo exibiremos um exemplo completo do objeto | | http | Objeto utilizado para fazer ajax calls | | utils | Objeto com funções auxiliar, as funções auxiliares estão listadas abaixo |
- Throttle
- LoadScript
- FlattenObject
getData
exemplo do objeto data:
{
form: {},
order: {
cart: {
id: 164943094,
hash: '640a1214704c0470410d0f0712ca4fe8efb9e5b1',
number: null,
prices: {
shipping: '0.00',
discount_gateway: 0,
discount_coupon: 1.99,
discount_promotion: 0,
discount_coupon_and_promotions: 1.99,
subtotal_with_promotions_and_coupon_applied: 0,
subtotal: 1.99,
total: 0,
total_usd: 0
},
lineItems: [
{
id: 180289687,
name: 'Barato do dia',
price: '1.99',
quantity: 1,
free_shipping: false,
product_id: 42077389,
variant_id: 108691186,
thumbnail: '//d26lpennugtm8s.cloudfront.net/stores/947/640/products/61193340_2332461190364712_7945763697455005696_n1-2cdc274080e83dfe2f15708278623450-100-0.jpg',
variant_values: '',
sku: null,
properties: [],
url: 'https://prefixnot2.lojavirtualnuvem.com.br/produtos/barato-do-dia/?variant=108691186'
}
],
currency: 'BRL',
currencyFormat: {
'short': 'R$%s',
'long': 'R$%s'
},
lang: 'pt',
langCode: 'pt_BR',
coupon: {
id: 535091,
code: 'NOT100',
type: 'percentage',
value: '100.00',
valid: true,
used: 0,
max_uses: null,
start_date: null,
end_date: null,
min_price: null,
categories: null
},
shipping: {
type: 'ship',
method: 'correios',
option: '04510',
branch: null,
disabled: null,
raw_name: 'Correios - PAC',
suboption: null
},
status: {
order: 'open',
order_cancellation_reason: null,
fulfillment: 'unpacked',
payment: 'pending'
},
completedAt: null,
line_items: [
{
id: 180289687,
name: 'Barato do dia',
price: '1.99',
quantity: 1,
free_shipping: false,
product_id: 42077389,
variant_id: 108691186,
thumbnail: '//d26lpennugtm8s.cloudfront.net/stores/947/640/products/61193340_2332461190364712_7945763697455005696_n1-2cdc274080e83dfe2f15708278623450-100-0.jpg',
variant_values: '',
sku: null,
properties: [],
url: 'https://prefixnot2.lojavirtualnuvem.com.br/produtos/barato-do-dia/?variant=108691186'
}
]
},
shippingAddress: {
zipcode: '31330290',
first_name: 'João',
last_name: 'Cesar',
address: 'Avenida Miguel Perrela',
number: '123',
floor: '',
locality: 'Castelo',
city: 'Belo Horizonte',
state: 'Minas Gerais',
country: 'BR',
phone: '',
between_streets: null,
reference: null
},
billingAddress: {
id_number: '12345678910',
zipcode: '31330000',
first_name: 'João',
last_name: 'Cesar',
address: 'Avenida Miguel Perrela',
number: '123',
floor: '',
locality: 'Castelo',
city: 'Belo Horizonte',
state: 'Minas Gerais',
country: 'BR',
phone: ''
},
contact: {
name: 'João Cesar',
email: '[email protected]',
phone: '31999999999',
}
},
country: 'BR',
totalPrice: 21,
storeId: 947640,
callbackUrls: {
success: 'https://acmestore.lojavirtualnuvem.com.br/checkout/v3/success/194667243/a69f9c70eade480302bf9544452f9b92c528624e',
failure: 'https://acmestore.lojavirtualnuvem.com.br/checkout/v3/next/194667243/a69f9c70eade480302bf9544452f9b92c528624e',
cancel: 'https://acmestore.lojavirtualnuvem.com.br/checkout/v3/next/194667243/a69f9c70eade480302bf9544452f9b92c528624e'
},
installments: null
}Exemplo da utilização do método getData no script de pagamento:
LoadCheckoutPaymentContext(function (Checkout, PaymentMethods) {
var Credit = PaymentMethods.Transparent.CardPayment({
id: 'credit',
name: 'credit',
onSubmit: function() {
// Obtem todos os dados do objeto de data que vimos acima
var data = Checkout.getData()
// Obtem apenas os dados da chave `form` do objeto de data
var form = Checkout.getData('form')
}
});
});http
exemplo:
Checkout.http.post('/checkout/payment/', {
cartId: cartId,
cartHash: cartHash,
endpoint: 'transparent',
method: 'moip'
}).then(function (response) {
// do something with response
});PaymentMethods [argument]
Cada método tem uma pré-configuração, abaixo temos a listagem de todos tipos de pagamento disponíveis:
| Nome | Descrição | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | CustomPayment | Classe contendo os métodos e configurações para o tipo de pagamento custom | | ModalPayment | Classe contendo os métodos e configurações para o tipo de pagamento modal | | RedirectPayment | Classe contendo os métodos e configurações para o tipo de pagamento redirect | | Transparent | Classe contendo os métodos e configurações para o tipo de pagamento transparent. O método transparente possi as seguintes subclasses: |
- CardPayment
- DebitPayment
- BankDebitPayment
- BoletoPayment
- TicketPayment
- WireTransferPayment
- PixPayment
- QrCodePayment
- WalletPayment
A diferença entre as classes dos métodos é o template e os inputs disponíveis em cada um. Lista de inputs
Exemplo utilizando CustomPayment
LoadCheckoutPaymentContext(function (Checkout, PaymentMethods) {
var Custom = PaymentMethods.CustomPayment({
id: 'custom',
name: 'custom'
});
Checkout.addPaymentOption(Custom);
});Se o método em questão for Transparent a instância deve ser invocada utilizando uma das subclasses. Ex:
var Credit = PaymentMethods.Transparent.CardPayment({
id: 'acme_credit'
});Parâmetros das instancias dos PaymentMethods:
No exemplo acima passamos apenas o id, abaixo iremos mostrar a lista completa.
fields
Utilizado para indicar quais inputs opcionais do checkout estarão habilitados. A lista de campos depende do template.
CardPayment:
| Nome | Descrição | Tipo | Exemplo | | ---------------------- | -------------------------- | ------- | ---------------------------------- | | bankList | Lista de bancos | array | [{ name: 'Bank1', code: '23' }...] | | issuerList | Lista de bancos (AR) | array | [{ name: 'Itau', id: '11' }...] | | card_holder_id_types | Lista de tipo de documento | array | [{ name: 'DNI', code: 'DNI' }, { name: 'CPF', code: 'CPF' }, { name: 'CNPJ', code: 'CNPJ' }, { name: 'CI', code: 'CI' }, { name: 'LC', code: 'LC' }, { name: 'LE', code: 'LE' }, { name: 'Otro', code: 'Otro'}] | | card_holder_id_number | Documento | boolean | true or false | | card_holder_birth_date | Data de aniversário | boolean | true or false | | card_holder_phone | Telefone | boolean | true or false |
DebitPayment:
| Nome | Descrição | Tipo | Exemplo | | ---------------------- | ----------------- | ------- | ---------------------------------- | | bank_list | Lista de bancos | array | [{ name: 'Bank1', code: '23' }...] | | debit_card_holder_name | Nome do comprador | boolean | true or false | | debit_card_id_number | Documento | boolean | true or false |
BoletoPayment:
| Nome | Descrição | Tipo | Exemplo | | ------------------ | ----------------- | ------- | ------------------------------------------- | | boleto_holder_name | Nome do comprador | boolean | true or false | | boleto_id_number | Documento | boolean | true or false | | efectivo_list | ? | array | [{ name: 'Rapipago', code: 'rapipago' }...] |
PixPayment:
| Nome | Descrição | Tipo | Exemplo | | ------------------ | ----------------- | ------- | ------------------------------------------- | | holder_name | Nome do comprador | boolean | true or false | | holder_id_number | Documento (CPF) | boolean | true or false |
Geral
| Nome | Descrição | Tipo | Exemplo | | ------------------ | ------------------------ | ------- | ----------------------- | | billing_address | Endereço de faturamento | boolean | true or false | | cardBrands | Lista de bandeiras de cartões | object/array | { credit_card: ['visa', ...]... } |
Lista completa de bandeiras de cartões disponiveis: [ 'amex'', 'argencard', 'aura', 'bapropagos', 'cabal', 'cabaldebit', 'cencosud', 'cobroexpress', 'dinersclub', 'discover', 'elo', 'hiper', 'hipercard', 'iltalcred', 'jcb', 'maestro', 'magna', 'mastercard', 'nativa', 'pagofacil', 'rapipago', 'tarjeta-naranja', 'tarjeta-shopping', 'todopago', 'unionpay', 'visa', 'visadebit' ]
Exemplo informando as bandeiras de cartão:
var Credit = PaymentMethods.Transparent.CardPayment({
id: 'credit',
name: 'credit',
fields: {
cardBrands: {
credit_card: ['visa', 'mastercard', 'elo', 'discover']
}
}
});As bandeiras de cartões são exibidas como imagens no checkout, ao acessar o meio de pagamento em questão
Exemplo ativando data de aniversário e telefone ao form:
var Credit = PaymentMethods.Transparent.CardPayment({
id: 'credit',
name: 'credit',
fields: {
card_holder_birth_date: true,
card_holder_phone: true
}
});Não é necessário informar o input como false, basta não informar que ele não será exibido.
Caso deseje atualizar um campo do formulário após a inicialização do script, você pode utilizar o método updateFields que faz parte do objeto Checkout.
Exemplo:
var Credit = PaymentMethods.Transparent.CardPayment({
id: 'credit',
name: 'credit',
onLoad: function() {
Checkout.updateFields({
method: 'credit', // Este valor é o valor do id inserido
value: { card_holder_birth_date: true }
});
}
});scripts
Utilizado para carregar algum script externo dependente, antes de add o método ao checkout.
onLoad
Função executada após o método ser adicionado.
onDataChange
Função executada sempre que algum dado do carrinho é alterado
onSubmit
Função executada quando o usuário clica em "Finalizar pedido" e todos os campos obrigatórios do carrinho foram preenchidos corretamente
A função onSubmit recebe um parâmetro chamado callback, este parâmetro é uma função que é utilizada para retornar ao checkout as informações sobre o processo de pagamento.
A função callback pode ser invocada passando um objeto como parâmetro, esse objeto aceita as seguintes chaves:
| Nome | Descrição |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| success | Se esta chave for passada como true, o checkout ira atualizar o pedido com as demais chaves passadas abaixo, se for passado false, o checkout irá exibir uma mensagem de erro ao usuário, a mensagem de erro pode ser definida na chave message |
| message | Mensagem exibida ao usuário quando o pagamento falha, a chave success deve ser passada como false |
| close | Fecha o pedido (true or false) |
| confirmed | Indica se o pagamento do pedido foi confirmado (true or false) |
| recovered | ? |
| extraBoletoUrl | url do boleto gerado (string) |
| extraAuthorized | ? |
| redirect | url de redirecionamento para o gateway de pagamento (string) |
| skipRedirect | Não realiza o redirecionamento no checkout, neste caso o redirecionamento deve ser feito diretamente no script |
Exemplo:
LoadCheckoutPaymentContext(function (Checkout, PaymentMethods) {
var Custom = PaymentMethods.CustomPayment({
id: 'custom',
name: 'custom',
scripts: 'https://meuscriptonline.com/payment.js',
onLoad: function() {
// do something after the script loads
// Example: generate a token
},
onDataChange: Checkout.utils.throttle(function () {
// do something when data change
// data changed is already available on `Checkout.getData()`
// Example: update credit card installments when order value change
}, 700),
onSubmit: function (callback) {
// do something when user submit payment
callback({
success: true/false,
...
})
}
});
Checkout.addPaymentOption(Custom);
});Checkout form data
Os dados do formulário do checkout podem ser encontrados no objeto Checkout.getData('form'), os possíveis dados são:
CardPayment:
| Nome | Descrição | Opcional | Opção correspondente |
| ------------------- | ---------------------------------------- | -------- | ---------------------- |
| cardNumber | número do cartão | Não | |
| cardHolderName | nome do titular do cartão | Não | |
| cardExpiration | data de expiração do cartão. ex: 12/20 | Não | |
| cardCvv | código de verificação do cartão | Não | |
| cardInstallments | número de parcelas | Não | |
| cardHolderIdNumber | documento do comprador | Sim | card_holder_id_number |
| cardHolderBirthDate | data de aniversário do comprador | Sim | card_holder_birth_date |
| cardHolderPhone | telefone do comprador | Sim | card_holder_phone |
| bankId | Instituição bancaria | Sim | bankList |
| issuerId | Instituição bancaria (Argentina) | Sim | issuerList |
| cardHolderIdType | Tipo do documento | Sim | card_holder_id_types |
DebitPayment:
| Nome | Descrição | Opcional | Opção correspondente | | -------------- | ---------------------- | -------- | ---------------------- | | bank | Instituição bancaria | Sim | bank_list | | holderName | Nome do comprador | Sim | debit_card_holder_name | | holderIdNumber | Documento do comprador | Sim | debit_card_id_number |
BoletoPayment:
| Nome | Descrição | Opcional | Opção correspondente | | -------------- | ---------------------------------------- | -------- | -------------------- | | holderName | Nome do comprador | Sim | boleto_holder_name | | holderIdNumber | Documento do comprador | Sim | boleto_id_number | | brand | Valor do select de efectivo (Somente AR) | Sim | efectivo_list |
As classes CustomPayment, ModalPayment e RedirectPayment não possuem inputs, pois o pagamento é realizado externamente. A diferença entre estes métodos é sua categorização e a exibição no checkout.
Parcelas
Para atualizar as parcelas do cartão de credito no checkout utilizamos o método setInstallments, exemplo:
O objeto dentro do array de installments deve ter as seguintes chaves:
| Nome | Descrição | | ----------------- | ----------------- | | quantity | número da parcela | | installmentAmount | Valor da parcela | | totalAmount | Valor total |
const installments = [{
quantity: 1,
installmentAmount: 25,
totalAmount: 25
}, {
quantity: 2,
installmentAmount: 13,
totalAmount: 26
}, {
quantity: 3,
installmentAmount: 10,
totalAmount: 30
}]
Checkout.setInstallments(installments)
Credit Card Payment Without Leaving the Checkout
LoadCheckoutPaymentContext(function(Checkout, PaymentMethods) {
var currentTotalPrice = Checkout.getData('order.cart.prices.total');
var currencCreditCardBin = null;
var getCardNumber = function () {
return Checkout.getData('form.cardNumber') || '';
};
var getCardNumberBin = function () {
return getCardNumber().substring(0, 6);
};
var refreshInstallments = function () {
var creditCardBin = getCardNumberBin();
var hasCreditCardBin = creditCardBin && creditCardBin.length >= 6;
var hasPrice = Boolean(Checkout.getData('totalPrice'));
var changedCreditCardBin = creditCardBin !== currencCreditCardBin;
var changedPrice = Checkout.getData('totalPrice') !== currentTotalPrice;
return (hasCreditCardBin && hasPrice) && (changedCreditCardBin || changedPrice);
};
var getInstallments = function() {
Checkout.http.post('https://app.acmepayments.com/installments', {
amount: Checkout.getData('totalPrice'),
bin: getCardNumberBin()
}).then(function (response) {
Checkout.setInstallments(response);
})
}
// Define an object to encapsulate the integration
var AcmeTransparentCredit = PaymentMethods.Transparent.CardPayment({
id: 'acme_credit',
name: 'ACME Credit Payment',
// This function will be called everytime a data on checkout change
onDataChange: Checkout.utils.throttle(function () {
if (refreshInstallments()) {
getInstallments()
} else if (!getCardNumberBin()) {
// Clear installments if customer remove credit card number
Checkout.setInstallments(null);
}
}, 700),
// This function will be called when the consumer finishes the checkout flow so you can initiate the transaction
onSubmit: function(callback) {
// Let's imagine the app providies this endpoint to proccess credit payments
Checkout.http.post('https://app.acmepayments.com/credit-payment', Checkout.getData('form'))
.then(function(response) {
// Now that we have the ACME Payments checkout, invoke the callback telling it we want to close order
callback({
success: true,
close: true,
confirmed: true
});
})
.catch(function(error){
// Handle a potential error in the http request
callback({
success: false
});
});
}
});
// Register the object in the checkout
Checkout.addPaymentOption(AcmeTransparentCredit);
});changePaymentBenefit
Altera dinamicamente o texto de benefício (desconto, parcelamento, "sem juros", etc.) exibido
abaixo do título da opção de pagamento, para um gateway adicionado por este script via
Checkout.addPaymentOption.
Equivale, dentro do contexto do PaymentLib, ao window.SDKCheckout.changePaymentBenefit que
o lojista usa do lado do tema. Os dois caminhos convergem para o mesmo estado
(partners.customBenefits), então o último a chamar vence.
Contrato
Checkout.changePaymentBenefit({
id: 'acme_credit', // string: id usado em PaymentMethods.X({ id })
value: '12x sem juros' // string: texto exibido como benefício
});iddeve ser o mesmoidpassado a umPaymentMethods.X({ id })já registrado viaCheckout.addPaymentOptionneste script. Ids não registrados são ignorados e logados.idevalueprecisam ser strings. Payloads inválidos são ignorados e logados.- Chamadas repetidas para o mesmo
idsobrescrevem o valor anterior. - Deve ser chamado depois de
addPaymentOption— tipicamente emonLoadouonDataChange.
Uso mínimo
LoadCheckoutPaymentContext(function (Checkout, PaymentMethods) {
var Credit = PaymentMethods.Transparent.CardPayment({
id: 'acme_credit',
name: 'ACME Credit',
onLoad: function () {
Checkout.changePaymentBenefit({
id: 'acme_credit',
value: '12x sem juros'
});
}
});
Checkout.addPaymentOption(Credit);
});Atualização dinâmica com onDataChange
LoadCheckoutPaymentContext(function (Checkout, PaymentMethods) {
var Credit = PaymentMethods.Transparent.CardPayment({
id: 'acme_credit',
name: 'ACME Credit',
onDataChange: Checkout.utils.throttle(function () {
var total = Checkout.getData('totalPrice');
var label = total >= 200 ? '12x sem juros' : '3x sem juros';
Checkout.changePaymentBenefit({
id: 'acme_credit',
value: label
});
}, 700)
});
Checkout.addPaymentOption(Credit);
});Múltiplos gateways do mesmo parceiro
LoadCheckoutPaymentContext(function (Checkout, PaymentMethods) {
var Credit = PaymentMethods.Transparent.CardPayment({ id: 'acme_credit' });
var Pix = PaymentMethods.Transparent.PixPayment({ id: 'acme_pix' });
Checkout.addPaymentOption(Credit);
Checkout.addPaymentOption(Pix);
Checkout.changePaymentBenefit({ id: 'acme_credit', value: '10% OFF em 1x' });
Checkout.changePaymentBenefit({ id: 'acme_pix', value: '15% OFF no Pix' });
});Utils
- Http (Já com suporte a promises, controle de CSRF com headers pré configurados)## Otimizações
- Hoje expomos alguns métodos que não deveriam estar disponíveis para nossos integrantes, no futuro deveríamos exibir somente o necessário.
- Mover o método http para dentro do objeto de utils
