1

我正在做一场真正的噩梦,试图让 PesaPal API 使用 Ruby 为我工作......

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

所以 PesaPal 开发者网站在这里:http: //developer.pesapal.com 他们的API 文档并没有提供太多关于如何在他们的网站上使用 OAuth 的线索,而且我对 PHP 的理解还不够好,无法确定我已经正确阅读了他们的PHP 示例

这是我在 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}"

当我尝试访问此代码返回的 URL 时,我得到:Problem: signature_invalid | Advice: > |从 API 返回。

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

谢谢

4

3 回答 3

3

在这里查看 pesapal RubyGem ... https://rubygems.org/gems/pesapal ...它会为您处理所有这些事情。

于 2013-09-28T07:54:56.517 回答
0

我遇到了同样的问题,我通过创建一种手动签名 url 的方法来解决它。创建自己的方法来像这样获取 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

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

于 2013-07-19T07:42:25.983 回答
0

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

错误的:

<?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>
于 2014-02-16T22:26:40.803 回答