pay2go_client 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 94c744431068dcfe778555adc0b846e716c240ec
4
+ data.tar.gz: 69ef98e01e9a55a5f49d993fff121bc4b667567f
5
+ SHA512:
6
+ metadata.gz: 5799cd9ec1151aa49c81d73b34a81b20d2c2119ddcf25065518d6b6ca8c2a19d7b46fb296f4ac68e019f9a7394fb6050b6ac940c4e4b4999958aa7cd751c241c
7
+ data.tar.gz: 11e7bcfbfb562ff6cd08b9f80213345ceef349cfd485dc806975459834696ed7aedaca441680b0c21ff3c75c689a282bdbd86a19bf746c07de9333d3ae01f836
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .DS_Store
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ - 2.2.0
5
+ - 2.1.5
6
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Calvert
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.
@@ -0,0 +1,161 @@
1
+ [![Build Status](https://travis-ci.org/CalvertYang/pay2go.svg?branch=master)](https://travis-ci.org/CalvertYang/pay2go)
2
+
3
+ # 智付寶 Pay2go
4
+
5
+ 這是智付寶 API 的 Ruby 包裝,更多資訊請參閱 [API 文件專區](https://www.pay2go.com/info/site_description/api_description)。
6
+
7
+ - 這不是 Rails 插件,只是個 API 包裝。
8
+ - 使用時只需要傳送需要的參數即可,不用產生檢查碼,`pay2go_client` 會自己產生。
9
+ - 感謝[大兜](https://github.com/tonytonyjan)撰寫的 [allpay](https://github.com/tonytonyjan/allpay)
10
+
11
+ ## 安裝
12
+
13
+ ```bash
14
+ gem install pay2go_client
15
+ ```
16
+
17
+ ## 使用
18
+
19
+ ```ruby
20
+ test_client = Pay2go::Client.new({
21
+ merchant_id: 'MERCHANT_ID',
22
+ hash_key: 'HASH_KEY',
23
+ hash_iv: 'HASH_IV',
24
+ mode: :test
25
+ })
26
+
27
+ production_client = Pay2go::Client.new({
28
+ merchant_id: 'MERCHANT_ID',
29
+ hash_key: 'HASH_KEY',
30
+ hash_iv: 'HASH_IV'
31
+ })
32
+
33
+ test_client.query_trade_info({
34
+ MerchantOrderNo: '4e19cab1',
35
+ Amt: 100
36
+ })
37
+ ```
38
+
39
+ 本文件撰寫時,智付寶共有 5 個 API:
40
+
41
+ API 名稱 | 說明
42
+ --- | ---
43
+ MPG API | MPG(Multi Payment Gateway),單一串接多種支付方式。<br>透過 MPG API 可串接平台提供的所有支付方式。
44
+ 交易狀態查詢 API | 透過交易查詢 API 可自動化查核所有交易是否同步更新付款資訊。
45
+ 信用卡-取消授權模組 API | 透過取消授權 API,可進行信用卡交易授權取消,以返還持卡人及商店信用卡額度。
46
+ 信用卡-請退款模組 API | 透過請退款 API,可進行信用卡交易的請退款。
47
+ 信用卡-定期定額 API | 透過信用卡定期定額 API,可進行信用卡定期定額交易。
48
+
49
+ 詳細 API 參數請參閱智付寶技術串接手冊,注意幾點:
50
+
51
+ - 使用時不用煩惱 `MerchantID`、`RespondType`、`CheckValue`、`TimeStamp` 及 `Version`,正如上述範例一樣。
52
+ - MPG/信用卡-定期定額 API 回傳的內容是 HTML,這個請求應該是交給瀏覽器發送的。
53
+
54
+ ## Pay2go::Client
55
+
56
+ 實體方法 | 回傳 | 說明
57
+ --- | --- | ---
58
+ `verify_check_code(params)` | `Boolean` | 會於檢查收到的參數,其檢查碼是否正確,用於智付寶的 `NotifyURL` 參數及檢核資料回傳的合法性。
59
+ `generate_mpg_params(params)` | `Hash` | 用於產生 MPG API 表單需要的參數。
60
+ `query_trade_info(params)` | `Hash` | 用於查詢交易狀態。
61
+ `credit_card_deauthorize(params)` | `Hash` | 用於進行信用卡交易授權取消作業。
62
+ `credit_card_deauthorize_by_merchant_order_no(params)` | `Hash` | `credit_card_deauthorize` 的捷徑方法,將 `IndexType` 設為 1
63
+ `credit_card_deauthorize_by_trade_no(params)` | `Hash` | `credit_card_deauthorize` 的捷徑方法,將 `IndexType` 設為 2
64
+ `credit_card_collect_refund(params)` | `Hash` | 用於進行信用卡交易的請退款作業。
65
+ `credit_card_collect_refund_by_merchant_order_no(params)` | `Hash` | `credit_card_collect_refund` 的捷徑方法,將 `IndexType` 設為 1
66
+ `credit_card_collect_refund_by_trade_no(params)` | `Hash` | `credit_card_collect_refund` 的捷徑方法,將 `IndexType` 設為 2
67
+ `generate_credit_card_period_params(params)` | `Hash` | 用於產生信用卡-定期定額 API 表單需要的參數。
68
+
69
+ ## 使用範例
70
+
71
+ ##### MPG、信用卡-定期定額
72
+ ```bash
73
+ git clone git@github.com:CalvertYang/pay2go.git
74
+ cd pay2go
75
+ bundle install
76
+ ruby examples/server.rb
77
+ ```
78
+
79
+ - MPG(GET):http://localhost:4567/mpg
80
+ - 信用卡-定期定額(GET):http://localhost:4567/period
81
+ - 驗證資料合法性(POST):http://localhost:4567/validate
82
+
83
+ ##### 交易狀態查詢
84
+ ```ruby
85
+ result = test_client.query_trade_info({
86
+ MerchantOrderNo: '4e19cab1',
87
+ Amt: 100
88
+ })
89
+
90
+ puts "Result: #{result}"
91
+ puts "Valid?: #{@client.verify_check_code(result)}"
92
+ ```
93
+
94
+ ##### 信用卡-取消授權模組
95
+ ```ruby
96
+ result = test_client.credit_card_deauthorize({
97
+ TradeNo: '16010112345678901',
98
+ Amt: 100,
99
+ IndexType: 1
100
+ })
101
+
102
+ puts "Result: #{result}"
103
+ puts "Valid?: #{@client.verify_check_code(result)}"
104
+ ```
105
+
106
+ ```ruby
107
+ result = test_client.credit_card_deauthorize_by_merchant_order_no({
108
+ MerchantOrderNo: '4e19cab1',
109
+ Amt: 100
110
+ })
111
+
112
+ puts "Result: #{result}"
113
+ puts "Valid?: #{@client.verify_check_code(result)}"
114
+ ```
115
+
116
+ ```ruby
117
+ result = test_client.credit_card_deauthorize_by_trade_no({
118
+ TradeNo: '16010112345678901',
119
+ Amt: 100
120
+ })
121
+
122
+ puts "Result: #{result}"
123
+ puts "Valid?: #{@client.verify_check_code(result)}"
124
+ ```
125
+
126
+ ##### 信用卡-請退款模組
127
+ ```ruby
128
+ result = test_client.credit_card_collect_refund({
129
+ MerchantOrderNo: '4e19cab1',
130
+ Amt: 100,
131
+ CloseType: 2,
132
+ IndexType: 1
133
+ })
134
+
135
+ puts "Result: #{result}"
136
+ ```
137
+
138
+ ```ruby
139
+ result = test_client.credit_card_collect_refund_by_merchant_order_no({
140
+ MerchantOrderNo: '4e19cab1',
141
+ Amt: 100,
142
+ CloseType: 2
143
+ })
144
+
145
+ puts "Result: #{result}"
146
+ ```
147
+
148
+ ```ruby
149
+ result = test_client.credit_card_collect_refund_by_trade_no({
150
+ TradeNo: '16010112345678901',
151
+ Amt: 100,
152
+ CloseType: 2
153
+ })
154
+
155
+ puts "Result: #{result}"
156
+ ```
157
+
158
+ ## License
159
+ MIT
160
+
161
+ ![Analytics](https://ga-beacon.appspot.com/UA-44933497-3/CalvertYang/pay2go?pixel)
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.pattern = 'test/**/*_test.rb'
7
+ t.verbose = true
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "pay2go_client"
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
@@ -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
@@ -0,0 +1,15 @@
1
+ table {
2
+ width: 100%;
3
+ }
4
+
5
+ table input {
6
+ width: 100%;
7
+ }
8
+
9
+ table .title {
10
+ width: 10%;
11
+ }
12
+
13
+ input[type="submit"] {
14
+ margin-top: 2em;
15
+ }
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+ $: << File.expand_path('../lib')
3
+ require 'sinatra'
4
+ require 'pay2go'
5
+
6
+ client = Pay2go::Client.new({
7
+ merchant_id: '123456',
8
+ hash_key: '12345678901234567890123456789012',
9
+ hash_iv: '1234567890123456',
10
+ mode: :test
11
+ })
12
+
13
+ get '/mpg' do
14
+ @client_options = client.options
15
+ @params = client.generate_mpg_params({
16
+ MerchantOrderNo: SecureRandom.hex(4),
17
+ Amt: 200,
18
+ ItemDesc: '一般交易測試',
19
+ Email: 'hello@localhost.com',
20
+ EmailModify: 0,
21
+ LoginType: 0,
22
+ CREDIT: 1
23
+ })
24
+
25
+ erb :mpg
26
+ end
27
+
28
+ get '/period' do
29
+ @client_options = client.options
30
+ @params = client.generate_credit_card_period_params({
31
+ MerchantOrderNo: SecureRandom.hex(4),
32
+ ProdDesc: '定期定額交易測試',
33
+ PeriodAmt: 100,
34
+ PeriodAmtMode: 'Total',
35
+ PeriodType: 'M',
36
+ PeriodPoint: '01',
37
+ PeriodStartType: 1,
38
+ PeriodTimes: '5',
39
+ })
40
+
41
+ erb :period
42
+ end
43
+
44
+ post '/validate' do
45
+ client.verify_check_code(request.POST).to_s
46
+ end
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>MPG API</title>
6
+ <link rel="stylesheet" type="text/css" href="<%= url("/style.css")%>">
7
+ </head>
8
+ <body>
9
+ <form action="https://capi.pay2go.com/MPG/mpg_gateway" method="post">
10
+ <table>
11
+ <caption>MPG API</caption>
12
+ <% @client_options.each do |k, v| %>
13
+ <tr>
14
+ <th class="title"><%= k %></th>
15
+ <td><%= v %></td>
16
+ </tr>
17
+ <% end %>
18
+ <% @params.each do |k, v| %>
19
+ <tr>
20
+ <th class="title"><%= k %></th>
21
+ <td><input type="text" name="<%= k %>" value="<%= v %>"></td>
22
+ </tr>
23
+ <% end %>
24
+ <tr>
25
+ <td colspan="2"><input type="submit"></td>
26
+ </tr>
27
+ </table>
28
+ </form>
29
+ </body>
30
+ </html>
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>信用卡-定期定額 API</title>
6
+ <link rel="stylesheet" type="text/css" href="<%= url("/style.css")%>">
7
+ </head>
8
+ <body>
9
+ <form action="https://capi.pay2go.com/API/PeriodAPI" method="post">
10
+ <table>
11
+ <caption>信用卡-定期定額 API</caption>
12
+ <% @client_options.each do |k, v| %>
13
+ <tr>
14
+ <th class="title"><%= k %></th>
15
+ <td><%= v %></td>
16
+ </tr>
17
+ <% end %>
18
+ <% @params.each do |k, v| %>
19
+ <tr>
20
+ <th class="title"><%= k %></th>
21
+ <td><input type="text" name="<%= k %>" value="<%= v %>"></td>
22
+ </tr>
23
+ <% end %>
24
+ <tr>
25
+ <td colspan="2"><input type="submit"></td>
26
+ </tr>
27
+ </table>
28
+ </form>
29
+ </body>
30
+ </html>
@@ -0,0 +1,5 @@
1
+ require 'pay2go/version'
2
+ require 'pay2go/client'
3
+
4
+ module Pay2go
5
+ end
@@ -0,0 +1,245 @@
1
+ require 'net/http'
2
+ require 'cgi'
3
+ require 'digest'
4
+ require 'pay2go/errors'
5
+ require 'pay2go/core_ext/hash'
6
+
7
+ module Pay2go
8
+ class Client
9
+ TRANSACTION_API_ENDPOINTS = {
10
+ test: 'https://capi.pay2go.com/API/QueryTradeInfo',
11
+ production: 'https://api.pay2go.com/API/QueryTradeInfo'
12
+ }.freeze
13
+ CREDITCARD_COLLECT_REFUND_API_ENDPOINTS = {
14
+ test: 'https://cweb.pay2go.com/API/CreditCard/Close',
15
+ production: 'https://web.pay2go.com/API/CreditCard/Close'
16
+ }.freeze
17
+ CREDITCARD_DEAUTHORIZE_API_ENDPOINTS = {
18
+ test: 'https://cweb.pay2go.com/API/CreditCard/Cancel',
19
+ production: 'https://web.pay2go.com/API/CreditCard/Cancel'
20
+ }.freeze
21
+ NEED_CHECK_VALUE_APIS = [
22
+ :query_trade_info # Transaction API
23
+ ]
24
+
25
+ attr_reader :options
26
+
27
+ def initialize options = {}
28
+ @options = { mode: :production }.merge!(options)
29
+
30
+ case @options[:mode]
31
+ when :test, :production
32
+ option_required! :merchant_id, :hash_key, :hash_iv
33
+ else
34
+ raise InvalidMode, %Q{option :mode is either :test or :production}
35
+ end
36
+
37
+ @options.freeze
38
+ end
39
+
40
+ def verify_check_code params = {}
41
+ stringified_keys = params.stringify_keys
42
+ check_code = stringified_keys.delete('CheckCode')
43
+ make_check_code(stringified_keys) == check_code
44
+ end
45
+
46
+ def generate_mpg_params params = {}
47
+ param_required! params, [:MerchantOrderNo, :Amt, :ItemDesc, :Email, :LoginType]
48
+
49
+ post_params = {
50
+ RespondType: 'String',
51
+ TimeStamp: Time.now.to_i,
52
+ Version: '1.2'
53
+ }.merge!(params)
54
+
55
+ generate_params(:mpg, post_params)
56
+ end
57
+
58
+ def query_trade_info params = {}
59
+ param_required! params, [:MerchantOrderNo, :Amt]
60
+
61
+ post_params = {
62
+ Version: '1.1',
63
+ RespondType: 'String',
64
+ TimeStamp: Time.now.to_i
65
+ }.merge!(params)
66
+
67
+ res = request :query_trade_info, post_params
68
+ Hash[res.body.split('&').map!{|i| URI::decode(i).split('=')}]
69
+ end
70
+
71
+ def credit_card_deauthorize params = {}
72
+ param_required! params, [:Amt, :IndexType]
73
+
74
+ raise MissingOption, %Q{One of the following param is required: MerchantOrderNo, TradeNo} if params[:MerchantOrderNo].nil? and params[:TradeNo].nil?
75
+
76
+ post_params = {
77
+ RespondType: 'String',
78
+ Version: '1.0',
79
+ TimeStamp: Time.now.to_i
80
+ }.merge!(params)
81
+
82
+ post_params.delete_if { |key, value| value.nil? }
83
+
84
+ res = request :credit_card_deauthorize, post_params
85
+ Hash[res.body.split('&').map!{|i| URI::decode(i.force_encoding('ASCII-8BIT').force_encoding('UTF-8')).split('=')}]
86
+ end
87
+
88
+ def credit_card_deauthorize_by_merchant_order_no params = {}
89
+ param_required! params, [:Amt, :MerchantOrderNo]
90
+
91
+ post_params = {
92
+ IndexType: 1
93
+ }.merge!(params)
94
+
95
+ credit_card_deauthorize post_params
96
+ end
97
+
98
+ def credit_card_deauthorize_by_trade_no params = {}
99
+ param_required! params, [:Amt, :TradeNo]
100
+
101
+ post_params = {
102
+ IndexType: 2
103
+ }.merge!(params)
104
+
105
+ credit_card_deauthorize post_params
106
+ end
107
+
108
+ def credit_card_collect_refund params = {}
109
+ param_required! params, [:Amt, :IndexType, :CloseType]
110
+
111
+ raise MissingOption, %Q{One of the following param is required: MerchantOrderNo, TradeNo} if params[:MerchantOrderNo].nil? and params[:TradeNo].nil?
112
+
113
+ post_params = {
114
+ RespondType: 'String',
115
+ Version: '1.0',
116
+ TimeStamp: Time.now.to_i
117
+ }.merge!(params)
118
+
119
+ res = request :credit_card_collect_refund, post_params
120
+ Hash[res.body.split('&').map!{|i| URI::decode(i.force_encoding('ASCII-8BIT').force_encoding('UTF-8')).split('=')}]
121
+ end
122
+
123
+ def credit_card_collect_refund_by_merchant_order_no params = {}
124
+ param_required! params, [:Amt, :MerchantOrderNo, :CloseType]
125
+
126
+ post_params = {
127
+ IndexType: 1
128
+ }.merge!(params)
129
+
130
+ credit_card_collect_refund post_params
131
+ end
132
+
133
+ def credit_card_collect_refund_by_trade_no params = {}
134
+ param_required! params, [:Amt, :TradeNo, :CloseType]
135
+
136
+ post_params = {
137
+ IndexType: 1
138
+ }.merge!(params)
139
+
140
+ credit_card_collect_refund post_params
141
+ end
142
+
143
+ def generate_credit_card_period_params params = {}
144
+ param_required! params, [:MerchantOrderNo, :ProdDesc, :PeriodAmt, :PeriodAmtMode, :PeriodType, :PeriodPoint, :PeriodStartType, :PeriodTimes]
145
+
146
+ generate_params(:credit_card_period, {
147
+ RespondType: 'String',
148
+ TimeStamp: Time.now.to_i,
149
+ Version: '1.0'
150
+ }.merge!(params))
151
+ end
152
+
153
+ def make_check_value type, params = {}
154
+ case type
155
+ when :mpg
156
+ check_value_fields = [:Amt, :MerchantID, :MerchantOrderNo, :TimeStamp, :Version]
157
+ padded = "HashKey=#{@options[:hash_key]}&%s&HashIV=#{@options[:hash_iv]}"
158
+ when :query_trade_info
159
+ check_value_fields = [:Amt, :MerchantID, :MerchantOrderNo]
160
+ padded = "IV=#{@options[:hash_iv]}&%s&Key=#{@options[:hash_key]}"
161
+ when :credit_card_period
162
+ check_value_fields = [:MerchantID, :MerchantOrderNo, :PeriodAmt, :PeriodType, :TimeStamp]
163
+ padded = "HashKey=#{@options[:hash_key]}&%s&HashIV=#{@options[:hash_iv]}"
164
+ else
165
+ raise UnsupportedType, "Unsupported API type."
166
+ end
167
+
168
+ param_required! params, check_value_fields
169
+
170
+ raw = params.select { |key, value| key.to_s.match(/^(#{check_value_fields.join('|')})$/) }
171
+ .sort_by{ |k, v| k.downcase }.map!{ |k, v| "#{k}=#{v}" }.join('&')
172
+
173
+ padded = padded % raw
174
+
175
+ Digest::SHA256.hexdigest(padded).upcase!
176
+ end
177
+
178
+ def encode_post_data data
179
+ cipher = OpenSSL::Cipher::AES256.new(:CBC)
180
+ cipher.encrypt
181
+ cipher.padding = 0
182
+ cipher.key = @options[:hash_key]
183
+ cipher.iv = @options[:hash_iv]
184
+ data = add_padding(data)
185
+ encrypted = cipher.update(data) + cipher.final
186
+ encrypted.unpack('H*').first
187
+ end
188
+
189
+ private
190
+
191
+ def option_required! *option_names
192
+ option_names.each do |option_name|
193
+ raise MissingOption, %Q{option "#{option_name}" is required.} if @options[option_name].nil?
194
+ end
195
+ end
196
+
197
+ def param_required! params, param_names
198
+ param_names.each do |param_name|
199
+ raise MissingParameter, %Q{param "#{param_name}" is required.} if params[param_name].nil?
200
+ end
201
+ end
202
+
203
+ def make_check_code params = {}
204
+ raw = params.select { |key, value| key.to_s.match(/^(Amt|MerchantID|MerchantOrderNo|TradeNo)$/) }
205
+ .sort_by{ |k, v| k.downcase }.map!{ |k, v| "#{k}=#{v}" }.join('&')
206
+ padded = "HashIV=#{@options[:hash_iv]}&#{raw}&HashKey=#{@options[:hash_key]}"
207
+ Digest::SHA256.hexdigest(padded).upcase!
208
+ end
209
+
210
+ def generate_params type, overwrite_params = {}
211
+ result = overwrite_params.clone
212
+ result[:MerchantID] = @options[:merchant_id]
213
+ result[:CheckValue] = make_check_value(type, result)
214
+ result
215
+ end
216
+
217
+ def request type, params = {}
218
+ case type
219
+ when :query_trade_info
220
+ api_url = TRANSACTION_API_ENDPOINTS[@options[:mode]]
221
+ when :credit_card_deauthorize
222
+ api_url = CREDITCARD_DEAUTHORIZE_API_ENDPOINTS[@options[:mode]]
223
+ when :credit_card_collect_refund
224
+ api_url = CREDITCARD_COLLECT_REFUND_API_ENDPOINTS[@options[:mode]]
225
+ end
226
+
227
+ if NEED_CHECK_VALUE_APIS.include?(type)
228
+ post_params = generate_params(type, params)
229
+ else
230
+ post_params = {
231
+ MerchantID_: @options[:merchant_id],
232
+ PostData_: encode_post_data(URI.encode(params.map{ |key, value| "#{key}=#{value}" }.join("&")))
233
+ }
234
+ end
235
+
236
+ Net::HTTP.post_form URI(api_url), post_params
237
+ end
238
+
239
+ def add_padding text, size = 32
240
+ len = text.length
241
+ pad = size - (len % size)
242
+ text = text + (pad.chr * pad)
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,9 @@
1
+ class Hash
2
+ def stringify_keys
3
+ result = self.class.new
4
+ each_key do |key|
5
+ result[key.to_s] = self[key]
6
+ end
7
+ result
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Pay2go
2
+ # Generic Pay2Go exception class.
3
+ class Pay2goError < StandardError; end
4
+ class MissingOption < Pay2goError; end
5
+ class MissingParameter < Pay2goError; end
6
+ class InvalidMode < Pay2goError; end
7
+ class UnsupportedType < Pay2goError; end
8
+ end
@@ -0,0 +1,3 @@
1
+ module Pay2go
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1 @@
1
+ require 'pay2go'
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pay2go/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "pay2go_client"
8
+ spec.version = Pay2go::VERSION
9
+ spec.authors = ["Calvert"]
10
+ spec.email = [""]
11
+
12
+ spec.summary = %q{API client for pay2go}
13
+ spec.description = %q{API client for pay2go}
14
+ spec.homepage = "https://github.com/CalvertYang/pay2go"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "bin"
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.8"
25
+ spec.add_development_dependency "minitest-reporters", "~> 1.1"
26
+ spec.add_development_dependency "sinatra"
27
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pay2go_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Calvert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-13 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.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
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: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sinatra
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: API client for pay2go
84
+ email:
85
+ - ''
86
+ executables:
87
+ - console
88
+ - setup
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/console
99
+ - bin/setup
100
+ - examples/public/style.css
101
+ - examples/server.rb
102
+ - examples/views/mpg.erb
103
+ - examples/views/period.erb
104
+ - lib/pay2go.rb
105
+ - lib/pay2go/client.rb
106
+ - lib/pay2go/core_ext/hash.rb
107
+ - lib/pay2go/errors.rb
108
+ - lib/pay2go/version.rb
109
+ - lib/pay2go_client.rb
110
+ - pay2go.gemspec
111
+ homepage: https://github.com/CalvertYang/pay2go
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.5.1
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: API client for pay2go
135
+ test_files: []