Skip to content

Commit

Permalink
Merge PR #33
Browse files Browse the repository at this point in the history
  • Loading branch information
rochacbruno committed Jul 11, 2016
1 parent 264cc79 commit 382321d
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 28 deletions.
1 change: 0 additions & 1 deletion examples/flask/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import tempfile
import flask
from flask import json
from flask_seguro.cart import Cart
from flask_seguro.products import Products


Expand Down
91 changes: 88 additions & 3 deletions pagseguro/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import requests
import xmltodict

from .configs import Config, ConfigSandbox, AbstractConfig
from .configs import Config, ConfigSandbox, AbstractConfig # noqa
from .utils import parse_date, is_valid_email, is_valid_cpf, is_valid_cnpj

logger = logging.getLogger()


class PagSeguroNotificationResponse(object):

def __init__(self, xml, config=None):
self.xml = xml
self.config = config or {}
Expand Down Expand Up @@ -37,6 +38,7 @@ def parse_xml(self, xml):


class PagSeguroPreApprovalNotificationResponse(object):

def __init__(self, xml, config=None):
self.xml = xml
self.config = config or {}
Expand Down Expand Up @@ -64,6 +66,7 @@ def parse_xml(self, xml):


class PagSeguroPreApprovalCancel(object):

def __init__(self, xml, config=None):
self.xml = xml
self.config = config or {}
Expand Down Expand Up @@ -91,6 +94,7 @@ def parse_xml(self, xml):


class PagSeguroCheckoutSession(object):

def __init__(self, xml, config=None):
self.xml = xml
self.config = config or {}
Expand All @@ -101,6 +105,7 @@ def __init__(self, xml, config=None):

def parse_xml(self, xml):
""" parse returned data """

try:
parsed = xmltodict.parse(xml, encoding="iso-8859-1")
except Exception as e:
Expand Down Expand Up @@ -144,6 +149,7 @@ def parse_xml(self, xml):


class PagSeguroCheckoutResponse(object):

def __init__(self, xml, config=None):
self.xml = xml
self.config = config or {}
Expand Down Expand Up @@ -220,6 +226,38 @@ def parse_xml(self, xml):
self.total_pages = int(self.total_pages)


class PagSeguroPreApproval(object):

def __init__(self, xml, config=None):
self.xml = xml
self.config = config or {}
self.errors = None
self.parse_xml(xml)

def __getitem__(self, key):
getattr(self, key, None)

def parse_xml(self, xml):
try:
parsed = xmltodict.parse(xml, encoding="iso-8859-1")
except Exception as e:
logger.debug(
"Cannot parse the returned xml '{0}' -> '{1}'".format(xml, e)
)
parsed = {}

result = parsed.get('preApproval', {})
self.name = result.get('name', None)
self.code = result.get('code', None)
self.date = parse_date(result.get('date'))
self.tracker = result.get('tracker', None)
self.status = result.get('status', None)
self.reference = result.get('reference', None)
self.last_event_date = result.get('lastEventDate', None)
self.charge = result.get('charge', None)
self.sender = result.get('sender', {})


class PagSeguroPreApprovalSearch(object):

current_page = None
Expand All @@ -244,6 +282,10 @@ def parse_xml(self, xml):
"Cannot parse the returned xml '{0}' -> '{1}'".format(xml, e))
parsed = {}

if 'errors' in parsed:
self.errors = parsed['errors']['error']
return

search_result = parsed.get('preApprovalSearchResult', {})
self.pre_approvals = search_result.get('preApprovals', {})
self.pre_approvals = self.pre_approvals.get('preApproval', [])
Expand All @@ -268,6 +310,7 @@ class PagSeguro(object):
NONE = 3

def __init__(self, email, token, data=None, config=None):

self.config = config or Config()
assert isinstance(self.config, AbstractConfig), \
"Config should be instance of AbstractConfig"
Expand All @@ -286,6 +329,7 @@ def __init__(self, email, token, data=None, config=None):
self.redirect_url = None
self.notification_url = None
self.abandon_url = None
self.credit_card = {}
self.pre_approval = {}
self.checkout_session = None
self.payment = {}
Expand Down Expand Up @@ -348,6 +392,32 @@ def build_checkout_params(self, **kwargs):
params['paymentMethod'] = self.payment.get('method')
params['paymentMode'] = self.payment.get('mode')

if self.credit_card:
params['billingAddressCountry'] = 'BRA'

credit_card_keys_map = [
('creditCardToken', 'credit_card_token'),
('installmentQuantity', 'installment_quantity'),
('installmentValue', 'installment_value'),
('noInterestInstallmentQuantity',
'no_interest_installment_quantity'),
('creditCardHolderName', 'card_holder_name'),
('creditCardHolderCPF', 'card_holder_cpf'),
('creditCardHolderBirthDate', 'card_holder_birth_date'),
('creditCardHolderAreaCode', 'card_holder_area_code'),
('creditCardHolderPhone', 'card_holder_phone'),
('billingAddressStreet', 'billing_address_street'),
('billingAddressNumber', 'billing_address_number'),
('billingAddressComplement', 'billing_address_complement'),
('billingAddressDistrict', 'billing_address_district'),
('billingAddressPostalCode', 'billing_address_postal_code'),
('billingAddressCity', 'billing_address_city'),
('billingAddressState', 'billing_address_state'),
]

for key_to_set, key_to_get in credit_card_keys_map:
params[key_to_set] = self.credit_card.get(key_to_get)

if self.pre_approval:

params['preApprovalCharge'] = self.pre_approval.get('charge')
Expand All @@ -374,6 +444,7 @@ def build_checkout_params(self, **kwargs):

def build_pre_approval_payment_params(self, **kwargs):
""" build a dict with params """

params = kwargs or {}

params['reference'] = self.reference
Expand Down Expand Up @@ -448,8 +519,8 @@ def check_pre_approval_notification(self, code):
""" check a notification by its code """
response = self.get(
url=self.config.PRE_APPROVAL_NOTIFICATION_URL % code)
return PagSeguroPreApprovalNotificationResponse(response.content,
self.config)
return PagSeguroPreApprovalNotificationResponse(
response.content, self.config)

def pre_approval_ask_payment(self, **kwargs):
""" ask form a subscribe payment """
Expand Down Expand Up @@ -526,11 +597,25 @@ def _consume_query_pre_approvals(self, initial_date, final_date, page=None,
'page': page,
'maxPageResults': max_results,
}

self.data.update(querystring)
self.clean_none_params()

response = self.get(url=self.config.QUERY_PRE_APPROVAL_URL)
return PagSeguroPreApprovalSearch(response.content, self.config)

def query_pre_approvals_by_code(self, code):

""" query pre-approvals by code """
result = self._consume_query_pre_approvals_by_code(code)
return result

def _consume_query_pre_approvals_by_code(self, code):

response = self.get(
url='%s/%s' % (self.config.QUERY_PRE_APPROVAL_URL, code)
)
return PagSeguroPreApproval(response.content, self.config)

def add_item(self, **kwargs):
self.items.append(kwargs)
49 changes: 26 additions & 23 deletions pagseguro/configs.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# coding: utf-8

import abc


class AbstractConfig(object):

__metaclass__ = abc.ABCMeta

def __init__(self, sandbox=False):
self.sandbox = sandbox

@classmethod
def get(cls, key, default=None):
return getattr(cls, key, default)
def get(self, key, default=None):
return getattr(self, key, default)

@abc.abstractproperty
def BASE_URL(self):
Expand Down Expand Up @@ -157,32 +158,34 @@ def DATETIME_FORMAT(self, value):


class Config(AbstractConfig):
BASE_URL = 'https://ws.pagseguro.uol.com.br'
VERSION = '/v2/'
CHECKOUT_SUFFIX = VERSION + 'checkout'
CHARSET = 'UTF-8' # ISO-8859-1
NOTIFICATION_SUFFIX = VERSION + 'transactions/notifications/%s'
PRE_APPROVAL_NOTIFICATION_SUFFIX = (VERSION + 'pre-approvals/notifications'
'/%s')
PRE_APPROVAL_PAYMENT_URL = BASE_URL + VERSION + 'pre-approvals/payment'
PRE_APPROVAL_CANCEL_URL = BASE_URL + VERSION + 'pre-approvals/cancel/%s'
TRANSACTION_SUFFIX = VERSION + 'transactions/%s'
QUERY_TRANSACTION_SUFFIX = VERSION + 'transactions'
SESSION_CHECKOUT_SUFFIX = VERSION + 'sessions/'

BASE_URL = "https://ws.pagseguro.uol.com.br"
VERSION = "/v2/"
CHECKOUT_SUFFIX = VERSION + "checkout"
CHARSET = "UTF-8" # ISO-8859-1
NOTIFICATION_SUFFIX = VERSION + "transactions/notifications/%s"
PRE_APPROVAL_NOTIFICATION_SUFFIX = (
VERSION + "pre-approvals/notifications/%s"
)
PRE_APPROVAL_PAYMENT_URL = BASE_URL + VERSION + "pre-approvals/payment"
PRE_APPROVAL_CANCEL_URL = BASE_URL + VERSION + "pre-approvals/cancel/%s"
TRANSACTION_SUFFIX = VERSION + "transactions/%s"
QUERY_TRANSACTION_SUFFIX = VERSION + "transactions"
SESSION_CHECKOUT_SUFFIX = VERSION + "sessions/"
SESSION_CHECKOUT_URL = BASE_URL + SESSION_CHECKOUT_SUFFIX
TRANSPARENT_CHECKOUT_URL = BASE_URL + QUERY_TRANSACTION_SUFFIX + '/'
CHECKOUT_URL = BASE_URL + CHECKOUT_SUFFIX
NOTIFICATION_URL = BASE_URL + NOTIFICATION_SUFFIX
PRE_APPROVAL_NOTIFICATION_URL = BASE_URL + PRE_APPROVAL_NOTIFICATION_SUFFIX
TRANSACTION_URL = BASE_URL + TRANSACTION_SUFFIX
QUERY_TRANSACTION_URL = BASE_URL + QUERY_TRANSACTION_SUFFIX
QUERY_PRE_APPROVAL_URL = BASE_URL + VERSION + 'pre-approvals'
CURRENCY = 'BRL'
CTYPE = 'application/x-www-form-urlencoded; charset={0}'.format(CHARSET)
HEADERS = {'Content-Type': CTYPE}
REFERENCE_PREFIX = 'REF%s'
PAYMENT_HOST = 'https://pagseguro.uol.com.br'
PAYMENT_URL = PAYMENT_HOST + CHECKOUT_SUFFIX + '/payment.html?code=%s'
QUERY_PRE_APPROVAL_URL = BASE_URL + VERSION + "pre-approvals"
CURRENCY = "BRL"
CTYPE = "application/x-www-form-urlencoded; charset={0}".format(CHARSET)
HEADERS = {"Content-Type": CTYPE}
REFERENCE_PREFIX = "REF%s"
PAYMENT_HOST = "https://pagseguro.uol.com.br"
PAYMENT_URL = PAYMENT_HOST + CHECKOUT_SUFFIX + "/payment.html?code=%s"
DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S'


Expand Down
2 changes: 1 addition & 1 deletion tests/test_pagseguro_sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import unittest

from pagseguro import PagSeguro, PagSeguroTransactionSearchResult
from pagseguro.configs import Config, ConfigSandbox
from pagseguro.configs import ConfigSandbox
from pagseguro.exceptions import PagSeguroValidationError
from pagseguro.utils import is_valid_email, is_valid_cpf

Expand Down

0 comments on commit 382321d

Please sign in to comment.