meowth 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d4bac154e511d7fd7194bb930df12b6cf56468b5
4
+ data.tar.gz: f50adfebd880b45bd652a6426b69881ea5e495a8
5
+ SHA512:
6
+ metadata.gz: 4bcc0ae5172fd7798f07d6a3fddb0880ef2fa8505be03ee5e7f4232b3c088345e98475859f3b1a467c414524aa376e3761db30b39142849955fc9f0fea205c70
7
+ data.tar.gz: 610a8a8fbad2a329f9638279c35787d8d9be930acacfae635e0fd3cfe7f09ff3ac9f387a69fc9f127304b6a9e45a1f786441c5a2106dba39f9ae2922883ebfd6
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.14.5
@@ -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 panjie@xdstar.net. 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,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in meowth.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Jack Pan
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,55 @@
1
+ # Meowth
2
+
3
+ ## 安装
4
+
5
+ 将以下内容添加到Gemfile:
6
+
7
+ ```ruby
8
+ gem 'meowth'
9
+ ```
10
+
11
+ 然后执行:
12
+ ```bash
13
+ $ bundle install
14
+ ```
15
+
16
+ 生成配置文件:
17
+ ```ruby
18
+ rails generate meowth:install
19
+ ```
20
+
21
+ ## 使用
22
+
23
+ ### 配置
24
+ 将自己的证书放到工程某个目录下,然后修改`meowth.yml`文件:
25
+ ```yaml
26
+ default: &default
27
+ sign_cert_path: "path/to/acp_test_sign.pfx"
28
+ sign_cert_password: "000000"
29
+ verify_sign_cert_path: "path/to/acp_test_verify_sign.cer"
30
+ encrypt_cert_path: "path/to/acp_test_enc.cer"
31
+
32
+ development:
33
+ <<: *default
34
+ front_url: "" # 商户前台回调地址
35
+ back_url: "" # 商户后台通知地址
36
+ ```
37
+
38
+ ### 网关类产品
39
+ 生成消费参数
40
+ ```ruby
41
+ requrie 'meowth/service'
42
+
43
+ mer_id = '111111' # 商户id
44
+ order_id = '22222222' # 订单ID
45
+ txn_amt = 100 # 订单金额,单位是分
46
+ params = Magneton::Service.create_gate_consume_params(mer_id, order_id, txn_amt)
47
+ ```
48
+ 之后,在前台页面,将生成的参数`post`给`Meowth::Config.config['front_trans_url']`,之后就会跳转到银联支付页面。
49
+
50
+ 其他产品使用方法类似,这里不再赘述。
51
+
52
+ ## License
53
+
54
+ The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
55
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "meowth"
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/config/meowth.yml ADDED
@@ -0,0 +1,59 @@
1
+ default: &default
2
+ sign_cert_path: "data/test/acp_test_sign.pfx"
3
+ sign_cert_password: "000000"
4
+ sign_cert_type: "PKCS12"
5
+ verify_sign_cert_path: "data/test/acp_test_verify_sign.cer"
6
+ validate_cert_dir: ""
7
+ encrypt_cert_path: "data/test/acp_test_enc.cer"
8
+ single_mode: true
9
+ front_trans_url: "https://101.231.204.80:5000/gateway/api/frontTransReq.do"
10
+ back_trans_url: "https://101.231.204.80:5000/gateway/api/backTransReq.do"
11
+ single_query_url: "https://101.231.204.80:5000/gateway/api/queryTrans.do"
12
+ batch_trans_url: "https://101.231.204.80:5000/gateway/api/batchTrans.do"
13
+ file_trans_url: "https://101.231.204.80:9080/"
14
+ app_trans_url: "https://101.231.204.80:5000/gateway/api/appTransReq.do"
15
+ card_trans_url: "https://101.231.204.80:5000/gateway/api/cardTransReq.do"
16
+ jf_front_trans_url: "https://101.231.204.80:5000/jiaofei/api/frontTransReq.do"
17
+ jf_back_trans_url: "https://101.231.204.80:5000/jiaofei/api/backTransReq.do"
18
+ jf_single_query_url: "https://101.231.204.80:5000/jiaofei/api/queryTrans.do"
19
+ jf_card_trans_url: "https://101.231.204.80:5000/jiaofei/api/cardTransReq.do"
20
+ jf_app_trans_url: "https://101.231.204.80:5000/jiaofei/api/appTransReq.do"
21
+ merchant_id: "777290058136630"
22
+ front_url: "http://101.231.204.84:11006/ACPTest/FrontRcvResponse.do"
23
+ back_url: "http://101.231.204.84:11006/ACPTest/BackRcvResponse.do"
24
+
25
+ development:
26
+ <<: *default
27
+ merchant_id: "777290058136630"
28
+ front_url: "http://101.231.204.84:11006/ACPTest/FrontRcvResponse.do"
29
+ back_url: "http://101.231.204.84:11006/ACPTest/BackRcvResponse.do"
30
+
31
+ test:
32
+ <<: *default
33
+ merchant_id: "777290058136630"
34
+ front_url: "http://101.231.204.84:11006/ACPTest/FrontRcvResponse.do"
35
+ back_url: "http://101.231.204.84:11006/ACPTest/BackRcvResponse.do"
36
+
37
+ production:
38
+ sign_cert_path: "acp_test_sign.pfx"
39
+ sign_cert_password: "000000"
40
+ sign_cert_type: "PKCS12"
41
+ validate_cert_dir: ""
42
+ encrypt_cert_path: ""
43
+ single_mode: true
44
+ front_trans_url: "https://gateway.95516.com/gateway/api/frontTransReq.do"
45
+ back_trans_url: "https://gateway.95516.com/gateway/api/backTransReq.do"
46
+ single_query_url: "https://gateway.95516.com/gateway/api/queryTrans.do"
47
+ batch_trans_url: "https://gateway.95516.com/gateway/api/batchTrans.do"
48
+ file_trans_url: "https://101.231.204.80:9080/"
49
+ app_trans_url: "https://gateway.95516.com/gateway/api/appTransReq.do"
50
+ card_trans_url: "https://gateway.95516.com/gateway/api/cardTransReq.do"
51
+
52
+ jf_front_trans_url: "https://gateway.95516.com/jiaofei/api/frontTransReq.do"
53
+ jf_back_trans_url: "https://gateway.95516.com/jiaofei/api/backTransReq.do"
54
+ jf_single_query_url: "https://gateway.95516.com/jiaofei/api/queryTrans.do"
55
+ jf_card_trans_url: "https://gateway.95516.com/jiaofei/api/cardTransReq.do"
56
+ jf_app_trans_url: "https://gateway.95516.com/jiaofei/api/appTransReq.do"
57
+
58
+ front_url: ""
59
+ back_url: ""
@@ -0,0 +1,25 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEQzCCAyugAwIBAgIFEAJkkicwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UEBhMC
3
+ Q04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhv
4
+ cml0eTEXMBUGA1UEAxMOQ0ZDQSBURVNUIE9DQTEwHhcNMTUxMjE1MDkxMTM1WhcN
5
+ MTcxMjE1MDkxMTM1WjCBgTELMAkGA1UEBhMCY24xFzAVBgNVBAoTDkNGQ0EgVEVT
6
+ VCBPQ0ExMRIwEAYDVQQLEwlDRkNBIFRFU1QxFDASBgNVBAsTC0VudGVycHJpc2Vz
7
+ MS8wLQYDVQQDFCYwNDFAWjIwMTQtMTEtMTFAMDAwNDAwMDA6U0lHTkAwMDAwMDAw
8
+ NTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANHnoPx0JZKZmFjIURxN
9
+ AbLlWAw2jiFFWBnDF2MIGkya2r0fGiR0knq8zkKUnoIyC+tzEiOavniQaSu0ucuv
10
+ /V4ugz66PSRxw1gaPcR2dDVdgojF00TcewxlJEA65fK3eKhUYfC3NbRaVQOMMdwv
11
+ 7nNEvzxvdExE47ceMya7FmsUPyLFu9X++chFQiYfr8nH+wdDeYo8w8vCX+Jd2vRu
12
+ qDOah29CQfkAmXsx3D68zg0q4AjlLI1t5gLKiU5YoG6yWrigPyreEHh716rV8HkT
13
+ jGWx3cxF/HsLZ/E4SgIr5yIZA6qw8RFqaSXuyw3iDrNf6aSJGO0GKlvxnvD20oGR
14
+ JokCAwEAAaOB6TCB5jAfBgNVHSMEGDAWgBTPcJ1h6518Lrj3ywJA9wmd/jN0gDBI
15
+ BgNVHSAEQTA/MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cu
16
+ Y2ZjYS5jb20uY24vdXMvdXMtMTQuaHRtMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6
17
+ Ly91Y3JsLmNmY2EuY29tLmNuL1JTQS9jcmw0NTE3LmNybDALBgNVHQ8EBAMCA+gw
18
+ HQYDVR0OBBYEFGjriHHUE1MnYX7H6GrFi+8R2zmUMBMGA1UdJQQMMAoGCCsGAQUF
19
+ BwMCMA0GCSqGSIb3DQEBBQUAA4IBAQAjsN0fyDqcxS9YKMpY3CIdlarCjvnus+wS
20
+ ExjNnPv7n2urqhz2Jf3yJuhxVVPzdgKT51C2UiR+/i1OJPWFx0IUos/v8js/TM5j
21
+ mTdPkBsRSxSDieHHiuE1nPUwGXUEO7mlOVkkzmLI75bJ86foxNflbQCF0+VvpMe7
22
+ KwQoNOR8DxIBxHdlsjSxE2RKM/ftXLhptrK4GK3K4FAcSiqBMEn5PF/5V9mHp5N6
23
+ 3LdkMYqBj4pRcy8vrclucq99b2glmMLw7CI6Kxu22WVoRnZESjcgXiMVLLe+qy55
24
+ 0pWcZ2BChS7Ln19tj49LnS3vFp6xf4qNSqxEBaQuNLEx0ObjI6pz
25
+ -----END CERTIFICATE-----
@@ -0,0 +1,23 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDzjCCAragAwIBAgIKGNDz/H99Hd/CxjANBgkqhkiG9w0BAQUFADBZMQswCQYD
3
+ VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g
4
+ QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODMwMDMx
5
+ NDMzWhcNMzEwNTExMDMxNDMzWjBYMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp
6
+ bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRcwFQYDVQQDEw5D
7
+ RkNBIFRFU1QgT0NBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALiL
8
+ J/BrdvHSbXNfLIMTwUg9tDtVjMRGXOl6aZnu9IpxjI5SMUJ4hVwgJnmbTokxs6GF
9
+ IXKsCLSm5H1jHLI22ysc/ltByEybLWj5jjJuC9+Uknbl3/Ls1RBG6MogUCqZckuo
10
+ hKrf5DmlV3C/jVLxGn3pUeanvmqVUi4TKpXxgm5QqKSPF8VtQY4qCpNcQwwZqbMr
11
+ D+IfJtfpGAeVrP+Kg6i1t65seeEnVSaLhqpRUDU0PTblOuUv3OhiKJWA3cYWxUrg
12
+ 7U7SIHNJLSEUWmjy4mKty+g7Cnjzt29F9qXFb6oB2mR8yt4GHCilw1Rc5RBXY63H
13
+ eTuOwdtGE3M2p7Q++OECAwEAAaOBmDCBlTAfBgNVHSMEGDAWgBR03sWNCn0QGqpp
14
+ g1tNIc6Gm8xxODAMBgNVHRMEBTADAQH/MDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6
15
+ Ly8yMTAuNzQuNDIuMy90ZXN0cmNhL1JTQS9jcmwxLmNybDALBgNVHQ8EBAMCAQYw
16
+ HQYDVR0OBBYEFM9wnWHrnXwuuPfLAkD3CZ3+M3SAMA0GCSqGSIb3DQEBBQUAA4IB
17
+ AQC0JOazrbkk0XMxMMeBCc3lgBId1RjQLgWUZ7zaUISpPstGIrE5A9aB6Ppq0Sxl
18
+ pt2gkFhPEKUqgOFN1CzCDEbP3n4H0chqK1DOMrgTCD8ID5UW+ECTYNe35rZ+1JiF
19
+ lOPEhFL3pv6XSkiKTfDnjum8+wFwUBGlfoWK1Hcx0P2Hk1jcZZKwGTx1IAkesF83
20
+ pufhxHE2Ur7W4d4tfp+eC7XXcA91pdd+VUrAfkj9eKHcDEYZz66HvHzmt6rtJVBa
21
+ pwrtCi9pW3rcm8c/1jSnEETZIaokai0fD7260h/LkD/GrNCibSWxFj1CqyP9Y5Yv
22
+ cj6aA5LnUcJYeNkrQ3V4XvVc
23
+ -----END CERTIFICATE-----
@@ -0,0 +1,22 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDkzCCAnugAwIBAgIKUhN+zB19hbc65jANBgkqhkiG9w0BAQUFADBZMQswCQYD
3
+ VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g
4
+ QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODI5MDUw
5
+ MTI5WhcNMzIwODI5MDUwMTI5WjBZMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp
6
+ bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRgwFgYDVQQDEw9D
7
+ RkNBIFRFU1QgQ1MgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
8
+ rMJGruH6rOBPFxUI7T1ybydSRRtOM1xvkVjQNX0qmYir8feE6Tb0ctgtKR7a20DI
9
+ YCj9kZ5ANBQqjRcj3Soq9XH3cirqhYHJ723OKyTpS0RPQ0N6vtVt3P5JQ+ztjWHd
10
+ qIbbTOQ6O024TGTiqi6uHgMuz9/OVur81X3a5YVkK7jFeZ9o8cTcvQxD853/1sgZ
11
+ QcmR9aUSw0RXH4XFLTrn7n4QSfWKiNotlD8Ag5gS1pH9ONUb6nGkMn3gh1xfJqjm
12
+ ONMSknPXTGiNpXtqvYi8oIvByVCbUDO59IwPP1r1SYyE3P8Nr7DdQRu0KQSdXLoG
13
+ iugSR3fn+toObVAQmplDAgMBAAGjXTBbMB8GA1UdIwQYMBaAFHTexY0KfRAaqmmD
14
+ W00hzoabzHE4MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBR0
15
+ 3sWNCn0QGqppg1tNIc6Gm8xxODANBgkqhkiG9w0BAQUFAAOCAQEAM0eTkM35D4hj
16
+ RlGC63wY0h++wVPUvOrObqAVBbzEEQ7ScBienmeY8Q6lWMUTXM9ALibZklpJPcJv
17
+ 3ntht7LL6ztd4wdX7E9RzZCQnRvbL9A/BU3NxWdeSpCg/OyPod5oCKP+6Uc7kApi
18
+ F9OtYNWnt3l2Zp/NiedzEQD8H4qEWQLAq+0dFo5BkfVhb/jPcktndpfPOuH1IMhP
19
+ tVcvo6jpFHw4U/nP2Jv59osIE97KJz/SPt2JAYnZOlIDqWwp9/Afvt0/MDr8y0PK
20
+ Q9c6eqIzBx7a9LpUTUl5u1jS+xSDZ/KF2lXnjwaFp7jICLWEMlBstCoogi7KwH9A
21
+ LpJP7/dj9g==
22
+ -----END CERTIFICATE-----
Binary file
@@ -0,0 +1,25 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEOjCCAyKgAwIBAgIFEAJkAUkwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UEBhMC
3
+ Q04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhv
4
+ cml0eTEXMBUGA1UEAxMOQ0ZDQSBURVNUIE9DQTEwHhcNMTUxMjA0MDMyNTIxWhcN
5
+ MTcxMjA0MDMyNTIxWjB5MQswCQYDVQQGEwJjbjEXMBUGA1UEChMOQ0ZDQSBURVNU
6
+ IE9DQTExEjAQBgNVBAsTCUNGQ0EgVEVTVDEUMBIGA1UECxMLRW50ZXJwcmlzZXMx
7
+ JzAlBgNVBAMUHjA0MUBaMTJAMDAwNDAwMDA6U0lHTkAwMDAwMDA2MjCCASIwDQYJ
8
+ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMUDYYCLYvv3c911zhRDrSWCedAYDJQe
9
+ fJUjZKI2avFtB2/bbSmKQd0NVvh+zXtehCYLxKOltO6DDTRHwH9xfhRY3CBMmcOv
10
+ d2xQQvMJcV9XwoqtCKqhzguoDxJfYeGuit7DpuRsDGI0+yKgc1RY28v1VtuXG845
11
+ fTP7PRtJrareQYlQXghMgHFAZ/vRdqlLpVoNma5C56cJk5bfr2ngDlXbUqPXLi1j
12
+ iXAFb/y4b8eGEIl1LmKp3aPMDPK7eshc7fLONEp1oQ5Jd1nE/GZj+lC345aNWmLs
13
+ l/09uAvo4Lu+pQsmGyfLbUGR51KbmHajF4Mrr6uSqiU21Ctr1uQGkccCAwEAAaOB
14
+ 6TCB5jAfBgNVHSMEGDAWgBTPcJ1h6518Lrj3ywJA9wmd/jN0gDBIBgNVHSAEQTA/
15
+ MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20u
16
+ Y24vdXMvdXMtMTQuaHRtMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly91Y3JsLmNm
17
+ Y2EuY29tLmNuL1JTQS9jcmw0NDkxLmNybDALBgNVHQ8EBAMCA+gwHQYDVR0OBBYE
18
+ FAFmIOdt15XLqqz13uPbGQwtj4PAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqG
19
+ SIb3DQEBBQUAA4IBAQB8YuMQWDH/Ze+e+2pr/914cBt94FQpYqZOmrBIQ8kq7vVm
20
+ TTy94q9UL0pMMHDuFJV6Wxng4Me/cfVvWmjgLg/t7bdz0n6UNj4StJP17pkg68WG
21
+ zMlcjuI7/baxtDrD+O8dKpHoHezqhx7dfh1QWq8jnqd3DFzfkhEpuIt6QEaUqoWn
22
+ t5FxSUiykTfjnaNEEGcn3/n2LpwrQ+upes12/B778MQETOsVv4WX8oE1Qsv1XLRW
23
+ i0DQetTU2RXTrynv+l4kMy0h9b/Hdlbuh2s0QZqlUMXx2biy0GvpF2pR8f+OaLuT
24
+ AtaKdU4T2+jO44+vWNNN2VoAaw0xY6IZ3/A1GL0x
25
+ -----END CERTIFICATE-----
@@ -0,0 +1,12 @@
1
+ module Meowth
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc 'Install Meowth config file'
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def copy_config
8
+ template 'config/meowth.yml'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,55 @@
1
+ default: &default
2
+ sign_cert_path: "acp_test_sign.pfx"
3
+ sign_cert_password: "000000"
4
+ sign_cert_type: "PKCS12"
5
+ verify_sign_cert_path: "acp_test_verify_sign.cer"
6
+ validate_cert_dir: ""
7
+ encrypt_cert_path: "acp_test_enc.cer"
8
+ single_mode: true
9
+ front_trans_url: "https://101.231.204.80:5000/gateway/api/frontTransReq.do"
10
+ back_trans_url: "https://101.231.204.80:5000/gateway/api/backTransReq.do"
11
+ single_query_url: "https://101.231.204.80:5000/gateway/api/queryTrans.do"
12
+ batch_trans_url: "https://101.231.204.80:5000/gateway/api/batchTrans.do"
13
+ file_trans_url: "https://101.231.204.80:9080/"
14
+ app_trans_url: "https://101.231.204.80:5000/gateway/api/appTransReq.do"
15
+ card_trans_url: "https://101.231.204.80:5000/gateway/api/cardTransReq.do"
16
+ jf_front_trans_url: "https://101.231.204.80:5000/jiaofei/api/frontTransReq.do"
17
+ jf_back_trans_url: "https://101.231.204.80:5000/jiaofei/api/backTransReq.do"
18
+ jf_single_query_url: "https://101.231.204.80:5000/jiaofei/api/queryTrans.do"
19
+ jf_card_trans_url: "https://101.231.204.80:5000/jiaofei/api/cardTransReq.do"
20
+ jf_app_trans_url: "https://101.231.204.80:5000/jiaofei/api/appTransReq.do"
21
+
22
+ development:
23
+ <<: *default
24
+ front_url: ""
25
+ back_url: ""
26
+
27
+ test:
28
+ <<: *default
29
+ merchant_id: "700000000000001"
30
+ front_url: "http://101.231.204.84:11006/ACPTest/FrontRcvResponse.do"
31
+ back_url: "http://101.231.204.84:11006/ACPTest/BackRcvResponse.do"
32
+
33
+ production:
34
+ sign_cert_path: "acp_test_sign.pfx"
35
+ sign_cert_password: "000000"
36
+ sign_cert_type: "PKCS12"
37
+ validate_cert_dir: ""
38
+ encrypt_cert_path: ""
39
+ single_mode: true
40
+ front_trans_url: "https://gateway.95516.com/gateway/api/frontTransReq.do"
41
+ back_trans_url: "https://gateway.95516.com/gateway/api/backTransReq.do"
42
+ single_query_url: "https://gateway.95516.com/gateway/api/queryTrans.do"
43
+ batch_trans_url: "https://gateway.95516.com/gateway/api/batchTrans.do"
44
+ file_trans_url: "https://101.231.204.80:9080/"
45
+ app_trans_url: "https://gateway.95516.com/gateway/api/appTransReq.do"
46
+ card_trans_url: "https://gateway.95516.com/gateway/api/cardTransReq.do"
47
+
48
+ jf_front_trans_url: "https://gateway.95516.com/jiaofei/api/frontTransReq.do"
49
+ jf_back_trans_url: "https://gateway.95516.com/jiaofei/api/backTransReq.do"
50
+ jf_single_query_url: "https://gateway.95516.com/jiaofei/api/queryTrans.do"
51
+ jf_card_trans_url: "https://gateway.95516.com/jiaofei/api/cardTransReq.do"
52
+ jf_app_trans_url: "https://gateway.95516.com/jiaofei/api/appTransReq.do"
53
+
54
+ front_url: ""
55
+ back_url: ""
@@ -0,0 +1,77 @@
1
+ require 'openssl'
2
+
3
+
4
+ module Meowth
5
+ module Config
6
+ def self.config
7
+ self.init unless @config
8
+ @config
9
+ end
10
+
11
+ def self.sign_cert_id
12
+ self.init unless @sign_cert
13
+ @sign_cert.certificate.serial.to_s
14
+ end
15
+
16
+ def self.sign_cert_private_key
17
+ self.init unless @sign_cert
18
+ @sign_cert.key
19
+ end
20
+
21
+ def self.verify_sign_cert_id
22
+ self.init unless @verify_sign_cert
23
+ @verify_sign_cert.serial.to_s
24
+ end
25
+
26
+ def self.verify_sign_cert_public_key
27
+ self.init unless @verify_sign_cert
28
+ @verify_sign_cert.public_key
29
+ end
30
+
31
+ def self.encrypt_cert_public_key
32
+ self.init unless @encrypt_cert
33
+ @encrypt_cert.public_key
34
+ end
35
+
36
+ def self.encrypt_cert_id
37
+ self.init unless @encrypt_cert
38
+ @encrypt_cert.serial.to_s
39
+ end
40
+
41
+ def self.init
42
+ self.init_constant
43
+ self.init_sign_cert
44
+ self.init_verify_sign_cert
45
+ self.init_encrypt_cert
46
+ end
47
+
48
+ def self.init_sign_cert
49
+ @sign_cert = OpenSSL::PKCS12.new(File.read(@config['sign_cert_path']), @config['sign_cert_password'])
50
+ end
51
+
52
+ def self.init_verify_sign_cert
53
+ @verify_sign_cert = OpenSSL::X509::Certificate.new(File.read(@config['verify_sign_cert_path']))
54
+ end
55
+
56
+ def self.init_encrypt_cert
57
+ @encrypt_cert = OpenSSL::X509::Certificate.new(File.read(@config['encrypt_cert_path']))
58
+ end
59
+
60
+ def self.init_constant
61
+ if defined?(::Rails) and Rails.root
62
+ config_file = Rails.root.join('config/meowth.yml')
63
+ return YAML.load(ERB.new(File.read(config_file)).result)[Rails.env] if File.exist?(config_file)
64
+ else
65
+ require "yaml"
66
+ rails_config_file = File.join(Dir.getwd, 'config/meowth.yml')
67
+ if File.exist?(rails_config_file)
68
+ rails_env = ENV['RAILS_ENV'] || 'default'
69
+ config = YAML.load(ERB.new(File.read(rails_config_file)).result)[rails_env]
70
+ if config
71
+ @config = config
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,233 @@
1
+ module Meowth
2
+ module Constant
3
+ # 版本号.
4
+ VERSION = "version";
5
+ # 证书ID.
6
+ CERT_ID = "certId";
7
+ # 签名.
8
+ SIGNATURE = "signature";
9
+ # 编码方式.
10
+ ENCODING = "encoding";
11
+ # 交易类型.
12
+ TXN_TYPE = "txnType";
13
+ # 交易子类.
14
+ TXN_SUB_TYPE = "txnSubType";
15
+ # 业务类型.
16
+ BIZ_TYPE = "bizType";
17
+ # 前台通知地址 .
18
+ FRONT_URL = "frontUrl";
19
+ # 后台通知地址.
20
+ BACK_URL = "backUrl";
21
+ # 接入类型.
22
+ ACCESS_TYPE = "accessType";
23
+ # 收单机构代码.
24
+ ACQ_INS_CODE = "acqInsCode";
25
+ # 商户类别.
26
+ MER_CAT_CODE = "merCatCode";
27
+ # 商户类型.
28
+ MER_TYPE = "merType";
29
+ # 商户代码.
30
+ MER_ID = "merId";
31
+ # 商户名称.
32
+ MER_NAME = "merName";
33
+ # 商户简称.
34
+ MER_ABBR = "merAbbr";
35
+ # 二级商户代码.
36
+ SUB_MER_ID = "subMerId";
37
+ # 二级商户名称.
38
+ SUB_MER_NAME = "subMerName";
39
+ # 二级商户简称.
40
+ SUB_MER_ABBR = "subMerAbbr";
41
+ # Cupsecure 商户代码.
42
+ CS_MER_ID = "csMerId";
43
+ # 商户订单号.
44
+ ORDER_ID = "orderId";
45
+ # 交易时间.
46
+ TXN_TIME = "txnTime";
47
+ # 发送时间.
48
+ TXN_SEND_TIME = "txnSendTime";
49
+ # 订单超时时间间隔.
50
+ ORDER_TIMEOUT_INTERVAL = "orderTimeoutInterval";
51
+ # 支付超时时间.
52
+ PAY_TIMEOUT_TIME = "payTimeoutTime";
53
+ # 默认支付方式.
54
+ DEFAULT_PAY_TYPE = "defaultPayType";
55
+ # 支持支付方式.
56
+ SUP_PAY_TYPE = "supPayType";
57
+ # 支付方式.
58
+ PAY_TYPE = "payType";
59
+ # 自定义支付方式.
60
+ CUSTOM_PAY_TYPE = "customPayType";
61
+ # 物流标识.
62
+ SHIPPING_FLAG = "shippingFlag";
63
+ # 收货地址-国家.
64
+ SHIPPING_COUNTRY_CODE = "shippingCountryCode";
65
+ # 收货地址-省.
66
+ SHIPPING_PROVINCE_CODE = "shippingProvinceCode";
67
+ # 收货地址-市.
68
+ SHIPPING_CITY_CODE = "shippingCityCode";
69
+ # 收货地址-地区.
70
+ SHIPPING_DISTRICT_CODE = "shippingDistrictCode";
71
+ # 收货地址-详细.
72
+ SHIPPING_STREET = "shippingStreet";
73
+ # 商品总类.
74
+ COMMODITY_CATEGORY = "commodityCategory";
75
+ # 商品名称.
76
+ COMMODITY_NAME = "commodityName";
77
+ # 商品URL.
78
+ COMMODITY_URL = "commodityUrl";
79
+ # 商品单价.
80
+ COMMODITY_UNIT_PRICE = "commodityUnitPrice";
81
+ # 商品数量.
82
+ COMMODITY_QTY = "commodityQty";
83
+ # 是否预授权.
84
+ IS_PRE_AUTH = "isPreAuth";
85
+ # 币种.
86
+ CURRENCY_CODE = "currencyCode";
87
+ # 账户类型.
88
+ ACC_TYPE = "accType";
89
+ # 账号.
90
+ ACC_NO = "accNo";
91
+ # 支付卡类型.
92
+ PAY_CARD_TYPE = "payCardType";
93
+ # 发卡机构代码.
94
+ ISS_INS_CODE = "issInsCode";
95
+ # 持卡人信息.
96
+ CUSTOMER_INFO = "customerInfo";
97
+ # 手机号.
98
+ PHONE_NO = "phoneNo";
99
+ # CVN2
100
+ CVN2 = "cvn2";
101
+ # 有效期
102
+ EXPIRED = "expired";
103
+ # 加密信息域
104
+ ENCRYPTED_INFO = "encryptedInfo";
105
+ # 交易金额.
106
+ TXN_AMT = "txnAmt";
107
+ # 余额.
108
+ BALANCE = "balance";
109
+ # 地区代码.
110
+ DISTRICT_CODE = "districtCode";
111
+ # 附加地区代码.
112
+ ADDITIONAL_DISTRICT_CODE = "additionalDistrictCode";
113
+ # 账单类型.
114
+ BILL_TYPE = "billType";
115
+ # 账单号码.
116
+ BILL_NO = "billNo";
117
+ # 账单月份.
118
+ BILL_MONTH = "billMonth";
119
+ # 账单查询要素.
120
+ BILL_QUERY_INFO = "billQueryInfo";
121
+ # 账单详情.
122
+ BILL_DETAIL_INFO = "billDetailInfo";
123
+ # 账单金额.
124
+ BILL_AMT = "billAmt";
125
+ # 账单金额符号.
126
+ BILL_AMT_SIGN = "billAmtSign";
127
+ # 绑定标识号.
128
+ BIND_ID = "bindId";
129
+ # 风险级别.
130
+ RISK_LEVEL = "riskLevel";
131
+ # 绑定信息条数.
132
+ BIND_INFO_QTY = "bindInfoQty";
133
+ # 绑定信息集.
134
+ BIND_INFO_LIST = "bindInfoList";
135
+ # 批次号.
136
+ BATCH_NO = "batchNo";
137
+ # 总笔数.
138
+ TOTAL_QTY = "totalQty";
139
+ # 总金额.
140
+ TOTAL_AMT = "totalAmt";
141
+ # 文件类型.
142
+ FILE_TYPE = "fileType";
143
+ # 文件名称.
144
+ FILE_NAME = "fileName";
145
+ # 批量文件内容.
146
+ FILE_CONTENT = "fileContent";
147
+ # 商户摘要.
148
+ MER_NOTE = "merNote";
149
+ # 商户自定义域.
150
+ # merReserved = "merReserved";#接口变更删除
151
+ # 请求方保留域.
152
+ REQ_RESERVED = "reqReserved";# 新增接口
153
+ # 保留域.
154
+ RESERVED = "reserved";
155
+ # 终端号.
156
+ TERM_ID = "termId";
157
+ # 终端类型.
158
+ TERM_TYPE = "termType";
159
+ # 交互模式.
160
+ INTERACT_MODE = "interactMode";
161
+ # 发卡机构识别模式.
162
+ # recognitionMode = "recognitionMode";
163
+ ISSUER_IDENTIFY_MODE = "issuerIdentifyMode";# 接口名称变更
164
+ # 商户端用户号.
165
+ MER_USER_ID = "merUserId";
166
+ # 持卡人IP.
167
+ CUSTOMER_IP = "customerIp";
168
+ # 查询流水号.
169
+ QUERY_ID = "queryId";
170
+ # 原交易查询流水号.
171
+ ORIG_QRY_ID = "origQryId";
172
+ # 系统跟踪号.
173
+ TRACE_NO = "traceNo";
174
+ # 交易传输时间.
175
+ TRACE_TIME = "traceTime";
176
+ # 清算日期.
177
+ SETTLE_DATE = "settleDate";
178
+ # 清算币种.
179
+ SETTLE_CURRENCY_CODE = "settleCurrencyCode";
180
+ # 清算金额.
181
+ SETTLE_AMT = "settleAmt";
182
+ # 清算汇率.
183
+ EXCHANGE_RATE = "exchangeRate";
184
+ # 兑换日期.
185
+ EXCHANGE_DATE = "exchangeDate";
186
+ # 响应时间.
187
+ RESP_TIME = "respTime";
188
+ # 原交易应答码.
189
+ ORIG_RESP_CODE = "origRespCode";
190
+ # 原交易应答信息.
191
+ ORIG_RESP_MSG = "origRespMsg";
192
+ # 应答码.
193
+ RESP_CODE = "respCode";
194
+ # 应答码信息.
195
+ RESP_MSG = "respMsg";
196
+ # 新增四个报文字段merUserRegDt merUserEmail checkFlag activateStatus
197
+ # 商户端用户注册时间.
198
+ MER_USER_REG_DT = "merUserRegDt";
199
+ # 商户端用户注册邮箱.
200
+ MER_USER_EMAIL = "merUserEmail";
201
+ # 验证标识.
202
+ CHECK_FLAG = "checkFlag";
203
+ # 开通状态.
204
+ ACTIVATE_STATUS = "activateStatus";
205
+ # 加密证书ID.
206
+ ENCRYPT_CERT_ID = "encryptCertId";
207
+ # 用户MAC、IMEI串号、SSID.
208
+ USER_MAC = "userMac";
209
+ # 关联交易.
210
+ # relationTxnType = "relationTxnType";
211
+ # 短信类型
212
+ SMS_TYPE = "smsType";
213
+ # 风控信息域
214
+ RISK_CTRL_INFO = "riskCtrlInfo";
215
+ # IC卡交易信息域
216
+ IC_TRANS_DATA = "ICTransData";
217
+ # VPC交易信息域
218
+ VPC_TRANS_DATA = "VPCTransData";
219
+ # 安全类型
220
+ SECURITY_TYPE = "securityType";
221
+ # 银联订单号
222
+ TN = "tn";
223
+ # 分期付款手续费率
224
+ INSTAL_RATE = "instalRate";
225
+ # 分期付款手续费率
226
+ MCHNT_FEE_SUBSIDY = "mchntFeeSubsidy";
227
+ # 签名方法
228
+ SIGN_METHOD = "signMethod"
229
+ # 渠道类型
230
+ CHANNEL_TYPE = "channelType"
231
+ end
232
+ end
233
+
@@ -0,0 +1,193 @@
1
+ require 'meowth/config'
2
+ require 'meowth/constant'
3
+ require 'meowth/util'
4
+ require 'base64'
5
+
6
+
7
+ module Meowth
8
+ module Service
9
+ # 网关产品 消费类交易 参数
10
+ def self.create_gate_consume_params(mer_id, order_id, txn_amt)
11
+ params = {}
12
+ # 基本信息
13
+ params[Meowth::Constant::VERSION] = "5.0.0"
14
+ params[Meowth::Constant::ENCODING] = "UTF-8"
15
+ params[Meowth::Constant::SIGN_METHOD] = "01"
16
+ params[Meowth::Constant::TXN_TYPE] = "01"
17
+ params[Meowth::Constant::TXN_SUB_TYPE] = "01"
18
+ params[Meowth::Constant::BIZ_TYPE] = "000201"
19
+ params[Meowth::Constant::CHANNEL_TYPE] = "07"
20
+ # 商户信息
21
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
22
+ params[Meowth::Constant::MER_ID] = mer_id
23
+ params[Meowth::Constant::FRONT_URL] = Meowth::Config.config['front_url']
24
+ params[Meowth::Constant::BACK_URL] = Meowth::Config.config['back_url']
25
+ # 订单信息
26
+ params[Meowth::Constant::ORDER_ID] = order_id
27
+ params[Meowth::Constant::CURRENCY_CODE] = "156"
28
+ params[Meowth::Constant::TXN_AMT] = txn_amt
29
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
30
+ Meowth::Util.sign(params)
31
+ end
32
+
33
+ # 网关产品 消费撤销类交易 参数
34
+ def self.create_gate_unconsume_params(mer_id, order_id, txn_amt, orig_query_id)
35
+ params = {}
36
+ # 基本信息
37
+ params[Meowth::Constant::VERSION] = "5.0.0"
38
+ params[Meowth::Constant::ENCODING] = "UTF-8"
39
+ params[Meowth::Constant::SIGN_METHOD] = "01"
40
+ params[Meowth::Constant::TXN_TYPE] = "31"
41
+ params[Meowth::Constant::TXN_SUB_TYPE] = "00"
42
+ params[Meowth::Constant::BIZ_TYPE] = "000201"
43
+ params[Meowth::Constant::CHANNEL_TYPE] = "07"
44
+ # 商户信息
45
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
46
+ params[Meowth::Constant::MER_ID] = mer_id
47
+ params[Meowth::Constant::BACK_URL] = Meowth::Config.config['back_url']
48
+ # 订单信息
49
+ params[Meowth::Constant::ORDER_ID] = order_id
50
+ params[Meowth::Constant::TXN_AMT] = txn_amt
51
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
52
+ # 通知信息
53
+ params[Meowth::Constant::ORIG_QRY_ID] = orig_query_id
54
+ Meowth::Util.sign(params)
55
+ end
56
+
57
+ # 网关产品 退货类交易 参数
58
+ def self.create_gate_return_params(mer_id, order_id, txn_amt, orig_query_id)
59
+ params = {}
60
+ # 基本信息
61
+ params[Meowth::Constant::VERSION] = "5.0.0"
62
+ params[Meowth::Constant::ENCODING] = "UTF-8"
63
+ params[Meowth::Constant::SIGN_METHOD] = "01"
64
+ params[Meowth::Constant::TXN_TYPE] = "04"
65
+ params[Meowth::Constant::TXN_SUB_TYPE] = "00"
66
+ params[Meowth::Constant::BIZ_TYPE] = "000201"
67
+ params[Meowth::Constant::CHANNEL_TYPE] = "07"
68
+ # 商户信息
69
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
70
+ params[Meowth::Constant::MER_ID] = mer_id
71
+ params[Meowth::Constant::BACK_URL] = Meowth::Config.config['back_url']
72
+ # 订单信息
73
+ params[Meowth::Constant::ORDER_ID] = order_id
74
+ params[Meowth::Constant::TXN_AMT] = txn_amt
75
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
76
+ # 通知信息
77
+ params[Meowth::Constant::ORIG_QRY_ID] = orig_query_id
78
+ Meowth::Util.sign(params)
79
+ end
80
+
81
+ # 网关产品 交易状态查询交易 参数
82
+ def self.create_gate_query_params(mer_id, order_id, query_id)
83
+ params = {}
84
+ # 基本信息
85
+ params[Meowth::Constant::VERSION] = "5.0.0"
86
+ params[Meowth::Constant::ENCODING] = "UTF-8"
87
+ params[Meowth::Constant::SIGN_METHOD] = "01"
88
+ params[Meowth::Constant::TXN_TYPE] = "00"
89
+ params[Meowth::Constant::TXN_SUB_TYPE] = "00"
90
+ params[Meowth::Constant::BIZ_TYPE] = "000201"
91
+ # 商户信息
92
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
93
+ params[Meowth::Constant::MER_ID] = mer_id
94
+ # 订单信息
95
+ params[Meowth::Constant::ORDER_ID] = order_id
96
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
97
+ # 通知信息
98
+ params[Meowth::Constant::QUERY_ID] = query_id
99
+ Meowth::Util.sign(params)
100
+ end
101
+
102
+ # 网关产品 文件传输类交易 参数
103
+ def self.create_gate_file_params(mer_id, order_id, txn_amt, query_id)
104
+ params = {}
105
+ # 基本信息
106
+ params[Meowth::Constant::VERSION] = "5.0.0"
107
+ params[Meowth::Constant::ENCODING] = "UTF-8"
108
+ params[Meowth::Constant::SIGN_METHOD] = "01"
109
+ params[Meowth::Constant::TXN_TYPE] = "76"
110
+ params[Meowth::Constant::TXN_SUB_TYPE] = "01"
111
+ params[Meowth::Constant::BIZ_TYPE] = "000000"
112
+ # 商户信息
113
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
114
+ params[Meowth::Constant::MER_ID] = mer_id
115
+ # 订单信息
116
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
117
+ params[Meowth::Constant::FILE_TYPE] = "00"
118
+ # 通知信息
119
+ # TODO 生成环境,23点之前,是今天,23点之后为明天;测试环境,13:30之前为昨天,之后为今天
120
+ params[Meowth::Constant::SETTLE_DATE] = Time.now.strftime('%m%d')
121
+ Meowth::Util.sign(params)
122
+ end
123
+
124
+ # B2B产品 消费类交易 参数
125
+ def self.create_b2b_params(mer_id, order_id, txn_amt)
126
+ params = {}
127
+ params[Meowth::Constant::VERSION] = "5.0.0"
128
+ params[Meowth::Constant::ENCODING] = "UTF-8"
129
+ params[Meowth::Constant::SIGN_METHOD] = "01"
130
+ params[Meowth::Constant::TXN_TYPE] = "01"
131
+ params[Meowth::Constant::TXN_SUB_TYPE] = "01"
132
+ params[Meowth::Constant::BIZ_TYPE] = "000202"
133
+ params[Meowth::Constant::CHANNEL_TYPE] = "07"
134
+ params[Meowth::Constant::MER_ID] = mer_id
135
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
136
+ params[Meowth::Constant::ORDER_ID] = order_id
137
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
138
+ params[Meowth::Constant::CURRENCY_CODE] = "156"
139
+ params[Meowth::Constant::TXN_AMT] = txn_amt
140
+ params[Meowth::Constant::FRONT_URL] = Meowth::Config.config['front_url']
141
+ params[Meowth::Constant::BACK_URL] = Meowth::Config.config['back_url']
142
+ Meowth::Util.sign(params)
143
+ end
144
+
145
+ # 代付产品 实名认证 参数
146
+ def self.create_pay_params(mer_id, order_id, txn_amt, acc_no, certif_id, customer_nm, phone_no)
147
+ params = {}
148
+ params[Meowth::Constant::VERSION] = "5.0.0"
149
+ params[Meowth::Constant::ENCODING] = "UTF-8"
150
+ params[Meowth::Constant::SIGN_METHOD] = "01"
151
+ params[Meowth::Constant::TXN_TYPE] = "12"
152
+ params[Meowth::Constant::TXN_SUB_TYPE] = "00"
153
+ params[Meowth::Constant::BIZ_TYPE] = "000401"
154
+ params[Meowth::Constant::CHANNEL_TYPE] = "07"
155
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
156
+ params[Meowth::Constant::MER_ID] = mer_id
157
+ params[Meowth::Constant::BACK_URL] = Meowth::Config.config['back_url']
158
+ params[Meowth::Constant::ORDER_ID] = order_id
159
+ params[Meowth::Constant::CURRENCY_CODE] = "156"
160
+ params[Meowth::Constant::TXN_AMT] = txn_amt
161
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
162
+ params[Meowth::Constant::ACC_TYPE] = "01"
163
+ params[Meowth::Constant::ACC_NO] = Meowth::Util.encrypt(acc_no)
164
+ encrypted_info = Meowth::Util.encrypt("phoneNo=#{phone_no}")
165
+ params[Meowth::Constant::CUSTOMER_INFO] = Base64.strict_encode64("{certifId=#{certif_id}&certifTp=01&customerNm=#{customer_nm}&encryptedInfo=#{encrypted_info}}")
166
+ params[Meowth::Constant::ENCRYPT_CERT_ID] = Meowth::Config.encrypt_cert_id
167
+ Meowth::Util.sign(params)
168
+ end
169
+
170
+ # 代付产品 实名认证 参数
171
+ def self.create_real_name_params(mer_id, order_id, acc_no, certif_id, customer_nm, phone_no)
172
+ params = {}
173
+ params[Meowth::Constant::VERSION] = "5.0.0"
174
+ params[Meowth::Constant::ENCODING] = "UTF-8"
175
+ params[Meowth::Constant::SIGN_METHOD] = "01"
176
+ params[Meowth::Constant::TXN_TYPE] = "72"
177
+ params[Meowth::Constant::TXN_SUB_TYPE] = "01"
178
+ params[Meowth::Constant::BIZ_TYPE] = "000401"
179
+ params[Meowth::Constant::CHANNEL_TYPE] = "07"
180
+ params[Meowth::Constant::ACCESS_TYPE] = "0"
181
+ params[Meowth::Constant::MER_ID] = mer_id
182
+ params[Meowth::Constant::BACK_URL] = Meowth::Config.config['back_url']
183
+ params[Meowth::Constant::ORDER_ID] = order_id
184
+ params[Meowth::Constant::TXN_TIME] = Time.now.strftime('%Y%m%d%H%M%S')
185
+ params[Meowth::Constant::ACC_TYPE] = "01"
186
+ params[Meowth::Constant::ACC_NO] = Meowth::Util.encrypt(acc_no)
187
+ encrypted_info = Meowth::Util.encrypt("phoneNo=#{phone_no}")
188
+ params[Meowth::Constant::CUSTOMER_INFO] = Base64.strict_encode64("{certifId=#{certif_id}&certifTp=01&customerNm=#{customer_nm}&encryptedInfo=#{encrypted_info}}")
189
+ params[Meowth::Constant::ENCRYPT_CERT_ID] = Meowth::Config.encrypt_cert_id
190
+ Meowth::Util.sign(params)
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,54 @@
1
+ require 'digest/sha1'
2
+ require 'base64'
3
+ require 'meowth/config'
4
+ require 'meowth/constant'
5
+
6
+
7
+ module Meowth
8
+ module Util
9
+ # 请求报文签名(sha1摘要算法)
10
+ # 插入certId字段,计算签名,再插入签名,最后返回整个请求报文
11
+ def self.sign(params)
12
+ params[Meowth::Constant::CERT_ID] = Meowth::Config.sign_cert_id
13
+ data = params.sort.map{ |k, v| "#{k}=#{v}" }.join('&')
14
+ digest = Digest::SHA1.hexdigest(data)
15
+ key = Meowth::Config.sign_cert_private_key
16
+ sign = Base64.strict_encode64(key.sign('sha1', digest))
17
+ params[Meowth::Constant::SIGNATURE] = sign
18
+ params
19
+ end
20
+
21
+ # 对响应报文签名验证(sha1摘要算法)
22
+ def self.verify(params)
23
+ sign = params[Meowth::Constant::SIGNATURE]
24
+ params.delete(Meowth::Constant::SIGNATURE)
25
+ data = params.sort.map{ |k, v| "#{k}=#{v}" }.join('&')
26
+ digest = Digest::SHA1.hexdigest(data)
27
+ key = Meowth::Config.verify_sign_cert_public_key
28
+ key.verify('sha1', Base64.strict_decode64(sign), digest)
29
+ end
30
+
31
+
32
+ def self.encrypt_pin(pin, card)
33
+ len = "%02d" % pin.length
34
+ tmp = len + pin + "F" * (14 - pin.length)
35
+ pin_byte = [tmp].pack("H*")
36
+ card_no = "0" * (13 - card.length) + card
37
+ tmp = "0000" + card_no[0..11]
38
+ card_byte = [tmp].pack("H*")
39
+ c = pin_byte.bytes.zip(card_byte.bytes).map{ |a, b| a ^ b }.pack('c*')
40
+ public_key = Meowth::Config.encrypt_cert_public_key
41
+ Base64.strict_encode64(public_key.public_encrypt(c))
42
+ end
43
+
44
+ def self.encrypt(plain_text)
45
+ public_key = Meowth::Config.encrypt_cert_public_key
46
+ Base64.strict_encode64(public_key.public_encrypt(plain_text))
47
+ end
48
+
49
+ def self.decrypt(ciper_text)
50
+ private_key = Meowth::Config.sign_cert_private_key
51
+ private_key.private_decrypt(Base64.strict_decode64(ciper_text))
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ module Meowth
2
+ VERSION = "0.0.1"
3
+ end
data/meowth.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'meowth/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "meowth"
8
+ spec.version = Meowth::VERSION
9
+ spec.authors = ["Jack Pan"]
10
+ spec.email = ["i@jackpan.me"]
11
+
12
+ spec.summary = %q{Ruby port of Union Pay SDK.}
13
+ spec.description = %q{Ruby port of Union Pay SDK. Because Union Pay only offers Java, PHP and .NET SDK. I write Ruby port based on Java SDK.}
14
+ spec.homepage = "https://github.com/junzhepan/meowth"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.14"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "rest-client"
28
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meowth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jack Pan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-03-14 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.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
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: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Ruby port of Union Pay SDK. Because Union Pay only offers Java, PHP and
70
+ .NET SDK. I write Ruby port based on Java SDK.
71
+ email:
72
+ - i@jackpan.me
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - ".travis.yml"
80
+ - CODE_OF_CONDUCT.md
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - bin/console
86
+ - bin/setup
87
+ - config/meowth.yml
88
+ - data/test/acp_test_enc.cer
89
+ - data/test/acp_test_middle.cer
90
+ - data/test/acp_test_root.cer
91
+ - data/test/acp_test_sign.pfx
92
+ - data/test/acp_test_verify_sign.cer
93
+ - lib/generators/meowth/install_generator.rb
94
+ - lib/generators/meowth/templates/config/meowth.yml
95
+ - lib/meowth/config.rb
96
+ - lib/meowth/constant.rb
97
+ - lib/meowth/service.rb
98
+ - lib/meowth/util.rb
99
+ - lib/meowth/version.rb
100
+ - meowth.gemspec
101
+ homepage: https://github.com/junzhepan/meowth
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.5.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Ruby port of Union Pay SDK.
125
+ test_files: []