reapal 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f666bd5dcc641e0493de86b32007b2a1f7126a64
4
+ data.tar.gz: 737efdcae2f36ec7c1b6566a744c3b734ce9ea3b
5
+ SHA512:
6
+ metadata.gz: fcb581a2aa92fc6bbeaa692735f753d0bd6f399bcd123c46c20a2fefa0ca4826598720d384ddf7e181e2a1d41c5ef11578bbc7aeddd1ffacc34260a29b012e8d
7
+ data.tar.gz: 80ab50ee402a58d45458830682df502418a2888dd4bcf656862e4b48c36d7a3b17765001da966abf9298cae1226262bb6f48deaf534bb44bd698fdbd8e53dbfa
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ .byebug_history
11
+ Gemfile.lock
12
+
13
+ # rspec failure tracking
14
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.5
5
+ before_install: gem install bundler -v 1.16.0
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at tony@omniaccount.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in reapal.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 tony
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # Reapal
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/reapal`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'reapal'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install reapal
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ### logger
28
+
29
+ ``` ruby
30
+ SuckerPunch.logger = Logger.new('sucker_punch.log')
31
+ SuckerPunch.logger # => #<Logger:0x007fa1f28b83f0>
32
+ ```
33
+
34
+ * Note: If Reapal is being used within a Rails application, Reapal's logger is set to Rails.logger by default. *
35
+
36
+ ## Development
37
+
38
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
39
+
40
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
41
+
42
+ ** 建议 **
43
+ 1. 使用 [fasterer](https://github.com/DamirSvrtan/fasterer) 来优化写的代码,怎么修改可以查看[这里](https://github.com/JuanitoFatas/fast-ruby)
44
+ 2. 使用 [rubycritic](https://github.com/whitesmith/rubycritic) 来检测代码质量
45
+
46
+ ## Contributing
47
+
48
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/reapal. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
49
+
50
+ ## License
51
+
52
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
53
+
54
+ ## Code of Conduct
55
+
56
+ Everyone interacting in the Reapal project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/reapal/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ task :build do
9
+ puts `gem build reapal.gemspec`
10
+ end
11
+
12
+ task :push do
13
+ puts `gem push reapal-#{Reapal::VERSION}.gem`
14
+ end
15
+
16
+ task :publish => [:build, :push]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "reapal"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/reapal.rb ADDED
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ require "uri"
3
+ require "net/http"
4
+ require "json"
5
+ require "openssl"
6
+ require "base64"
7
+ require 'macaddr'
8
+ require 'byebug'
9
+ require 'logger'
10
+
11
+ require "reapal/version"
12
+ require "reapal/utils"
13
+ require "reapal/sign/md5"
14
+ require "reapal/encrypt/rsa"
15
+ require "reapal/encrypt/aes"
16
+ require "reapal/http/communicate"
17
+ require "reapal/http/response"
18
+
19
+ # 自动加载所有 api
20
+ Dir["#{File.dirname(__FILE__)}/reapal/api/**/*.rb"].each { |file|
21
+ require file
22
+ }
23
+
24
+ require "reapal/client"
25
+
26
+ # 融宝存管
27
+ # 主入口
28
+ module Reapal
29
+
30
+ class << self
31
+ def logger
32
+ @logger ||= default_logger
33
+ end
34
+
35
+ def default_logger
36
+ _logger = Logger.new(STDOUT)
37
+ _logger.level = Logger::INFO
38
+ _logger
39
+ end
40
+
41
+ def logger=(log)
42
+ @logger = (log ? log : Logger.new('/dev/null'))
43
+ end
44
+ end
45
+ end
46
+
47
+ require 'reapal/railtie' if defined?(::Rails)
@@ -0,0 +1,77 @@
1
+ # coding: utf-8
2
+
3
+ module Reapal
4
+ module Api
5
+ module Agreement
6
+ module Agree
7
+
8
+ # 个人一键签约(API)
9
+ #
10
+ # @param flow_id [ String ] 订单号
11
+ # @param true_name [ String ] 真实姓名
12
+ # @param identity_id [ String ] 身份证号
13
+ # @param phone [ String ] 手机号
14
+ # @param bus_way [ String ] 00:PC端;01:手机端;02:Pad端;03:其它
15
+ #
16
+ # @return [ Hash ] 结果集
17
+ # * :result [String] "S"/"F"/"P"
18
+ # * :error_msg [String] 错误提示
19
+ # * :error_code [String] 融宝的错误编号
20
+ # * :data [Hash] 成功数据,返回的数据不一定是上送数据,比如手机号。所以要以返回数据为准
21
+ # * :contracts [String] 用户签约协议号
22
+ # * :userName [String] 姓名
23
+ # * :userIdentity [String] 身份证
24
+ # * :userMobile [String] 手机号
25
+ #
26
+ def agree(flow_id, true_name, identity_id, phone, bus_way='01')
27
+ service = 'reapal.trust.onekeyContract'
28
+ post_path = '/reagw/agreement/agree.htm'
29
+
30
+ params = {
31
+ orderNo: flow_id,
32
+ userName: true_name,
33
+ userIdentity: identity_id,
34
+ userMobile: phone,
35
+ busway: bus_way,
36
+ remark: '',
37
+ applyTime: Time.now.strftime('%Y-%m-%d %H:%M:%S'),
38
+ }
39
+
40
+ response = Http.post(service, params, @config, post_path)
41
+
42
+ error_result = {
43
+ data: nil,
44
+ result: "F",
45
+ error_msg: "未知错误",
46
+ }
47
+
48
+ # 如果数据不合法
49
+ unless response.data_valid
50
+ error_result[:error_msg] = "返回数据不合法"
51
+ return error_result
52
+ end
53
+
54
+ # 如果网络出错,包括超时或者非200类数据
55
+ unless response.http_response.kind_of?(Net::HTTPSuccess)
56
+ error_result[:error_msg] = "网络出错"
57
+ return error_result
58
+ end
59
+
60
+ # 个人签约只有返回码是 '0000', '0007' 才成功
61
+ if ['0000', '0007'].include?(response.data[:resultCode])
62
+ return {
63
+ data: response.data,
64
+ result: "S",
65
+ error_msg: nil,
66
+ }
67
+ else
68
+ error_result[:error_code] = response.data[:errorCode]
69
+ error_result[:error_msg] = response.data[:errorMsg]
70
+ return error_result
71
+ end
72
+ end
73
+
74
+ end # module Agree
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+
3
+ module Reapal
4
+ module Api
5
+ module Agreement
6
+ module AgreeQuery
7
+
8
+ # 个人一键签约(API)
9
+ #
10
+ # @param flow_id [ String ] 订单号
11
+ # @param true_name [ String ] 真实姓名
12
+ # @param identity_id [ String ] 身份证号
13
+ # @param phone [ String ] 手机号
14
+ # @param bus_way [ String ] 00:PC端;01:手机端;02:Pad端;03:其它
15
+ #
16
+ # @return [ Hash ] 结果集
17
+ # * :result [String] "S"/"F"/"P"
18
+ # * :error_msg [String] 错误提示
19
+ # * :data [Hash] 成功数据,解析和【个人签约API】/【企业签约API】一致
20
+ #
21
+ def agree_query(ori_flow_id)
22
+ # TODO(tony): 目前我们只用个人签约,个人签约都是同步返回,所以先不做实现
23
+ raise "Not Implement"
24
+
25
+ # service = 'reapal.trust.contractQuery'
26
+ # post_path = '/reagw/agreement/agreeApi.htm'
27
+
28
+ # params = {
29
+ # orderNo: ori_flow_id,
30
+ # applyTime: Time.now.strftime('%Y-%m-%d %H:%M:%S'),
31
+ # }
32
+
33
+ # response = Http.post(service, params, @config, post_path)
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ # 客户端
3
+
4
+ module Reapal
5
+ class Client
6
+
7
+ attr_accessor :config
8
+
9
+ def initialize(options_arg)
10
+ options = Utils.symbolize_keys(options_arg)
11
+ @config = {
12
+ server_url: options[:server_url],
13
+ partner_id: options[:partner_id],
14
+ merchant_id: options[:merchant_id],
15
+ md5_key: options[:md5_key],
16
+ private_key: OpenSSL::PKey::RSA.new(options[:private_key], options[:private_key_pwd]),
17
+ public_key: OpenSSL::X509::Certificate.new(options[:public_key]).public_key,
18
+ }
19
+
20
+ # 自动 include api 下的模块
21
+ recursive_include_api('Reapal::Api')
22
+ end
23
+
24
+ private
25
+ def recursive_include_api(module_chain)
26
+ modules = eval("#{module_chain}.constants").each{ |constant| eval("#{module_chain}::#{constant}").class.kind_of?(Module) }
27
+
28
+ if modules.empty?
29
+ self.class.send(:include, eval(module_chain))
30
+ else
31
+ modules.each{ |constant| recursive_include_api("#{module_chain}::#{constant}") }
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ module Reapal
3
+ module Encrypt
4
+ module AES
5
+
6
+ def self.encrypt(content, key)
7
+ cipher = OpenSSL::Cipher.new("AES-128-ECB")
8
+ cipher.encrypt
9
+ cipher.key = key
10
+ encrypted = cipher.update(content) + cipher.final
11
+ Base64.strict_encode64(encrypted)
12
+ end
13
+
14
+ def self.decrypt(content, key)
15
+ encrypted = Base64.strict_decode64(content)
16
+ cipher = OpenSSL::Cipher.new("AES-128-ECB")
17
+ cipher.decrypt
18
+ cipher.key = key
19
+ cipher.update(encrypted) + cipher.final
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+ module Reapal
3
+ module Encrypt
4
+ module RSA
5
+
6
+ def self.encrypt(content, public_key)
7
+ content_str = public_key.public_encrypt(content)
8
+ Base64.strict_encode64(content_str)
9
+ end
10
+
11
+ def self.decrypt(content, private_key)
12
+ content_str = Base64.strict_decode64(content)
13
+ private_key.private_decrypt(content_str)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,116 @@
1
+ # coding: utf-8
2
+ module Reapal
3
+ module Http
4
+
5
+ SIGN_TYPE = '0' # 0 表示 md5
6
+ VERSION = '1.0' # 版本号
7
+
8
+ def self.post(service, params, config, post_path)
9
+ post_body = get_body(service, params, config)
10
+ uri = URI(config[:server_url] + post_path)
11
+
12
+ Reapal.logger.info "[#{service}] 请求内容为:\n#{params}\n"
13
+ Reapal.logger.info "[#{service}(#{uri})] 最终发送内容为:\n#{post_body}\n"
14
+
15
+ result = {}
16
+
17
+ begin
18
+ response = Net::HTTP.post_form(uri, post_body)
19
+ Reapal.logger.info "[#{service}] 返回的报文为:\n#{response.body}"
20
+
21
+ if response.is_a?(Net::HTTPSuccess) # 返回 200 才处理
22
+ response_raw_body = unpack_body(response.body, config)
23
+ result = Reapal::Http::Response.new(service: service,
24
+ flow_id: params[:orderNo],
25
+ http_response: response,
26
+ raw_body: response_raw_body,
27
+ data: response_raw_body[:resData],
28
+ data_valid: response_raw_body[:data_valid])
29
+ else
30
+ # 非 200 请求,结果为 Fail
31
+ result = Reapal::Http::Response.new(service: service,
32
+ flow_id: params[:orderNo],
33
+ http_response: response,
34
+ raw_body: response.body,
35
+ data_valid: true)
36
+ end
37
+ rescue
38
+ # 请求超时等网络原因,结果为 pending,等待下次查询
39
+ result = Reapal::Http::Response.new(service: service,
40
+ flow_id: params[:orderNo],
41
+ http_response: response,
42
+ data_valid: true)
43
+ end
44
+
45
+ Reapal.logger.info "[#{service}] 返回结果为:\n#{result}\n\n"
46
+
47
+ result
48
+ end
49
+
50
+ private
51
+
52
+ def self.get_body(service, params, config)
53
+ data = {
54
+ version: VERSION,
55
+ service: service,
56
+ partner: config[:partner_id],
57
+ sign: Sign::MD5.sign(params.to_json, config[:md5_key]),
58
+ signType: SIGN_TYPE,
59
+ reqData: params.to_json,
60
+ }
61
+
62
+ random_key = Reapal::Utils.random_key
63
+ body = {
64
+ merchant_id: config[:merchant_id],
65
+ encryptkey: Encrypt::RSA.encrypt(random_key, config[:public_key]),
66
+ data: Encrypt::AES.encrypt(data.to_json, random_key),
67
+ }
68
+ end
69
+
70
+ def self.unpack_body(body_string, config)
71
+ # 返回是 json 字符串格式
72
+ body = Utils.symbolize_keys(JSON.parse(body_string))
73
+
74
+ # 1. 拿到用来加密的16位随机字符串
75
+ random_key = Encrypt::RSA.decrypt(body[:encryptkey],
76
+ config[:private_key])
77
+
78
+ # 2. 用16位随机字符串解密返回的数据
79
+ data_string = Encrypt::AES.decrypt(body[:data], random_key)
80
+ data = parse_data_string(data_string)
81
+ data[:resData] = Utils.symbolize_keys(JSON.parse(data[:resData]))
82
+
83
+ # 3. 验签,错误时候 sign 是没有值的
84
+ if (data[:sign].nil? && data[:resData][:errorCode]) \
85
+ || (data[:sign] && Sign::MD5.verify?(data[:resData].to_json, config[:md5_key], data[:sign]))
86
+ data[:data_valid] = true
87
+ else
88
+ data[:data_valid] = false
89
+ end
90
+
91
+ data
92
+ end
93
+
94
+ # 正确的返回字符串例子:
95
+ # 'version=1.0&service=reapal.trust.onekeyContract&signType=0&sign=cdab41a05d595d6a5f5a818af2b39398&resData={"contracts":"RB1711167FYG9U29","userName":"王五","userIdentity":"330602198711160034","userMobile":"18357101332","orderNo":"5a0d488fe0c016049a000001","resultCode":"0007","processTime":"2017-11-16 16:13:04"}'
96
+ #
97
+ # 异常的返回字符串例子:
98
+ # '{"orderNo":"FFSS1","errorCode":"0107","service":"reapal.trust.onekeyContract","errorMsg":"姓名不能为空"}'
99
+ def self.parse_data_string(data_string)
100
+ result = {}
101
+ arr = data_string.split('&')
102
+
103
+ if 1 == arr.size # 此次返回的是异常信息
104
+ result[:resData] = arr.first
105
+ else
106
+ arr.each{ |sub_str|
107
+ sub_arr = sub_str.split('=')
108
+ result[sub_arr[0].to_sym] = sub_arr[1]
109
+ }
110
+ end
111
+
112
+ result
113
+ end
114
+
115
+ end
116
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ module Reapal
3
+ module Http
4
+
5
+ class Response
6
+ attr_accessor :service, :flow_id
7
+ attr_accessor :http_response, :raw_body
8
+ attr_accessor :data, :data_valid
9
+
10
+ def initialize(params)
11
+ self.data_valid = true
12
+
13
+ params.each do |key, value|
14
+ instance_variable_set("@#{key}", value)
15
+ end
16
+ end
17
+
18
+ def [] key
19
+ instance_variable_get("#{key}")
20
+ end
21
+
22
+ def to_s
23
+ arr = ["{"]
24
+ self.instance_variables.map{ |value|
25
+ arr << "\t#{value.to_s} => #{self[value.to_sym]}"
26
+ }
27
+ arr << ["}"]
28
+ arr.join("\n")
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ module Reapal
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "reapal.logger" do
4
+ Reapal.logger = Rails.logger
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+ module Reapal
3
+ module Sign
4
+ module MD5
5
+
6
+ def self.sign(content, key)
7
+ md5 = Digest::MD5.new
8
+ md5 << (content + key)
9
+ md5.hexdigest
10
+ end
11
+
12
+ def self.verify?(content, key, sign_str)
13
+ sign(content, key) == sign_str
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+
3
+ # 通用工具类方法
4
+
5
+ module Reapal
6
+ module Utils
7
+
8
+ # 把 hash 中的 key,都转化为 symbol 类型
9
+ #
10
+ # @param hash [Hash] 需要更改的 hash
11
+ # @return [Hash] 更改后的 hash
12
+ def self.symbolize_keys(hash)
13
+ new_hash = {}
14
+ hash.each do |key, value|
15
+ new_hash[(key.to_sym rescue key) || key] = value
16
+ end
17
+ new_hash
18
+ end
19
+
20
+ # 通过时间,返回唯一一个24位flow id(支持分布)
21
+ # 同一秒,同一台机器,同一个进程,最多可以产生 16777214 个不一样的订单号
22
+ #
23
+ # @example
24
+ # JytPay::Utils.gen_flow_id
25
+ #
26
+ # @param [ Integer ] 时间(默认是 now)
27
+ # @return [ String ] flow id
28
+ def self.gen_flow_id(time=Time.now.to_i)
29
+ machine_id = Digest::MD5.digest(::Mac.addr).unpack("N")[0]
30
+ process_id = Process.pid % 0xFFFF
31
+
32
+ @counter ||= 0
33
+ @counter += 1
34
+ count = (@counter) % 0xFFFFFF
35
+
36
+ return [ time, machine_id, process_id, count << 8 ].pack("N NX lXX NX").unpack("H*")[0].force_encoding('UTF-8')
37
+ end
38
+
39
+ # 随机产生 size 位字符串(大小写,数字组成)
40
+ # @param size [Int] 需要的位数,默认 16 位
41
+ # @return [String] 随机字符串
42
+ def self.random_key(size=16)
43
+ ((0..9).to_a + ('a'..'z').to_a + ('A'..'Z').to_a).sample(size).join()
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module Reapal
2
+ VERSION = "0.1.0"
3
+ end
data/reapal.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "reapal/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "reapal"
9
+ spec.version = Reapal::VERSION
10
+ spec.authors = ["tony"]
11
+ spec.email = ["tony@omniaccount.com"]
12
+
13
+ spec.summary = %q{融宝支付的SDK}
14
+ spec.description = %q{富民银行的存管实现}
15
+ spec.homepage = "https://github.com/omniaccountcorp/reapal"
16
+ spec.license = "MIT"
17
+
18
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
20
+ if spec.respond_to?(:metadata)
21
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
22
+ else
23
+ raise "RubyGems 2.0 or newer is required to protect against " \
24
+ "public gem pushes."
25
+ end
26
+
27
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
28
+ f.match(%r{^(test|spec|features)/})
29
+ end
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_development_dependency "bundler", "~> 1.16"
35
+ spec.add_development_dependency "rake", "~> 10.0"
36
+ spec.add_development_dependency "rspec", "~> 3.0"
37
+ spec.add_development_dependency 'macaddr', '~> 1.7', '>= 1.7.1'
38
+ spec.add_development_dependency 'byebug', '~> 9.1'
39
+ spec.add_development_dependency 'faker', '~> 1.8', '>= 1.8.4'
40
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reapal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - tony
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-11-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: macaddr
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 1.7.1
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '1.7'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.7.1
75
+ - !ruby/object:Gem::Dependency
76
+ name: byebug
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '9.1'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '9.1'
89
+ - !ruby/object:Gem::Dependency
90
+ name: faker
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.8'
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 1.8.4
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '1.8'
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 1.8.4
109
+ description: 富民银行的存管实现
110
+ email:
111
+ - tony@omniaccount.com
112
+ executables: []
113
+ extensions: []
114
+ extra_rdoc_files: []
115
+ files:
116
+ - ".gitignore"
117
+ - ".rspec"
118
+ - ".travis.yml"
119
+ - CODE_OF_CONDUCT.md
120
+ - Gemfile
121
+ - LICENSE.txt
122
+ - README.md
123
+ - Rakefile
124
+ - bin/console
125
+ - bin/setup
126
+ - lib/reapal.rb
127
+ - lib/reapal/api/agreement/agree.rb
128
+ - lib/reapal/api/agreement/agree_query.rb
129
+ - lib/reapal/client.rb
130
+ - lib/reapal/encrypt/aes.rb
131
+ - lib/reapal/encrypt/rsa.rb
132
+ - lib/reapal/http/communicate.rb
133
+ - lib/reapal/http/response.rb
134
+ - lib/reapal/railtie.rb
135
+ - lib/reapal/sign/md5.rb
136
+ - lib/reapal/utils.rb
137
+ - lib/reapal/version.rb
138
+ - reapal.gemspec
139
+ homepage: https://github.com/omniaccountcorp/reapal
140
+ licenses:
141
+ - MIT
142
+ metadata:
143
+ allowed_push_host: https://rubygems.org
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubyforge_project:
160
+ rubygems_version: 2.6.14
161
+ signing_key:
162
+ specification_version: 4
163
+ summary: 融宝支付的SDK
164
+ test_files: []