-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2adc0b2
commit ee3e533
Showing
14 changed files
with
286 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,18 @@ | ||
# alipay-global | ||
Unofficial gem for linking up to global.alipay for remote payment | ||
|
||
Development of this gem is largely influenced by the unofficial alipay gem | ||
|
||
## Configuration | ||
|
||
If you're using MD5, the api_secret_key needs to be initialized. If RSA is used, the private_key_location needs to be initialized. DSA is currently not supported. | ||
|
||
```ruby | ||
AlipayGlobal.pid = 'YOUR_PID' | ||
AlipayGlobal.key = 'YOUR_KEY' | ||
AlipayGlobal.api_partner_id = 'YOUR_PID' | ||
AlipayGlobal.api_secret_key = 'YOUR_KEY' | ||
|
||
#AlipayGlobal.private_key_location = 'YOUR PRIVATE KEY LOCATION' #Your .pem file location | ||
|
||
#Alipay.sign_type = 'MD5' # Available values: MD5, RSA. Default is MD5 | ||
#Alipay.debug_mode = true # Enable parameter check. Default is true. | ||
#AlipayGlobal.sign_type = 'MD5' # Available values: MD5, RSA. Default is MD5 | ||
#AlipayGlobal.debug_mode = true # Enable parameter check. Default is true. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require "bundler/gem_tasks" | ||
require "rake/testtask" | ||
|
||
Rake::TestTask.new do |t| | ||
t.libs << "test" | ||
t.test_files = FileList['test/**/*_test.rb'] | ||
end | ||
|
||
task :default => :test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
-----BEGIN PUBLIC KEY----- | ||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRA | ||
FljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQE | ||
B/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5Ksi | ||
NG9zpgmLCUYuLkxpLQIDAQAB | ||
-----END PUBLIC KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
MIIEpAIBAAKCAQEAxF1vOOysBibP9gquwCqjCigUBIGZpPsTiAyeGvt38NRwixPI | ||
56wZgVvCMp02pVBWH7np99Qi91Axg1/A7j1z4MAqBru6XNPgn2LLIEv8xuSvJ0mI | ||
YeB1MXZOttD2tsaNgFdU0LQsSz+HEicSfh5/1xJ5nCwQmJg/2AIGOL1igcAkqCct | ||
cs4umwK9GFQ1FROsqz4OXUbjzByuCxmY9C5r4ALAycmjKhsy9luE1Pp9VEzT0jeJ | ||
xfAH0vAPkGCqNv50swxJ6n+s98/ves/XmxXL3dIxAW/6RvmriNXwANsuwyn0DMsv | ||
u1nFMZIxeCUvfwmrwkpGb5lHFBvW9pTbOCOMIwIDAQABAoIBACjRX0hO8idJNBtp | ||
9w9dDY0T7a1OH1kLE/FI5iinszPthQNz9mQqAxc/squAwJY2j+CCbd8lSqtsEQ7E | ||
/b7IKWlDqLjDlyaqqFuZVq38/at+Z+Zbw6zM0q+Ybx5Ta6Vsuoc+IBROD5MIvpQI | ||
aTCsOFjFr1/GTSDbLRJCwXZT78EWiYMDnDscmvAQ/3A7c+2uQcMUAUMsPZ1gi0WY | ||
2IdNetD9D2bwowYwoCJ82BKlciqxx2bL9ue3KnFea01pvQFisOjO69421C1baqV2 | ||
6ghT001ghrL80SvG7SNuArEGSqm+WeUC3/BoeK1/1BEsrgiXFVZZvvrMcQwWWetk | ||
JOkJTskCgYEA6DfE2a44tdIN2spg4Wl5O/pRAA4cnpBsKCL/RYTaIXmHj5tDyqlO | ||
oRrJuVQBesv2WDxTwaqRDA7Wbro3jtWObKHtXiiPNKw4bb2OpODdIlJXLLvRpXkq | ||
PhiO1+0RaBX3TGyVs+JJvNWZVAj03IeMNfzjZq18fkLwDYw1PUqgNrcCgYEA2Hmv | ||
B9Ee/SkFbheM6KYYBGNSCU6qxb0C6aaOFKrq8Ryml/3Li4Q+nFwzDiFQHPhM0m4e | ||
mv5y/mMGR2jnkn/KwKYa3jTICp+F/ilkAop0k8yKcXrdVkb/Fb/lQw2pkqkLbKaG | ||
/Ao20TS+hlWjAZfpvU2aVqS215PTyO6I4L9zSfUCgYEA5djtexi7ARycogbWxcaE | ||
PR2Stx9ArKH+q+uYB9NrpN6Jk1b3Ts0uCsBdEpdXr5faiZOMw5B0aR72mDqxaytu | ||
AZB1RlGXDWe5osWRPxljR+mAZ8Kvy72WVkgwewEnzYKQeJCxzI8atVImpcsHspBn | ||
87gPzT3Cj6bpvD8fIz+OPRkCgYAdMINGdY9NKavexXQtpr/UT6QvNxlV4n+zC89a | ||
wBU//9IC6qj4nhNnOBN2U02fKmgJc+nSkn7lCGs/U8jt+ydWxM8YqVtT+2Cw/dnL | ||
cen4R/tfA+c2jAo3X5HFceEssnik5OuMrr/ng8oxCPka7OYKrZ0jE8DH3toO3QM9 | ||
8vLTxQKBgQDTQSlorlACRywudw2KE4Li7yRM9CodwBnIJPGze8N+54f3uxxc39AZ | ||
9jT6UeK/vaiuD9VrPxF5Ze4/ZPaHctMy5O2uD4m+zPTBQo/uUGBg4m++i8b3PWfx | ||
e8OjaXP26YiACWG/RRan8R0ZRPy8M/zLgFJUMiNrSrxchUrVXoiM4w== | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
-----BEGIN PUBLIC KEY----- | ||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxF1vOOysBibP9gquwCqj | ||
CigUBIGZpPsTiAyeGvt38NRwixPI56wZgVvCMp02pVBWH7np99Qi91Axg1/A7j1z | ||
4MAqBru6XNPgn2LLIEv8xuSvJ0mIYeB1MXZOttD2tsaNgFdU0LQsSz+HEicSfh5/ | ||
1xJ5nCwQmJg/2AIGOL1igcAkqCctcs4umwK9GFQ1FROsqz4OXUbjzByuCxmY9C5r | ||
4ALAycmjKhsy9luE1Pp9VEzT0jeJxfAH0vAPkGCqNv50swxJ6n+s98/ves/XmxXL | ||
3dIxAW/6RvmriNXwANsuwyn0DMsvu1nFMZIxeCUvfwmrwkpGb5lHFBvW9pTbOCOM | ||
IwIDAQAB | ||
-----END PUBLIC KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
module Alipay | ||
module Sign | ||
@alipay_rsa_public_key = File.read("#{File.dirname __dir__}/../keys/alipay_public_key.pem") | ||
|
||
def self.generate(params) | ||
params = Utils.stringify_keys(params) | ||
sign_type = AlipayGlobal.sign_type.upcase | ||
key = AlipayGlobal.api_secret_key | ||
string = params_to_string(params) | ||
|
||
case sign_type | ||
when 'MD5' | ||
MD5.sign(string, key) | ||
when 'RSA' | ||
RSA.sign(string) | ||
when 'DSA' | ||
DSA.sign(key, string) | ||
else | ||
raise ArgumentError, "invalid sign_type #{sign_type}, allow value: 'MD5', 'RSA', 'DSA'" | ||
end | ||
end | ||
|
||
def self.verify?(params, options = {}) | ||
params = Utils.stringify_keys(params) | ||
|
||
sign_type = params.delete('sign_type') | ||
sign = params.delete('sign') | ||
string = params_to_string(params) | ||
|
||
case sign_type | ||
when 'MD5' | ||
key = options[:key] || AlipayGlobal.api_secret_key | ||
MD5.verify?(string, key, sign) | ||
when 'RSA' | ||
RSA.verify?(string, @alipay_rsa_public_key, sign) | ||
when 'DSA' | ||
DSA.verify?(string, sign) | ||
else | ||
false | ||
end | ||
end | ||
|
||
def self.params_to_string(params) | ||
params.sort.map { |item| item.join('=') }.join('&') | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
require 'digest/md5' | ||
|
||
module AlipayGlobal | ||
module Sign | ||
class MD5 | ||
#pre-signed string should not be url encoded | ||
def self.sign(string, secret_key) | ||
Digest::MD5.hexdigest("#{string}#{secret_key}") | ||
end | ||
|
||
def self.verify?(string, secret_key, sign) | ||
sign == sign(string, secret_key) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
require 'openssl' | ||
require 'base64' | ||
|
||
module AlipayGlobal | ||
module Sign | ||
class RSA | ||
def self.private_key | ||
raise ArgumentError, "Assign valid location for RSA private key location :: #AlipayGlobal.private_key_location = #{AlipayGlobal.private_key_location}" if !AlipayGlobal.private_key_location | ||
File.read(AlipayGlobal.private_key_location) | ||
end | ||
|
||
def self.sign(string, supplied_private_key = nil) | ||
key = supplied_private_key || private_key | ||
rsa = OpenSSL::PKey::RSA.new(key) | ||
Base64.encode64(rsa.sign(OpenSSL::Digest::SHA256.new, string)) | ||
end | ||
|
||
def self.verify?(string, public_key, sign) | ||
rsa = OpenSSL::PKey::RSA.new(public_key) | ||
rsa.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(sign), string) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require 'test_config' | ||
|
||
describe "AlipayGlobal", "basic gem config" do | ||
|
||
before do | ||
@alipay = AlipayGlobal | ||
end | ||
|
||
it "has a basic debug mode default" do | ||
assert @alipay.debug_mode? | ||
end | ||
|
||
it "has a default MD5 mode" do | ||
assert_equal 'MD5', @alipay.sign_type | ||
end | ||
|
||
describe "api_partner_id & api_secret_key assignment" do | ||
|
||
before do | ||
@alipay.api_partner_id = '2088101122136241' | ||
@alipay.api_secret_key = '760bdzec6y9goq7ctyx96ezkz78287de' | ||
end | ||
|
||
it "has assigned api_partner_id and api_secret_key" do | ||
@alipay.api_partner_id.wont_be_nil true | ||
@alipay.api_secret_key.wont_be_nil true | ||
end | ||
|
||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require 'test_config' | ||
|
||
describe "AlipayGlobal::Sign::MD5", "md5 signature test" do | ||
|
||
before do | ||
@alipay = AlipayGlobal | ||
@alipay.api_partner_id = '2088101122136241' | ||
@alipay.api_secret_key = '760bdzec6y9goq7ctyx96ezkz78287de' | ||
|
||
@params = "_input_charset=gbk&out_trade_no=6741334835157966&partner=2088101568338364&payment_type=1&return_url=http://www.test.com/alipay/return_url.asp¤cy=USD&service=create_forex_trade&subject=a book&bodu=nice book&total_fee=100" | ||
|
||
@md5_signature = "db017da14ac139afef3bb7357bb284b2" | ||
end | ||
|
||
describe "MD5#sign" do | ||
it "should generate the correct signature" do | ||
assert_equal @md5_signature, @alipay::Sign::MD5.sign(@params, @alipay.api_secret_key) | ||
end | ||
end | ||
|
||
describe "MD5#verify?" do | ||
it "should return true for the correct signature match" do | ||
@alipay::Sign::MD5.verify?(@params, @alipay.api_secret_key, @md5_signature).must_equal true | ||
end | ||
|
||
it "should return false for incorrect signature match" do | ||
@alipay::Sign::MD5.verify?(@params, @alipay.api_secret_key, "mike#{@md5_signature}").must_equal false | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
require 'test_config' | ||
|
||
describe "AlipayGlobal::Sign::RSA", "rsa signature test" do | ||
|
||
before do | ||
@alipay = AlipayGlobal | ||
|
||
@params = "_input_charset=gbk&out_trade_no=6741334835157966&partner=2088101568338364&payment_type=1&return_url=http://www.test.com/alipay/return_url.asp¤cy=USD&service=create_forex_trade&subject=a book&bodu=nice book&total_fee=100" | ||
|
||
@rsa_signature = "i6GcANd+q8dTGY5kif3ClSqQbysmvPwf+gFowbB+ukKLKdcd4dlEUAWKlirK\nBviHoJwydMkUwavi5XvUieU6582UdqrlZgz1UlRSgL5NHSv7DWckhnYL7IKL\n2sTHb5derwrhjcJD/diYSnAMA0K+sRwVZ6Rs4fvQH3NN7sY4x0rb5W54QkPe\nCLqI+MzTggrcfqme2Grx19jOXSigETGWAm74CoI2lztlNgEjBpuqTmXHaBz1\nJ968XI9hVBj2mGnHU4EXj5hPSY/bFK2gVItOQ3w5RbTQCgjdpBYkM1LwTOlc\nu1/BlmWuUh82NGEK/qBrmne6z/W4GnG+6sqoAERA4g==\n" | ||
|
||
@test_rsa_private_key = File.read("#{File.dirname __dir__}/../keys/test_private_key.pem") | ||
@test_rsa_public_key = File.read("#{File.dirname __dir__}/../keys/test_public_key.pem") | ||
end | ||
|
||
describe "RSA#sign" do | ||
describe "AlipayGlobal.private_key_location is empty" do | ||
before do | ||
@alipay.private_key_location = nil | ||
end | ||
|
||
it "should throw an Argument Error when private_key is not supplied :: #sign(params)" do | ||
exception = proc{ (@alipay::Sign::RSA.sign(@params)).call }.must_raise(ArgumentError) | ||
exception.message.must_equal "Assign valid location for RSA private key location :: #AlipayGlobal.private_key_location = #{@alipay.private_key_location}" | ||
end | ||
|
||
it "should generate the correct signature :: #sign(params, private_key)" do | ||
assert_equal @rsa_signature, @alipay::Sign::RSA.sign(@params, @test_rsa_private_key) | ||
end | ||
end | ||
|
||
describe "AlipayGlobal.private_key_location is invalid" do | ||
before do | ||
@alipay.private_key_location = "#{File.dirname __dir__}/../keys/test_private_key.danger.pem" | ||
end | ||
|
||
it "should throw an Argument Error when private_key is not supplied :: #sign(params)" do | ||
exception = proc{ (@alipay::Sign::RSA.sign(@params)).call }.must_raise(Errno::ENOENT) | ||
exception.message.must_include "No such file or directory" | ||
end | ||
end | ||
|
||
describe "AlipayGlobal.private_key_location is filled with a valid location" do | ||
before do | ||
@alipay.private_key_location = "#{File.dirname __dir__}/../keys/test_private_key.pem" | ||
end | ||
|
||
it "should generate the correct signature :: #sign(params)" do | ||
assert_equal @rsa_signature, @alipay::Sign::RSA.sign(@params) | ||
end | ||
end | ||
end | ||
|
||
describe "RSA#verify?" do | ||
it "should return true for the correct signature match" do | ||
@alipay::Sign::RSA.verify?(@params, @test_rsa_public_key, @rsa_signature).must_equal true | ||
end | ||
|
||
it "should return false for incorrect signature match" do | ||
@alipay::Sign::RSA.verify?(@params, @test_rsa_public_key, "mike#{@rsa_signature}").must_equal false | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
require 'minitest' | ||
require 'minitest/autorun' | ||
require 'alipay_global' | ||
require 'fakeweb' |