Is there a Facebook Credits Ruby On Rails gem out there yet? Or ruby version of their Facebook Credits sample app?

本小妞迷上赌 提交于 2019-12-02 19:28:39

Here is my code taking the FB example and RORing it:

require 'facebook_signed_request.rb'

class FacebookCreditsController < ApplicationController

skip_before_filter :verify_authenticity_token
layout nil

  def index
    facebook_request = FacebookSignedRequest.new(request.params['signed_request'])
    data = { "content" => {} }
    # handle invalid request
    if !facebook_request.valid?
      return
    end

    signed_request = facebook_request.signed_request

    # handle invalid signed request
    if signed_request.nil?
      return
    end

    method = request.params['method']

    order_id = request.params['order_id']

    # second state response from facebook
    if method == 'payments_status_update'
      status = request.params['status']

      if status == 'placed'
        next_state = 'settled'
        data['content']['status'] = next_state
      elsif status == 'settled'
        redirect_to '/lots'
        return
      end

      # compose returning data array_change_key_case
      data['content']['order_id'] = order_id

    # first stage response from facebook
    elsif method == 'payments_get_items'

      order_info = request.params['order_info']

      item = JSON.parse(order_info)
      item['price'] = item['price'].to_i

      # for url fields, if not prefixed by http://, prefix them
      url_key = [ 'product_url', 'image_url' ]
      url_key.each do |key|
        if item[key][0..6] != 'http://'
          item[key] = "http://#{item[key]}"
        end
      end

      # if payload['test_mode']
      if request.params['test_mode']
        update_keys = ['title', 'description']
        update_keys.each do |key|
            item[key] = '[Test Mode] ' + item[key]
        end
      end

      data['content'] = [item]  
    end

    data['method'] = method

    render :json => data
  end

end

Then in addition to this there is:

require 'base64'
require 'json'
require 'openssl'

class FacebookSignedRequest

  attr_reader :signed_request

  def initialize(signed_request)
    @signed_request = signed_request
  end

  def base64_url_decode str
    encoded_str = str.gsub('-','+').gsub('_','/')
    encoded_str += '=' while !(encoded_str.size % 4).zero?
    Base64.decode64(encoded_str)
  end

  def valid?
    # TODO: move it to some configuration
    secret = " << my secret is here >>"

    # decode data
    encoded_sig, payload = signed_request.split('.')
    sig = base64_url_decode(encoded_sig).unpack("H*")[0]
    data = JSON.parse base64_url_decode(payload)

    if data['algorithm'].to_s.upcase != 'HMAC-SHA256'
    # Rails.logger.error 'Unknown algorithm. Expected HMAC-SHA256'
      return false
    end

    #check sig
    expected_sig = OpenSSL::HMAC.hexdigest('sha256', secret, payload)
    if expected_sig != sig
    # Rails.logger.error 'Bad Signed JSON signature!'
      return false
    end

    data
  end

I don't know if this helps anyone else but it's all working for me. Sorry for taking so long to remember to come back and post my working code...

View related code as requested:

#view
<%= javascript_include_tag "premium_signup" %>
<script type="text/javascript">
    $(document).ready(function() {
        $('#premium_signup_button').click(function() {
            signupAsPremiumMember('Premium Membership', 'Create unlimited auctions with no extra charge at all for 1 year.', "1", '', '');
        });
    });
</script>
...
<button id="premium_signup_button">Signup as a premium member</button>

#premium_signup.js
function signupAsPremiumMember(title, desc, price, imageURL, productURL) {
var order_info = {
    "title": title,
    "description": desc,
    "price": price,
    "image_url": imageURL,
    "product_url": productURL
};

var payload = {
    "method": 'pay',
    "order_info": order_info,
    "purchase_type": 'item'
};

console.log(FB.ui(payload, facebookPurchaseCompletionCallback));
}

function facebookPurchaseCompletionCallback(data) {
    if (data['order_id']) {
        console.log(data['order_id']);
    }
    else if (data['error_code']) {
        console.log(data['error_code']);
    }
    else {
        console.log("failed");
    }
}

#in the layout
#in head
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<%= javascript_include_tag 'application' %>
#in body
  <div id="fb-root"></div>
    <script>
      FB.init({
        appId  : '############',
        status : true, // check login status
        cookie : true, // enable cookies to allow the server to access the session
        xfbml  : true  // parse XFBML
      });

Now all of this is coming from a guy who sat down and learned to program in Ruby On Rails with as little supporting Javascript knowledge as I can get away with, in about 12 weeks last year with a few more weeks thrown in this year for good measure. I say that by way of caution - the code I've posted might be garbage... but it works :-)

And if anyone actually finds any of this useful a VOTE UP on the answer would be appreciated - just sayin' :-)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!