alipay_dualfun 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +34 -2
- data/alipay_dualfun.gemspec +1 -1
- data/lib/alipay_dualfun.rb +38 -167
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NDdiYWE3ODE2OTE1Y2IyNzcwNjE4NzUwZjc5Y2QyYzlmZDk5MzA0Nw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
Y2ZmM2ZiZmY1YzI0ODc4OGUyMDY0ZGM0NDU2ZjAxYmYxNjkxNmM2Mw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
M2IxMTIwZmYzYTU0N2QwYmFiN2FhMmExNGMyYjEzNjRkYWFlODMzMzllZWYx
|
10
|
+
ZTNiMzZkMTFlOWNlZmViZTE1MWM3NDFkZmJkNGMzNzRmYmRiOTFmN2U1Y2E3
|
11
|
+
YjE5NTg4MDk2MjdmZTNjMjViNzhiODllMjc5ZGI1NTBlZmY1Y2E=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NDljMDkzNmRmOTc1ZmU0YTE5NmNjOTUxZWMwYmFlZTkzY2U5Y2VmOWRiMjVm
|
14
|
+
MGIwMDJhZTFlMjk4N2JhMjQzYWM1OWI0OTRlZDAxMTA2YTAyOGZmMDc0MWNj
|
15
|
+
ODQyNTNlMjRkMTY0ZjI1ZTIwMTY2MjE0NjJkY2U2Y2I4NWFhNDc=
|
data/README.md
CHANGED
@@ -2,16 +2,48 @@
|
|
2
2
|
|
3
3
|
A ruby gem.
|
4
4
|
|
5
|
-
##
|
5
|
+
## Demo
|
6
|
+
|
7
|
+
http://alidemo.happycasts.net/
|
8
|
+
|
9
|
+
## Install
|
6
10
|
|
7
11
|
Add this line to your application's Gemfile:
|
8
12
|
|
9
13
|
gem 'alipay_dualfun'
|
10
14
|
|
15
|
+
|
16
|
+
or development version
|
17
|
+
|
18
|
+
gem 'alipay_dualfun', :github => 'happypeter/alipay_dualfun'
|
19
|
+
|
11
20
|
And then execute:
|
12
21
|
|
13
22
|
$ bundle
|
14
23
|
|
15
24
|
### Thanks
|
16
25
|
|
17
|
-
|
26
|
+
- <https://github.com/chloerei/alipay>
|
27
|
+
- <https://github.com/daqing/china_pay>
|
28
|
+
|
29
|
+
|
30
|
+
Generate payment url
|
31
|
+
|
32
|
+
options = {
|
33
|
+
:out_trade_no => 'YOUR_ORDER_ID', # 20130801000001
|
34
|
+
:subject => 'YOUR_ORDER_SUBJECCT',
|
35
|
+
:partner => 'PID',
|
36
|
+
:seller_email => 'SELLER_EMAIL',
|
37
|
+
:price => '10.00',
|
38
|
+
:quantity => 12,
|
39
|
+
:discount => '20.00'
|
40
|
+
:return_url => 'YOUR_ORDER_RETURN_URL',
|
41
|
+
:notify_url => 'YOUR_ORDER_NOTIFY_URL'
|
42
|
+
}
|
43
|
+
|
44
|
+
Alipay.trade_create_by_buyer_url(options) # 标准双接口
|
45
|
+
# => 'https://mapi.alipay.com/gateway.do?out_trade_no=...'
|
46
|
+
|
47
|
+
You can redirect user to this payment url, and user will see a payment page
|
48
|
+
for his/her order.
|
49
|
+
|
data/alipay_dualfun.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = "alipay_dualfun"
|
7
|
-
gem.version = "0.
|
7
|
+
gem.version = "0.2"
|
8
8
|
gem.authors = ["happypeter"]
|
9
9
|
gem.email = ["happypeter1983@gmail.com"]
|
10
10
|
gem.description = %q{This gem can help you integrate Alipay Dual-function Payment.}
|
data/lib/alipay_dualfun.rb
CHANGED
@@ -1,183 +1,54 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require '
|
3
|
-
require 'uri'
|
4
|
-
require '
|
2
|
+
require 'cgi'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'digest/md5'
|
5
5
|
|
6
6
|
module AlipayDualfun
|
7
|
-
GATEWAY_URL = 'https://mapi.alipay.com/gateway.do'
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def self.trade_create_by_buyer_url(options = {})
|
9
|
+
gateway_url = 'https://mapi.alipay.com/gateway.do'
|
10
|
+
trade_create_by_buyer_required_options = %w( service partner _input_charset out_trade_no subject payment_type logistics_type logistics_fee logistics_payment seller_email price quantity )
|
11
|
+
options = {
|
12
|
+
'service' => 'trade_create_by_buyer',
|
13
|
+
'_input_charset' => 'utf-8',
|
14
|
+
'payment_type' => '1',
|
15
|
+
'logistics_type' => 'DIRECT',
|
16
|
+
'logistics_fee' => '0',
|
17
|
+
'logistics_payment' => 'SELLER_PAY'
|
18
|
+
}.merge(stringify_keys(options))
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
:sign_type, :sign, :notify_url, :return_url,
|
17
|
-
:out_trade_no, :subject, :payment_type, :seller_email,
|
18
|
-
:logistics_type, :logistics_fee, :logistics_payment,
|
19
|
-
:price, :quantity
|
20
|
-
]
|
21
|
-
end
|
22
|
-
|
23
|
-
class DualfunPay < Base
|
24
|
-
NAME = '双功能收款'
|
25
|
-
SERVICE_LABEL = :trade_create_by_buyer
|
26
|
-
|
27
|
-
def initialize(order)
|
28
|
-
@order = order
|
29
|
-
@params = {}
|
30
|
-
end
|
31
|
-
|
32
|
-
def notification_callback_url(url)
|
33
|
-
@params[:notify_url] = url
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
def after_payment_redirect_url(url)
|
38
|
-
@params[:return_url] = url
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
def gateway_api_url
|
43
|
-
secure_signature = create_signature
|
44
|
-
request_params = sign_params.merge(
|
45
|
-
:sign_type => SIGN_TYPE_MD5,
|
46
|
-
:sign => secure_signature
|
47
|
-
)
|
48
|
-
|
49
|
-
lost_attributes = ATTR_REQUIRED - request_params.keys
|
50
|
-
if lost_attributes.any?
|
51
|
-
raise "the following keys are lost: #{lost_attributes.inspect}"
|
52
|
-
end
|
53
|
-
|
54
|
-
uri = URI(GATEWAY_URL)
|
55
|
-
uri.query = URI.encode_www_form(request_params.sort)
|
56
|
-
|
57
|
-
uri.to_s
|
58
|
-
end
|
59
|
-
|
60
|
-
# 出错通知异步调用 URL
|
61
|
-
#
|
62
|
-
# NOTE: 需要联系技术支持才能开通
|
63
|
-
def error_callback_url(url)
|
64
|
-
@params[:error_notify_url] = url
|
65
|
-
self
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
20
|
+
@secret_key = options['key']
|
21
|
+
options.delete('key')
|
69
22
|
|
70
|
-
|
71
|
-
params = @order.attributes.merge(@params)
|
72
|
-
params[:service] = SERVICE_LABEL
|
73
|
-
params[:partner] = @order.merchant.partner
|
74
|
-
params[:_input_charset] = DEFAULT_CHARSET
|
75
|
-
@sign_params ||= params
|
76
|
-
end
|
23
|
+
check_required_options(options, trade_create_by_buyer_required_options)
|
77
24
|
|
78
|
-
|
79
|
-
sequence = sign_params.sort.map {|k, v| "#{k}=#{v}"}.join('&')
|
80
|
-
Digest::MD5.hexdigest(sequence + @order.merchant.key)
|
81
|
-
end
|
82
|
-
end
|
25
|
+
"#{gateway_url}?#{query_string(options)}"
|
83
26
|
end
|
84
27
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
attr_accessor :merchant
|
89
|
-
attr_reader :attributes
|
90
|
-
|
91
|
-
def initialize(order_id, subject, description)
|
92
|
-
@attributes = {
|
93
|
-
:out_trade_no => order_id,
|
94
|
-
:subject => subject,
|
95
|
-
:body => description }
|
96
|
-
|
97
|
-
@attributes[:payment_type] = PAYMENT_TYPE_BUYING
|
98
|
-
end
|
99
|
-
|
100
|
-
def seller_email(email)
|
101
|
-
@attributes[:seller_email] = email
|
102
|
-
self
|
28
|
+
def self.check_required_options(options, names)
|
29
|
+
names.each do |name|
|
30
|
+
warn("Ailpay Warn: missing required option: #{name}") unless options.has_key?(name)
|
103
31
|
end
|
104
|
-
|
105
|
-
|
106
|
-
def set_price_and_quantity(price, quantity)
|
107
|
-
@attributes[:price] = price
|
108
|
-
@attributes[:quantity] = quantity
|
109
|
-
self
|
110
|
-
end
|
111
|
-
|
112
|
-
def buyer_email(email)
|
113
|
-
@attributes[:buyer_email] = email
|
114
|
-
self
|
115
|
-
end
|
116
|
-
|
117
|
-
#收银台页面上,商品展示的超链接。
|
118
|
-
def product_url(url)
|
119
|
-
@attributes[:show_url] = url
|
120
|
-
self
|
121
|
-
end
|
122
|
-
|
123
|
-
def set_logistics(type, payment, fee)
|
124
|
-
@attributes[:logistics_type] = type
|
125
|
-
@attributes[:logistics_payment] = payment
|
126
|
-
@attributes[:logistics_fee] = fee
|
127
|
-
self
|
128
|
-
end
|
129
|
-
|
130
|
-
# set to 0, for virtaul goods with no delivery
|
131
|
-
def no_logistics
|
132
|
-
@attributes[:logistics_type] = 'POST'
|
133
|
-
@attributes[:logistics_payment] = 'BUYER_PAY'
|
134
|
-
@attributes[:logistics_fee] = '0'
|
135
|
-
self
|
136
|
-
end
|
137
|
-
|
138
|
-
def dualfun_pay
|
139
|
-
Product::DualfunPay.new(self)
|
140
|
-
end
|
141
|
-
|
142
32
|
end
|
143
33
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
@partner = partner
|
149
|
-
@key = key
|
150
|
-
end
|
151
|
-
|
152
|
-
def create_order(order_id, subject, description)
|
153
|
-
order = Order.new(order_id, subject, description)
|
154
|
-
order.merchant = self
|
155
|
-
order
|
34
|
+
def self.stringify_keys(hash)
|
35
|
+
new_hash = {}
|
36
|
+
hash.each do |key, value|
|
37
|
+
new_hash[(key.to_s rescue key) || key] = value
|
156
38
|
end
|
39
|
+
new_hash
|
157
40
|
end
|
158
41
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
}
|
172
|
-
uri.query = params.map {|k, v| "#{k}=#{URI.escape(v.to_s)}"}.join('&')
|
173
|
-
|
174
|
-
Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
|
175
|
-
req = Net::HTTP::Get.new uri.request_uri
|
176
|
-
|
177
|
-
response = http.request(req)
|
178
|
-
response.body == 'true'
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
42
|
+
def self.query_string(options)
|
43
|
+
options.merge('sign_type' => 'MD5', 'sign' => generate_sign(options)).map do |key, value|
|
44
|
+
"#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
|
45
|
+
end.join('&')
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.generate_sign(params)
|
49
|
+
query = params.sort.map do |key, value|
|
50
|
+
"#{key}=#{value}"
|
51
|
+
end.join('&')
|
52
|
+
Digest::MD5.hexdigest("#{query}#{@secret_key}")
|
53
|
+
end
|
182
54
|
end
|
183
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alipay_dualfun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- happypeter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This gem can help you integrate Alipay Dual-function Payment.
|
14
14
|
email:
|