Example #1
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
Example #2
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, params)

    # 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'])
Example #3
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, params)

    # 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']
    )
Example #4
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