open-pay / openpay-python

Openpay Python Bindings
19 stars 32 forks source link

Create card from client side generated token #16

Closed JavierPiedra closed 4 years ago

JavierPiedra commented 4 years ago

Hola!

Estoy haciendo la integración de openpay con una aplicación creada en react en el client side y utilizo django para el back.

Estoy siguiendo la ruta marcada de OpenPay.js; de crear una tarjeta sin que pase por el servidor usando tokens, sin embargo, en ningún lugar de la documentación viene como asignar una tarjeta creada en el cliente side a través del método:

# Uso window porque es React.
window.OpenPay.token.create(
        {
          card_number: card,
          holder_name: state.ccName,
          expiration_year: expYear,
          expiration_month: expMonth,
          cvv2: cvc,
......etc

El token generado lo estoy pasando al back pero a la hora querer ejecutar algo similar a: customer.cards.create(token)

Me da un error. Vi que en esta sección había un método con node para crear una tarjeta siguiendo estos pasos:

var cardRequest = {
  'token_id' : 'tokgslwpdcrkhlgxqi9a',
  'device_session_id' : '8VIoXj0hN5dswYHQ9X1mVCiB72M7FY9o'
}

openpay.customers.cards.create('a9pvykxz4g5rg0fplze0', cardRequest, function(error, card)  {
  // ...
});

Sin embargo, no me fue posible crear una tarjeta en un cliente resultadon en el siguiente error:

>>> card_request = {
... 'device_session_id': device,
... 'token_id':token,
... }
>>> openpay.customers.cards.create(customer_id, card_request)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: module 'openpay' has no attribute 'customers'

Ni de esta manera:

>>> customer.cards.create(card_request)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: create() takes 1 positional argument but 2 were given

Tambien intenté de esta forma

>>> token = "xxxxxx"
>>> device = "zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
>>> from django.conf import settings
>>> openpay = settings.OPENPAY
>>> customer = openpay.Customer.retrieve('ayp7zw9xrp1gx05jjvje')
>>> card = {
... 'source_id':token,
... 'device_session_id': device
... }
>>> new_card = customer.cards.create(card=card)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/xxxxxxxxxxxxxxxxx", line 237, in create
    return self.request('post', self['url'], params)
  File "/hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", line 142, in request
    response, api_key = requestor.request(method, url, params)
  File "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, line 75, in request
    resp = self.interpret_response(rbody, rcode)
  File "xxxxxxxxxxxxxxxxxxxxxxxxxxx", line 181, in interpret_response
    self.handle_api_error(rbody, rcode, resp)
  File "xxxxxxxxxxxxxxxxxxxxxx", line 84, in handle_api_error
    raise error.InvalidRequestError(
openpay.error.InvalidRequestError: holder_name is required, card_number is required, expiration_month is required, error code: 1001

La única manera en la que he podido hacerlo es con un request derecho:

headers = {'Content-type': 'application/json'}
        data = {
            'token_id': token_id,
            'device_session_id': device_session_id
        }
        url = (
            f'https://sandbox-api.openpay.mx/v1/\
                {merchant_id}/customers/{customer.id}/cards'
        )
        new_card = requests.post(
            url, headers=headers, json=data, auth=(api_key, ''))
JavierPiedra commented 4 years ago

Disculpen, ya pude. Por si alguien tiene duda, al pasar el device_session_id y el token generado en el front, puedes crear la tarjeta y hacer el cargo así:


new_card = openpay.Card.create(
    customer=userprofile.openpay_id,
    token_id=token,
    device_session_id=device_session_id
)
# antes guardo los datos en un modelo "card" en donde guardo el id generado en new_card

charge = openpay.Charge.create(
    device_session_id=device_session_id,
    customer=userprofile.openpay_id,
    source_id=card.openpay_id,
    method="card",
    amount=amount_to_charge,
    description=f"Mi empresa: Orden {order.id}",
    capture=True
)