Last active
February 4, 2026 20:59
-
-
Save gamelio-pv/3c75f3e985ed079d30683ed739b3c54b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Payvalida 3DS Implementation Example</title> | |
| <style> | |
| body { | |
| font-family: sans-serif; | |
| padding: 2rem; | |
| max-width: 600px; | |
| margin: 0 auto; | |
| } | |
| .form-group { | |
| margin-bottom: 1rem; | |
| } | |
| label { | |
| display: block; | |
| margin-bottom: 0.5rem; | |
| font-weight: bold; | |
| } | |
| input { | |
| width: 100%; | |
| padding: 0.5rem; | |
| font-size: 1rem; | |
| } | |
| button { | |
| background-color: #007bff; | |
| color: white; | |
| padding: 0.75rem 1.5rem; | |
| border: none; | |
| cursor: pointer; | |
| font-size: 1rem; | |
| } | |
| button:hover { | |
| background-color: #0056b3; | |
| } | |
| #status-log { | |
| margin-top: 1rem; | |
| padding: 1rem; | |
| background: #f4f4f4; | |
| border: 1px solid #ddd; | |
| display: none; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Checkout</h1> | |
| <!-- Simple Payment Form --> | |
| <div id="payment-form"> | |
| <!-- Form... --> | |
| <button id="pay-button">Pay</button> | |
| </div> | |
| <!-- 1. Import the SDK --> | |
| <script src="https://3ds.payvalida.com/sdk@latest.min.js" type="module"></script> | |
| <!-- 2. Implementation Script --> | |
| <script type="module"> | |
| const sdkInstance = new window.PayvalidaSDK({ | |
| environment: "sandbox", | |
| isSinglePageApp: false, // Set to true if you are handling routing in JS | |
| threedsConfig: { | |
| consumerAuthenticationInformation: { | |
| transactionMode: "01", | |
| mcc: "1234", | |
| requestorId: "123456", | |
| requestorName: "REQUESTOR NAME", | |
| }, | |
| acquirerInformation: { | |
| acquirerBin: "123456", | |
| merchantId: "123456", | |
| }, | |
| merchantInformation: { | |
| merchantDescriptor: { | |
| name: "MERCHANT DESCRIPTOR NAME", | |
| url: "https://payvalida.com", | |
| }, | |
| }, | |
| }, | |
| }); | |
| const payBtn = document.getElementById('pay-button'); | |
| payBtn.addEventListener('click', async () => { | |
| payBtn.disabled = true; | |
| log("Initializing 3DS SDK..."); | |
| const response = await sdkInstance.startAntiFraudValidator({ | |
| cardNumber: "4111111111111111", | |
| expirationMonth: "12", | |
| expirationYear: "2026", | |
| cvv: "123", | |
| token: "1234567890", | |
| }); | |
| if (response.threeDSRequired) { | |
| console.log('Se requiere validación 3DS'); | |
| // Guardar pvThreedsId y referenceId para usar en startThreedsValidator | |
| const { pvThreedsId, referenceId } = response.data; | |
| const formData = { | |
| billAddrCity: "Medellín", | |
| billAddrCountry: "CO", | |
| billAddrLine1: "Calle 12345", | |
| billAddrLine2: "Calle 12345", | |
| billAddrPostCode: "050047", | |
| billAddrState: "Antioquia", | |
| cardNumber: "4111111111111111", | |
| installments: 1, | |
| cvv: "123", | |
| di: "1234567890", | |
| expirationMonth: "12", | |
| expirationYear: "2026", | |
| lastName: "Doe", | |
| name: "John", | |
| token: "1234567890", | |
| typeDI: "CC", | |
| cellPhone: "3141234123", | |
| email: "support@payvalida.com", | |
| pvThreedsId: pvThreedsId, | |
| referenceId: referenceId, | |
| } | |
| // Llamando a startThreedsValidator de esta forma, | |
| // se mostrará el desafío en el contenedor automáticamente en el centro de la pantalla | |
| const threedsResponse = await sdkInstance.startThreedsValidator(formData); | |
| // O si quieres usar un contenedor propio: | |
| // const threedsResponse = await sdkInstance.startThreedsValidator(formData, 'mi-contenedor-3ds'); | |
| if (!threedsResponse.isApproved) { | |
| console.error('Error:', threedsResponse.error); | |
| console.error('Error Code:', threedsResponse.errorCode); | |
| payBtn.disabled = false; | |
| return; | |
| } | |
| console.log('Transacción aprobada por 3DS'); | |
| // Procesar la transacción... | |
| payBtn.disabled = false; | |
| return; | |
| } | |
| if (response.isApproved) { | |
| console.log('Análisis de fraude aprobado'); | |
| if (response.data && response.data.kountSessionID) { | |
| console.log('Kount Session ID:', response.data.kountSessionID); | |
| // IMPORTANTE: Si se recibe un kountSessionID, este deberá ser enviado | |
| // en el endpoint de transaction, de lo contrario, tu transacción será rechazada. | |
| } | |
| // Procesar la transacción... | |
| payBtn.disabled = false; | |
| return; | |
| } | |
| console.error('Error:', response.error); | |
| console.error('Error Code:', response.errorCode); | |
| payBtn.disabled = false; | |
| return; | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment