Created
March 15, 2016 19:12
-
-
Save Verurteilt/37e175e670c3b6956a57 to your computer and use it in GitHub Desktop.
This file contains 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
# -*- coding: utf-8 -*- | |
import json | |
import requests | |
import hashlib | |
REPORTS = 'reports' | |
PAYMENTS = 'payments' | |
class PayU(object): | |
TRANSACTION_RESPONSE_CODES = { | |
u'ERROR': u'Ocurrió un error general.', | |
u'APPROVED': u'La transacción fue aprobada.', | |
u'ANTIFRAUD_REJECTED': u'La transacción fue rechazada por el sistema anti-fraude.', | |
u'PAYMENT_NETWORK_REJECTED': u'La red financiera rechazó la transacción.', | |
u'ENTITY_DECLINED': u'La transacción fue declinada por el banco o por la red financiera debido a un error.', | |
u'INTERNAL_PAYMENT_PROVIDER_ERROR': u'Ocurrió un error en el sistema intentando procesar el pago.', | |
u'INACTIVE_PAYMENT_PROVIDER': u'El proveedor de pagos no se encontraba activo.', | |
u'DIGITAL_CERTIFICATE_NOT_FOUND': u'La red financiera reportó un error en la autenticación.', | |
u'INVALID_EXPIRATION_DATE_OR_SECURITY_CODE': u'El código de seguridad o la fecha de expiración estaba inválido.', | |
u'INSUFFICIENT_FUNDS': u'La cuenta no tenía fondos suficientes.', | |
u'CREDIT_CARD_NOT_AUTHORIZED_FOR_INTERNET_TRANSACTIONS': u'La tarjeta de crédito no estaba autorizada para transacciones por Internet.', | |
u'INVALID_TRANSACTION': u'La red financiera reportó que la transacción fue inválida.', | |
u'INVALID_CARD': u'La tarjeta es inválida.', | |
u'EXPIRED_CARD': u'La tarjeta ya expiró.', | |
u'RESTRICTED_CARD': u'La tarjeta presenta una restricción.', | |
u'CONTACT_THE_ENTITY': u'Debe contactar al banco.', | |
u'REPEAT_TRANSACTION': u'Se debe repetir la transacción.', | |
u'ENTITY_MESSAGING_ERROR': u'La red financiera reportó un error de comunicaciones con el banco.', | |
u'BANK_UNREACHABLE': u'El banco no se encontraba disponible.', | |
u'EXCEEDED_AMOUNT': u'La transacción excede un monto establecido por el banco.', | |
u'NOT_ACCEPTED_TRANSACTION': u'La transacción no fue aceptada por el banco por algún motivo.', | |
u'ERROR_CONVERTING_TRANSACTION_AMOUNTS': u'Ocurrió un error convirtiendo los montos a la moneda de pago.', | |
u'EXPIRED_TRANSACTION': u'La transacción expiró.', | |
u'PENDING_TRANSACTION_REVIEW': u'La transacción fue detenida y debe ser revisada, esto puede ocurrir por filtros de seguridad.', | |
u'PENDING_TRANSACTION_CONFIRMATION': u'La transacción está pendiente de ser confirmada.', | |
u'PENDING_TRANSACTION_TRANSMISSION': u'La transacción está pendiente para ser trasmitida a la red financiera. Normalmente esto aplica para transacciones con medios de pago en efectivo.', | |
u'PAYMENT_NETWORK_BAD_RESPONSE': u'El mensaje retornado por la red financiera es inconsistente.', | |
u'PAYMENT_NETWORK_NO_CONNECTION': u'No se pudo realizar la conexión con la red financiera.', | |
u'PAYMENT_NETWORK_NO_RESPONSE': u'La red financiera no respondió.', | |
u'FIX_NOT_REQUIRED': u'Clínica de transacciones: Código de manejo interno.' | |
} | |
TRANSACTION_PENDING_CODES =['PENDING_TRANSACTION_REVIEW', 'PENDING_TRANSACTION_CONFIRMATION', 'PENDING_TRANSACTION_TRANSMISSION'] | |
WEBCHECKOUT = 'WEB_CHECKOUT' | |
TOKEN = 'TOKEN' | |
PAGOS = 'PAGO' | |
CONSULTA = 'CONSULTA' | |
url_webcheckout = "" | |
url_token = "" | |
url_pagos = "" | |
url_consulta = "" | |
test = True | |
def __init__(self, cuenta, moneda, urls): | |
""" Datos de la cuenta de PayU necesarios para usar la API""" | |
self.cuenta = cuenta | |
self.api_login = cuenta.api_login | |
self.api_key = cuenta.api_key | |
self.account_id = cuenta.account_id | |
self.merchant_id = cuenta.merchant_id | |
self.buyer = cuenta.payer_email | |
self.test = cuenta.test | |
self.language = cuenta.language | |
self.currency = moneda.divisa if moneda else "MXN" | |
self.paymentCountry = cuenta.paymentCountry | |
self._asigna_urls(urls) | |
# Default data for every request | |
self.payload = { | |
'language': self.language, | |
'command': 'PING', | |
'merchant': { | |
'apiLogin': self.api_login, | |
'apiKey': self.api_key | |
}, | |
'test': self.test | |
} | |
self.order = { | |
'language': self.language, | |
'accountId': self.account_id | |
} | |
self.transaction_data = { | |
'type': 'AUTHORIZATION_AND_CAPTURE', | |
'paymentCountry': self.paymentCountry, | |
} | |
self._currency = self.currency | |
def get_cuenta(self): | |
return self.cuenta | |
def _send_request(self, payload, url_envio): | |
headers = { | |
'Content-type': 'application/json; charset=utf-8;', | |
'Accept': 'application/json;charset=utf-8;' | |
} | |
response = requests.post( | |
url_envio, | |
data=json.dumps(payload), | |
headers=headers, | |
verify=False | |
) | |
return response | |
def create_token(self, | |
payer_id, | |
full_name, | |
payment_method, | |
card_number, | |
expiration_date): | |
payload = self.payload.copy() | |
payload.update({ | |
'command': 'CREATE_TOKEN', | |
'creditCardToken': { | |
'payerId': payer_id, | |
'name': full_name, | |
'paymentMethod': payment_method, | |
'number': card_number, | |
'expirationDate': expiration_date | |
} | |
}) | |
response = self._send_request(payload, self.url_token) | |
return json.loads(response.text) | |
def get_tokens(self, payer_id, token_id): | |
""" Información sobre el token """ | |
payload = self.payload.copy() | |
payload.update({ | |
'command': 'GET_TOKENS', | |
'creditCardTokenInformation': { | |
'payerId': payer_id, | |
'creditCardTokenId': token_id, | |
"startDate": "2014-01-15T15:30:00", | |
"endDate": "2020-01-16T17:40:00" | |
} | |
}) | |
response = self._send_request(payload, self.url_pagos) | |
return json.loads(response.text) | |
def remove_token(self, payer_id, token_id): | |
""" Información sobre el token """ | |
payload = self.payload.copy() | |
payload.update({ | |
'command': 'REMOVE_TOKEN', | |
'removeCreditCardToken': { | |
'payerId': payer_id, | |
'creditCardTokenId': token_id | |
} | |
}) | |
response = self._send_request(payload, self.url_token) | |
return json.loads(response.text) | |
def submit_token_transaction(self, | |
token_id, | |
reference_code, | |
description, | |
notify_url, | |
value, | |
email, | |
device_id, | |
ip_address, | |
user_agent, | |
cookie=None, | |
payment_method=None, | |
currency=None, | |
buyer=None, | |
payer=None | |
): | |
order = self.order.copy() | |
currency = currency if currency else self._currency | |
signature = hashlib.md5('%s~%s~%s~%s~%s' % ( | |
self.api_key, | |
self.merchant_id, | |
reference_code, | |
value, | |
currency | |
)) | |
order.update({ | |
'referenceCode': reference_code, | |
'description': description, | |
'signature': signature.hexdigest(), | |
'notifyUrl': notify_url, | |
'additionalValues': { | |
'TX_VALUE': { | |
'value': value, | |
'currency': self.currency | |
} | |
} | |
}) | |
if buyer: | |
order.update({ | |
'buyer': buyer | |
}) | |
transaction = self.transaction_data.copy() | |
ip_address = '127.0.0.1' | |
transaction.update({ | |
'order': order, | |
'creditCardTokenId': token_id, | |
'payer': { | |
'emailAddress': email | |
}, | |
'ipAddress': ip_address, | |
'deviceSessionId': device_id, | |
'userAgent': user_agent | |
}) | |
if payer: | |
transaction.update({ | |
'payer': payer | |
}) | |
if payment_method: | |
transaction.update({ | |
'paymentMethod': payment_method | |
}) | |
if cookie: | |
transaction.update({ | |
'cookie': cookie | |
}) | |
payload = self.payload.copy() | |
payload.update({ | |
'command': 'SUBMIT_TRANSACTION', | |
'transaction': transaction | |
}) | |
response = self._send_request(payload, self.url_pagos) | |
return response.json() | |
def submit_direct_transaction(self, | |
reference_code, | |
description, | |
notify_url, | |
value, | |
email, | |
device_id, | |
ip_address, | |
cookie, | |
user_agent, | |
creditCard, | |
payment_method, | |
currency=None, | |
buyer=None, | |
payer=None): | |
order = self.order.copy() | |
currency = currency if currency else self._currency | |
signature = hashlib.md5('%s~%s~%s~%s~%s' % ( | |
self.api_key, | |
self.merchant_id, | |
reference_code, | |
value, | |
currency | |
)) | |
order.update({ | |
'referenceCode': reference_code, | |
'description': description, | |
'signature': signature.hexdigest(), | |
'notifyUrl': notify_url, | |
'additionalValues': { | |
'TX_VALUE': { | |
'value': value, | |
'currency': self.currency | |
} | |
} | |
}) | |
if buyer: | |
order.update({ | |
'buyer': buyer | |
}) | |
transaction = self.transaction_data.copy() | |
ip_address = '127.0.0.1' | |
transaction.update({ | |
'paymentMethod': payment_method, | |
'order': order, | |
'creditCard': creditCard, | |
'payer': { | |
'emailAddress': email | |
}, | |
'ipAddress': ip_address, | |
# 'deviceSessionId': device_id, | |
# 'cookie': cookie, | |
# 'userAgent': user_agent | |
}) | |
if payer: | |
transaction.update({ | |
'payer': payer | |
}) | |
payload = self.payload.copy() | |
payload.update({ | |
'command': 'SUBMIT_TRANSACTION', | |
'transaction': transaction | |
}) | |
response = self._send_request(payload, self.url_pagos) | |
return json.loads(response.text) | |
def submit_web_checkout(self, | |
reference_code, | |
description, | |
amount, | |
currency=None, | |
confirmationUrl=None, | |
responseUrl=None, | |
buyer=None, | |
payer=None, | |
otros={}): | |
order = self.order.copy() | |
currency = currency if currency else self._currency | |
buyer = buyer if buyer else self.buyer | |
signature = hashlib.md5('%s~%s~%s~%s~%s' % ( | |
self.merchant_id, | |
self.api_key, | |
reference_code, | |
amount, | |
currency | |
)) | |
order.update({ | |
'accountId': self.account_id, | |
'merchantId': self.merchant_id, | |
'referenceCode': reference_code, | |
'description': description, | |
'signature': signature.hexdigest(), | |
'amount': amount, | |
'tax': 0, | |
'taxReturnBase': 0, | |
'currency': currency, | |
'test': self.test, | |
'buyerEmail': buyer | |
}) | |
if responseUrl: | |
order.update({ | |
'responseUrl': responseUrl | |
}) | |
if confirmationUrl: | |
order.update({ | |
'confirmationUrl': confirmationUrl | |
}) | |
order.update(otros) | |
response = self._send_request(order, self.url_webcheckout) | |
return json.loads(response.text) | |
def order_detail(self, order_id): | |
payload = self.payload.copy() | |
payload.update({ | |
'command': 'ORDER_DETAIL', | |
'details': { | |
'orderId': order_id | |
} | |
}) | |
response = self._send_request(payload, url_envio=self.url_consulta) | |
return json.loads(response.text) | |
def transaction_response_detail(self, transaction_id): | |
payload = self.payload.copy() | |
payload.update({ | |
'command': 'TRANSACTION_RESPONSE_DETAIL', | |
'details': { | |
'transactionId': transaction_id | |
} | |
}) | |
response = self._send_request(payload, url_envio=self.url_consulta) | |
return json.loads(response.text) | |
def _asigna_urls(self, urls): | |
for url in urls: | |
if url.tipo == self.WEBCHECKOUT: | |
self.url_webcheckout = url.url | |
continue | |
if url.tipo == self.TOKEN: | |
self.url_token = url.url | |
continue | |
if url.tipo == self.PAGOS: | |
self.url_pagos = url.url | |
continue | |
if url.tipo == self.CONSULTA: | |
self.url_consulta = url.url | |
continue | |
def get_signature(self, reference_code, amount, currency=None): | |
return hashlib.md5('%s~%s~%s~%s~%s' % ( | |
self.api_key, | |
self.merchant_id, | |
reference_code, | |
amount, | |
currency if currency else self._currency | |
)).hexdigest() | |
class PayUError(Exception): | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment