unionpay 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/README.md +25 -3
- data/lib/unionpay/conf.rb +7 -7
- data/lib/unionpay/service.rb +42 -16
- data/lib/unionpay/version.rb +1 -1
- data/lib/unionpay.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/test/unionpay/service_test.rb +41 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f48073a80b07c6fd61921bcc1388898f84833fb2
|
4
|
+
data.tar.gz: 245748a08af3eb86f98742e091ba53fb2b26ad68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5b7b187138754c8aa138d81a9df4e0abe98e07f4fa878a85881930896124e134bf176fdc8ddb16575a2e85b69f39552f32c792940bcc6379045c895e2b6fa37
|
7
|
+
data.tar.gz: 409320bf75366b6353b76cffe8dada0a365d72b1c4b62e1e64f303279dd3447d88285fb078ee99c3c465685efa3bc1394703b154369c62c70ab051c588c5bcdd
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -18,17 +18,17 @@ UnionPay.mer_abbr = '商户名称'
|
|
18
18
|
UnionPay.security_key = '88888888'
|
19
19
|
```
|
20
20
|
|
21
|
-
### Generate payment form
|
21
|
+
### Generate front payment form
|
22
22
|
```ruby
|
23
23
|
param = {}
|
24
|
-
param['transType'] = UnionPay::CONSUME #交易类型,CONSUME or PRE_AUTH
|
25
24
|
param['orderAmount'] = 11000 #交易金额
|
26
25
|
param['orderNumber'] = Time.now.strftime('%Y%m%d%H%M%S') #订单号,必须唯一
|
27
26
|
param['customerIp'] = '127.0.0.1'
|
28
27
|
param['frontEndUrl'] = "http://www.example.com/sdk/utf8/front_notify.php" #前台回调URL
|
29
28
|
param['backEndUrl'] = "http://www.example.com/sdk/utf8/back_notify.php" #后台回调URL
|
30
29
|
|
31
|
-
#
|
30
|
+
# 非必填字段
|
31
|
+
# param['transType'] = UnionPay::CONSUME #交易类型,CONSUME or PRE_AUTH
|
32
32
|
# param['commodityUrl'] = "http://www.example.com/product?name=商品" #商品URL
|
33
33
|
# param['commodityName'] = '商品名称' # 商品名称
|
34
34
|
# param['commodityUnitPrice'] = 11000 #商品单价
|
@@ -59,3 +59,25 @@ def unionpay_notify
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
```
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
### Generate back payment post params
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
# 交易类型 退货=REFUND 或 消费撤销=CONSUME_VOID, 如果原始交易是PRE_AUTH,那么后台接口也支持对应的
|
69
|
+
# PRE_AUTH_VOID(预授权撤销), PRE_AUTH_COMPLETE(预授权完成), PRE_AUTH_VOID_COMPLETE(预授权完成撤销)
|
70
|
+
param = {}
|
71
|
+
param['transType'] = UnionPay::REFUND
|
72
|
+
param['origQid'] = '201110281442120195882' #原交易返回的qid, 从数据库中获取
|
73
|
+
param['orderAmount'] = 11000 #交易金额
|
74
|
+
param['orderNumber'] = '20131220151706'
|
75
|
+
param['orderTime'] = '20131220151706'
|
76
|
+
param['customerIp'] = '127.0.0.1' #用户IP
|
77
|
+
param['frontEndUrl'] = "" #前台回调URL, 后台交易可为空
|
78
|
+
param['backEndUrl'] = "http://www.example.com/sdk/utf8/back_notify.php" #后台回调URL
|
79
|
+
|
80
|
+
service = UnionPay::Service.back_pay(param)
|
81
|
+
service.args ## get args
|
82
|
+
service.post ## do post
|
83
|
+
```
|
data/lib/unionpay/conf.rb
CHANGED
@@ -9,7 +9,7 @@ module UnionPay
|
|
9
9
|
Sign_method = "md5" #摘要算法,目前仅支持md5 (2011-08-22)
|
10
10
|
|
11
11
|
# 支付请求预定义字段
|
12
|
-
|
12
|
+
PayParams = {
|
13
13
|
'version' => '1.0.0',
|
14
14
|
'charset' => 'UTF-8', #UTF-8, GBK等
|
15
15
|
'merId' => '88888888', #商户填写
|
@@ -35,7 +35,7 @@ module UnionPay
|
|
35
35
|
CURRENCY_CNY = "156"
|
36
36
|
|
37
37
|
# 支付请求可为空字段(但必须填写)
|
38
|
-
|
38
|
+
PayParamsEmpty = {
|
39
39
|
"origQid" => "",
|
40
40
|
"acqCode" => "",
|
41
41
|
"merCode" => "",
|
@@ -53,7 +53,7 @@ module UnionPay
|
|
53
53
|
}
|
54
54
|
|
55
55
|
# 支付请求必填字段检查
|
56
|
-
|
56
|
+
PayParamsCheck = [
|
57
57
|
"version",
|
58
58
|
"charset",
|
59
59
|
"transType",
|
@@ -83,7 +83,7 @@ module UnionPay
|
|
83
83
|
]
|
84
84
|
|
85
85
|
# 查询请求必填字段检查
|
86
|
-
|
86
|
+
QueryParamsCheck = [
|
87
87
|
"version",
|
88
88
|
"charset",
|
89
89
|
"transType",
|
@@ -94,7 +94,7 @@ module UnionPay
|
|
94
94
|
]
|
95
95
|
|
96
96
|
# 商户保留域可能包含的字段
|
97
|
-
|
97
|
+
MerParamsReserved = [
|
98
98
|
# NEW NAME OLD NAME
|
99
99
|
"cardNumber", "pan",
|
100
100
|
"cardPasswd", "password",
|
@@ -112,7 +112,7 @@ module UnionPay
|
|
112
112
|
"origOrderTime",
|
113
113
|
]
|
114
114
|
|
115
|
-
|
115
|
+
NotifyParamCheck = [
|
116
116
|
"version",
|
117
117
|
"charset",
|
118
118
|
"transType",
|
@@ -137,7 +137,7 @@ module UnionPay
|
|
137
137
|
"signature",
|
138
138
|
]
|
139
139
|
|
140
|
-
|
140
|
+
SignIgnoreParams = [
|
141
141
|
"bank",
|
142
142
|
]
|
143
143
|
end
|
data/lib/unionpay/service.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require 'open-uri'
|
3
3
|
require 'digest'
|
4
4
|
require 'rack'
|
5
|
+
require 'curb'
|
5
6
|
module UnionPay
|
6
7
|
RESP_SUCCESS = "00" #返回成功
|
7
8
|
QUERY_SUCCESS = "0" #查询成功
|
@@ -19,14 +20,33 @@ module UnionPay
|
|
19
20
|
trans_type = param['transType']
|
20
21
|
if [UnionPay::CONSUME, UnionPay::PRE_AUTH].include? trans_type
|
21
22
|
@api_url = UnionPay.front_pay_url
|
22
|
-
|
23
|
-
@param_check = UnionPay::
|
23
|
+
self.args = PayParamsEmpty.merge(PayParams).merge(param)
|
24
|
+
@param_check = UnionPay::PayParamsCheck
|
24
25
|
else
|
25
26
|
# 前台交易仅支持 消费 和 预授权
|
26
27
|
raise("Bad trans_type for front_pay. Use back_pay instead")
|
27
28
|
end
|
28
|
-
service
|
29
|
-
|
29
|
+
service
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.back_pay(param)
|
34
|
+
new.instance_eval do
|
35
|
+
param['orderTime'] ||= Time.now.strftime('%Y%m%d%H%M%S') #交易时间, YYYYmmhhddHHMMSS
|
36
|
+
param['orderCurrency'] ||= UnionPay::CURRENCY_CNY #交易币种,CURRENCY_CNY=>人民币
|
37
|
+
param['transType'] ||= UnionPay::REFUND
|
38
|
+
@api_url = UnionPay.back_pay_url
|
39
|
+
self.args = PayParamsEmpty.merge(PayParams).merge(param)
|
40
|
+
@param_check = PayParamsCheck
|
41
|
+
trans_type = param['transType']
|
42
|
+
if [UnionPay::CONSUME, UnionPay::PRE_AUTH].include? trans_type
|
43
|
+
if !self.args['cardNumber'] && !self.args['pan']
|
44
|
+
raise('consume OR pre_auth transactions need cardNumber!')
|
45
|
+
end
|
46
|
+
else
|
47
|
+
raise('origQid is not provided') if self.args['origQid'] !~ /[^[:space:]]/
|
48
|
+
end
|
49
|
+
service
|
30
50
|
end
|
31
51
|
end
|
32
52
|
|
@@ -44,6 +64,7 @@ module UnionPay
|
|
44
64
|
end
|
45
65
|
param.merge! cup_reserved
|
46
66
|
param.delete 'cupReserved'
|
67
|
+
self.args = param
|
47
68
|
self
|
48
69
|
end
|
49
70
|
end
|
@@ -51,7 +72,7 @@ module UnionPay
|
|
51
72
|
|
52
73
|
def self.sign(args)
|
53
74
|
sign_str = args.sort.map do |k,v|
|
54
|
-
"#{k}=#{v}&" unless UnionPay::
|
75
|
+
"#{k}=#{v}&" unless UnionPay::SignIgnoreParams.include? k
|
55
76
|
end.join
|
56
77
|
Digest::MD5.hexdigest(sign_str + Digest::MD5.hexdigest(UnionPay.security_key))
|
57
78
|
end
|
@@ -71,35 +92,40 @@ module UnionPay
|
|
71
92
|
html.join
|
72
93
|
end
|
73
94
|
|
95
|
+
def post
|
96
|
+
Curl.post @api_url, self.args
|
97
|
+
end
|
98
|
+
|
74
99
|
def [] key
|
75
100
|
self.args[key]
|
76
101
|
end
|
77
102
|
|
78
103
|
private
|
79
|
-
def service
|
80
|
-
if
|
81
|
-
|
104
|
+
def service
|
105
|
+
if self.args['commodityUrl']
|
106
|
+
self.args['commodityUrl'] = URI::encode(self.args['commodityUrl'])
|
82
107
|
end
|
83
108
|
|
84
109
|
arr_reserved = []
|
85
|
-
UnionPay::
|
86
|
-
arr_reserved << "#{k}=#{
|
110
|
+
UnionPay::MerParamsReserved.each do |k|
|
111
|
+
arr_reserved << "#{k}=#{self.args.delete k}" if self.args.has_key? k
|
87
112
|
end
|
88
113
|
|
89
114
|
if arr_reserved.any?
|
90
|
-
|
115
|
+
self.args['merReserved'] = arr_reserved.join('&')
|
91
116
|
else
|
92
|
-
|
117
|
+
self.args['merReserved'] ||= ''
|
93
118
|
end
|
94
119
|
|
95
120
|
@param_check.each do |k|
|
96
|
-
raise("KEY [#{k}] not set in params given") unless
|
121
|
+
raise("KEY [#{k}] not set in params given") unless self.args.has_key? k
|
97
122
|
end
|
98
123
|
|
99
124
|
# signature
|
100
|
-
|
101
|
-
|
102
|
-
|
125
|
+
self.args['signature'] = Service.sign(self.args)
|
126
|
+
self.args['signMethod'] = UnionPay::Sign_method
|
127
|
+
|
128
|
+
self
|
103
129
|
end
|
104
130
|
end
|
105
131
|
end
|
data/lib/unionpay/version.rb
CHANGED
data/lib/unionpay.rb
CHANGED
@@ -7,11 +7,11 @@ module UnionPay
|
|
7
7
|
attr_accessor :mer_id, :security_key, :mer_abbr, :environment
|
8
8
|
|
9
9
|
def mer_id= v
|
10
|
-
UnionPay::
|
10
|
+
UnionPay::PayParams['merId'] = v
|
11
11
|
end
|
12
12
|
|
13
13
|
def mer_abbr= v
|
14
|
-
UnionPay::
|
14
|
+
UnionPay::PayParams['merAbbr'] = v
|
15
15
|
end
|
16
16
|
|
17
17
|
def environment= e
|
data/test/test_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'unionpay'
|
3
3
|
|
4
|
-
UnionPay.environment = :development ## 测试环境, :pre_production #预上线环境, 默认 # 线上环境
|
4
|
+
# UnionPay.environment = :development ## 测试环境, :pre_production #预上线环境, 默认 # 线上环境
|
5
5
|
UnionPay.mer_id = '105550149170027'
|
6
6
|
UnionPay.mer_abbr = '商户名称'
|
7
7
|
UnionPay.security_key = '88888888'
|
@@ -14,16 +14,55 @@ class UnionPay::ServiceTest < Test::Unit::TestCase
|
|
14
14
|
UnionPay::Service.front_pay(param)
|
15
15
|
end
|
16
16
|
|
17
|
+
def generate_back_pay_service
|
18
|
+
#交易类型 退货=REFUND 或 消费撤销=CONSUME_VOID, 如果原始交易是PRE_AUTH,那么后台接口也支持对应的
|
19
|
+
# PRE_AUTH_VOID(预授权撤销), PRE_AUTH_COMPLETE(预授权完成), PRE_AUTH_VOID_COMPLETE(预授权完成撤销)
|
20
|
+
param = {}
|
21
|
+
param['transType'] = UnionPay::REFUND
|
22
|
+
|
23
|
+
param['origQid'] = '201110281442120195882'; #原交易返回的qid, 从数据库中获取
|
24
|
+
|
25
|
+
param['orderAmount'] = 11000; #交易金额
|
26
|
+
param['orderNumber'] = '20131220151706'
|
27
|
+
param['orderTime'] = '20131220151706'
|
28
|
+
|
29
|
+
param['customerIp'] = '127.0.0.1'; #用户IP
|
30
|
+
param['frontEndUrl'] = "" #前台回调URL, 后台交易可为空
|
31
|
+
param['backEndUrl'] = "http://www.example.com/sdk/utf8/back_notify.php" #后台回调URL
|
32
|
+
UnionPay::Service.back_pay(param)
|
33
|
+
|
34
|
+
end
|
35
|
+
|
17
36
|
def test_generate_form
|
18
37
|
assert_not_nil generate_form.form(target: '_blank', id: 'form'){"<input type='submit' />"}
|
19
38
|
end
|
20
39
|
|
21
|
-
def
|
40
|
+
def test_front_pay_generate_form_with_different_environment
|
22
41
|
UnionPay.environment = :development
|
23
42
|
dev_form = generate_form.form(target: '_blank', id: 'form'){"<input type='submit' />"}
|
24
|
-
UnionPay.environment = :
|
43
|
+
UnionPay.environment = :pre_production
|
25
44
|
pro_form = generate_form.form(target: '_blank', id: 'form'){"<input type='submit' />"}
|
26
45
|
assert dev_form != pro_form
|
27
46
|
end
|
28
47
|
|
48
|
+
def test_back_pay_service
|
49
|
+
dev_form = generate_back_pay_service
|
50
|
+
p dev_form.args
|
51
|
+
assert dev_form.post
|
52
|
+
end
|
53
|
+
def test_responce
|
54
|
+
test = {
|
55
|
+
"charset" => "UTF-8", "cupReserved" => "", "exchangeDate" => "",
|
56
|
+
"exchangeRate" => "", "merAbbr" => "银联商城(公司)", "merId" => "105550149170027",
|
57
|
+
"orderAmount" => "9300", "orderCurrency" => "156", "orderNumber" => "D201312240006",
|
58
|
+
"qid" => "201312241123141054552", "respCode" => "00", "respMsg" => "Success!",
|
59
|
+
"respTime" => "20131224112352", "settleAmount" => "9300", "settleCurrency" => "156",
|
60
|
+
"settleDate" => "1224", "traceNumber" => "105455", "traceTime" => "1224112314",
|
61
|
+
"transType" => "01", "version" => "1.0.0", "signMethod" => "MD5",
|
62
|
+
"signature" => "5b19db55d07290c739de97cb117ce884",
|
63
|
+
# "controller" => "front_money_payment_records", "action" => "unionpay_notify"
|
64
|
+
}
|
65
|
+
assert UnionPay::Service.responce(test).args['respCode'] == UnionPay::RESP_SUCCESS
|
66
|
+
end
|
67
|
+
|
29
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unionpay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -45,6 +45,7 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- Gemfile
|
48
49
|
- README.md
|
49
50
|
- Rakefile
|
50
51
|
- lib/unionpay.rb
|