示例#1
0
def multiuse_pay(request):
    """
    error response:
    <?xml version="1.0"?>
    <Response><Errors><Error><Code>InvalidRequest</Code><Message>The request doesn't conform to the interface specification in the WSDL. Element/Parameter "http://fps.amazonaws.com/doc/2008-09-17/:recipient_token_id" in request is either invalid or is found at unexpected location</Message></Error></Errors><RequestID>744ab3b6-17c2-4ab0-ad24-28eba41a5079</RequestID></Response>

or

   <?xml version="1.0"?>
<Response><Errors><Error><Code>InvalidParams</Code><Message>"recipientTokenId" has to be a valid token ID. Specified value: NONE</Message></Error></Errors><RequestID>f9f9d847-13b9-4a84-9be5-7295dae61f85</RequestID></Response>

https://fps.sandbox.amazonaws.com
RefundTokenId=R1VX241BUXNS41329VP62LVLLTNCNAHEBPIB7GKZZQ848HZFR8J56C5JZEUMEZWB
SignatureVersion=1
RecipientTokenId=R7VXG4TBUJNM41J2ZVPX2KVLDTGCNUHQBPEBIGKUZM84VHNFR3J86CUJ6EUZE4WU
MarketplaceFixedFee=null
Version=2008-09-17
AWSAccessKeyId=AKIAIQP3UWTD7ZIDK2NQ
Timestamp=2009-09-26T15%3A52%3A04Z
SenderTokenId=I39FL7CM3X8I3XUHPB9M7PZEXXBKLUO86PSK5ES8AKBTL9J4H2X4GVVBJIKAGIWP
MarketplaceVariableFee=0.1
CallerReference=lipqDdR5QKV0
Signature=ZHSwy68P7BQB6hHqNn7%2BGMnI3%2Bw%3D
Action=Pay
TransactionAmount=0.22


    error response:
<?xml version="1.0"?>
<Response>
    <Errors>
        <Error>
            <Code>IncompatibleTokens</Code>
            <Message>Maximum values of marketplace fees not defined in Recipient token or are unreadable.</Message>
        </Error>
    </Errors>
    <RequestID>27d73b73-d6fc-4f83-81ee-f7c7534e9225</RequestID>
</Response>

<?xml version="1.0"?>
<Response>
    <Errors>
        <Error>
            <Code>InvalidParams</Code>
            <Message>Transaction amount must be greater than Recipient Fee liability.</Message>
        </Error>
    </Errors>
    <RequestID>0b80acb2-2105-4e44-acbe-6520a1cdafe6</RequestID>
</Response>

success!!!
<?xml version="1.0"?>
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/">
    <PayResult>
        <TransactionId>14FUAIBTQ5ECRD1CVD8HIH1E445NK43FIQ6</TransactionId>
        <TransactionStatus>Pending</TransactionStatus>
    </PayResult>
    <ResponseMetadata>
        <RequestId>8292cb68-d09d-4bec-a5bf-df5c2923cfc1:0</RequestId>
    </ResponseMetadata>
</PayResponse>

<?xml version="1.0"?>
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/">
    <PayResult>
        <TransactionId>14FUV9H5S5COG9TU5VU3GVBKRP3PJ955TTH</TransactionId>
        <TransactionStatus>Pending</TransactionStatus>
    </PayResult>
    <ResponseMetadata>
        <RequestId>137cb61d-b28c-4491-a1b3-ad7233ff6a84:0</RequestId>
    </ResponseMetadata>
</PayResponse>
    """
    if not settings.DJANGO_SERVER and not request.is_secure():
        message = "must secure data via HTTPS: request=%s" % request
        Log.Error(message, "request_error")
        return json_failure(message)

    expected_parameters = [
        "timestamp", "caller_reference", "marketplace_fixed_fee",
        "marketplace_variable_fee", "transaction_amount", "recipient_slug",
        "sender_token_id", "private_key", "version"
    ]

    response = extract_parameters(request, "POST", expected_parameters)
    if not response['success']:
        return json_failure("Something went wrong extracting parameters: %s" %
                            response['reason'])

    #print
    #for x in response['parameters']:
    #    print x, "=", response['parameters'][x]
    #print

    response['parameters']['timestamp'] = time.strftime(
        "%Y-%m-%dT%H:%M:%SZ", time.gmtime())

    # params to send back to client
    lower_parameters = response['parameters']
    private_key = lower_parameters['private_key']
    del lower_parameters['private_key']

    user = User.get_or_none(private_key=private_key)
    if not user:
        message = "unknown user: %s, request=%s" % (private_key, request)
        Log.Error(message, "unknown_user")
        return json_failure(message)

    rslug = lower_parameters['recipient_slug']
    recipient = Recipient.get_or_none(slug=rslug)
    if not recipient:
        return json_failure("No recipient found that matches %s" % rslug)

    fpsr = recipient.fps_data
    if not fpsr:
        return json_failure("No FPS Recipient data found for %s." % recipient)

    del lower_parameters['recipient_slug']
    lower_parameters['recipient_token_id'] = fpsr.token_id
    #lower_parameters['refund_token_id'] = fpsr.refund_token_id
    #lower_parameters['marketplace_fixed_fee'] = 0.00
    #lower_parameters['marketplace_variable_fee'] = 10.00

    #lower_parameters['RecipientTokenId'] = fpsr.token_id
    #lower_parameters['RefundTokenId'] = fpsr.refund_token_id
    #lower_parameters['SenderTokenId'] = lower_parameters['sender_token_id']
    #del lower_parameters['sender_token_id']

    # params for FPS REST request
    camel_parameters = _switch_cases(response['parameters'],
                                     to_lower=False,
                                     cbui=False)
    camel_parameters['TransactionAmount.Value'] = camel_parameters[
        'TransactionAmount']
    camel_parameters['TransactionAmount.CurrencyCode'] = 'USD'
    del camel_parameters['TransactionAmount']
    camel_parameters['MarketplaceFixedFee.Value'] = camel_parameters[
        'MarketplaceFixedFee']
    camel_parameters['MarketplaceFixedFee.CurrencyCode'] = 'USD'
    del camel_parameters['MarketplaceFixedFee']

    camel_parameters.update({
        'Action': 'Pay',
        'AWSAccessKeyId': settings.FPS['callerKey'],
        'SignatureVersion': 1,
    })
    # add signature
    finalize_parameters(camel_parameters, type=REST_TYPE)

    full_url = "%s?%s" % (AMAZON_FPS_API_URL,
                          urllib.urlencode(camel_parameters))

    print
    print
    print full_url
    print

    content = _get(full_url)

    xmlns_re = re.compile(' xmlns="http://fps.amazonaws.com/doc/[\d-]+/"')
    version_re = re.compile(' xmlns="http://fps.amazonaws.com/doc/([\d-]+)/"')

    has_match = version_re.search(content)
    if has_match:
        if has_match.group(1) != lower_parameters['version']:
            # versions are out of synch!
            pass
        # we need to use a compiled re that doesn't extract the version, otherwise split
        # will include the version
        content = ''.join(xmlns_re.split(content))

    response_dict = ConvertXmlToDict(content)
    # p23 of Advanced Quick Start Dev Guide says that only the first error is ever reported
    # so errors is expected to always contain at most one error.
    errors = []
    error_code = None
    error_message = None
    transaction_id = None
    transaction_status = FPSMultiusePay.STATUSES['ERROR']
    request_id = None
    for key in response_dict:
        if key == 'Response':
            # error response
            """
            {'Response': {'Errors': {'Error': [{'Code': 'InvalidParams',
                                    'Message': 'Transaction amount must be greater than Recipient Fee liability.'},
                                   {'Code': 'Error2',
                                    'Message': 'Another error'}]},
              'RequestID': '0b80acb2-2105-4e44-acbe-6520a1cdafe6'}}
            """
            for error in response_dict['Response']['Errors']['Error']:
                errors.append(error)
                error_code = response_dict['Response']['Errors']['Error'][
                    'Code']
                error_message = response_dict['Response']['Errors']['Error'][
                    'Message']
            request_id = response_dict['Response']['RequestID']
        elif key == 'PayResponse':
            # success
            transaction_id = response_dict['PayResponse']['PayResult'][
                'TransactionId']
            transaction_status = FPSMultiusePay.STATUSES[response_dict[
                'PayResponse']['PayResult']['TransactionStatus'].upper()]
            request_id = response_dict['PayResponse']['ResponseMetadata'][
                'RequestId']
        else:
            error_code = '?'
            error_message = "unknown fps.multiusepay response %s for %s" % (
                response_dict, full_url)
            Log.Error(error_message)

    pay = FPSMultiusePay.add(
        user,
        recipient,
        lower_parameters['caller_reference'],
        lower_parameters['timestamp'],
        lower_parameters['marketplace_fixed_fee'],
        lower_parameters['marketplace_variable_fee'],
        lower_parameters['recipient_token_id'],
        #lower_parameters['refund_token_id'],
        lower_parameters['sender_token_id'],
        lower_parameters['transaction_amount'],
        request_id,
        transaction_id,
        transaction_status,
        error_message,
        error_code)
    if errors:
        print {
            'pay': pay.deep_dict(),
            'log': "%s: %s" % (error_code, error_message)
        }
        return json_success({
            'pay': pay.deep_dict(),
            'log': "%s: %s" % (error_code, error_message)
        })
    else:
        print {'pay': pay.deep_dict()}
        return json_success({'pay': pay.deep_dict()})
示例#2
0
def authorize_multiuse(request):
    """
    expect parameters
        timestamp
        callerReference - use this so can resubmit pay requests, etc.
        globalAmountLimit - total $$ ever that can flow across token during token's lifetime
        paymentMethod - "ABT,ACH,CC"
        paymentReason - html
        recipient_slug_list - 'sluga,slugb,slugc' or 'all'
        version - one of ["2009-01-09"]
    
    returns
        parameters
        
    """
    #f = open('/var/sites/ProcrasDonate/auth.log', 'w')
    #import time
    #f.write("\n\n %s AUTHORIZE MULTIUSE WEASELS: " % (time.time(), request))
    #f.close()
    if not settings.DJANGO_SERVER and not request.is_secure():
        message = "must secure data via HTTPS: request=%s" % request
        Log.Error(message, "request_error")
        return json_failure(message)

    errors = []
    expected_parameters = [
        "caller_reference",
        "payment_reason",
        "payment_method",
        "global_amount_limit",
        "recipient_slug_list",
        "version",
        #"timestamp",
        "private_key"
    ]

    response = extract_parameters(request, "POST", expected_parameters)
    if not response['success']:
        return json_failure("Something went wrong extracting parameters: %s" %
                            response['reason'])

    # params to send back to client and use locally (database worthy)
    lower_parameters = response['parameters']
    private_key = lower_parameters['private_key']
    del lower_parameters['private_key']

    # params for FPS REST request
    camel_parameters = _switch_cases(response['parameters'], to_lower=False)

    recipients = []
    if camel_parameters['recipient_slug_list'] == "all":
        allr = Recipient.objects.filter(
            fpsrecipient__status=FPSRecipient.STATUSES['SUCCESS'])
    else:
        allr = Recipient.objects.filter(
            fpsrecipient__status=FPSRecipient.STATUSES['SUCCESS'])
        allr = allr.filter(
            slug__in=camel_parameters['recipient_slug_list'].split(','))

    for recipient in allr:
        recipients.append(recipient)

    recipient_token_list = ",".join(
        [recipient.fps_data.token_id for recipient in recipients])
    del camel_parameters['recipient_slug_list']
    camel_parameters['recipientTokenList'] = recipient_token_list

    camel_parameters.update({#'RecipientCobranding': "true",
                           #'paymentMethod': 'CC,ACH,ABT',
                           # common CBUI parameters
                           'cobrandingUrl': settings.FPS['cobrandingUrl'],
                           'websiteDescription': settings.FPS['websiteDescription'],
                           'pipelineName': "MultiUse",
                           'returnURL': "%s%s" % (settings.DOMAIN,
                                                  reverse('multiuse_authorize_callback',
                                                          args=(camel_parameters['callerReference'],))),
                                                          #kwargs={'caller_reference': parameters['callerReference']})),
                           'callerKey': settings.FPS['callerKey'],
                           })

    # add timestampe and signature
    print "PRE FINALIZE"
    for x in camel_parameters:
        print x, "=", camel_parameters[x]
    finalize_parameters(camel_parameters, type=CBUI_TYPE)
    print "POST FINALIZE"
    for x in camel_parameters:
        print x, "=", camel_parameters[x]

    full_url = "%s?%s" % (AMAZON_CBUI_URL, urllib.urlencode(camel_parameters))
    print
    print "FULL_URL", full_url
    print

    user = User.get_or_none(private_key=private_key)
    if not user:
        message = "unknown user: %s, request=%s" % (private_key, request)
        Log.Error(message, "unknown_user")
        return json_failure(message)

    multiuse = FPSMultiuseAuth.get_or_none(
        caller_reference=lower_parameters['caller_reference'])
    if not multiuse:
        multiuse = FPSMultiuseAuth.add(user, lower_parameters)

    return HttpResponseRedirect(full_url)
示例#3
0
def cancel_multiuse(request):
    """
    request:
    https://fps.sandbox.amazonaws.com?
    SignatureVersion=1
    ReasonText=User+clicked+cancel
    Version=2009-01-09
    AWSAccessKeyId=AKIAIQP3UWTD7ZIDK2NQ
    TokenId=8S1TI29UK1F36M57ZM4T69SILWPLA6XHJJ5CGUUVRLGNAP8BSG3BAK2WCAAUEHCE
    action=CancelToken
    Timestamp=1253825694
    Signature=wLY9ASy363Q9%2FQO5h3DxWqMJxS0%3D
    
    https://fps.amazonaws.com/?
      Action=CancelToken&
  AWSAccessKeyId=0656Example83G2&
  SignatureVersion=1&
  Timestamp=2008-08-06T13%3A00%3A01Z&    2008-08-06T13:00:01Z
  TokenId=254656Example83987&
  Version=2008-09-17&
  Signature=<URL-encoded signature value>
    
    #@TODO IMPORTANT: if user already has token, but make pipeline auth request with 
    different callerReference, then no problem, (just returns data we already know??).
    same callerReference, then has problem.
    
    error response:
    
    response:
    <?xml version="1.0"?>
    <CancelTokenResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/"><ResponseMetadata><RequestId>c0536599-b904-4cee-a504-5c80d7812464:0</RequestId></ResponseMetadata></CancelTokenResponse>
    
    """
    if not settings.DJANGO_SERVER and not request.is_secure():
        message = "must secure data via HTTPS: request=%s" % request
        Log.Error(message, "request_error")
        return json_failure(message)

    print
    print "CANCEL MULTIUSE"
    print json.dumps(request.POST, indent=2)
    print
    expected_parameters = [
        "token_id", "reason_text", "private_key", "version", "timestamp"
    ]

    response = extract_parameters(request, "POST", expected_parameters)
    if not response['success']:
        return json_failure("Something went wrong extracting parameters: %s" %
                            response['reason'])

    print
    print "TIMESTAMP before"
    print response['parameters']['timestamp']
    response['parameters']['timestamp'] = datetime.datetime.fromtimestamp(
        float(response['parameters']['timestamp']))
    print
    print "TIMESTAMP after"
    print response['parameters']['timestamp']
    response['parameters']['timestamp'] = response['parameters'][
        'timestamp'].strftime("%Y-%m-%dT%H:%M:%SZ")
    print
    print "TIMESTAMP after"
    print response['parameters']['timestamp']
    print

    response['parameters']['timestamp'] = time.strftime(
        "%Y-%m-%dT%H:%M:%SZ", time.gmtime())
    print
    print "TIMESTAMP gmt"
    print response['parameters']['timestamp']
    print

    # params to send back to client
    lower_parameters = response['parameters']
    private_key = lower_parameters['private_key']
    del lower_parameters['private_key']

    # params for FPS REST request
    camel_parameters = _switch_cases(response['parameters'],
                                     to_lower=False,
                                     cbui=False)

    camel_parameters.update({
        'Action': 'CancelToken',
        'AWSAccessKeyId': settings.FPS['callerKey'],
        'SignatureVersion': 1,
    })
    # add signature
    finalize_parameters(camel_parameters, type=REST_TYPE)

    full_url = "%s?%s" % (AMAZON_FPS_API_URL,
                          urllib.urlencode(camel_parameters))

    user = User.get_or_none(private_key=private_key)
    print "----  USER ----"
    print user
    if not user:
        message = "unknown user: %s, request=%s" % (private_key, request)
        Log.Error(message, "unknown_user")
        return json_failure(message)

    FPSMultiuseCancelToken.add(user,
                               token_id=lower_parameters['token_id'],
                               reason_text=lower_parameters['reason_text'],
                               timestamp=lower_parameters['timestamp'])

    print
    print "FULL URL"
    print full_url
    content = _get(full_url)
    print
    print "CONTENT"
    print content

    multiauth = FPSMultiuseAuth.get_or_none(
        token_id=lower_parameters['token_id'])
    multiauth.status = FPSMultiuseAuth.STATUSES['CANCELLED']
    multiauth.save()

    return json_success()
示例#4
0
def authorize(request, rescuetime_key):
    # if not settings.DJANGO_SERVER and not request.is_secure():
    #    message = "must secure data via HTTPS: request=%s" % request
    #    Log.Error(message, "request_error")
    #    return HttpResponseRedirect(reverse('rt_dashboard', args=(rescuetime_key, )))

    rt = RescueTimeUser.get_or_none(rescuetime_key=rescuetime_key)
    if not rt:
        return HttpResponseRedirect(reverse("rt_signup"))

    lower_parameters = {
        "caller_reference": create_id(12),
        "payment_reason": "ProcrasDonating for a good cause",
        "payment_method": "ABT,ACH,CC",
        "global_amount_limit": "100",
        "recipient_slug_list": "all",
        "version": settings.FPS["version"],
    }
    # "timestamp",

    # params for FPS REST request
    camel_parameters = _switch_cases(lower_parameters, to_lower=False)

    recipients = []
    if camel_parameters["recipient_slug_list"] == "all":
        allr = Recipient.objects.filter(fpsrecipient__status=FPSRecipient.STATUSES["SUCCESS"])
        print "ALLR", allr
        allr = allr.exclude(slug="PD")
        print "ALLR2", allr
    else:
        allr = Recipient.objects.filter(fpsrecipient__status=FPSRecipient.STATUSES["SUCCESS"])
        allr = allr.filter(slug__in=camel_parameters["recipient_slug_list"].split(","))

    print
    for recipient in allr:
        print "RECIPIENT", recipient
        recipients.append(recipient)

    recipient_token_list = ",".join([recipient.fps_data.token_id for recipient in recipients])
    if not recipient_token_list:
        Log.error("Empty recipient token list! %s" % request, "empty_recipient_token_list")
    del camel_parameters["recipient_slug_list"]
    camel_parameters["recipientTokenList"] = recipient_token_list

    camel_parameters.update(
        {  #'RecipientCobranding': "true",
            #'paymentMethod': 'CC,ACH,ABT',
            # common CBUI parameters
            "cobrandingUrl": settings.FPS["cobrandingUrl"],
            "websiteDescription": settings.FPS["websiteDescription"],
            "pipelineName": "MultiUse",
            "returnURL": "%s%s"
            % (
                settings.DOMAIN,
                reverse("rt_authorize_callback", args=(rescuetime_key, camel_parameters["callerReference"])),
            ),
            # kwargs={'caller_reference': parameters['callerReference']})),
            "callerKey": settings.FPS["callerKey"],
        }
    )

    # add timestampe and signature
    finalize_parameters(camel_parameters, type=CBUI_TYPE)
    print "POST FINALIZE"
    for x in camel_parameters:
        print x, "=", camel_parameters[x]

    full_url = "%s?%s" % (AMAZON_CBUI_URL, urllib.urlencode(camel_parameters))
    print
    print "FULL_URL", full_url
    print

    multiuse = FPSMultiuseAuth.get_or_none(caller_reference=lower_parameters["caller_reference"])
    if not multiuse:
        multiuse = FPSMultiuseAuth.add(rt.user, lower_parameters)

    return HttpResponseRedirect(full_url)
示例#5
0
def multiuse_pay(request):
    """
    error response:
    <?xml version="1.0"?>
    <Response><Errors><Error><Code>InvalidRequest</Code><Message>The request doesn't conform to the interface specification in the WSDL. Element/Parameter "http://fps.amazonaws.com/doc/2008-09-17/:recipient_token_id" in request is either invalid or is found at unexpected location</Message></Error></Errors><RequestID>744ab3b6-17c2-4ab0-ad24-28eba41a5079</RequestID></Response>

or

   <?xml version="1.0"?>
<Response><Errors><Error><Code>InvalidParams</Code><Message>"recipientTokenId" has to be a valid token ID. Specified value: NONE</Message></Error></Errors><RequestID>f9f9d847-13b9-4a84-9be5-7295dae61f85</RequestID></Response>

https://fps.sandbox.amazonaws.com
RefundTokenId=R1VX241BUXNS41329VP62LVLLTNCNAHEBPIB7GKZZQ848HZFR8J56C5JZEUMEZWB
SignatureVersion=1
RecipientTokenId=R7VXG4TBUJNM41J2ZVPX2KVLDTGCNUHQBPEBIGKUZM84VHNFR3J86CUJ6EUZE4WU
MarketplaceFixedFee=null
Version=2008-09-17
AWSAccessKeyId=AKIAIQP3UWTD7ZIDK2NQ
Timestamp=2009-09-26T15%3A52%3A04Z
SenderTokenId=I39FL7CM3X8I3XUHPB9M7PZEXXBKLUO86PSK5ES8AKBTL9J4H2X4GVVBJIKAGIWP
MarketplaceVariableFee=0.1
CallerReference=lipqDdR5QKV0
Signature=ZHSwy68P7BQB6hHqNn7%2BGMnI3%2Bw%3D
Action=Pay
TransactionAmount=0.22


    error response:
<?xml version="1.0"?>
<Response>
    <Errors>
        <Error>
            <Code>IncompatibleTokens</Code>
            <Message>Maximum values of marketplace fees not defined in Recipient token or are unreadable.</Message>
        </Error>
    </Errors>
    <RequestID>27d73b73-d6fc-4f83-81ee-f7c7534e9225</RequestID>
</Response>

<?xml version="1.0"?>
<Response>
    <Errors>
        <Error>
            <Code>InvalidParams</Code>
            <Message>Transaction amount must be greater than Recipient Fee liability.</Message>
        </Error>
    </Errors>
    <RequestID>0b80acb2-2105-4e44-acbe-6520a1cdafe6</RequestID>
</Response>

success!!!
<?xml version="1.0"?>
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/">
    <PayResult>
        <TransactionId>14FUAIBTQ5ECRD1CVD8HIH1E445NK43FIQ6</TransactionId>
        <TransactionStatus>Pending</TransactionStatus>
    </PayResult>
    <ResponseMetadata>
        <RequestId>8292cb68-d09d-4bec-a5bf-df5c2923cfc1:0</RequestId>
    </ResponseMetadata>
</PayResponse>

<?xml version="1.0"?>
<PayResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/">
    <PayResult>
        <TransactionId>14FUV9H5S5COG9TU5VU3GVBKRP3PJ955TTH</TransactionId>
        <TransactionStatus>Pending</TransactionStatus>
    </PayResult>
    <ResponseMetadata>
        <RequestId>137cb61d-b28c-4491-a1b3-ad7233ff6a84:0</RequestId>
    </ResponseMetadata>
</PayResponse>
    """
    if not settings.DJANGO_SERVER and not request.is_secure():
        message = "must secure data via HTTPS: request=%s" % request
        Log.Error(message, "request_error")
        return json_failure(message)
    
    expected_parameters = ["timestamp",
                           "caller_reference",
                           "marketplace_fixed_fee",
                           "marketplace_variable_fee",
                           "transaction_amount",
                           "recipient_slug",
                           "sender_token_id",
                           "private_key",
                           "version"]

    response = extract_parameters(request, "POST", expected_parameters)
    if not response['success']:
        return json_failure("Something went wrong extracting parameters: %s" % response['reason'])

    #print
    #for x in response['parameters']:
    #    print x, "=", response['parameters'][x]
    #print

    response['parameters']['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
    
    # params to send back to client
    lower_parameters = response['parameters']
    private_key = lower_parameters['private_key']
    del lower_parameters['private_key']
    
    user = User.get_or_none(private_key=private_key)
    if not user:
        message = "unknown user: %s, request=%s" % (private_key, request)
        Log.Error(message, "unknown_user")
        return json_failure(message)
    
    rslug = lower_parameters['recipient_slug']
    recipient = Recipient.get_or_none(slug=rslug)
    if not recipient:
        return json_failure("No recipient found that matches %s" % rslug)
    
    fpsr = recipient.fps_data
    if not fpsr:
        return json_failure("No FPS Recipient data found for %s." % recipient)
    
    del lower_parameters['recipient_slug']
    lower_parameters['recipient_token_id'] = fpsr.token_id
    #lower_parameters['refund_token_id'] = fpsr.refund_token_id
    #lower_parameters['marketplace_fixed_fee'] = 0.00
    #lower_parameters['marketplace_variable_fee'] = 10.00
    
    #lower_parameters['RecipientTokenId'] = fpsr.token_id
    #lower_parameters['RefundTokenId'] = fpsr.refund_token_id
    #lower_parameters['SenderTokenId'] = lower_parameters['sender_token_id']
    #del lower_parameters['sender_token_id']

    # params for FPS REST request
    camel_parameters = _switch_cases(response['parameters'], to_lower=False, cbui=False)
    camel_parameters['TransactionAmount.Value'] =  camel_parameters['TransactionAmount']
    camel_parameters['TransactionAmount.CurrencyCode'] =  'USD'
    del camel_parameters['TransactionAmount']
    camel_parameters['MarketplaceFixedFee.Value'] =  camel_parameters['MarketplaceFixedFee']
    camel_parameters['MarketplaceFixedFee.CurrencyCode'] =  'USD'
    del camel_parameters['MarketplaceFixedFee']
    
    camel_parameters.update({'Action': 'Pay',
                             'AWSAccessKeyId': settings.FPS['callerKey'],
                             'SignatureVersion': 1,
                             })
    # add signature
    finalize_parameters(camel_parameters, type=REST_TYPE)
    
    full_url = "%s?%s" % (AMAZON_FPS_API_URL,
                          urllib.urlencode(camel_parameters))

    print
    print
    print full_url
    print

    content = _get(full_url)
    
    xmlns_re = re.compile(' xmlns="http://fps.amazonaws.com/doc/[\d-]+/"')
    version_re = re.compile(' xmlns="http://fps.amazonaws.com/doc/([\d-]+)/"')
    
    has_match = version_re.search(content)
    if has_match:
        if has_match.group(1) != lower_parameters['version']:
            # versions are out of synch!
            pass
        # we need to use a compiled re that doesn't extract the version, otherwise split
        # will include the version
        content = ''.join(xmlns_re.split(content))
    
    response_dict = ConvertXmlToDict(content)
    # p23 of Advanced Quick Start Dev Guide says that only the first error is ever reported
    # so errors is expected to always contain at most one error.
    errors = []
    error_code = None
    error_message = None
    transaction_id = None
    transaction_status = FPSMultiusePay.STATUSES['ERROR']
    request_id = None
    for key in response_dict:
        if key == 'Response':
            # error response
            """
            {'Response': {'Errors': {'Error': [{'Code': 'InvalidParams',
                                    'Message': 'Transaction amount must be greater than Recipient Fee liability.'},
                                   {'Code': 'Error2',
                                    'Message': 'Another error'}]},
              'RequestID': '0b80acb2-2105-4e44-acbe-6520a1cdafe6'}}
            """
            for error in response_dict['Response']['Errors']['Error']:
                errors.append(error)
                error_code = response_dict['Response']['Errors']['Error']['Code']
                error_message = response_dict['Response']['Errors']['Error']['Message']
            request_id = response_dict['Response']['RequestID']
        elif key == 'PayResponse':
            # success
            transaction_id = response_dict['PayResponse']['PayResult']['TransactionId']
            transaction_status = FPSMultiusePay.STATUSES[ response_dict['PayResponse']['PayResult']['TransactionStatus'].upper() ]
            request_id = response_dict['PayResponse']['ResponseMetadata']['RequestId']
        else:
            error_code = '?'
            error_message = "unknown fps.multiusepay response %s for %s" % (response_dict, full_url)
            Log.Error(error_message)
    
    pay = FPSMultiusePay.add(user, recipient,
                             lower_parameters['caller_reference'],
                             lower_parameters['timestamp'],
                             lower_parameters['marketplace_fixed_fee'],
                             lower_parameters['marketplace_variable_fee'],
                             lower_parameters['recipient_token_id'],
                             #lower_parameters['refund_token_id'],
                             lower_parameters['sender_token_id'],
                             lower_parameters['transaction_amount'],
                             request_id,
                             transaction_id,
                             transaction_status,
                             error_message,
                             error_code)
    if errors:    
        print {'pay': pay.deep_dict(),
               'log': "%s: %s" % (error_code, error_message)}
        return json_success({'pay': pay.deep_dict(),
                             'log': "%s: %s" % (error_code, error_message)})
    else:
        print {'pay': pay.deep_dict()}
        return json_success({'pay': pay.deep_dict()})
示例#6
0
def cancel_multiuse(request):
    """
    request:
    https://fps.sandbox.amazonaws.com?
    SignatureVersion=1
    ReasonText=User+clicked+cancel
    Version=2009-01-09
    AWSAccessKeyId=AKIAIQP3UWTD7ZIDK2NQ
    TokenId=8S1TI29UK1F36M57ZM4T69SILWPLA6XHJJ5CGUUVRLGNAP8BSG3BAK2WCAAUEHCE
    action=CancelToken
    Timestamp=1253825694
    Signature=wLY9ASy363Q9%2FQO5h3DxWqMJxS0%3D
    
    https://fps.amazonaws.com/?
      Action=CancelToken&
  AWSAccessKeyId=0656Example83G2&
  SignatureVersion=1&
  Timestamp=2008-08-06T13%3A00%3A01Z&    2008-08-06T13:00:01Z
  TokenId=254656Example83987&
  Version=2008-09-17&
  Signature=<URL-encoded signature value>
    
    #@TODO IMPORTANT: if user already has token, but make pipeline auth request with 
    different callerReference, then no problem, (just returns data we already know??).
    same callerReference, then has problem.
    
    error response:
    
    response:
    <?xml version="1.0"?>
    <CancelTokenResponse xmlns="http://fps.amazonaws.com/doc/2008-09-17/"><ResponseMetadata><RequestId>c0536599-b904-4cee-a504-5c80d7812464:0</RequestId></ResponseMetadata></CancelTokenResponse>
    
    """
    if not settings.DJANGO_SERVER and not request.is_secure():
        message = "must secure data via HTTPS: request=%s" % request
        Log.Error(message, "request_error")
        return json_failure(message)
    
    print
    print "CANCEL MULTIUSE"
    print json.dumps(request.POST, indent=2)
    print
    expected_parameters = ["token_id",
                           "reason_text",
                           "private_key",
                           "version",
                           "timestamp"]

    response = extract_parameters(request, "POST", expected_parameters)
    if not response['success']:
        return json_failure("Something went wrong extracting parameters: %s" % response['reason'])
    
    print
    print "TIMESTAMP before"
    print  response['parameters']['timestamp'] 
    response['parameters']['timestamp'] = datetime.datetime.fromtimestamp(float(response['parameters']['timestamp']))
    print
    print "TIMESTAMP after"
    print  response['parameters']['timestamp']
    response['parameters']['timestamp'] = response['parameters']['timestamp'].strftime("%Y-%m-%dT%H:%M:%SZ")
    print
    print "TIMESTAMP after"
    print  response['parameters']['timestamp']
    print
    
    response['parameters']['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
    print
    print "TIMESTAMP gmt"
    print  response['parameters']['timestamp']
    print
    
    # params to send back to client
    lower_parameters = response['parameters']
    private_key = lower_parameters['private_key']
    del lower_parameters['private_key']
    
    # params for FPS REST request
    camel_parameters = _switch_cases(response['parameters'], to_lower=False, cbui=False)

    camel_parameters.update({'Action': 'CancelToken',
                             'AWSAccessKeyId': settings.FPS['callerKey'],
                             'SignatureVersion': 1,
                             })
    # add signature
    finalize_parameters(camel_parameters, type=REST_TYPE)
    
    full_url = "%s?%s" % (AMAZON_FPS_API_URL,
                          urllib.urlencode(camel_parameters))

    user = User.get_or_none(private_key=private_key)
    print "----  USER ----"
    print user
    if not user:
        message = "unknown user: %s, request=%s" % (private_key, request)
        Log.Error(message, "unknown_user")
        return json_failure(message)
    
    FPSMultiuseCancelToken.add(user,
                               token_id=lower_parameters['token_id'],
                               reason_text=lower_parameters['reason_text'],
                               timestamp=lower_parameters['timestamp'])
    
    print
    print "FULL URL"
    print full_url
    content = _get(full_url)
    print
    print "CONTENT"
    print content
    
    multiauth = FPSMultiuseAuth.get_or_none(token_id=lower_parameters['token_id'])
    multiauth.status = FPSMultiuseAuth.STATUSES['CANCELLED']
    multiauth.save()
        
    return json_success()
示例#7
0
def authorize_multiuse(request):
    """
    expect parameters
        timestamp
        callerReference - use this so can resubmit pay requests, etc.
        globalAmountLimit - total $$ ever that can flow across token during token's lifetime
        paymentMethod - "ABT,ACH,CC"
        paymentReason - html
        recipient_slug_list - 'sluga,slugb,slugc' or 'all'
        version - one of ["2009-01-09"]
    
    returns
        parameters
        
    """
    #f = open('/var/sites/ProcrasDonate/auth.log', 'w')
    #import time
    #f.write("\n\n %s AUTHORIZE MULTIUSE WEASELS: " % (time.time(), request))
    #f.close()
    if not settings.DJANGO_SERVER and not request.is_secure():
        message = "must secure data via HTTPS: request=%s" % request
        Log.Error(message, "request_error")
        return json_failure(message)
    
    errors = []
    expected_parameters = ["caller_reference",
                           "payment_reason",
                           "payment_method",
                           "global_amount_limit",
                           "recipient_slug_list",
                           "version",
                           #"timestamp",
                           "private_key"]

    response = extract_parameters(request, "POST", expected_parameters)
    if not response['success']:
        return json_failure("Something went wrong extracting parameters: %s" % response['reason'])
    
    # params to send back to client and use locally (database worthy)
    lower_parameters = response['parameters']
    private_key = lower_parameters['private_key']
    del lower_parameters['private_key']
    
    # params for FPS REST request
    camel_parameters = _switch_cases(response['parameters'], to_lower=False)
    
    recipients = []
    if camel_parameters['recipient_slug_list'] == "all":
        allr = Recipient.objects.filter(fpsrecipient__status=FPSRecipient.STATUSES['SUCCESS'])
    else:
        allr = Recipient.objects.filter(fpsrecipient__status=FPSRecipient.STATUSES['SUCCESS'])
        allr = allr.filter(slug__in=camel_parameters['recipient_slug_list'].split(','))
    
    for recipient in allr:
        recipients.append(recipient)

    recipient_token_list = ",".join( [recipient.fps_data.token_id for recipient in recipients] )
    del camel_parameters['recipient_slug_list']
    camel_parameters['recipientTokenList'] = recipient_token_list
    
    camel_parameters.update({#'RecipientCobranding': "true",
                           #'paymentMethod': 'CC,ACH,ABT',
                           # common CBUI parameters
                           'cobrandingUrl': settings.FPS['cobrandingUrl'],
                           'websiteDescription': settings.FPS['websiteDescription'],
                           'pipelineName': "MultiUse",
                           'returnURL': "%s%s" % (settings.DOMAIN,
                                                  reverse('multiuse_authorize_callback',
                                                          args=(camel_parameters['callerReference'],))),
                                                          #kwargs={'caller_reference': parameters['callerReference']})),
                           'callerKey': settings.FPS['callerKey'],
                           })

    # add timestampe and signature
    print "PRE FINALIZE"
    for x in camel_parameters:
        print x,"=",camel_parameters[x]
    finalize_parameters(camel_parameters, type=CBUI_TYPE)
    print "POST FINALIZE"
    for x in camel_parameters:
        print x,"=",camel_parameters[x]
    
    full_url = "%s?%s" % (AMAZON_CBUI_URL, urllib.urlencode(camel_parameters))
    print
    print "FULL_URL", full_url
    print
    
    user = User.get_or_none(private_key=private_key)
    if not user:
        message = "unknown user: %s, request=%s" % (private_key, request)
        Log.Error(message, "unknown_user")
        return json_failure(message)
    
    multiuse = FPSMultiuseAuth.get_or_none(caller_reference=lower_parameters['caller_reference'])
    if not multiuse:
        multiuse = FPSMultiuseAuth.add(user, lower_parameters)
    
    return HttpResponseRedirect(full_url)
示例#8
0
def authorize(request, rescuetime_key):
    #if not settings.DJANGO_SERVER and not request.is_secure():
    #    message = "must secure data via HTTPS: request=%s" % request
    #    Log.Error(message, "request_error")
    #    return HttpResponseRedirect(reverse('rt_dashboard', args=(rescuetime_key, )))

    rt = RescueTimeUser.get_or_none(rescuetime_key=rescuetime_key)
    if not rt:
        return HttpResponseRedirect(reverse('rt_signup'))

    lower_parameters = {
        "caller_reference": create_id(12),
        "payment_reason": "ProcrasDonating for a good cause",
        "payment_method": "ABT,ACH,CC",
        "global_amount_limit": "100",
        "recipient_slug_list": "all",
        "version": settings.FPS['version']
    }
    #"timestamp",

    # params for FPS REST request
    camel_parameters = _switch_cases(lower_parameters, to_lower=False)

    recipients = []
    if camel_parameters['recipient_slug_list'] == "all":
        allr = Recipient.objects.filter(
            fpsrecipient__status=FPSRecipient.STATUSES['SUCCESS'])
        print "ALLR", allr
        allr = allr.exclude(slug="PD")
        print "ALLR2", allr
    else:
        allr = Recipient.objects.filter(
            fpsrecipient__status=FPSRecipient.STATUSES['SUCCESS'])
        allr = allr.filter(
            slug__in=camel_parameters['recipient_slug_list'].split(','))

    print
    for recipient in allr:
        print "RECIPIENT", recipient
        recipients.append(recipient)

    recipient_token_list = ",".join(
        [recipient.fps_data.token_id for recipient in recipients])
    if not recipient_token_list:
        Log.error("Empty recipient token list! %s" % request,
                  "empty_recipient_token_list")
    del camel_parameters['recipient_slug_list']
    camel_parameters['recipientTokenList'] = recipient_token_list

    camel_parameters.update({#'RecipientCobranding': "true",
                           #'paymentMethod': 'CC,ACH,ABT',
                           # common CBUI parameters
                           'cobrandingUrl': settings.FPS['cobrandingUrl'],
                           'websiteDescription': settings.FPS['websiteDescription'],
                           'pipelineName': "MultiUse",
                           'returnURL': "%s%s" % (settings.DOMAIN,
                                                  reverse('rt_authorize_callback',
                                                          args=(rescuetime_key, camel_parameters['callerReference']))),
                                                          #kwargs={'caller_reference': parameters['callerReference']})),
                           'callerKey': settings.FPS['callerKey'],
                           })

    # add timestampe and signature
    finalize_parameters(camel_parameters, type=CBUI_TYPE)
    print "POST FINALIZE"
    for x in camel_parameters:
        print x, "=", camel_parameters[x]

    full_url = "%s?%s" % (AMAZON_CBUI_URL, urllib.urlencode(camel_parameters))
    print
    print "FULL_URL", full_url
    print

    multiuse = FPSMultiuseAuth.get_or_none(
        caller_reference=lower_parameters['caller_reference'])
    if not multiuse:
        multiuse = FPSMultiuseAuth.add(rt.user, lower_parameters)

    return HttpResponseRedirect(full_url)