djangofacebookfacebook-credits

Facebook Credits Callback on Django


This question is following a previous one which i posted: Django Callback on Facebook Credits

So basically, I have a static HTML page with a button. Upon pressing of the button the purchase dialog for Facebook Credits should show up.

As shown in the Facebook blog post, here is my page link view the HTML source.

I have a view for the URL, which is the link that is registered in Facebook Developers. The view goes as followed:

def fb_credits_callback(request):
    #Data array that will be returned
    data = {
    }

    string = ''
    if request.method == 'GET':
        string = 'GET'
    elif request.method == 'POST':
        string = 'POST'

    send_mail(
        'TestDare Debug',
        'Received '+string+" request",
        'registration@my_domain.com',
        ['my_personal_email@gmail.com'],
        fail_silently=True
    )

    signed_request = request['signed_request']
    plain_request = parse_signed_request(signed_request, FACEBOOK_APP_ID)

Now naturally this is only a preliminary test (there's much debugging to do later), but I don't even receive the email when I click the button on my page. Which means that for some reason Facebook is not executing the callback to my application. If I execute a GET to that view I receive an email as expected.

Upon clicking the button I get the following error:

"There Was a Problem Processing Your Payment Sorry, but we're having trouble processing your payment. You have not been charged for this transaction. Please try again."

If someone could help me trace why the callback is not working I would really appreciate it.

Thank you


Solution

  • The signed_request parameter is a simple way to make sure that the data you're receiving is the actual data sent by Facebook. It is signed using your application secret which is only known by you and Facebook. If someone were to make a change to the data, the signature would no longer validate as they wouldn't know your application secret to also update the signature.

    As i known Facebook's python-sdk does not support parsing request parameter.

    Here is piece of code snippet for parsing "signed_request".

    import base64
    import hashlib
    import hmac
    import simplejson as json
    
    def base64_url_decode(inp):
        padding_factor = (4 - len(inp) % 4) % 4
        inp += "="*padding_factor 
        return base64.b64decode(unicode(inp).translate(dict(zip(map(ord, u'-_'), u'+/'))))
    
    def parse_signed_request(signed_request, secret):
    
        l = signed_request.split('.', 2)
        encoded_sig = l[0]
        payload = l[1]
    
        sig = base64_url_decode(encoded_sig)
        data = json.loads(base64_url_decode(payload))
    
        if data.get('algorithm').upper() != 'HMAC-SHA256':
            log.error('Unknown algorithm')
            return None
        else:
            expected_sig = hmac.new(secret, msg=payload, digestmod=hashlib.sha256).digest()
    
        if sig != expected_sig:
            return None
        else:
            log.debug('valid signed request received..')
            return data
    

    I know there is some cryptic code in base64_url_decode because translate, maketrans does not work that well with unicode strings. Anyways, if you have any questions, just drop a line in the commments below.

    Myabe you can find here more details.

    Thanks..