def setUp(self):
     with mock.patch('requests.post') as mock_post:
         response = mock.Mock()
         response.status_code = 200
         response.text = ERROR_RESPONSE
         mock_post.return_value = response
         self.pairs = post('http://example.com', {})
예제 #2
0
 def setUp(self):
     with mock.patch('requests.post') as mock_post:
         response = mock.Mock()
         response.status_code = 200
         response.content = ERROR_RESPONSE
         mock_post.return_value = response
         self.pairs = post('http://example.com', {})
예제 #3
0
def _fetch_response(method, extra_params):
    """
    Fetch the response from PayPal and return a transaction object
    """
    # Build parameter string
    params = {
        'METHOD': method,
        'VERSION': API_VERSION,
        'USER': settings.PAYPAL_API_USERNAME,
        'PWD': settings.PAYPAL_API_PASSWORD,
        'SIGNATURE': settings.PAYPAL_API_SIGNATURE,
    }
    params.update(extra_params)

    if getattr(settings, 'PAYPAL_SANDBOX_MODE', True):
        url = 'https://api-3t.sandbox.paypal.com/nvp'
    else:
        url = 'https://api-3t.paypal.com/nvp'
    pairs = gateway.post(url, params)

    # Record transaction data - we save this model whether the txn
    # was successful or not
    txn = models.ExpressTransaction(
        method=method,
        version=API_VERSION,
        ack=pairs['ACK'],
        raw_request=pairs['_raw_request'],
        raw_response=pairs['_raw_response'],
        response_time=pairs['_response_time'],
    )
    if txn.is_successful:
        txn.correlation_id = pairs['CORRELATIONID']
        if method == SET_EXPRESS_CHECKOUT:
            txn.amount = params['PAYMENTREQUEST_0_AMT']
            txn.currency = params['PAYMENTREQUEST_0_CURRENCYCODE']
            txn.token = pairs['TOKEN']
        elif method == GET_EXPRESS_CHECKOUT:
            txn.token = params['TOKEN']
            txn.amount = D(pairs['PAYMENTREQUEST_0_AMT'])
            txn.currency = pairs['PAYMENTREQUEST_0_CURRENCYCODE']
        elif method == DO_EXPRESS_CHECKOUT:
            txn.token = params['TOKEN']
            txn.amount = D(pairs['PAYMENTINFO_0_AMT'])
            txn.currency = pairs['PAYMENTINFO_0_CURRENCYCODE']
    else:
        # There can be more than one error, each with its own number.
        if 'L_ERRORCODE0' in pairs:
            txn.error_code = pairs['L_ERRORCODE0']
        if 'L_LONGMESSAGE0' in pairs:
            txn.error_message = pairs['L_LONGMESSAGE0']
    txn.save()

    if not txn.is_successful:
        msg = "Error %s - %s" % (txn.error_code, txn.error_message)
        logger.error(msg)
        raise exceptions.PayPalError(msg)

    return txn
예제 #4
0
def _fetch_response(extra_params):
    """
    Fetch the response from PayPal and return a transaction object
    """
    # Build parameter string
    params = {
        'METHOD': 'AddressVerify',
        'VERSION': API_VERSION,
        'USER': settings.PAYPAL_API_USERNAME,
        'PWD': settings.PAYPAL_API_PASSWORD,
        'SIGNATURE': settings.PAYPAL_API_SIGNATURE,
    }
    params.update(extra_params)

    if getattr(settings, 'PAYPAL_SANDBOX_MODE', True):
        url = 'https://api-3t.sandbox.paypal.com/nvp'
    else:
        url = 'https://api-3t.paypal.com/nvp'

    param_str = "\n".join(["%s: %s" % x for x in params.items()])
    logger.debug("Making AddressVerify request to %s with params:\n%s", url,
                 param_str)

    # Make HTTP request
    pairs = gateway.post(url, params)

    pairs_str = "\n".join([
        "%s: %s" % x for x in sorted(pairs.items()) if not x[0].startswith('_')
    ])
    logger.debug("Response with params:\n%s", pairs_str)

    if 'Failure' in pairs['ACK']:
        msg = "Error %s - %s" % (pairs['L_ERRORCODE0'],
                                 pairs['L_LONGMESSAGE0'])
        logger.error(msg)
        raise exceptions.PayPalError(msg)

    try:
        confcode = pairs['CONFIRMATIONCODE']
    except KeyError:
        confcode = None

    try:
        street = pairs['STREETMATCH']
    except KeyError:
        street = None

    try:
        zip = pairs['ZIPMATCH']
    except KeyError:
        zip = None

    try:
        countrycode = pairs['COUNTRYCODE']
    except KeyError:
        countrycode = None

    return confcode, street, zip, countrycode
예제 #5
0
def _fetch_response(method, extra_params):
    """
    Fetch the response from PayPal and return a transaction object
    """
    # Build parameter string
    params = {
        'METHOD': method,
        'VERSION': API_VERSION,
        'USER': settings.PAYPAL_API_USERNAME,
        'PWD': settings.PAYPAL_API_PASSWORD,
        'SIGNATURE': settings.PAYPAL_API_SIGNATURE,
    }
    params.update(extra_params)

    if getattr(settings, 'PAYPAL_SANDBOX_MODE', True):
        url = 'https://api-3t.sandbox.paypal.com/nvp'
    else:
        url = 'https://api-3t.paypal.com/nvp'

    # Print easy-to-read version of params for debugging
    param_str = "\n".join(["%s: %s" % x for x in sorted(params.items())])
    logger.debug("Making %s request to %s with params:\n%s", method, url,
                 param_str)

    # Make HTTP request
    pairs = gateway.post(url, params)

    pairs_str = "\n".join(["%s: %s" % x for x in sorted(pairs.items())
                           if not x[0].startswith('_')])
    logger.debug("Response with params:\n%s", pairs_str)

    # Record transaction data - we save this model whether the txn
    # was successful or not
    txn = models.ExpressTransaction(
        method=method,
        version=API_VERSION,
        ack=pairs['ACK'],
        raw_request=pairs['_raw_request'],
        raw_response=pairs['_raw_response'],
        response_time=pairs['_response_time'],
    )
    if txn.is_successful:
        txn.correlation_id = pairs['CORRELATIONID']
        if method == SET_EXPRESS_CHECKOUT:
            txn.amount = params['PAYMENTREQUEST_0_AMT']
            txn.currency = params['PAYMENTREQUEST_0_CURRENCYCODE']
            txn.token = pairs['TOKEN']
        elif method == GET_EXPRESS_CHECKOUT:
            txn.token = params['TOKEN']
            txn.amount = D(pairs['PAYMENTREQUEST_0_AMT'])
            txn.currency = pairs['PAYMENTREQUEST_0_CURRENCYCODE']
        elif method == DO_EXPRESS_CHECKOUT:
            txn.token = params['TOKEN']
            txn.amount = D(pairs['PAYMENTINFO_0_AMT'])
            txn.currency = pairs['PAYMENTINFO_0_CURRENCYCODE']
    else:
        # There can be more than one error, each with its own number.
        if 'L_ERRORCODE0' in pairs:
            txn.error_code = pairs['L_ERRORCODE0']
        if 'L_LONGMESSAGE0' in pairs:
            txn.error_message = pairs['L_LONGMESSAGE0']
    txn.save()

    if not txn.is_successful:
        msg = "Error %s - %s" % (txn.error_code, txn.error_message)
        logger.error(msg)
        raise exceptions.PayPalError(msg)

    return txn
예제 #6
0
def _transaction(extra_params):
    """
    Perform a transaction with PayPal.

    :extra_params: Additional parameters to include in the payload other than
    the user credentials.
    """
    if 'TRXTYPE' not in extra_params:
        raise RuntimeError("All transactions must specify a 'TRXTYPE' paramter")

    # Validate constraints on parameters
    constraints = {
        codes.AUTHORIZATION: ('ACCT', 'AMT', 'EXPDATE'),
        codes.SALE: ('AMT',),
        codes.DELAYED_CAPTURE: ('ORIGID',),
        codes.CREDIT: ('ORIGID',),
        codes.VOID: ('ORIGID',),
    }
    trxtype = extra_params['TRXTYPE']
    for key in constraints[trxtype]:
        if key not in extra_params:
            raise RuntimeError(
                "A %s parameter must be supplied for a %s transaction" % (
                    key, trxtype))

    # At a minimum, we require a vendor ID and a password.
    for setting in ('PAYPAL_PAYFLOW_VENDOR_ID',
                    'PAYPAL_PAYFLOW_PASSWORD'):
        if not hasattr(settings, setting):
            raise exceptions.ImproperlyConfigured(
                "You must define a %s setting" % setting
            )

    # Set credentials
    params = {
        'VENDOR': settings.PAYPAL_PAYFLOW_VENDOR_ID,
        'PWD': settings.PAYPAL_PAYFLOW_PASSWORD,
        'USER': getattr(settings, 'PAYPAL_PAYFLOW_USER',
                        settings.PAYPAL_PAYFLOW_VENDOR_ID),
        'PARTNER': getattr(settings, 'PAYPAL_PAYFLOW_PARTNER',
                           'PayPal')
    }
    params.update(extra_params)

    # Ensure that any amounts have a currency and are formatted correctly
    if 'AMT' in params:
        if 'CURRENCY' not in params:
            params['CURRENCY'] = getattr(settings,
                                         'PAYPAL_PAYFLOW_CURRENCY', 'USD')
        params['AMT'] = "%.2f" % params['AMT']

    if getattr(settings, 'PAYPAL_PAYFLOW_PRODUCTION_MODE', False):
        url = 'https://payflowpro.paypal.com'
    else:
        url = 'https://pilot-payflowpro.paypal.com'

    logger.info("Performing %s transaction (trxtype=%s)",
                codes.trxtype_map[trxtype], trxtype)

    pairs = gateway.post(
        url,
        '&'.join(['{}={}'.format(n,v) for n,v in params.items()]), 
        encode=False
    )

    # Beware - this log information will contain the Payflow credentials
    # only use it in development, not production.
    logger.debug("Raw request: %s", pairs['_raw_request'])
    logger.debug("Raw response: %s", pairs['_raw_response'])

    return models.PayflowTransaction.objects.create(
        comment1=params['COMMENT1'],
        trxtype=params['TRXTYPE'],
        tender=params.get('TENDER', None),
        amount=params.get('AMT', None),
        pnref=pairs.get('PNREF', None),
        ppref=pairs.get('PPREF', None),
        cvv2match=pairs.get('CVV2MATCH', None),
        avsaddr=pairs.get('AVSADDR', None),
        avszip=pairs.get('AVSZIP', None),
        result=pairs.get('RESULT', None),
        respmsg=pairs.get('RESPMSG', None),
        authcode=pairs.get('AUTHCODE', None),
        raw_request=pairs['_raw_request'],
        raw_response=pairs['_raw_response'],
        response_time=pairs['_response_time']
    )
예제 #7
0
def _fetch_response(method, extra_params):
    """
    Fetch the response from PayPal and return a transaction object
    """
    # Build parameter string
    params = {
        "METHOD": method,
        "VERSION": API_VERSION,
        "USER": settings.PAYPAL_API_USERNAME,
        "PWD": settings.PAYPAL_API_PASSWORD,
        "SIGNATURE": settings.PAYPAL_API_SIGNATURE,
    }
    params.update(extra_params)

    if getattr(settings, "PAYPAL_SANDBOX_MODE", True):
        url = "https://api-3t.sandbox.paypal.com/nvp"
    else:
        url = "https://api-3t.paypal.com/nvp"

    param_str = "\n".join(["%s: %s" % x for x in params.items()])
    logger.debug("Making %s request to %s with params:\n%s", method, url, param_str)

    # Make HTTP request
    pairs = gateway.post(url, params)

    pairs_str = "\n".join(["%s: %s" % x for x in sorted(pairs.items()) if not x[0].startswith("_")])
    logger.debug("Response with params:\n%s", pairs_str)

    # Record transaction data - we save this model whether the txn
    # was successful or not
    txn = models.ExpressTransaction(
        method=method,
        version=API_VERSION,
        ack=pairs["ACK"],
        raw_request=pairs["_raw_request"],
        raw_response=pairs["_raw_response"],
        response_time=pairs["_response_time"],
    )
    if txn.is_successful:
        txn.correlation_id = pairs["CORRELATIONID"]
        if method == SET_EXPRESS_CHECKOUT:
            txn.amount = params["PAYMENTREQUEST_0_AMT"]
            txn.currency = params["PAYMENTREQUEST_0_CURRENCYCODE"]
            txn.token = pairs["TOKEN"]
        elif method == GET_EXPRESS_CHECKOUT:
            txn.token = params["TOKEN"]
            txn.amount = D(pairs["PAYMENTREQUEST_0_AMT"])
            txn.currency = pairs["PAYMENTREQUEST_0_CURRENCYCODE"]
        elif method == DO_EXPRESS_CHECKOUT:
            txn.token = params["TOKEN"]
            txn.amount = D(pairs["PAYMENTINFO_0_AMT"])
            txn.currency = pairs["PAYMENTINFO_0_CURRENCYCODE"]
    else:
        # There can be more than one error, each with its own number.
        if "L_ERRORCODE0" in pairs:
            txn.error_code = pairs["L_ERRORCODE0"]
        if "L_LONGMESSAGE0" in pairs:
            txn.error_message = pairs["L_LONGMESSAGE0"]
    txn.save()

    if not txn.is_successful:
        msg = "Error %s - %s" % (txn.error_code, txn.error_message)
        logger.error(msg)
        raise exceptions.PayPalError(msg)

    return txn
예제 #8
0
def _fetch_response(method, extra_params):
    """
    Fetch the response from PayPal and return a transaction object
    """
    # Build parameter string
    params = {
        'METHOD': method,
        'VERSION': API_VERSION,
        'USER': settings.PAYPAL_API_USERNAME,
        'PWD': settings.PAYPAL_API_PASSWORD,
        'SIGNATURE': settings.PAYPAL_API_SIGNATURE,
    }
    us_params = {
        'USER': settings.PAYPAL_API_US_USERNAME,
        'PWD': settings.PAYPAL_API_US_PASSWORD,
        'SIGNATURE': settings.PAYPAL_API_US_SIGNATURE,
    }
    # Use different API keys for US dollars
    currency = extra_params.get('PAYMENTREQUEST_0_CURRENCYCODE')
    if currency == 'USD':
        params.update(us_params)
    # If token is present retrieve the currency type for it
    token = extra_params.get('TOKEN')
    if token and _get_token_api_type(token) == 'USD':
        params.update(us_params)
    params.update(extra_params)

    if getattr(settings, 'PAYPAL_SANDBOX_MODE', True):
        url = 'https://api-3t.sandbox.paypal.com/nvp'
    else:
        url = 'https://api-3t.paypal.com/nvp'

    # Print easy-to-read version of params for debugging
    param_str = "\n".join(["%s: %s" % x for x in sorted(params.items())])
    logger.debug("Making %s request to %s with params:\n%s", method, url,
                 param_str)

    # Make HTTP request
    pairs = gateway.post(url, params)

    pairs_str = "\n".join(["%s: %s" % x for x in sorted(pairs.items())
                           if not x[0].startswith('_')])
    logger.debug("Response with params:\n%s", pairs_str)

    # Record transaction data - we save this model whether the txn
    # was successful or not
    txn = models.ExpressTransaction(
        method=method,
        version=API_VERSION,
        ack=pairs['ACK'],
        raw_request=pairs['_raw_request'],
        raw_response=pairs['_raw_response'],
        response_time=pairs['_response_time'],
    )
    if txn.is_successful:
        txn.correlation_id = pairs['CORRELATIONID']
        if method == SET_EXPRESS_CHECKOUT:
            txn.amount = params['PAYMENTREQUEST_0_AMT']
            txn.currency = params['PAYMENTREQUEST_0_CURRENCYCODE']
            txn.token = pairs['TOKEN']
        elif method == GET_EXPRESS_CHECKOUT:
            txn.token = params['TOKEN']
            txn.amount = D(pairs['PAYMENTREQUEST_0_AMT'])
            txn.currency = pairs['PAYMENTREQUEST_0_CURRENCYCODE']
        elif method == DO_EXPRESS_CHECKOUT:
            txn.token = params['TOKEN']
            txn.amount = D(pairs['PAYMENTINFO_0_AMT'])
            txn.currency = pairs['PAYMENTINFO_0_CURRENCYCODE']
    else:
        # There can be more than one error, each with its own number.
        if 'L_ERRORCODE0' in pairs:
            txn.error_code = pairs['L_ERRORCODE0']
        if 'L_LONGMESSAGE0' in pairs:
            txn.error_message = pairs['L_LONGMESSAGE0']
    txn.save()

    if not txn.is_successful:
        msg = "Error %s - %s" % (txn.error_code, txn.error_message)
        logger.error(msg)
        raise exceptions.PayPalError(msg)

    return txn