在Ruby中生成PayPal签名,'X-PAYPAL-AUTHORIZATION'是什么?

4
有没有Ruby的库可以生成必须使用Paypal Permissions API授权我们代表账户持有人发出调用所需的签名'X-PAYPAL-AUTHORIZATION'头。我已经完成了权限流程并获得了所需的访问令牌和令牌密钥。我觉得我生成的签名不正确,因为我的所有调用都失败了。它们会给出以下错误:

NVP调用返回:
您无权进行此API调用

而GetBasicPersonalData调用返回:
身份验证失败。API凭据不正确。

有没有人在Ruby中做过这个?生成签名的最佳方法是什么?Paypal只提供了一些Java、Paypal的SDK,但没有提供生成签名的算法。

谢谢,
Nilesh

2个回答

3

看一下 PayPal 权限 gem。

https://github.com/moshbit/paypal_permissions

具体来说,lib/paypal_permissions/x_pp_authorization.rb 需要 'CGI'、'OpenSSL' 和 '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

示例参数:

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

X-PAYPAL-AUTHORIZATION头部是通过URL“https://svcs.paypal.com/Permissions/GetBasicPersonalData”生成的(请参见链接的第23页和第7章)。

NVP报告“您没有权限进行此API调用”意味着您的API凭据是正确的,只是您的账户没有特定API的访问权限。您提交的两个调用之间有一些东西未使用相同的API凭据。

我得到的NVP调用是:

什么NVP调用?

TransactionSearch(请参见下面的注释)

此外,如果您还没有这样做,您需要在沙盒中使用沙盒APP-ID进行测试,并且您需要向PayPal的开发技术服务(DTS)申请一个应用程序ID以获取实时应用程序ID。

编辑:

要使用TransactionSearch API,您应该只提交以下内容。您不需要指定任何额外的标头。

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

感谢@SgtPooki。我确实拥有权限,能够成功完成权限流程。是的,我在沙盒中,并使用沙盒APP-ID:APP-80W284485P519543T 我所做的NVP调用是“TransactionSearch”,并且已经获得了所需的权限。我觉得即使我拥有权限,我也会收到“您没有权限进行此API调用”的消息,因为我在生成签名和“X-PAYPAL-AUTHORIZATION”头时犯了一些错误。因此,我正在寻找一些正确执行此操作的Ruby示例或某种方法来知道它是否已正确生成。 - Nilesh
@Nilesh,感谢您的回顾!TransactionSearch不是Adaptive Payments API的一部分,因此不需要发送X-PayPal-Authorization。请参见上面所做的编辑。 - SgtPooki
我需要代表已经授权我的账户持有人进行TransactionSearch调用,因此我肯定需要'X-PAYPAL-AUTHORIZATION'头。我正在寻找的是一个能够生成此头的Ruby库。 - Nilesh
1
@Nilesh,不需要。TransactionSearch不是AdaptivePayments API的一部分,因此根本不需要X-PAYPAL blah blah,我保证。如果您代表其他人提交API调用,则只需设置“subject=accountholderspaypal@email.com”。 - SgtPooki
谢谢,但我在哪里可以找到这个文档?我问这个问题是因为我没有在任何地方读到过它,也没有看到过以这种方式实现。此外,要获取“accountholderspaypal@email.com”,我将不得不调用“GetBasicPersonalData”,并且我会得到以下响应:“身份验证失败。API凭据不正确。”我想获得这个结果,而不必向用户询问,以使用户体验更加流畅。 - Nilesh
嘿,我尝试了你的建议,它起作用了。我在这里找到了文档:https://www.paypalobjects.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/overview.html谢谢你,没有人指出这一点,我也错过了。但我的问题仍然存在: “要获取'accountholderspaypal@email.com',我将不得不调用'GetBasicPersonalData',并且我会得到以下响应:“身份验证失败。API凭据不正确。”我想隐式地获取它,而不必向用户询问,以使用户体验更加流畅。 - Nilesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接