Skip to content

Commit

Permalink
Initial version of PreApprovals
Browse files Browse the repository at this point in the history
Added mock as dev dependency
  • Loading branch information
marcelometal committed Aug 17, 2018
1 parent 68090c2 commit ce225ba
Show file tree
Hide file tree
Showing 12 changed files with 1,245 additions and 21 deletions.
30 changes: 30 additions & 0 deletions docs/tutorial.rst
Expand Up @@ -250,6 +250,36 @@ Efetue o checkout transparent::
>>> data = api.checkout()


====================================
Trabalhando com a API de Assinaturas
====================================

Criando um Plano ::

>>> from pagseguro.api import PagSeguroApiPreApproval
>>> from django.utils import timezone
>>>
>>> pagseguro_api = PagSeguroApiPreApproval(reference='id-unico-de-referencia-do-seu-sistema')
>>> final_date = timezone.now() + timezone.timedelta(days=180)
>>> pre_approval_plan_data = {
... 'name': 'Seguro contra roubo de Notebook',
... 'amount_per_payment': 100,
... 'period': 'Monthly',
... 'final_date': final_date,
... 'max_total_amount': 300,
... 'charge': 'auto',
... 'details': 'Todo dia 28 será cobrado o valor de R100,00',
... }
>>> pagseguro_api.create_plan(**pre_approval_plan_data)

Cancelando uma assinatura via vendedor ::

>>> from pagseguro.api import PagSeguroApiPreApproval
>>>
>>> pagseguro_api = PagSeguroApiPreApproval()
>>> data = pagseguro_api.pre_approval_cancel('codigo')


===================================
Trabalhando com Signals de checkout
===================================
Expand Down
45 changes: 42 additions & 3 deletions pagseguro/admin.py
Expand Up @@ -2,7 +2,10 @@
from __future__ import unicode_literals
from django.contrib import admin

from pagseguro.models import Checkout, Transaction, TransactionHistory
from pagseguro.models import (
Checkout, Transaction, TransactionHistory, PreApprovalPlan,
PreApproval, PreApprovalHistory
)


class CheckoutAdmin(admin.ModelAdmin):
Expand All @@ -25,14 +28,50 @@ class TransactionHistoryInline(admin.TabularInline):

class TransactionAdmin(admin.ModelAdmin):

list_display = ('code', 'reference', 'status', 'date', 'last_event_date')
list_display = (
'code', 'reference', 'status', 'date', 'last_event_date',
'transaction_type',
)
list_display_links = ('code', )
search_fields = ['code', 'reference']
list_filter = ('status', 'date', 'last_event_date')
list_filter = ('status', 'date', 'last_event_date', 'transaction_type')
inlines = [
TransactionHistoryInline,
]

class PreApprovalPlanAdmin(admin.ModelAdmin):

list_display = (
'id', 'name', 'amount_per_payment', 'reference', 'period',
'redirect_code'
)
list_display_links = ('id', 'name')
search_fields = ['redirect_code', 'name', 'reference']
list_filter = ('charge', 'period')

class PreApprovalHistoryInline(admin.TabularInline):

list_display = ('id', 'pre_approval', 'status', 'date')
list_display_links = ('id', )
search_fields = ['pre_approval__code', ]
list_filter = ('status', 'date')
model = PreApprovalHistory
extra = 0

class PreApprovalAdmin(admin.ModelAdmin):

list_display = (
'code', 'tracker', 'reference', 'status', 'date', 'last_event_date'
)
list_display_links = ('code', )
search_fields = ['code', 'reference']
list_filter = ('status', 'date', 'last_event_date')
inlines = [
PreApprovalHistoryInline,
]


admin.site.register(Checkout, CheckoutAdmin)
admin.site.register(Transaction, TransactionAdmin)
admin.site.register(PreApprovalPlan, PreApprovalPlanAdmin)
admin.site.register(PreApproval, PreApprovalAdmin)
189 changes: 179 additions & 10 deletions pagseguro/api.py
Expand Up @@ -8,11 +8,16 @@

from pagseguro.settings import (
PAGSEGURO_EMAIL, PAGSEGURO_TOKEN, CHECKOUT_URL, PAYMENT_URL,
NOTIFICATION_URL, TRANSACTION_URL, SESSION_URL
NOTIFICATION_URL, TRANSACTION_URL, SESSION_URL, PRE_APPROVAL_URL,
PRE_APPROVAL_REQUEST_URL, PRE_APPROVAL_REDIRECT_URL,
PRE_APPROVAL_NOTIFICATION_URL, PRE_APPROVAL_CANCEL_URL
)
from pagseguro.signals import (
notificacao_recebida, NOTIFICATION_STATUS, checkout_realizado,
checkout_realizado_com_sucesso, checkout_realizado_com_erro
checkout_realizado_com_sucesso, checkout_realizado_com_erro,
PRE_APPROVAL_NOTIFICATION_STATUS, pre_approval_notification,
pre_approval_status_cancelled, pre_approval_create_plan,
pre_approval_create_plan_error
)
from pagseguro.forms import PagSeguroItemForm

Expand Down Expand Up @@ -74,6 +79,12 @@ def __init__(self, checkout_url=None, redirect_url=None,
self.base_params.update(kwargs)
self.params = {}
self.items = []
# FIXME
self.pre_approval_url = PRE_APPROVAL_URL
self.pre_approval_request_url = PRE_APPROVAL_REQUEST_URL
self.pre_approval_redirect_url = PRE_APPROVAL_REDIRECT_URL
self.pre_approval_notification_url = PRE_APPROVAL_NOTIFICATION_URL
self.pre_approval_cancel_url = PRE_APPROVAL_CANCEL_URL

def add_item(self, item):
self.items.append(item)
Expand Down Expand Up @@ -141,7 +152,9 @@ def checkout(self):
logger.debug('operation=api_checkout, data={!r}'.format(data))
return data

def get_notification(self, notification_id):
def _get_notification(self, notification_id, url, notification_type,
notification_signal, notification_status):

response = requests.get(
self.notification_url + '/{}'.format(notification_id),
params={
Expand All @@ -152,17 +165,15 @@ def get_notification(self, notification_id):

if response.status_code == 200:
root = xmltodict.parse(response.text)
transaction = root['transaction']
notificacao_recebida.send(
transaction = root[notification_type]
notification_signal.send(
sender=self, transaction=transaction
)

status = transaction['status']
if status in NOTIFICATION_STATUS:
signal = NOTIFICATION_STATUS[status]
signal.send(
sender=self, transaction=transaction
)
if status in notification_status:
signal = notification_status[status]
signal.send(sender=self, transaction=transaction)

logger.debug(
'operation=api_get_notification, '
Expand All @@ -174,6 +185,25 @@ def get_notification(self, notification_id):
)
return response

def get_notification(self, notification_id, notification_type='transaction'):
if notification_type == 'transaction':
response = self._get_notification(
notification_id,
self.notification_url,
'transaction',
notificacao_recebida,
NOTIFICATION_STATUS,
)
else:
response = self._get_notification(
notification_id,
self.pre_approval_notification_url,
'preApproval',
pre_approval_notification,
PRE_APPROVAL_NOTIFICATION_STATUS,
)
return response

def get_transaction(self, transaction_id):
response = requests.get(
self.transaction_url + '/{}'.format(transaction_id),
Expand Down Expand Up @@ -211,6 +241,35 @@ def get_transaction(self, transaction_id):
)
return data

def get_pre_approval(self, pre_approval_id):
response = requests.get(
'{0}/{1}'.format(self.pre_approval_url, pre_approval_id),
params={
'email': self.base_params['email'],
'token': self.base_params['token']
}
)

if response.status_code == 200:
root = xmltodict.parse(response.text)
transaction = root['preApproval']

data = {
'transaction': transaction,
'status_code': response.status_code,
'success': True,
'date': timezone.now()
}
else:
data = {
'status_code': response.status_code,
'message': response.text,
'success': False,
'date': timezone.now()
}

return data


class PagSeguroApiTransparent(PagSeguroApi):
def __init__(self, session_url=None, **kwargs):
Expand Down Expand Up @@ -363,3 +422,113 @@ def get_session_id(self):
'data={!r}'.format(data)
)
return data


class PagSeguroApiPreApproval(PagSeguroApi):

def create(self, name, amount_per_payment, period, max_total_amount,
final_date='', max_amount_per_payment='', charge='auto',
details='', redirect_code=''):

from pagseguro.models import PreApprovalPlan

pre_approval = PreApprovalPlan(
name=name,
amount_per_payment=amount_per_payment,
period=period.upper(),
final_date=final_date,
max_total_amount=max_total_amount,
charge=charge,
details=details,
reference=self.base_params.get('reference', ''),
redirect_code=redirect_code,
)
pre_approval.save()

def set_pre_approval_data(self, name, amount_per_payment, period,
max_total_amount, final_date, charge='auto',
details=''):

self.params['preApprovalName'] = name
self.params['preApprovalAmountPerPayment'] = amount_per_payment
self.params['preApprovalPeriod'] = period
self.params['preApprovalFinalDate'] = final_date.isoformat()
self.params['preApprovalMaxTotalAmount'] = max_total_amount
self.params['preApprovalCharge'] = charge
self.params['preApprovalDetails'] = details

def create_plan(self, *args, **kwargs):
kwargs['max_total_amount'] = '{0:.2f}'.format(
kwargs['max_total_amount']
)
kwargs['amount_per_payment'] = '{0:.2f}'.format(
kwargs['amount_per_payment']
)

self.set_pre_approval_data(**kwargs)

self.build_params()
headers = {
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
response = requests.post(
self.pre_approval_request_url, self.params, headers=headers
)

if response.status_code == 200:
root = xmltodict.parse(response.text)
pre_approval = root['preApprovalRequest']

self.create(redirect_code=pre_approval['code'], **kwargs)

# FIXME
data = {
'pre_approval': pre_approval,
'status_code': response.status_code,
'success': True,
'date': parse(pre_approval['date']),
'code': pre_approval['code'],
'redirect_url': '{0}?code={1}'.format(
self.pre_approval_redirect_url, pre_approval['code']
),
}
pre_approval_create_plan.send(sender=self, data=data)
else:
# FIXME
data = {
'status_code': response.status_code,
'message': response.text,
'success': False,
'date': timezone.now()
}
pre_approval_create_plan_error.send(sender=self, data=data)

return data

def pre_approval_cancel(self, pre_approval_code):
# FIXME
headers = {
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
}

params = {
'email': self.base_params['email'],
'token': self.base_params['token'],
}

url = '{0}/{1}'.format(self.pre_approval_cancel_url, pre_approval_code)
response = requests.get(url, params, headers=headers)

if response.status_code == 200:
data = self.get_pre_approval(pre_approval_code).get('transaction')
pre_approval_notification.send(sender=self, transaction=data)
pre_approval_status_cancelled.send(sender=self, transaction=data)
else:
data = {
'status_code': response.status_code,
'message': response.text,
'success': False,
'date': timezone.now(),
}

return data

0 comments on commit ce225ba

Please sign in to comment.