Generating Paypal Signature, 'X-PAYPAL-AUTHORIZATION' in Ruby

情到浓时终转凉″ 提交于 2019-12-23 15:14:59

问题


Is there any library in Ruby that generates the Signature, 'X-PAYPAL-AUTHORIZATION' header that is required to make calls on behalf of the account holder who has authorized us through the paypal Permissions API. I am done with the permissions flow and get the required access token, tokenSecret. I feel I am generating the signature incorrectly as all my calls with the the generated 'X-PAYPAL-AUTHORIZATION' fail. They give the following errors:

For NVP call I get:
You do not have permissions to make this API call

And for the GetBasicPersonalData call I get:
Authentication failed. API credentials are incorrect.

Has anyone gone through this in Ruby? What is best way to generate signature. Paypal has just provided some SDK in Paypal, Java, but not the algorithm to generate signature.

Thanks,
Nilesh


回答1:


Take a look at the PayPal Permissions gem.

https://github.com/moshbit/paypal_permissions

Specifically lib/paypal_permissions/x_pp_authorization.rb require 'cgi' require 'openssl' require 'base64'

class Hash
  def to_paypal_permissions_query
    collect do |key, value|
      "#{key}=#{value}"
    end.sort * '&'
  end
end

module ActiveMerchant #:nodoc:
  module Billing #:nodoc:
    module XPPAuthorization
      public
      def x_pp_authorization_header url, api_user_id, api_password, access_token, access_token_verifier
        timestamp = Time.now.to_i.to_s
        signature = x_pp_authorization_signature url, api_user_id, api_password, timestamp, access_token, access_token_verifier
        { 'X-PAYPAL-AUTHORIZATION' => "token=#{access_token},signature=#{signature},timestamp=#{timestamp}" }
      end

      public
      def x_pp_authorization_signature url, api_user_id, api_password, timestamp, access_token, access_token_verifier
        # no query params, but if there were, this is where they'd go
        query_params = {}
        key = [
          paypal_encode(api_password),
          paypal_encode(access_token_verifier),
        ].join("&")

        params = query_params.dup.merge({
          "oauth_consumer_key" => api_user_id,
          "oauth_version" => "1.0",
          "oauth_signature_method" => "HMAC-SHA1",
          "oauth_token" => access_token,
          "oauth_timestamp" => timestamp,
        })
        sorted_query_string = params.to_paypal_permissions_query

        base = [
          "POST",
          paypal_encode(url),
          paypal_encode(sorted_query_string)
        ].join("&")
        base = base.gsub /%([0-9A-F])([0-9A-F])/ do
          "%#{$1.downcase}#{$2.downcase}"  # hack to match PayPal Java SDK bit for bit
        end

        digest = OpenSSL::HMAC.digest('sha1', key, base)
        Base64.encode64(digest).chomp
      end

      # The PayPalURLEncoder java class percent encodes everything other than 'a-zA-Z0-9 _'.
      # Then it converts ' ' to '+'.
      # Ruby's CGI.encode takes care of the ' ' and '*' to satisfy PayPal
      # (but beware, URI.encode percent encodes spaces, and does nothing with '*').
      # Finally, CGI.encode does not encode '.-', which we need to do here.
      def paypal_encode str
        s = str.dup
        CGI.escape(s).gsub('.', '%2E').gsub('-', '%2D')
      end
    end
  end
end

Sample parameters:

url = 'https://svcs.sandbox.paypal.com/Permissions/GetBasicPersonalData'
api_user_id = 'caller_1234567890_biz_api1.yourdomain.com'
api_password = '1234567890'
access_token = 'YJGjMOmTUqVPlKOd1234567890-jdQV3eWCOLuCQOyDK1234567890'
access_token_verifier = 'PgUjnwsMhuuUuZlPU1234567890'



回答2:


The X-PAYPAL-AUTHORIZATION header [is] generated with URL "https://svcs.paypal.com/Permissions/GetBasicPersonalData". (see page 23, and chapter 7, at the link)

NVP stating "You do not have permissions to make this API call" means your API credentials are correct, just that your account does not have permission for the particular API you are trying to call. Something between the two calls you are submitting is not using the same API credentials.

For NVP call I get:

What NVP call?

TransactionSearch (see comments below)

Also, if you haven't already done so, you will want to use the sandbox APP-ID for testing in the sandbox, and you will need to apply for an app-id with Developer Technical Services (DTS) at PayPal to get an App-ID for live.

EDIT:

To use the TransactionSearch API, all you should be submitting is below. You do not need to specify any extra headers.

USER=xxxxxxxxxxxxxxxxxx
PWD=xxxxxxxxxxxxxxxxxx
SIGNATURE=xxxxxxxxxxxxxxxxxx
METHOD=TransactionSearch
VERSION=86.0
STARTDATE=2009-10-11T00:00:00Z
TRANSACTIONID=1234567890
//And for submitting API calls on bob's behalf, if his PayPal email was bob@bob.com:
SUBJECT=bob@bob.com


来源:https://stackoverflow.com/questions/9578895/generating-paypal-signature-x-paypal-authorization-in-ruby

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