Skip to content

Instantly share code, notes, and snippets.

@Verurteilt
Created March 15, 2016 19:16
Show Gist options
  • Save Verurteilt/af398e4acaaccbf7ab9f to your computer and use it in GitHub Desktop.
Save Verurteilt/af398e4acaaccbf7ab9f to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
import base64
import six
import datetime
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from General.utils import desencripta_rsa
from General.utils import encripta_rsa
from Simoba.bancos.models import Moneda, CuentaBanco, ClaconBanco
from General.emails.views.emails import envia_excepcion
from Simoba.bancos.models import obtener_datos_concentrador, FormaPago
from Simoba.concentrador.models import CatalogoMovimiento, MovimientoDestino
# MANAGERS ---------------------------
class UrlPAyUManager(models.Manager):
# Segun el ambiente regresara las urls payu
def get_queryset(self):
return super(UrlPAyUManager, self).get_queryset().filter(test=settings.TEST)
class CuentaPayUManager(models.Manager):
def encripta_cuentas(self, cuenta=None):
if cuenta:
cuenta.merchant_id = str(cuenta._merchant_id)
cuenta.account_id = str(cuenta._account_id)
cuenta.api_login = str(cuenta._api_login)
cuenta.api_key = str(cuenta._api_key)
cuenta.public_key = str(cuenta._public_key)
cuenta.tokenize_account_id = str(cuenta._tokenize_account_id)
cuenta.save()
return cuenta
else:
cuentas = super(CuentaPayUManager, self).get_queryset().all()
for cuenta in cuentas:
cuenta.merchant_id = str(cuenta._merchant_id)
cuenta.account_id = str(cuenta._account_id)
cuenta.api_login = str(cuenta._api_login)
cuenta.api_key = str(cuenta._api_key)
cuenta.public_key = str(cuenta._public_key)
cuenta.tokenize_account_id = str(cuenta._tokenize_account_id)
cuenta.save()
return True
def get_queryset(self):
return super(CuentaPayUManager, self).get_queryset().filter(test=settings.TEST)
# MODELS ---------------------------------------------
# Cuentas payu
class CuentaPayU(models.Model):
_merchant_id = models.TextField(db_column='merchant_id')
_account_id = models.TextField(db_column='account_id')
_api_login = models.TextField(db_column='api_login')
_api_key = models.TextField(db_column='api_key')
_public_key = models.TextField(db_column='public_key')
_tokenize_account_id = models.TextField(db_column='tokenize_account_id')
payer_email = models.CharField(max_length=100)
language = models.CharField(max_length=10, default="es")
paymentCountry = models.CharField(max_length=10, default="MX")
test = models.BooleanField(default=True)
habilitado = models.BooleanField(default=True)
cuentabanco = models.ForeignKey(CuentaBanco, default=8)
claconbanco_tdc = models.ForeignKey(ClaconBanco, default=7, related_name="clacon_tdc")
claconbanco_dom = models.ForeignKey(ClaconBanco, default=54, related_name="clacon_dom")
objects = CuentaPayUManager()
def get_merchant_id(self):
return self.desencriptar(self._merchant_id)
def set_merchant_id(self, merchant_id):
self._merchant_id = base64.encodestring(encripta_rsa(merchant_id))
merchant_id = property(get_merchant_id, set_merchant_id)
def get_account_id(self):
return self.desencriptar(self._account_id)
def set_account_id(self, account_id):
self._account_id = base64.encodestring(encripta_rsa(account_id))
account_id = property(get_account_id, set_account_id)
def get_api_login(self):
return self.desencriptar(self._api_login)
def set_api_login(self, api_login):
self._api_login = base64.encodestring(encripta_rsa(api_login))
api_login = property(get_api_login, set_api_login)
def get_api_key(self):
return self.desencriptar(self._api_key)
def set_api_key(self, api_key):
self._api_key = base64.encodestring(encripta_rsa(api_key))
api_key = property(get_api_key, set_api_key)
def get_public_key(self):
return self.desencriptar(self._public_key)
def set_public_key(self, public_key):
self._public_key = base64.encodestring(encripta_rsa(public_key))
public_key = property(get_public_key, set_public_key)
def get_tokenize_account_id(self):
return self.desencriptar(self._tokenize_account_id)
def set_tokenize_account_id(self, tokenize_account_id):
self._tokenize_account_id = base64.encodestring(encripta_rsa(tokenize_account_id))
tokenize_account_id = property(get_tokenize_account_id, set_tokenize_account_id)
def desencriptar(self, data):
return desencripta_rsa(base64.decodestring(data))
class UrlPayu(models.Model):
url = models.CharField(max_length=150)
tipo = models.CharField(max_length=30)
descripcion = models.CharField(max_length=150)
habilitado = models.BooleanField(default=True)
test = models.BooleanField(default=True)
objects = UrlPAyUManager()
class Meta:
unique_together = ("url", "tipo", 'test')
# Nos permitira identifcar que cuenta usar en caso de cada campus, programa, nivel
class ProgramaCuentaPayU(models.Model):
cuenta = models.ForeignKey("CuentaPayU")
moneda = models.ForeignKey(Moneda, default=1)
campus = models.CharField(max_length=100, null=True)
programa = models.CharField(max_length=100, null=True)
# Token que guardarmos de payu para la domiciliacion del alumno
class TokenPayu(models.Model):
alumno = models.ForeignKey(User)
programacuentapayu = models.ForeignKey(ProgramaCuentaPayU)
token = models.CharField(max_length=72)
metodo = models.CharField(max_length=25, null=True, blank=True)
mascara = models.CharField(max_length=20, null=True, blank=True)
creator = models.ForeignKey(User, related_name='creator')
created = models.DateTimeField(auto_now_add=True)
lastupdate = models.DateTimeField(auto_now=True)
payment_day = models.PositiveSmallIntegerField(null=True, blank=True)
habilitado = models.BooleanField(blank=True, default=True)
prioridad = models.PositiveIntegerField(null=True, blank=True)
def obtener_informacion(self):
from Simoba.payu.views.payu_core import PayU
cuenta = self.programacuentapayu.cuenta
urls = UrlPayu.objects.all()
obj_payu = PayU(cuenta, self.programacuentapayu.moneda, urls)
tokens = obj_payu.get_tokens(self.alumno.username, self.token)
return tokens
def guarda_informacion(self):
if self.valida_estado():
info = self.obtener_informacion()
_token = info.get('creditCardTokenList')[0]
self.metodo = _token.get("paymentMethod", "")
self.mascara = _token.get("maskedNumber", "")
self.save()
return True
return False
def valida_estado(self):
tokens = self.obtener_informacion()
if tokens.get('code', None):
_tokens = tokens.get('creditCardTokenList')[0]
if _tokens.get('name') == u"APPROVED":
return True
else:
return False
return False
# Guardamos las transacciones realizadas
class TransactionPayU(models.Model):
code = models.CharField(max_length=30, null=True, blank=True)
orderId = models.IntegerField(default=0)
transactionId = models.CharField(max_length=72, null=True, blank=True)
state = models.CharField(max_length=30, null=True, blank=True)
paymentNetworkResponseCode = models.CharField(max_length=30, null=True, blank=True)
paymentNetworkResponseErrorMessage = models.CharField(max_length=100, null=True, blank=True)
trazabilityCode = models.CharField(max_length=30, null=True, blank=True)
authorizationCode = models.CharField(max_length=30, null=True, blank=True)
pendingReason = models.CharField(max_length=100, null=True, blank=True)
responseCode = models.CharField(max_length=100, null=True, blank=True)
errorCode = models.CharField(max_length=30, null=True, blank=True)
responseMessage = models.CharField(max_length=250, null=True, blank=True)
transactionDate = models.CharField(max_length=30, null=True, blank=True)
transactionTime = models.CharField(max_length=30, null=True, blank=True)
operationDate = models.CharField(max_length=30, null=True, blank=True)
extraParameters = models.CharField(max_length=100, null=True, blank=True)
monto = models.DecimalField(max_digits=14, decimal_places=2)
# Para llevar un control de estados de la transaccion
tran_num = models.IntegerField(default=-1, null=True, blank=True) # Campo para enviar que se va a pagar en banner
procesado = models.BooleanField(default=False)
token = models.ForeignKey(TokenPayu, null=True)
datos_enviados = models.TextField(null=True, blank=True)
referencia_siu = models.CharField(max_length=72)
creator = models.ForeignKey(User, null=True, blank=True)
date_update = models.DateTimeField(auto_now=True, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
super(TransactionPayU, self).save(*args, **kwargs)
try:
if self.code:
log = TransactionPayULog()
log.transaction = self
log.state = self.state
log.responseCode = self.responseCode
log.responseMessage = self.responseMessage
log.save()
except Exception:
envia_excepcion("save")
pass
def obtener_informacion(self):
try:
from Simoba.payu.views.payu_core import PayU
cuenta = self.token.programacuentapayu.cuenta
urls = UrlPayu.objects.all()
obj_payu = PayU(cuenta, self.token.programacuentapayu.moneda, urls)
return obj_payu.transaction_response_detail(self.transactionId)
except Exception:
envia_excepcion(funcion="TransactionPayU.obtener_informacion()")
return None
def actualiza_datos(self):
informacion_nueva = self.obtener_informacion()
try:
code = informacion_nueva.get("code", self.code)
if not code == "SUCCESS":
return None
datos = informacion_nueva.get("result", {}).get("payload", {})
self.state = datos.get("state", self.state)
self.responseCode = datos.get("responseCode", self.responseCode)
self.save()
except Exception:
envia_excepcion(funcion="TransactionPayU.actualiza_datos()")
return None
def bajar_concentrador(self):
from Simoba.concentrador.models import Concentrador
if self.responseCode == "APPROVED":
datos_concentrador = self.obtener_datos_concentrador()
if self.tran_num > -1:
datos_concentrador["iddestino"] = self.tran_num
concentrador = Concentrador.objects.create(**datos_concentrador)
if concentrador:
concentrador.aplicar_pago_en_banner()
return True
def obtener_clacon_banco(self):
return self.token.programacuentapayu.cuenta.claconbanco_dom
def obtener_matricula_referencia(self):
return str(self.referencia_siu).split("-")[1]
def obtener_numero_transaccion(self):
return int(str(self.referencia_siu).split("-")[2])
####METHODS TO CONCENTRADOR
def obtener_monto(self):
return self.monto
def obtener_forma_pago(self):
return ConfiguracionPayu.objects.first().forma_pago_domiciliacion
def obtener_fecha_movimiento(self):
return datetime.datetime.fromtimestamp(int(self.operationDate) / 1e3)
def obtener_folio_pago(self):
return self.orderId
def obtener_conciliador(self):
return ConfiguracionPayu.objects.first().usuario_conciliador_domiciliacion
def obtener_cuenta_banco(self):
return self.token.programacuentapayu.cuenta.cuentabanco
def obtener_usuario(self):
return self.token.alumno
def obtener_cuenta_contable(self):
return None
def obtener_tipo_movimiento(self):
return ConfiguracionPayu.objects.first().catalogomovimiento
def obtener_destino(self):
return MovimientoDestino.objects.get_destino(movimiento = self.obtener_tipo_movimiento())
def obtener_periodo(self):
usuario = self.obtener_usuario()
periodo = usuario and usuario.obtener_periodo_banner() or u''
return periodo or u''
def obtener_clacon_destino(self):
clacon_banco = self.token.programacuentapayu.cuenta.claconbanco_dom
return clacon_banco and clacon_banco.clacon_destino or None
class TransactionPayULog(models.Model):
transaction = models.ForeignKey(TransactionPayU)
state = models.CharField(max_length=30, null=True, blank=True)
responseCode = models.CharField(max_length=100, null=True, blank=True)
responseMessage = models.CharField(max_length=250, null=True, blank=True)
date_update = models.DateTimeField(auto_now=True, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
# Guardamos las 2 respuesta de payu para tener un mejor control
# Lo que nos regresa en la pagina de respuesta
class RespuestaWebCheckout(models.Model):
fecha_simoba = models.DateTimeField(auto_now_add=True)
merchantId = models.CharField(max_length=20, null=True, blank=True)
transactionState = models.SmallIntegerField(null=True, blank=True)
risk = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True)
polResponseCode = models.CharField(max_length=100, null=True, blank=True)
referenceCode = models.CharField(max_length=60, null=True, blank=True)
reference_pol = models.CharField(max_length=255, null=True, blank=True)
signature = models.CharField(max_length=255, null=True, blank=True)
polPaymentMethod = models.CharField(max_length=255, null=True, blank=True)
polPaymentMethodType = models.SmallIntegerField(null=True, blank=True)
installmentsNumber = models.SmallIntegerField(null=True, blank=True)
tx_value = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True)
tx_tax = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True)
buyerEmail = models.CharField(max_length=255, null=True, blank=True)
processingDate = models.CharField(max_length=150, null=True, blank=True)
currency = models.CharField(max_length=10, null=True, blank=True)
cus = models.CharField(max_length=255, null=True, blank=True)
pseBank = models.CharField(max_length=255, null=True, blank=True)
lng = models.CharField(max_length=10, null=True, blank=True)
description = models.CharField(max_length=255, null=True, blank=True)
lapResponseCode = models.CharField(max_length=80, null=True, blank=True)
lapPaymentMethod = models.CharField(max_length=255, null=True, blank=True)
lapPaymentMethodType = models.CharField(max_length=255, null=True, blank=True)
lapTransactionState = models.CharField(max_length=50, null=True, blank=True)
message = models.CharField(max_length=255, null=True, blank=True)
extra1 = models.CharField(max_length=255, null=True, blank=True)
extra2 = models.CharField(max_length=255, null=True, blank=True)
extra3 = models.CharField(max_length=255, null=True, blank=True)
authorizationCode = models.CharField(max_length=20, null=True, blank=True)
merchant_address = models.CharField(max_length=255, null=True, blank=True)
merchant_name = models.CharField(max_length=255, null=True, blank=True)
merchant_url = models.CharField(max_length=255, null=True, blank=True)
orderLanguage = models.CharField(max_length=10, null=True, blank=True)
pseCycle = models.CharField(max_length=50, null=True, blank=True)
pseReference1 = models.CharField(max_length=255, null=True, blank=True)
pseReference2 = models.CharField(max_length=255, null=True, blank=True)
pseReference3 = models.CharField(max_length=255, null=True, blank=True)
telephone = models.CharField(max_length=30, null=True, blank=True)
transactionId = models.CharField(max_length=40, null=True, blank=True)
trazabilityCode = models.CharField(max_length=80, null=True, blank=True)
tx_administrative_fee = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True)
tx_tax_administrative_fee = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True)
tx_tax_administrative_fee_return_base = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True)
action_code_description = models.CharField(max_length=255, null=True, blank=True)
cc_holder = models.CharField(max_length=150, null=True, blank=True)
cc_number = models.CharField(max_length=150, null=True, blank=True)
processing_date_time = models.CharField(max_length=150, null=True, blank=True)
request_number = models.CharField(max_length=20, null=True, blank=True)
polTransactionState = models.CharField(max_length=20, null=True, blank=True)
procesado = models.BooleanField(default=False)
otros_datos = models.TextField(null=True, blank=True)
def obtener_matricula_referencia(self):
return str(self.referenceCode).split("-")[0]
def obtener_numero_transaccion(self):
return int(str(self.referenceCode).split("-")[1])
def obtener_programacuentapayu(self):
return ProgramaCuentaPayU.objects.get(pk=self.extra1)
####METHODS TO CONCENTRADOR
def obtener_clacon_banco(self):
return self.obtener_programacuentapayu().cuenta.claconbanco_tdc
def obtener_monto(self):
return self.tx_value
def obtener_forma_pago(self):
return ConfiguracionPayu.objects.first().forma_pago_webcheckout
def obtener_fecha_movimiento(self):
return self.processingDate
def obtener_folio_pago(self):
return self.reference_pol
def obtener_conciliador(self):
return ConfiguracionPayu.objects.first().usuario_conciliador_webcheckout
def obtener_cuenta_banco(self):
return self.obtener_programacuentapayu().cuenta.cuentabanco
def obtener_usuario(self):
return User.objects.get(username=self.obtener_matricula_referencia())
def obtener_cuenta_contable(self):
return None
def obtener_tipo_movimiento(self):
return ConfiguracionPayu.objects.first().catalogomovimiento
def obtener_destino(self):
return MovimientoDestino.objects.get_destino(movimiento = self.obtener_tipo_movimiento())
def obtener_periodo(self):
usuario = self.obtener_usuario()
periodo = usuario and usuario.obtener_periodo_banner() or u''
return periodo or u''
def obtener_clacon_destino(self):
clacon_banco = self.obtener_programacuentapayu().cuenta.claconbanco_tdc
return clacon_banco and clacon_banco.clacon_destino or None
# Lo que nos regresa en la pagina de confirmacion
class ConfirmacionWebCheckout(models.Model):
fecha_simoba = models.DateTimeField(auto_now_add=True)
respuesta = models.OneToOneField(RespuestaWebCheckout, null=True, blank=True)
merchant_id = models.CharField(max_length=20, blank=True, null=True)
state_pol = models.CharField(max_length=40, blank=True, null=True)
risk = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
response_code_pol = models.CharField(max_length=255, blank=True, null=True)
reference_sale = models.CharField(max_length=255, blank=True, null=True)
reference_pol = models.CharField(max_length=255, blank=True, null=True)
sign = models.CharField(max_length=255, blank=True, null=True)
extra1 = models.CharField(max_length=255, blank=True, null=True)
extra2 = models.CharField(max_length=255, blank=True, null=True)
payment_method = models.CharField(max_length=20, blank=True, null=True)
payment_method_type = models.CharField(max_length=20, blank=True, null=True)
installments_number = models.CharField(max_length=20, blank=True, null=True)
value = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
tax = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
additional_value = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
transaction_date = models.CharField(max_length=150, blank=True, null=True)
currency = models.CharField(max_length=10, blank=True, null=True)
email_buyer = models.CharField(max_length=200, blank=True, null=True)
cus = models.CharField(max_length=100, blank=True, null=True)
pse_bank = models.CharField(max_length=150, blank=True, null=True)
test = models.BooleanField(blank=True)
description = models.CharField(max_length=255, blank=True, null=True)
billing_address = models.CharField(max_length=255, blank=True, null=True)
shipping_address = models.CharField(max_length=100, blank=True, null=True)
phone = models.CharField(max_length=30, blank=True, null=True)
office_phone = models.CharField(max_length=30, blank=True, null=True)
account_number_ach = models.CharField(max_length=40, blank=True, null=True)
account_type_ach = models.CharField(max_length=40, blank=True, null=True)
administrative_fee = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
administrative_fee_base = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
administrative_fee_tax = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
airline_code = models.CharField(max_length=10, blank=True, null=True)
attempts = models.SmallIntegerField(blank=True, null=True)
authorization_code = models.CharField(max_length=20, blank=True, null=True)
bank_id = models.CharField(max_length=255, blank=True, null=True)
billing_city = models.CharField(max_length=255, blank=True, null=True)
billing_country = models.CharField(max_length=10, blank=True, null=True)
commision_pol = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
commision_pol_currency = models.CharField(max_length=10, blank=True, null=True)
customer_number = models.IntegerField(blank=True, null=True)
date = models.CharField(max_length=150, blank=True, null=True)
error_code_bank = models.CharField(max_length=255, blank=True, null=True)
error_message_bank = models.CharField(max_length=255, blank=True, null=True)
exchange_rate = models.DecimalField(max_digits=14, decimal_places=2, blank=True, null=True)
ip = models.CharField(max_length=50, blank=True, null=True)
nickname_buyer = models.CharField(max_length=200, blank=True, null=True)
nickname_seller = models.CharField(max_length=200, blank=True, null=True)
payment_method_id = models.IntegerField(blank=True, null=True)
payment_request_state = models.CharField(max_length=40, blank=True, null=True)
pseReference1 = models.CharField(max_length=255, blank=True, null=True)
pseReference2 = models.CharField(max_length=255, blank=True, null=True)
pseReference3 = models.CharField(max_length=255, blank=True, null=True)
response_message_pol = models.CharField(max_length=255, blank=True, null=True)
shipping_city = models.CharField(max_length=60, blank=True, null=True)
shipping_country = models.CharField(max_length=2, blank=True, null=True)
transaction_bank_id = models.CharField(max_length=255, blank=True, null=True)
transaction_id = models.CharField(max_length=40, blank=True, null=True)
payment_method_name = models.CharField(max_length=255, blank=True, null=True)
otros_datos = models.TextField(null=True, blank=True)
def obtener_matricula_referencia(self):
return str(self.reference_sale).split("-")[0]
def obtener_numero_transaccion(self):
return int(str(self.reference_sale).split("-")[1])
def obtener_programacuentapayu(self):
return ProgramaCuentaPayU.objects.get(pk=self.extra1)
def obtener_clacon_banco(self):
return self.obtener_programacuentapayu().cuenta.claconbanco_tdc
####METHODS TO CONCENTRADOR
def obtener_monto(self):
return self.value
def obtener_forma_pago(self):
return ConfiguracionPayu.objects.first().forma_pago_webcheckout
def obtener_fecha_movimiento(self):
return self.transaction_date
def obtener_folio_pago(self):
return self.reference_pol
def obtener_conciliador(self):
return ConfiguracionPayu.objects.first().usuario_conciliador_webcheckout
def obtener_cuenta_banco(self):
return self.obtener_programacuentapayu().cuenta.cuentabanco
def obtener_usuario(self):
return User.objects.get(username=self.obtener_matricula_referencia())
def obtener_cuenta_contable(self):
return None
def obtener_tipo_movimiento(self):
return ConfiguracionPayu.objects.first().catalogomovimiento
def obtener_destino(self):
from Simoba.concentrador.models import MovimientoDestino
return MovimientoDestino.objects.get_destino(movimiento = self.obtener_tipo_movimiento())
def obtener_periodo(self):
usuario = self.obtener_usuario()
periodo = usuario and usuario.obtener_periodo_banner() or u''
return periodo or u''
def obtener_clacon_destino(self):
clacon_banco = self.obtener_programacuentapayu().cuenta.claconbanco_tdc
return clacon_banco and clacon_banco.clacon_destino or None
class ConfiguracionPayu(models.Model):
forma_pago_webcheckout = models.ForeignKey(FormaPago, related_name="forma_pago_webcheckout", default=22)
forma_pago_domiciliacion = models.ForeignKey(FormaPago, related_name="forma_pago_domiciliacion", default=15)
catalogomovimiento = models.ForeignKey(CatalogoMovimiento, default=1)
usuario_conciliador_webcheckout = models.ForeignKey(User, related_name="usuario_conciliador_webcheckout", default=56)
usuario_conciliador_domiciliacion = models.ForeignKey(User, related_name="usuario_conciliador_domiciliacion", default=56)
monto_minimo = models.DecimalField(max_digits=14, decimal_places=2, default="40.00")
descripcion_pago_domiciliado = models.CharField(max_length=250, default="Pago domiciliado")
TransactionPayU.add_to_class("obtener_datos_concentrador", obtener_datos_concentrador)
RespuestaWebCheckout.add_to_class("obtener_datos_concentrador", obtener_datos_concentrador)
ConfirmacionWebCheckout.add_to_class("obtener_datos_concentrador", obtener_datos_concentrador)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment