r-martins / PagSeguro-Magento-Transparente

Módulo de checkout transparente para Pagseguro - com api v. 2.0
GNU General Public License v2.0
66 stars 0 forks source link

Problema com falha de pagamento Cartão - Encontrei o motivo #172

Closed fchiqueto closed 8 years ago

fchiqueto commented 8 years ago

Olá a todos, estou já ha algum tempo com problema ao cliente fechar um pedido com cartão, da falha de pagamento junto ao pagseguro.

Tirei o dia para fazer testes e encontrei o motivo, utilizo OSC 6 ultima versão do github + magento 1.9.2.2 e o modulo pro do @r-martins .

Durante o processo de finalizar a compra se o cliente escolher uma forma de envio e preencher os dados do cartão é carregado a bandeira do cartão, porem se o mesmo trocar a forma de envio a bandeira some no refresh do OSC6 ai ao clicar em finalizar ocorre o erro no pagseguro.js: 92,93 conforma a imagem abaixo: ss

Só volta a funcionar se atualizar a página e preencher corretamente os dados > forma de envio > meio de pagamento > concluir pedido.

Mesmo apagando o numero do cartão e digitando o mesmo novamente não carrega a bandeira e da erro.

Só é registrado isso no log e nada mais:

2016-07-08T20:56:45+00:00 DEBUG (7): Falha ao obter o token do cartao ou sender_hash. Veja se os dados "sender_hash" e "credit_card_token" foram enviados no formulário. Um problema de JavaScript pode ter ocorrido. Se esta for apenas uma atualização de blocos via ajax não se preocupe.

Queria saber de quem tem esse erro para testar para ver se confere e se alguém tiver resolvido posta aqui como fez por favor, obrigado

r-martins commented 8 years ago

@fchiqueto não consegui simular fazendo o que falou na loja demo com osc

Consegue simular e passar o passo-a-passo pra chegar no problema? Será que você não está usando algum tema ou algum js que tente adicionar máscara no campo de cartão?

Pelo que vi, o do deivison não faz isso.

r-martins commented 8 years ago

Como disse, depois consegui simular. Estou vendo uma forma de arrumar sem ter que mexer no checkout do Deivison. Mas a princípio, se chamar

RMPagSeguro.updateSessionId();

antes da finalização do checkout ou antes do submit dos ajax dos eventos de savePayment do payment.js do Deivison, resolve todos os problemas.

fchiqueto commented 8 years ago

Obrigado Ricardo, fico no aguardo então eu não consigo inserir esse código sem dar algum outro tipo de erro, não tenho a habilidade para isso e olha que eu tentei rsrs...

Em 8 de julho de 2016 21:42, Ricardo Martins notifications@github.com escreveu:

Como disse, depois consegui simular. Estou vendo uma forma de arrumar sem ter que mexer no checkout do Deivison. Mas a princípio, se chamar

RMPagSeguro.updateSessionId();

antes da finalização do checkout ou antes do submit dos ajax dos eventos de savePayment do payment.js do Deivison, resolve todos os problemas.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/r-martins/PagSeguro-Magento-Transparente/issues/172#issuecomment-231503669, or mute the thread https://github.com/notifications/unsubscribe/AQxP0PZ1AU6vdgSf9ayZ0XdIMVbz4EOFks5qTu5tgaJpZM4JIZ_j .

fchiqueto commented 8 years ago

Boa tarde Ricardo,

Nenhuma novidade sobre o erro ao trocar de frete? Você poderia me enviar o arquivo com o RMPagSeguro.updateSessionId para eu ver como você fez? Fiquei tentando inserir sem sucesso o código e perdemos vendas novamente :( Em 09/07/2016 00:03, "Fernando Gustavo Chiqueto" chiqueto.x@gmail.com escreveu:

Obrigado Ricardo, fico no aguardo então eu não consigo inserir esse código sem dar algum outro tipo de erro, não tenho a habilidade para isso e olha que eu tentei rsrs...

Em 8 de julho de 2016 21:42, Ricardo Martins notifications@github.com escreveu:

Como disse, depois consegui simular. Estou vendo uma forma de arrumar sem ter que mexer no checkout do Deivison. Mas a princípio, se chamar

RMPagSeguro.updateSessionId();

antes da finalização do checkout ou antes do submit dos ajax dos eventos de savePayment do payment.js do Deivison, resolve todos os problemas.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/r-martins/PagSeguro-Magento-Transparente/issues/172#issuecomment-231503669, or mute the thread https://github.com/notifications/unsubscribe/AQxP0PZ1AU6vdgSf9ayZ0XdIMVbz4EOFks5qTu5tgaJpZM4JIZ_j .

r-martins commented 8 years ago

Oi @fchiqueto Ainda não consegui nesse fds. Os preparativos pro casamento não me deixaram tempo livre. Segue o arquivo do payment.js do Deivison com minhas alterações. Não é o jeito ideal. Quero encontrar um jeito de ajustar isso dentro do modulo, mas por enquanto deve lhe atender.

skin/frontend/base/default/onestepcheckout/js/payment.js Abs

payment.js.zip

fchiqueto commented 8 years ago

Obrigado @r-martins eu upei o arquivo fiz as limpezas nos caches etc mais mesmo assim não funcionou ainda persiste o erro, aguardo modificação no modulo mesmo.

perrera commented 8 years ago

As Issues 161, 171 e 172 são o mesmo problema. O fchiqueto conseguiu descrever o passo a passo do erro. É exatamente isso que ocorre na Issue 161 que eu abri. Quando o erro ocorre comigo ele não volta a funcionar. Mesmo se eu recarregar a página. Ele só volta a funcionar se editar o campo do número do cartão de crédito. O que eu fiz foi apagar o ultimo numero do cartão de crédito e digitar novamente. Então eu clico em finalizar a compra por duas vezes e ele gera o pedido.

fchiqueto commented 8 years ago

@perrera no meu caso funciona se atualizar a página já que limpa os campos e ao digitar o nº do cartão ele carrega a bandeira novamente, mais se trocar de frete da o refresh ai já não funciona. Acredito que as issues #163 e #157 também sejam relacionadas a essa. No caso da #163 pode ser ao trocar de frete mesmo escolhendo boleto o mesmo não é gerado, estou sem loja teste para tirar essa dúvida no momento, o @r-martins já está resolvendo essa issue e acredito que resolva todas as outras por sequencia.

r-martins commented 8 years ago

Mais difícil do que imaginei. Ainda não achei o evento certo pra corrigir para todos os cenários.

LucasGusmao commented 8 years ago

Boa noite galera!

Estou sendo assolado por este erro a um tempo, acredito que já perdi cerca de 50k de pedidos reais devido a este erro!

Tirei o dia para entende-lo e acho que agora com umas 15 horas de trabalho na causa consegui arrumar!

Quando você troca o método de entrega após o preenchimento dos dados do cartão de crédito, os valores dos hiddens "payment[sender_hash]" e "payment[credit_card_token]" são apagados, não por uma instrução Javascript mas por um comportamento padrão do html dentro do escopo em que são declarados.

O @r-martins já havia feito uma function Javascript para corrigir a parte do sender_hash( RMPagSeguro.reCheckSenderHash ), porém o credit_card_token não era recarregado.

Utilizei da mesma function, que checa o conteúdo do sender_hash, para checar também o conteúdo do credit_card_token e caso seja vazio executa a function RMPagSeguro.updateCreditCardToken(); para popula-lo novamente.

Do ponto de vista de padrão de projeto não é uma boa solução, pois a function não foi desenhada para isto, mas era a forma de editar de maneira não oficial a menor quantidade de código, para ser mais fácil aplicar depois a solução definitiva escolhida pelo @r-martins .

A primeira vista parece criar uma referência circular já que reCheckSenderHash chama updateCreditCardToken e updateCreditCardToken chama reCheckSenderHash, mas a situação não ocorre divido as verificações se houve sucesso em obter o token e se o conteúdo está correto na hora de gera-lo.

Segue o trecho do código como ficou.

RMPagSeguro.reCheckSenderHash = function() { if($$('input[name="payment[sender_hash]"]').first().value == '') { RMPagSeguro.updateSenderHash(); } if($$('input[name="payment[credit_card_token]"]').first().value == '') { RMPagSeguro.updateCreditCardToken(); } }

fchiqueto commented 8 years ago

Opa, testei aqui e funcionou @LucasGusmao pelo menos nessa simulação em trocar o frete após ter preenchido os dados do cartão, estou sem loja teste então foi na online mesmo e funcionou. Você utiliza qual método de checkout?

Obrigado pelo esforço!

LucasGusmao commented 8 years ago

É @fchiqueto , eu também fiz tudo live em ambiente de prod.

Eu utilizo o OSC6 do Deivison.

Tenho recebido de 15 a 20 logs de transações que falharam por este motivo por dia.

Vou acompanhar aqui e caso não solucione por completo, ou seja, continue aparecendo no log volto a postar a respeito.

r-martins commented 8 years ago

@LucasGusmao a correção deste erro era minha prioridade. Minha abordagem estava sendo na tentativa de fazer com que a criação dos campos sender_hash e creditcard_token ocorressem fora do form que contém os dados do cartão, desta forma, não seriam atualizados por nenhuma chamada de ajax. Como esse tipo de tarefa eu só consigo fazer em casa com uma internet estável (diferente das outras, que faço no onibus) até hoje não tinha conseguido finalizar e evoluir. Pelo que vi aqui, sua solução foi ótima e funciona no OSC. Vou testar aqui no onepagecheckout (que deve funcionar) e subirei uma nova versão com a sua solução. Voltamos a falar em breve.

r-martins commented 8 years ago

@LucasGusmao tudo certo! Ainda quero conseguir ter um tempo pra dar um tapa nesse js. Mas com o casamento se aproximando e uma série de outros compromissos, fica dificil. Deixa te perguntar, a conta do pagseguro que vc esta usando no baudaeletronica é sua ou da empresa? Se for da empresa, me mande o seu email do pagseguro por favor. Mais uma vez, obrigado pela contribuição e por compartilhar sua solução.

LucasGusmao commented 8 years ago

Fala @r-martins ! Li sua resposta pelo cel mas só pude responder agora!

O Js em si está bacana, as chamadas para ele que eu acredito que ocorrem algumas vezes sem necessidade por algumas redundâncias mas num todo está tudo bem redondo.

A conta que usamos é a contato@baudaeletronica.com.br pois nela há uma tarifa diferenciada negociada com o pagseguro.

Que isso cara, eu que agradeço este espetáculo de módulo que você fez aí para todos nós!

Lhe enviei um contato pelo seu site, comentando algumas coisas e pedindo se pode passar um contato pessoal seu para batermos um papo! Meu email é lucas.gusmao@baudaeletronica.com.br , me retorna lá para abrirmos uma thread e trocar umas ideias! Acredito que pode dar bons frutos!

Abraço!

perrera commented 8 years ago

Vou testar essa solução e posto. Maravilha esse pessoal...

Em 31 de julho de 2016 21:39, Lucas Gusmao notifications@github.com escreveu:

Fala @r-martins https://github.com/r-martins ! Li sua resposta pelo cel mas só pude responder agora!

O Js em si está bacana, as chamadas para ele que eu acredito que ocorrem algumas vezes sem necessidade por algumas redundâncias mas num todo está tudo bem redondo.

A conta que usamos é a contato@baudaeletronica.com.br pois nela há uma tarifa diferenciada negociada com o pagseguro.

Que isso cara, eu que agradeço este espetáculo de módulo que você fez aí para todos nós!

Lhe enviei um contato pelo seu site, comentando algumas coisas e pedindo se pode passar um contato pessoal seu para batermos um papo! Meu email é lucas.gusmao@baudaeletronica.com.br , me retorna lá para abrirmos uma thread e trocar umas ideias! Acredito que pode dar bons frutos!

Abraço!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/r-martins/PagSeguro-Magento-Transparente/issues/172#issuecomment-236467261, or mute the thread https://github.com/notifications/unsubscribe-auth/ANTJA6jtcCdRQorItWg6bKeP9nMsW7iCks5qbUA0gaJpZM4JIZ_j .

fchiqueto commented 8 years ago

Pessoal, encontrei um erro relacionado a essa atualização, simulando seria como o outro, ao trocar de frete acusa dados do cartão invalido e cai em loop infinito (ver barra de rolagem) com este erro no console: Falha ao obter o token do cartao. pagseguro.js:92 Object {30400: "invalid creditcard data"} pagseguro.js:93

Veja a imagem: ss1

Além disso bloqueou ip do cliente junto ao Pagseguro devido ao numero de requisições, segue imagem ao tentar acessar minha conta que não é a mesma cadastrada no pagseguro: ss2

Seria possivél @LucasGusmao e @perrera você fazer um teste também? Esqueci de mencionar que este erro aconteceu ao comprar e cadastrar um novo endereço ao mesmo tempo e usando um endereço já existente e que não estava ocorrendo até ontem.

Se lembrar de mais algum detalhe volto a postar aqui.

LucasGusmao commented 8 years ago

@fchiqueto Muito obrigado valiosíssima observação!!!

Consegui reproduzir, o erro acontece, ao manter atendidas as condições da function updateCreditCardToken e invalidas na checagem interna, e depois disto, mantendo os dados inválidos você trocar a forma de envio!

É incrível como o usuário desafia a lógica!!!

Vamos lá!

@r-martins te peço perdão de coração mas terminei de gambiarrar com tudo!! Como falamos lá no começo, minha solução foi na correria, e em loja live que precisa vender, então fiz a coisa mais rápida que deu, e para resolver isto não foi diferente.

pagseguro.txt

Na linha 9, declarei uma variável de escopo "global", na verdade não global mas comum às duas functions, e chamei de errors, com valor default false;

Na linha 87, setei esta variável para true, dentro do bloco que atribui os erros que estão sendo lançados na tela, e na linha 69 retornei ela para true dentro do escopo de success, já explico mais para frente o porque.

Na linha 157, onde eu havia feito a alteração anterior, que checava se estava em branco o credit_card_token, eu coloquei um && olhando também se existem erros, que caso positivo, não chamaria a função novamente evitando o loop.

Quando os dados do cartão forem corrigidos, a function updateCreditCardToken é invocada pelos observers setados nos campos e nisto, caso a checagem obtenha sucesso o valor errors é voltado para true, como comentei em cima. Com isto, mais uma chamada desnecessária ocorre na função updateCreditCardToken, mas não consegui evita-la, pois caso não retornasse a variável para true, causando uma execução do loop, caso a pessoa fizesse o fluxo:

Preencher dados do cartão errados -> alterar endereço -> preencher dados do cartão corretos -> alterar o endereço novamente

teríamos novamente o erro original aparecendo! (Confuso não? eu achei)

Testei diversos cenários, inclusive de troca de endereços apesar de não fazer muito sentido, e tudo funcionou normalmente, mas como falei em um bate papo esta semana com o @r-martins , programador não pode testar!

Vejam se funciona! e Ricardo, mais uma vez desculpe pelas gambiarras no seu módulo, mas é um durepox para que possamos viver até que você tenha tempo de pensar em algo mais profissional!

Abraço!

r-martins commented 8 years ago

Eu não consegui reproduzir. O que você quis dizer com "invalidas na checagem interna" ? Como reproduz rs?

LucasGusmao commented 8 years ago

Eu quis dizer que são condições que satisfazem o if (ccNum.length > 6 && ccExpMo != "" && ccExpYr != "" && ccCvv.length >= 3)

Mas que vão falhar na checagem dos dados do cartão e cairão em error dentro do psresponse.

Vamos lá, para reproduzir:

Preencha um cartão valido com todos os dados para rolar o savepayment do checkout.

Ex. 4111111111111111 Após isto, troque a forma de envio,

Altere um digito do cartão para que fique inválido. Ex. 4111111111111112

altere a forma de envio novamente e o loop ocorrerá.

É quase um alinhamento planetário, mas acontece!

fchiqueto commented 8 years ago

Nenhuma novidade sobre essa issue @r-martins ?

r-martins commented 8 years ago

Na verdade eu não consegui reproduzir ainda, ou alinhar os planetas como disse o @LucasGusmao rs. Veja: http://g.recordit.co/XaBPmsIWQO.gif

perrera commented 8 years ago

Eu consegui reproduzir um erro na minha loja,mas como estava em produção tirei do ar. Tambem nao consegui reproduzir na sua loja de exemplo pois não tem o módulo de boleto. Eu uso o modulo de boleto Magento BR 1.6.8. Eu tenho uma regra de desconto para quem paga usando boleto ter desconto de 5%. Quando a pessoa escolhe a forma de pagamento boleto, recebe o desconto. Porém se ela alternar para Pagseguro cartão de crédito o desconto ainda aparece no checkout. Por isso ao clicar em finalizar compra ocorre o erro "Falha ao obter o token do cartao ou sender_hash." Eu consigo ver ainda que quando selecionado o Pagseguro, o desconto ainda aparece.

r-martins commented 8 years ago

@perrera a loja de exemplo tem boleto sim. Provavelmente na hora que vc acessou alguém tinha desabilitado. Ela é restaurada a cada 6 horas. Acho que essa questão do desconto é outra historia, não?

fchiqueto commented 8 years ago

@r-martins consegui simular na sua loja teste é como o @LucasGusmao disse só preencher tudo normal trocar o numero do cartão de credito que da o erro e ao trocar o frete que cai em loop. vou te manda o vídeo por email porque o gif cortou na metade.

r-martins commented 8 years ago

@LucasGusmao obrigado pela correção. Tenho muita vontade de reescrever esse JS inteiro, e colocar o sender_hash e creditcard_token fora do form que contém os dados do pagamento. Isso resolveria todos os problemas de checkout, e não precisaria mais desses loops de timeout. Só falta o tempo mesmo...

@fchiqueto obrigado pela paciência, por gravar video e pelos testes. Graças a sua insistência :) consegui reproduzir localmente o problema.

fchiqueto commented 8 years ago

Opa @r-martins que bom, vou fazer mais testes em breve te passo um feedback obrigado pela insistência também :)

fchiqueto commented 8 years ago

@r-martins fiquei de testar esse fix mais não tive tempo então para testar atualizei o modulo do meu site mesmo e acompanhei por uma semana como se comportava o momento do checkout com clientes e o erro ainda persiste, queria fazer o teste no seu site (http://pagseguro-exemplo-osc.ricardomartins.net.br/) mais da erro token inválido. Mais resumindo o problema parece ser o mesmo se o cliente preenche o dados do cartão sem o escolher o método de envio e clicar em concluir da erro e se trocar de frete da o mesmo erro. Vou continuar analisando e vou testar com mais calma para tentar descobrir o momento exato do que da erro ai posto aqui.

rafatriolo commented 8 years ago

@r-martins bom dia , eu atualizei o modulo do pagseguro e o módulo do OSC 6 , o cartao não estava funcionando a principio , porem vi um post que vc fez na central de ajuda do pagseguro falando sobre lib/card.js e pra mim resolveu o problema. Vejam se isso ajuda vcs tbm! segue o link da central de ajuda https://pagsegurotransparente.zendesk.com/hc/pt-br

rafatriolo commented 8 years ago

Pessoal , sei que não é o post certo pra perguntar isso , mas onde posso aprender mais sobre prototype pra poder contribuir mais com os modulos ! abs

Tokem commented 6 years ago

Pessoal boa noite! Procurando e quebrando muito a cabeça com o erro 30400: "invalid creditcard data" consegui resolver e vou deixar minha solução para vocês espero ajudar, pois já fui ajudado bastante e nunca retribui...

1- Ao entrar na página do checkout verificar se existe sessão ativa (geralmente gravamos o session id em uma variável global, quando retornamos do servidor) se não tiver criar, e depois setar a sessão com o método PagSeguroDirectPayment.setSessionId(TOKEN), um problema que encontrei, o PagSeguro não recomenda você utilizar o método PagSeguroDirectPayment.getSenderHash() no "OnLoad" da página por causa de dependências, apenas quando o usuário clicar no botão de finalizar pagamento, foi o que fiz.

2- Após setar a sessão verificada e inciada se for o caso, você deve quase por obrigação chamar o método PagSeguroDirectPayment.getPaymentMethods mesmo que não use pra nada (No meu caso não existe parcelamento na loja), caso contrário ao tentar criar o Token do cartão de crédito você sempre irá cair no erro "30400".

3- Quando conseguir pegar o token do cartão de crédito e clicar para finalizar o pagamento gere o senderHash com o método, PagSeguroDirectPayment.getSenderHash(), se você seguir estes passos tudo funcionará bem, mas se voltar para fazer uma nova compra minutos após, teremos o problema de cair novamente no erro "30400" e não adianta iniciar novamente uma sessão, você só deve iniciar uma nova sessão quando cair no erro "30403":"invalid session" ai sim você deve avisar ao usuário e depois criar novamente a sessão.

4- Para reforçar a sessão do PagSeguro deve ser criada e mantida até que caiamos no erro 30403, caso contrário não precisamos ficar chamando método para refazer a sessão nem muito menos o SenderHash que soh deve ser chamado no final de tudo.

OBS: antes de realizarem outros procedimentos depois de usar o método PagSeguroDirectPayment.setSessionId(TOKEN) usem um timerOut para esperar 1 ou 2 segundos, as vezes da erro porque a sessão não foi criada, pois o procedimento é feito com javascript, também não tentem pegar um retorno dessa função, algo que deveria existir e não existe :(

Obrigado a todos e ao Ricardo que já precisei em outro momento e me respondeu rapidamente.

yuribtt commented 6 years ago

@Tokem então, de acordo com o passo 3, não tem como evitar o erro no caso de uma compra seguida de outra? entendi errado?

Tokem commented 6 years ago

@yuribtt Opa corrigindo! essa foi a situação que aconteceu comigo, toda vez que entrava pra repetir uma compra iniciava a sessão novamente com isso caia no erro 30400, então pra ficar claro:

3- Só devemos iniciar uma nova sessão quando cair no erro 30403":"invalid session., caso contrario grave o sessionId em uma variável global e antes de iniciar o pagamento verifique se ela já foi "setada" se sim, é porque o usuário já realizou uma compra e vai realizar outra na sequência, se não, ele vai realizar uma compra pela primeira vez e o sessionId não foi "setado"

Tokem commented 6 years ago

@yuribtt o passo 4 falava a mesma coisa, incluindo o SenderHash.

yuribtt commented 6 years ago

@Tokem ah sim, obg. Estou tendo esse erro também, valeu pela ajuda!

r-martins commented 6 years ago

Vocês chegaram a testar com as novas implementações da versão 3.5.1 (Mais detalhes em http://bit.ly/2A5SHk0. Fixes #251) ?