rubyjrubyactivemerchantpaypal

PayPal express ActiveMerchant gateway not working


According to this, the ActiveMerchant PayPal Express Gateway is initialized like this:

paypal_options = {
  login: "API_USERNAME_HERE",
  password: "API_PASSWORD_HERE",
  signature: "API_SIGNATURE_HERE"
}

::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)

I'm definitely supplying a signature, yet I'm getting this error:

An API Certificate or API Signature is required to make requests to PayPal

The PayPal initializer looks like this (found here):

def initialize(options = {})
    requires!(options, :login, :password)

    headers = {'X-PP-AUTHORIZATION' => options.delete(:auth_signature), 'X-PAYPAL-MESSAGE-PROTOCOL' => 'SOAP11'} if options[:auth_signature]
    options = {
        :pem => pem_file,
        :signature => signature,
        :headers => headers || {}
    }.update(options)

    if options[:pem].blank? && options[:signature].blank?
        raise ArgumentError, "An API Certificate or API Signature is required to make requests to PayPal"
    end

    super(options)
end

I don't understand what this initializer is doing with the signature and why it's not accepting it as per the example.

Here are the options I'm passing, which I've put to STDOUT:

{  
   "password"   =>"***************",
   "signature"   =>"AVtrAKGQXoUNJFduUU0pn1dewq80AK9KYWenyFwYcduz8elS85B8T0Wc",
   "allow_guest_checkout"   =>true,
   "login"   =>"********************",
   "test"   =>true
}

Can someone help me with this please?
Note that I'm using this in JRuby, but I don't think that makes any difference in this case.


EDIT after @PiersC's comments:

I hardcoded this instead of taking them as params from Java and it worked:

  options = {
      login: "*************",
      password: "*****************",
      signature: "AVtrAKGQXoUNJFduUU0pn1dewq80AK9KYWenyFwYcduz8elS85B8T0Wc"
  }

However this has led to another question. I've been converting the Java maps to Ruby hashes like this:

def self.convert_hash(map)
    hsh = {}
    map.each {|key, value| hsh[key] = value}
    hsh.with_indifferent_access
end

And this has worked on all other gateways. How do I convert the Java map correctly to the options hash in Ruby?


Solution

  • Your option keys are strings but should be symbols, eg. { password: '***', ... } ActiveSupport::HashWithInvalidAccess hides (obscures?) the difference between symbol keys and string keys, but if you are using a regular Hash then { 'signature' => signature } is not the same as { signature: signature }.