Comunidade
Criptografia do cartão com React
Olá,
Estou integrando a API e estou no passo onde é solicitado que o cartão de crédito seja criptografado (link abaixo). Essa parte da documentação solicita que eu adicione uma script externa no site para conseguir fazer a criptografia do cartão. Porém, isso não funciona corretamente no React com Typescript. Por favor, vocês possuem um módulo NPM, de preferência com tipagem, dessa biblioteca de encriptação de cartão?
https://dev.pagseguro.uol.com.br/reference/order-pay-credit-encrypted
Bom dia!
A única maneira de utilizar a criptografia do cartão é utilizando o SDK disponibilizado em nossa documentação.
Olá Roberto, encontrei uma solução talvez até paliativa para esse problema, infelizmente, as APIs do PagSeguro ainda não estão adaptadas a tecnologias como React. Esperamos que se adequem, afinal React domina a área de desenvolvimento de aplicações para Web.
Criei um componente onde simplesmente peguei o código de "https://assets.pagseguro.com.br/checkout-sdk-js/rc/dist/browser/pagseguro.js" e nesse componente criei uma função que exportei por padrão
...Código importado do link mencionado acima
// Aqui você pode adaptar, criando os devidos parâmetros
export default function Encrypt() {
const card = PagSeguro.encryptCard({
publicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr+ZqgD892U9/HXsa7XqBZUayPquAfh9xx4iwUbTSUAvTlmiXFQNTp0Bvt/5vK2FhMj39qSv1zi2OuBjvW38q1E374nzx6NNBL5JosV0+SDINTlCG0cmigHuBOyWzYmjgca+mtQu4WczCaApNaSuVqgb8u7Bd9GCOL4YJotvV5+81frlSwQXralhwRzGhj/A57CGPgGKiuPT+AOGmykIGEZsSD9RKkyoKIoc0OS8CPIzdBOtTQCIwrLn2FxI83Clcg55W8gkFSOS6rWNbG5qFZWMll6yl02HtunalHmUlRUL66YeGXdMDC2PuRcmZbGO5a/2tbVppW6mfSWG3NPRpgwIDAQAB",
holder: "Nome Sobrenome",
number: "4242424242424242",
expMonth: "12",
expYear: "2030",
securityCode: "123"
})
return card
}
Qualquer coisa entre em contato comigo: marcelo@dezenve.com.br
Até mais, espero ter ajudado.
Alguém já conseguiu aplicar em angular?
Olá pessoal, seguindo a ideia do amigo ai em cima, fiz da seguinte forma.
Criei um arquivo encryptPagSeguro.js e o código ficou assim:
const pagSeguroScript = document.createElement('script')
pagSeguroScript.setAttribute('src', 'https://assets.pagseguro.com.br/checkout-sdk-js/rc/dist/browser/pagseguro.min.js')
document.head.appendChild(pagSeguroScript)
export function encryptCardPagSeguro(cardData) {
const card = PagSeguro.encryptCard({
publicKey: process.env.NEXT_PUBLIC_PAG_SEGURO_PUBLIC_KEY,
holder: cardData.holder,
number: cardData.number,
expMonth: cardData.expMonth,
expYear: cardData.expYear,
securityCode: cardData.securityCode
})
return card
}
No caso do Next.js, para erros tipo "document is not defined":
if (typeof window !== 'undefined') {
const pagSeguroScript = document.createElement('script')
pagSeguroScript.setAttribute(
'src',
'https://assets.pagseguro.com.br/checkout-sdk-js/rc/dist/browser/pagseguro.min.js'
)
document.head.appendChild(pagSeguroScript)
}
Ola, alguem pode me dar uma ajuda para fazer a criptografia do cartão, utilizando ReactNative
Salve William!
Tu pode usar a solução do nosso amigo acima!
cria uma function PagSeguro.js e copiar o codigo de dentro do https://assets.pagseguro.com.br/checkout-sdk-js/rc/dist/browser/pagseguro.js
e exporta a mesma para você usar dentro de sua aplicação.
//Chris, no angular vai ficar a mesma ideia da colega Camila:
//1- vai criar seu arquivo em: "assets/js/PagSeguro.js" com o conteudo abaixo:
const pagSeguroScript = document.createElement("script");
pagSeguroScript.setAttribute(
"src",
"https://assets.pagseguro.com.br/checkout-sdk-js/rc/dist/browser/pagseguro.min.js"
);
document.head.appendChild(pagSeguroScript);
function Encrypt(cardData) {
const card = PagSeguro.encryptCard({
publicKey: " ... ",
holder: cardData.holder,
number: cardData.number,
expMonth: cardData.expMonth,
expYear: cardData.expYear,
securityCode: cardData.securityCode,
});
if (!card.hasErrors || !card.errors) {
return card.encryptedCard;
} else {
return null;
}
}
//2- No index.html:
;//3- No component especifico... fazer seu uso da seguinte forma:
//A- declare a função
declare function Encrypt(cardData: any): any;
//B- Na criação do seu objeto... faça o uso da função abaixo... passando seus valores, claro!
card: {
encrypted: Encrypt( {...} )
}
obs: testado e aprovado, abraços!!!
Olha, fiz o seguinte:
Baixei a lib pagseguro.js
Depois mudei o fonte pra:# primeira linhafunction doExport(exports) {
// ultima linha:
module.exports = doExport({});
Criei um arquivo pagseguro.d.ts com a seguinte estrutura:
export declare module PagSeguro {
}
export declare type EncryptRequest = {
publicKey: string
holder: string
number: string
expMonth: string
expYear: string
securityCode: string
}
declare type ErrorEncryptionResult = {
errors: { code: string, message: string }[],
hasErrors: true
}
declare type SuccessEncryptionResult = {
encryptedCard: string
hasErrors: false
}
export declare function encryptCard(card: EncryptRequest): ErrorEncryptionResult | SuccessEncryptionResult;
E aí no código que preciso usar o encrypt:
import { encryptCard, EncryptRequest } from "~/app/pagseguro"
...
doEncrypt(payload: EncryptRequest){
var ret = encryptCard(payload);
if(ret.hasErrors){
// implicitily type guard due to declaration type for error have "true" in that field
}else{
return ret.encryptedCard
}
}
Usando o Copilot eu converti a função js em Ts e agora consigo usar no nextjs.
import JSEncrypt from "jsencrypt";
export interface CardData {
publicKey: string;
holder: string;
number: string;
expMonth: string;
expYear: string;
securityCode?: string;
}
export interface EncryptCardResult {
errors: { code: string; message: string }[];
encryptedCard: string | null;
hasErrors: boolean;
}
// You must install 'jsencrypt' and import it, or use your own JS encryption logic.
// import JSEncrypt from 'jsencrypt';
export function encryptCard(card: CardData): EncryptCardResult {
// --- Validation logic (copied from your JS) ---
function isNumber(val: string) {
return !isNaN(Number(val));
}
function containsNumber(input: string) {
return /\d/.test(input);
}
function sanitizeHolder(input: string) {
return input
.replace("'", "")
.replace("/", "")
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.replace(/[^a-zA-Z\s]/g, "");
}
function trunkAndSanitizeString(field: string, maxLength: number) {
return sanitizeHolder((field || "").substring(0, maxLength));
}
function formatExpMonth(expMonth: string) {
const month = (expMonth || "").trim();
return month.length === 1 ? 0${month}
: month;
}
function sanitize(creditCard: CardData) {
return {
holder: trunkAndSanitizeString(creditCard.holder, 30),
number: (creditCard.number || "").trim(),
securityCode: (creditCard.securityCode || "").trim(),
expMonth: formatExpMonth(creditCard.expMonth),
expYear: (creditCard.expYear || "").trim(),
publicKey: (creditCard.publicKey || "").trim(),
};
}
// --- Error definitions ---
const validationErrors = {
INVALID_NUMBER: {
code: "INVALID_NUMBER",
message: "invalid card number
",
},
INVALID_NUMBER_LENGTH: {
code: "INVALID_NUMBER",
message:
"invalid field number
. You must pass a value between 13 and 19 digits",
},
INVALID_SECURITY_CODE: {
code: "INVALID_SECURITY_CODE",
message:
"invalid field securityCode
. You must pass a value with 3, 4 or none digits",
},
INVALID_EXPIRATION_MONTH: {
code: "INVALID_EXPIRATION_MONTH",
message:
"invalid field expMonth
. You must pass a value between 1 and 12",
},
INVALID_EXPIRATION_YEAR: {
code: "INVALID_EXPIRATION_YEAR",
message:
"invalid field expYear
. You must pass a value between 1900 and 2099",
},
INVALID_PUBLIC_KEY: {
code: "INVALID_PUBLIC_KEY",
message: "invalid publicKey
",
},
INVALID_HOLDER: { code: "INVALID_HOLDER", message: "invalid holder
" },
};
// --- Validators ---
function validateCard(card: ReturnType) {
const errors: { code: string; message: string }[] = [];
if (!card.number) errors.push(validationErrors.INVALID_NUMBER);
if (card.number && !isNumber(card.number))
errors.push(validationErrors.INVALID_NUMBER);
if (card.number && !(card.number.length >= 13 && card.number.length <= 19))
errors.push(validationErrors.INVALID_NUMBER_LENGTH);
if (
card.securityCode &&
(!isNumber(card.securityCode) ||
(card.securityCode.length !== 3 && card.securityCode.length !== 4))
)
errors.push(validationErrors.INVALID_SECURITY_CODE);
if (
!card.expMonth ||
!isNumber(card.expMonth) ||
parseInt(card.expMonth, 10) < 1 ||
parseInt(card.expMonth, 10) > 12
)
errors.push(validationErrors.INVALID_EXPIRATION_MONTH);
if (
!card.expYear ||
!isNumber(card.expYear) ||
parseInt(card.expYear, 10) < 1900 ||
parseInt(card.expYear, 10) > 2099
)
errors.push(validationErrors.INVALID_EXPIRATION_YEAR);
if (!card.holder || containsNumber(card.holder))
errors.push(validationErrors.INVALID_HOLDER);
if (!card.publicKey) errors.push(validationErrors.INVALID_PUBLIC_KEY);
return errors;
}
// --- Main logic ---
const sanitizedCard = sanitize(card);
const errors = validateCard(sanitizedCard);
let encryptedCard: string | null = null;
if (errors.length === 0) {
const jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(sanitizedCard.publicKey);
encryptedCard =
jsEncrypt.encrypt(
[
sanitizedCard.number,
sanitizedCard.securityCode,
sanitizedCard.expMonth,
sanitizedCard.expYear,
sanitizedCard.holder,
Date.now(),
].join(";")
) || null;
}
return {
errors,
encryptedCard,
hasErrors: errors.length > 0,
};
}