open-pay / openpay-js

Openpay Javascript bindings
Apache License 2.0
24 stars 28 forks source link

OpenPay.deviceData.setup() en React js #20

Open EmmanuelSkapple opened 4 years ago

EmmanuelSkapple commented 4 years ago

Hola que tal, estoy tratando de implementar el metodo para obtener el id de session del dispositivo que se requiere para realizar un cargo. Estoy utilizando React js, pero he tenido problemas porque si cargo el script que viene en la documentacion que es este: https://resources.openpay.mx/lib/openpay-data-js/1.2.38/openpay-data.v1.min.js me sale este error

openpay-data.v1.min.js:2 Uncaught ReferenceError: OpenPay is not defined at openpay-data.v1.min.js:2 at openpay-data.v1.min.js:2 si instalo el npm que tienen que es el de openpay-js, al mandar a llamar el paquete me sale este error: openpay-card.v1.js:950 Uncaught ReferenceError: jQuery is not defined at Object.<anonymous> (openpay-card.v1.js:950) at Object../node_modules/openpay-js/lib/openpay-card.v1.js (openpay-card.v1.js:950) at __webpack_require__ (bootstrap:784) at fn (bootstrap:150) at Module../src/components/userComponents/finalizarCompra.js (ResumenCuenta.js:68) at __webpack_require__ (bootstrap:784) at fn (bootstrap:150) at Module../src/routers/userRoute.js (routerMain.js:136) at __webpack_require__ (bootstrap:784) at fn (bootstrap:150) at Module../src/routers/routerMain.js (adminRoute.js:39) at __webpack_require__ (bootstrap:784) at fn (bootstrap:150) at Module../src/App.js (App.css?4433:45) at __webpack_require__ (bootstrap:784) at fn (bootstrap:150) at Module../src/index.js (index.css?f3f6:45) at __webpack_require__ (bootstrap:784) at fn (bootstrap:150) at Object.1 (slideBar.css?9134:45) at __webpack_require__ (bootstrap:784) at checkDeferredModules (bootstrap:45) at Array.webpackJsonpCallback [as push] (bootstrap:32) at main.chunk.js:1

me pueden ayudar para poder implementar esto. Gracias , Saludos.

senter-logistics commented 4 years ago

+1

EmmanuelSkapple commented 4 years ago

Lo pude resolver tienes que poner estos tres scripts

  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
   <script type="text/javascript" src="https://js.openpay.mx/openpay.v1.min.js"></script>
    <script type='text/javascript' src="https://js.openpay.mx/openpay-data.v1.min.js"></script>

en ese orden, para que funcione lo anterior

diamardan commented 4 years ago

tengo el problema del deviceData.setup. a mi de da el siguiente error

openpay_js__WEBPACK_IMPORTED_MODULE_1___default.a.deviceData is undefined

tengo instalada la biblioteca openpay-js de npm y también los 3 scripts, jquery, openpay.v1 y openpay-data, pero aún así me sigue dando ese error.

Solo es al hacer el OpenPay.deviceData.setup('form-id', 'device_session_id') les agradecería si pueden ayudarme

carlossc88 commented 4 years ago

Yo también estoy atorado con el deviceSessionId, tengo el siguiente error:

`Unhandled Rejection (TypeError): Cannot read property 'setup' of undefined getToken src/components/ui/pagos/Tarjeta.jsx:46

43 | OpenPay.setId(process.env.REACT_APP_OPENPAY_ID); 44 | OpenPay.setApiKey(process.env.REACT_APP_OPENPAY_PUBLIC); 45 | OpenPay.setSandboxMode(true);

46 | const deviceSessionId = await OpenPay.deviceData.setup('tarjetaForm'); | ^ 47 | OpenPay.token.create({ 48 | "device_session_id": deviceSessionId, 49 | "card_number": card.replace(/ /g, ""),`

Si comento la creación del deviceSessionId puedo crear el token sin problemas, pero cuando quiero crear el cargo enviando los datos desde mi servidor al servidor de openpay me devuelve el error device_session_id es necesario.

"title": "OpenpayApiRequestError", "type": "OpenpayApiRequestError", "code": 500, "message": "Attribute device_session_id is required",

EmmanuelSkapple commented 4 years ago

les recomiendo llamen a su numero de soporte, por aqui no constestan, yo les marque y si te resuelven de volada los problemas. el numero lo encuentran en su pagina oficial.

diamardan commented 4 years ago

ACTUALIZACIÓN.

No hace falta el paquete de npm openpay-js. Solo en public/index.html agregar los 3 links, jquery, openpay v1 y openpay data.


<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" />
<script type="text/javascript" src="https://js.openpay.mx/openpay.v1.min.js" />
<script type='text/javascript' src="https://js.openpay.mx/openpay-data.v1.min.js" />

Ahora, no encontramos con el problema de que no podemos acceder a la variable OpenPay para usar las funciones setId etc, como lo resolvemos?

Fácil, invocando la variable mediante window, es decir, si en la documentación dice que hagamos OpenPay.setId, usaremos window.OpenPay.setId, lo mismo para OpenPay.deviceData.setup quedaría como window.OpenPay.deviceData.setup().

Así de fácil así de rico :3

JavierPiedra commented 3 years ago

Ahí les va mi solución compas. Yo tengo un componente para updatear el head desde cualquier lugar. Entonces no es necesario que lo hagan en el html, especialmente si tienes varios html's (ejemplo usando gatsby.js)

scriptLoader.js

export default function loadScript(src, position, id) {
  if (!position) {
    return;
  }

  const script = document.createElement('script');
  script.setAttribute('async', '');
  script.setAttribute('id', id);
  script.src = src;
  position.appendChild(script);
}
export function loadAndSetScript(innerHtml, position, id) {
  if (!position) {
    return;
  }

  const script = document.createElement('script');
  script.setAttribute('async', '');
  script.setAttribute('id', id);
  script.type = 'text/javascript';
  script.innerHTML = innerHtml;
  position.appendChild(script);
}

setOpenPay.js

/* eslint-disable no-undef */
import loadScript, { loadAndSetScript } from './scriptLoader';

const head = typeof document !== 'undefined' ? document.querySelector('head') : '';

export const loadOpenPay = setOpenPayLoaded => {
  if (!document.querySelector('#openPayInstance')) {
    loadScript('https://js.openpay.mx/openpay.v1.min.js', head, 'openPayInstance');
    document.querySelector('#openPayInstance').addEventListener('load', () => {
      const openpay = window.OpenPay;
      openpay.setId(process.env.OPENPAY_MERCHANT_ID);
      openpay.setApiKey(process.env.OPENPAY_PUBLISHABLE_KEY);
      openpay.setSandboxMode(process.env.NODE_ENV === 'development' ? true : false);
      setOpenPayLoaded(true);
    });
  }
};

export const loadAntiFraud = setAntiFraudLoaded => {
  if (!document.querySelector('#openPayAntiFraud')) {
    loadScript('https://js.openpay.mx/openpay-data.v1.min.js', head, 'openPayAntiFraud');
    document.querySelector('#openPayAntiFraud').addEventListener('load', () => {
      loadAndSetScript(
        `var deviceSessionId = OpenPay.deviceData.setup(
                            "paymentFormId", "hiddenDevice"
                          );`,
        head,
        'deviceSessionid'
      );
      setAntiFraudLoaded(true);
    });
  }
};

TuComponentConFormulario.js (jaja)

import React, { useEffect, useState, useReducer } from 'react';
import { loadAntiFraud, loadOpenPay } from '........setOpenPay';

const ComponenteConFormulario = () => {
  const [openPayLoaded, setOpenPayLoaded] = useState(false);
  const [antiFraudLoaded, setAntiFraudLoaded] = useState(false);
  useEffect(() => {
    if (!openPayLoaded) {
      loadOpenPay(setOpenPayLoaded);
    } else if (!antiFraudLoaded) {
      loadAntiFraud(setAntiFraudLoaded);
    } else if (antiFraudLoaded) {
      let newCardValidators = window.OpenPay.card;
     # aqui puedes determinar los validadores de tarjeta, cvc, etc... yo lo puse en el estado.
      setCardValidators({
        validateCardNumber: newCardValidators.validateCardNumber,
        validateCVC: newCardValidators.validateCVC,
        validateExpiry: newCardValidators.validateExpiry,
        cardType: newCardValidators.cardType,
      });
    }
  }, [openPayLoaded, antiFraudLoaded]);

return(
# En esta parte puedes poner un componente <Loading/> en lo que antiFraudLoaded es false
<form onSubmit={ e => handleSubmit(e) } id="paymentFormId">
...........