我有一个真正的噩梦试图让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: > |
。
有谁能想到我在这里做错了什么?
由于
答案 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>