Skip to content

Instantly share code, notes, and snippets.

@Verurteilt
Created March 15, 2016 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Verurteilt/37e175e670c3b6956a57 to your computer and use it in GitHub Desktop.
Save Verurteilt/37e175e670c3b6956a57 to your computer and use it in GitHub Desktop.
# -*- 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