使用带有Ruby的PesaPal API时出现OAuth signature_invalid错误

时间:2013-05-21 17:16:38

标签: php ruby oauth

我有一个真正的噩梦试图让PesaPal API为我使用Ruby ...

我很欣赏它可能不是最常用的API,但是如果有人在网上有更多使用OAuth的经验,和/或PHP经验谁可以提供一双新鲜的眼睛,我会很感激。

所以PesaPal开发者网站就在这里:http://developer.pesapal.com 他们的API docs并没有提供太多关于如何在他们的网站上使用OAuth的线索,我不太了解PHP,以确保我已正确阅读他们的PHP sample

这是我在Ruby中实现它的尝试:

require 'oauth'
require 'uri'

key = '<my sandbox key>'
sec = '<my sandbox secret>' 

API_DOMAIN = 'https://demo.pesapal.com'

# An XML string of param data to include with our request
RAW_XML  = %{<?xml version=\"1.0\" encoding=\"utf-8\"?><PesapalDirectOrderInfo xmlns:xsi=\"http://www.w3.org/2001/XMLSchemainstance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" Amount=\"12.34\" Description=\"Bob Test 1\" Type=\"MERCHANT\" Reference=\"808\" FirstName=\"Bo\" LastName=\"Tester\" Email=\"bodacious@bodacious.com\" xmlns=\"http://www.pesapal.com\" />}

# Escape the XML
@post_xml = URI.escape(RAW_XML)

# Create a new OAuth Consumer
@consumer = OAuth::Consumer.new(key, sec, {
  site: API_DOMAIN, 
  scheme: :query_string
})

# The signed request object
@signed_request  = @consumer.create_signed_request('get', "#{API_DOMAIN}/API/PostPesapalDirectOrderV4")

# Join the pesapal_request_data and oauth_callback with '&' for valid URL params
@params = { 
  oauth_callback: URI.escape('http://localhost:3000'),
  pesapal_request_data: @post_xml,
}.map { |k,v| "#{k}=#{v}" }.join('&')

# This is the URL we should redirect to
puts redirect_url = "#{@signed_request.path}&#{@params}"

当我尝试访问此代码返回的网址时,我从API返回Problem: signature_invalid | Advice: > |

有谁能想到我在这里做错了什么?

由于

3 个答案:

答案 0 :(得分:3)

在这里查看pesapal RubyGem ... https://rubygems.org/gems/pesapal ...它可以为您处理所有这些内容。

答案 1 :(得分:0)

我遇到了同样的问题,我通过创建手动签名网址的方法解决了这个问题。创建自己的方法来获得像这样的oauth_nonce。

def nonce
Array.new( 5 ) { rand(256) }.pack('C*').unpack('H*').first
end

签名方法如下所示:

def signature
key = percent_encode( @consumer_secret ) + '&' + percent_encode( @token_secret )

digest = OpenSSL::Digest::Digest.new( 'sha1' )
hmac = OpenSSL::HMAC.digest( digest, key, @base_str )

Base64.encode64( hmac ).chomp.gsub( /\n/, '' )
end

这是@base_str实例变量:

@base_str = [@req_method,
percent_encode( req_url ),
percent_encode( query_string )
].join( '&' )

这是query_string方法:

def query_string
pairs = []
@params.sort.each { | key, val |
pairs.push( "#{ percent_encode( key ) }=#{ percent_encode( val.to_s ) }" )
}
pairs.join '&'
end

然后,您可以使用上面的签名方法获取要在生成的URL中使用的oauth_signature参数

答案 2 :(得分:0)

我知道OP对解决Ruby域的解决方案感兴趣,但我觉得注意到我在PHP上遇到类似的问题可能会有所帮助,解决方案是确保我在XML中没有空格发布数据结构。

<强> WRONG:

<?xml version="1.0" encoding="utf-8"?>
<PesapalDirectOrderInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                        Amount="200" 
                        Currency="KES" 
                        Description="Computer Accessory" 
                        Type="MERCHANT" 
                        Reference="dd19f9ede4db6f0a13b7053111f02825" 
                        FirstName="Stack" 
                        LastName="Overflow" 
                        Email="so@stackoverflow.com" 
                        PhoneNumber="" 
                        xmlns="http://www.pesapal.com" >
                        <lineitems>
                            <lineitem uniqueid="29" 
                                      particulars="Keyboard" 
                                      quantity="1" 
                                      unitcost="200" 
                                      subtotal="200.00" >
                            </lineitem>
                        </lineitems>
</PesapalDirectOrderInfo>

<强>正确:

<?xml version="1.0" encoding="utf-8"?><PesapalDirectOrderInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Amount="200" Currency="KES" Description="Computer Accessory" Type="MERCHANT" Reference="dd19f9ede4db6f0a13b7053111f02825" FirstName="Stack" LastName="Overflow" Email="so@stackoverflow.com" PhoneNumber="" xmlns="http://www.pesapal.com" ><lineitems><lineitem uniqueid="29" particulars="Keyboard" quantity="1" unitcost="200" subtotal="200.00" ></lineitem></lineitems></PesapalDirectOrderInfo>