alipay_dualfun 0.1 → 0.2
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 +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:
|