Создание подписи Paypal, 'X-PAYPAL-AUTHORIZATION' в Ruby - PullRequest
4 голосов
/ 06 марта 2012

Есть ли в Ruby библиотека, которая генерирует заголовок Signature, 'X-PAYPAL-AUTHORIZATION', который необходим для совершения звонков от имени владельца учетной записи, который авторизовал нас через API разрешений PayPal. Я закончил с потоком разрешений и получил требуемый токен доступа, tokenSecret. Я чувствую, что генерирую подпись неправильно, так как все мои вызовы с сгенерированным 'X-PAYPAL-AUTHORIZATION' терпят неудачу. Они дают следующие ошибки:

Для звонка по NVP я получаю:
You do not have permissions to make this API call

А для вызова GetBasicPersonalData я получаю:
Authentication failed. API credentials are incorrect.

Кто-нибудь прошел через это в Ruby? Каков наилучший способ создания подписи. Paypal только что предоставил некоторый SDK в Paypal, Java, но не алгоритм для генерации подписи.

Спасибо,
Nilesh

Ответы [ 2 ]

3 голосов
/ 17 апреля 2012

Посмотрите на драгоценный камень PayPal Permissions.

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 голосов
/ 07 марта 2012

Заголовок X-PAYPAL-AUTHORIZATION [генерируется] с URL-адресом "https://svcs.paypal.com/Permissions/GetBasicPersonalData". (см. Стр. 23 и главу 7 по ссылке)

Заявление NVP" У вас нет правсделать этот вызов API "означает, что ваши учетные данные API верны, просто ваша учетная запись не имеет разрешения для конкретного API, который вы пытаетесь вызвать. Что-то между двумя отправляемыми вызовами не использует те же учетные данные API.

Для вызова NVP я получаю:

Какой вызов NVP?

TransactionSearch (см. Комментарииниже)

Кроме того, если вы еще этого не сделали, вы можете использовать APP-ID песочницы для тестирования в песочнице, и вам необходимо подать заявку на ID приложения сТехническая служба разработчика (DTS) в PayPal для получения идентификатора приложения для работы в реальном времени.

РЕДАКТИРОВАТЬ:

Чтобы использовать API TransactionSearch, все, что вы должны отправить, это ниже. Вам не нужно указывать дополнительные заголовки.

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
...