qiwi-pay 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +1 -0
- data/lib/qiwi-pay/version.rb +1 -1
- data/spec/qiwi-pay/api/capture_operation_spec.rb +12 -0
- data/spec/qiwi-pay/api/refund_operation_spec.rb +12 -0
- data/spec/qiwi-pay/api/response_spec.rb +21 -0
- data/spec/qiwi-pay/api/reversal_operation_spec.rb +12 -0
- data/spec/qiwi-pay/api/status_operation_spec.rb +109 -0
- data/spec/qiwi-pay/cheque_spec.rb +52 -0
- data/spec/qiwi-pay/confirmation_spec.rb +113 -0
- data/spec/qiwi-pay/qiwi_pay_spec.rb +5 -0
- data/spec/qiwi-pay/signature_spec.rb +31 -0
- data/spec/qiwi-pay/wpf/auth_operation_spec.rb +12 -0
- data/spec/qiwi-pay/wpf/sale_operation_spec.rb +12 -0
- data/spec/shared/api_payment_operation.rb +40 -0
- data/spec/shared/payment_operation.rb +63 -0
- data/spec/shared/wpf_payment_operation.rb +35 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/external_requests.rb +17 -0
- metadata +39 -11
- data/.gitignore +0 -11
- data/.rspec +0 -3
- data/.rubocop.yml +0 -8
- data/.ruby-version +0 -1
- data/.travis.yml +0 -5
- data/qiwi-pay.gemspec +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e92f908e1718fc717f78be6507cd0da5401fc314b60ab8f5d1106c8f952537f7
|
4
|
+
data.tar.gz: 3fdd3ee34bf0578185c8ef3bd946655c5550303c38ea014feb47f4cbf7a273e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2c37ad0df653f1c9e8b889bf5a9ae2308c734b005def2b5aa48f250d8084c02a18b202aec872e2eef1fe29536bceecd0eb4bf44f248c59bc2d2309407525047
|
7
|
+
data.tar.gz: 2778e9b7a249669b81a69feb0f75b328ca5e3268506964e5bb17f45ab421ee160620a5f3c3b63f7c271d607395e504695e20764b509ad305e572d919bc0821ba
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
qiwi-pay (0.1.
|
4
|
+
qiwi-pay (0.1.1)
|
5
5
|
rest-client (>= 1.8.0, < 2.1)
|
6
6
|
|
7
7
|
GEM
|
@@ -18,9 +18,9 @@ GEM
|
|
18
18
|
http-cookie (1.0.3)
|
19
19
|
domain_name (~> 0.5)
|
20
20
|
luhn (1.0.2)
|
21
|
-
mime-types (3.
|
21
|
+
mime-types (3.2.2)
|
22
22
|
mime-types-data (~> 3.2015)
|
23
|
-
mime-types-data (3.
|
23
|
+
mime-types-data (3.2018.0812)
|
24
24
|
netrc (0.11.0)
|
25
25
|
public_suffix (3.0.2)
|
26
26
|
rake (10.5.0)
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[![Build Status](https://travis-ci.org/OnlinetoursGit/qiwi-pay.svg?branch=master)](https://travis-ci.org/OnlinetoursGit/qiwi-pay)
|
2
2
|
[![Maintainability](https://api.codeclimate.com/v1/badges/eb4dda5c934aec79ef99/maintainability)](https://codeclimate.com/github/OnlinetoursGit/qiwi-pay/maintainability)
|
3
3
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/eb4dda5c934aec79ef99/test_coverage)](https://codeclimate.com/github/OnlinetoursGit/qiwi-pay/test_coverage)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/qiwi-pay.svg)](https://badge.fury.io/rb/qiwi-pay)
|
4
5
|
|
5
6
|
# QiwiPay
|
6
7
|
|
data/lib/qiwi-pay/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'shared/payment_operation'
|
2
|
+
require 'shared/api_payment_operation'
|
3
|
+
|
4
|
+
RSpec.describe QiwiPay::Api::CaptureOperation do
|
5
|
+
describe 'act as PaymentOperation' do
|
6
|
+
include_examples 'payment_operation'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'act as API PaymentOperation' do
|
10
|
+
include_examples 'api_payment_operation'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'shared/payment_operation'
|
2
|
+
require 'shared/api_payment_operation'
|
3
|
+
|
4
|
+
RSpec.describe QiwiPay::Api::RefundOperation do
|
5
|
+
describe 'act as PaymentOperation' do
|
6
|
+
include_examples 'payment_operation'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'act as API PaymentOperation' do
|
10
|
+
include_examples 'api_payment_operation'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
RSpec.describe QiwiPay::Api::Response do
|
2
|
+
let(:json) { '{"txn_id":"123", "error_code":"0", "c":"ttt"}' }
|
3
|
+
let(:http_code) { 200 }
|
4
|
+
subject { described_class.new http_code, json }
|
5
|
+
|
6
|
+
describe '#new' do
|
7
|
+
it { expect(subject).to be_success }
|
8
|
+
|
9
|
+
it 'converts integer attributes to integer' do
|
10
|
+
expect(subject.txn_id).to eq 123
|
11
|
+
expect(subject.error_code).to eq 0
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'received `http_code` parameter in json' do
|
15
|
+
let(:json) { '{"txn_id":"123", "http_code":100500}' }
|
16
|
+
it 'returns valid http_code' do
|
17
|
+
expect(subject.http_code).to eq 200
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'shared/payment_operation'
|
2
|
+
require 'shared/api_payment_operation'
|
3
|
+
|
4
|
+
RSpec.describe QiwiPay::Api::ReversalOperation do
|
5
|
+
describe 'act as PaymentOperation' do
|
6
|
+
include_examples 'payment_operation'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'act as API PaymentOperation' do
|
10
|
+
include_examples 'api_payment_operation'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'shared/payment_operation'
|
2
|
+
require 'shared/api_payment_operation'
|
3
|
+
|
4
|
+
RSpec.describe QiwiPay::Api::StatusOperation do
|
5
|
+
describe 'act as PaymentOperation' do
|
6
|
+
include_examples 'payment_operation'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'act as API PaymentOperation' do
|
10
|
+
include_examples 'api_payment_operation'
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:params) do
|
14
|
+
{
|
15
|
+
merchant_site: 123,
|
16
|
+
txn_id: 1265,
|
17
|
+
order_id: 'dsfkjdslkfjdlks'
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:ok_response_body) do
|
22
|
+
<<-RESP
|
23
|
+
{
|
24
|
+
"transactions": [
|
25
|
+
{
|
26
|
+
"error_code": 0,
|
27
|
+
"txn_id": 3666050,
|
28
|
+
"txn_status": 2,
|
29
|
+
"txn_type": 2,
|
30
|
+
"txn_date": "2017-03-09T17:16:06+00:00",
|
31
|
+
"pan": "400000******0002",
|
32
|
+
"amount": 10000,
|
33
|
+
"currency": 643,
|
34
|
+
"auth_code": "181218",
|
35
|
+
"merchant_site": 99,
|
36
|
+
"card_name": "cardholder name",
|
37
|
+
"card_bank": "",
|
38
|
+
"order_id": "41324123412342"
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"error_code": 0,
|
42
|
+
"txn_id": 3684050,
|
43
|
+
"txn_status": 3,
|
44
|
+
"txn_type": 4,
|
45
|
+
"txn_date": "2017-03-09T17:16:09+00:00",
|
46
|
+
"pan": "400000******0002",
|
47
|
+
"amount": 100,
|
48
|
+
"currency": 643,
|
49
|
+
"merchant_site": 99,
|
50
|
+
"card_name": "cardholder name",
|
51
|
+
"card_bank": ""
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"error_code": 0,
|
55
|
+
"txn_id": 3685050,
|
56
|
+
"txn_status": 3,
|
57
|
+
"txn_type": 4,
|
58
|
+
"txn_date": "2017-03-19T17:16:06+00:00",
|
59
|
+
"pan": "400000******0002",
|
60
|
+
"amount": 100,
|
61
|
+
"currency": 643,
|
62
|
+
"merchant_site": 99,
|
63
|
+
"card_name": "cardholder name",
|
64
|
+
"card_bank": ""
|
65
|
+
}
|
66
|
+
],
|
67
|
+
"error_code": 0
|
68
|
+
}
|
69
|
+
RESP
|
70
|
+
end
|
71
|
+
let(:ok_response) { Struct.new(:code, :body).new(200, ok_response_body) }
|
72
|
+
let(:api_client) { double('api_client') }
|
73
|
+
|
74
|
+
subject { described_class.new credentials, params }
|
75
|
+
|
76
|
+
describe '#perform' do
|
77
|
+
before do
|
78
|
+
allow(RestClient::Resource).to receive(:new).and_return(api_client)
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'making valid request' do
|
82
|
+
it 'should make POST request with correct parameters' do
|
83
|
+
expect(api_client).to receive(:post) do |params|
|
84
|
+
expect(params).to eq '{"opcode":"30",'\
|
85
|
+
'"txn_id":"1265",'\
|
86
|
+
'"merchant_site":"123",'\
|
87
|
+
'"order_id":"dsfkjdslkfjdlks",'\
|
88
|
+
'"sign":"07bbb1f2f41327e64f7f80b24c9a64ff887d8f0b4abe8cca04cc4b7e0eeaf08f"}'
|
89
|
+
ok_response
|
90
|
+
end
|
91
|
+
subject.perform
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should return api response object' do
|
95
|
+
allow(api_client).to receive(:post).and_return(ok_response)
|
96
|
+
r = subject.perform
|
97
|
+
expect(r).to be_a QiwiPay::Api::Response
|
98
|
+
expect(r.http_code).to eq ok_response.code
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'making forbidden request' do
|
103
|
+
it 'raises error' do
|
104
|
+
expect(api_client).to receive(:post).and_raise(RestClient::Forbidden)
|
105
|
+
expect { subject.perform }.to raise_error(RuntimeError)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
RSpec.describe QiwiPay::Cheque do
|
2
|
+
let(:params) {
|
3
|
+
{
|
4
|
+
seller_id: 3123011520,
|
5
|
+
cheque_type: 1,
|
6
|
+
customer_contact: "foo@domain.tld",
|
7
|
+
tax_system: 1,
|
8
|
+
positions: [
|
9
|
+
{
|
10
|
+
quantity: 2,
|
11
|
+
price: 322.94,
|
12
|
+
tax: 4,
|
13
|
+
description: "Товар/Услуга 1"
|
14
|
+
},
|
15
|
+
{
|
16
|
+
quantity: 1,
|
17
|
+
price: 500,
|
18
|
+
tax: 4,
|
19
|
+
description: "Товар/Услуга 2"
|
20
|
+
}
|
21
|
+
]
|
22
|
+
}
|
23
|
+
}
|
24
|
+
subject{ described_class.new params }
|
25
|
+
|
26
|
+
describe '#to_json' do
|
27
|
+
it 'returns JSON' do
|
28
|
+
json = subject.to_json
|
29
|
+
expect{JSON.parse(json)}.not_to raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'includes required parameters' do
|
33
|
+
json = subject.to_json
|
34
|
+
expect(json).to include 'seller_id'
|
35
|
+
expect(json).to include 'cheque_type'
|
36
|
+
expect(json).to include 'customer_contact'
|
37
|
+
expect(json).to include 'tax_system'
|
38
|
+
expect(json).to include 'positions'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#encode' do
|
43
|
+
it 'returns a string' do
|
44
|
+
expect(subject.encode).to be_a String
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'encode string properly' do
|
48
|
+
data = Base64.strict_encode64(Zlib::Deflate.deflate(subject.to_json))
|
49
|
+
expect(subject.encode).to eq data
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
RSpec.describe QiwiPay::Confirmation do
|
2
|
+
let(:params) do
|
3
|
+
{
|
4
|
+
txn_id: '20728960050',
|
5
|
+
pan: '510621******3082',
|
6
|
+
email: 'mklimenko@onlinetours.ru',
|
7
|
+
country: 'RUS',
|
8
|
+
city: 'Moscow',
|
9
|
+
product_name: 'Оплата тура',
|
10
|
+
ip: '196.54.55.20',
|
11
|
+
order_id: 1232,
|
12
|
+
txn_status: 1,
|
13
|
+
txn_date: '2018-05-03T15:55:18+00:00',
|
14
|
+
txn_type: 1,
|
15
|
+
error_code: 8001,
|
16
|
+
amount: '1000.00',
|
17
|
+
currency: 643,
|
18
|
+
sign: '27A56431CD3A14BA3455956766F772EA5732FC5E1C74541B33F58D7F7766D98A'
|
19
|
+
}
|
20
|
+
end
|
21
|
+
subject { described_class.new credentials, params }
|
22
|
+
|
23
|
+
describe '#sign calculates signature for params' do
|
24
|
+
it { expect(subject.send(:sign)).to eq params[:sign] }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#valid_sign? tests signature for validity' do
|
28
|
+
describe 'for valid signature' do
|
29
|
+
it { expect(subject.valid_sign?).to be_truthy }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'for invalid signature' do
|
33
|
+
before { params[:sign] = 'invalidsignature' }
|
34
|
+
it { expect(subject.valid_sign?).to be_falsy }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#success? and #error? test operation for successfulness' do
|
39
|
+
describe 'with no error' do
|
40
|
+
before { params[:error_code] = '0' }
|
41
|
+
|
42
|
+
describe 'with valid sign' do
|
43
|
+
before { params[:sign] = '1E61076344971F540138D1107FB6E3E31A7E07EF811CE7E91F31178DF8EFDD5C' }
|
44
|
+
it { expect(subject.success?).to be_truthy }
|
45
|
+
it { expect(subject.error?).to be_falsy }
|
46
|
+
end
|
47
|
+
describe 'with invalid sign' do
|
48
|
+
before { params[:sign] = 'invalidsignature' }
|
49
|
+
it { expect(subject.success?).to be_falsy }
|
50
|
+
it { expect(subject.error?).to be_falsy }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'with error present' do
|
55
|
+
describe 'with valid sign' do
|
56
|
+
it { expect(subject.success?).to be_falsy }
|
57
|
+
it { expect(subject.error?).to be_truthy }
|
58
|
+
end
|
59
|
+
describe 'with invalid sign' do
|
60
|
+
before { params[:sign] = 'invalidsignature' }
|
61
|
+
it { expect(subject.success?).to be_falsy }
|
62
|
+
it { expect(subject.error?).to be_truthy }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'with creepy hash as params' do
|
68
|
+
let(:params) { Hash.new(:some_val) }
|
69
|
+
|
70
|
+
before do
|
71
|
+
params[:txn_id] = 20728960050
|
72
|
+
params[:email] = 'mklimenko@onlinetours.ru'
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'extracts params' do
|
76
|
+
expect(subject.txn_id).to eq params[:txn_id]
|
77
|
+
expect(subject.email).to eq params[:email]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'with string params values given' do
|
82
|
+
let(:params) { Hash.new(:some_val) }
|
83
|
+
|
84
|
+
before do
|
85
|
+
params[:txn_id] = '20728960050'
|
86
|
+
params[:txn_status] = '1'
|
87
|
+
params[:txn_type] = '2'
|
88
|
+
params[:currency] = '643'
|
89
|
+
params[:error_code] = '11'
|
90
|
+
params[:email] = 'mklimenko@onlinetours.ru'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'converts certain valuest to integer' do
|
94
|
+
expect(subject.txn_id).to eq params[:txn_id].to_i
|
95
|
+
expect(subject.txn_status).to eq params[:txn_status].to_i
|
96
|
+
expect(subject.txn_type).to eq params[:txn_type].to_i
|
97
|
+
expect(subject.currency).to eq params[:currency].to_i
|
98
|
+
expect(subject.error_code).to eq params[:error_code].to_i
|
99
|
+
expect(subject.email).to eq params[:email]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#to_h converts object to hash' do
|
104
|
+
it { expect(subject.to_h).to be_a Hash }
|
105
|
+
it 'includes all confirmation params' do
|
106
|
+
described_class::ALLOWED_PARAMS.each do |p|
|
107
|
+
expect(subject.to_h.keys).to include p
|
108
|
+
end
|
109
|
+
end
|
110
|
+
it { expect(subject.to_h.keys).to include :txn_status_message }
|
111
|
+
it { expect(subject.to_h.keys).to include :txn_type_message }
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
RSpec.describe QiwiPay::Signature do
|
2
|
+
subject { described_class.new(params, 'secret') }
|
3
|
+
let(:params) { { b: :b, zzz: :zzz, cdf: :cdf, abc: :abc, 'asd' => 'asd' } }
|
4
|
+
let(:signature) { 'd6575188a24edb6960d7f63564f3f5c0752553b6d4f305d12f4d39c00ee5f0a4' }
|
5
|
+
|
6
|
+
describe '#build_params_string' do
|
7
|
+
subject { described_class.new(params, 'secret').send(:build_params_string) }
|
8
|
+
|
9
|
+
it 'builds string from param values ordered by keys joined with bar' do
|
10
|
+
expect(subject).to eq 'abc|asd|b|cdf|zzz'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should reject blank values' do
|
14
|
+
params[:abc] = nil
|
15
|
+
params[:zzz] = ''
|
16
|
+
expect(subject).to eq 'asd|b|cdf'
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should ignore `sign` parameter' do
|
20
|
+
params[:sign] = 'sign1'
|
21
|
+
params['sign'] = 'sign2'
|
22
|
+
expect(subject).to eq 'abc|asd|b|cdf|zzz'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#sign' do
|
27
|
+
it 'calculates signature' do
|
28
|
+
expect(subject.sign).to eq signature
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'shared/payment_operation'
|
2
|
+
require 'shared/wpf_payment_operation'
|
3
|
+
|
4
|
+
RSpec.describe QiwiPay::Wpf::AuthOperation do
|
5
|
+
describe 'act as PaymentOperation' do
|
6
|
+
include_examples 'payment_operation'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'act as WPF PaymentOperation' do
|
10
|
+
include_examples 'wpf_payment_operation'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'shared/payment_operation'
|
2
|
+
require 'shared/wpf_payment_operation'
|
3
|
+
|
4
|
+
RSpec.describe QiwiPay::Wpf::SaleOperation do
|
5
|
+
describe 'act as PaymentOperation' do
|
6
|
+
include_examples 'payment_operation'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'act as WPF PaymentOperation' do
|
10
|
+
include_examples 'wpf_payment_operation'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
RSpec.shared_examples "api_payment_operation" do
|
2
|
+
let(:params) do
|
3
|
+
{
|
4
|
+
merchant_site: 1234
|
5
|
+
}
|
6
|
+
end
|
7
|
+
|
8
|
+
subject { described_class.new credentials, params }
|
9
|
+
|
10
|
+
before do
|
11
|
+
# Stub unimplemented method
|
12
|
+
allow(subject).to receive(:opcode).and_return(0)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#perform' do
|
16
|
+
describe 'making request to QiwiPay API' do
|
17
|
+
it 'perform signed POST request to QiwiPay API URL' do
|
18
|
+
subject.perform
|
19
|
+
expect(WebMock).to(
|
20
|
+
have_requested(:post, 'https://acquiring.qiwi.com/merchant/direct').with do |req|
|
21
|
+
req.body.include?('"opcode":"0"') &&
|
22
|
+
req.body.include?('"merchant_site":"1234"') &&
|
23
|
+
req.body.include?('"sign":')
|
24
|
+
end
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns Response object with parsed data' do
|
29
|
+
r = subject.perform
|
30
|
+
expect(r).to be_a QiwiPay::Api::Response
|
31
|
+
expect(r.http_code).to eq 200
|
32
|
+
expect(r.error_code).to eq 0
|
33
|
+
expect(r.txn_id).to eq 123
|
34
|
+
expect(r.txn_status).to eq 3
|
35
|
+
expect(r.txn_type).to eq 3
|
36
|
+
expect(r.txn_date).to eq '2017-03-09T17:16:06+00:00'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
RSpec.shared_examples "payment_operation" do
|
2
|
+
let(:params) do
|
3
|
+
{
|
4
|
+
merchant_site: 1234,
|
5
|
+
currency: 643,
|
6
|
+
amount: 100.134,
|
7
|
+
abra_kadabra: 'abracadabra',
|
8
|
+
cheque: 'asdljhaskjdhkajsdhkaj',
|
9
|
+
callback_url: 'https://example.com/notify',
|
10
|
+
order_expire: Time.new(2018, 1, 1, 1, 1, 1) + 3600
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { described_class.new credentials, params }
|
15
|
+
|
16
|
+
describe 'constructor' do
|
17
|
+
it 'assigns parameters to attributes' do
|
18
|
+
expect(subject.merchant_site).to eq 1234
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'does not assign unknow attributes' do
|
22
|
+
expect(subject.instance_variable_get(:@abra_kadabra)).to be_nil
|
23
|
+
expect { subject.abra_kadabra }.to raise_error NoMethodError
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'memoizes credentials internally' do
|
27
|
+
expect(subject.instance_variable_get(:@credentials)).to be_a QiwiPay::Credentials
|
28
|
+
expect { subject.secret }.to raise_error NoMethodError
|
29
|
+
end
|
30
|
+
|
31
|
+
if described_class.in_params.include? :order_expire
|
32
|
+
it 'converts time to string' do
|
33
|
+
expect(subject.order_expire).to start_with '2018-01-01T02:01:01'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# if amount parameter present
|
39
|
+
if described_class.in_params.include? :amount
|
40
|
+
it 'formats amount as currency' do
|
41
|
+
expect(subject.amount).to eq '100.13'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'requires https callback url' do
|
46
|
+
expect do
|
47
|
+
subject.callback_url = 'http://example.com/notify'
|
48
|
+
end.to raise_error ArgumentError
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#request_params' do
|
52
|
+
it 'returns hash with request parameters' do
|
53
|
+
params = subject.send(:request_params)
|
54
|
+
expect(params).to be_a Hash
|
55
|
+
params_not_in_list = params.keys - described_class.in_params
|
56
|
+
expect(params_not_in_list).to match_array %i[opcode sign]
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'calculates signature parameter' do
|
60
|
+
expect(subject.send(:request_params)[:sign]).to match /^[\dabcdef]+$/
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
RSpec.shared_examples "wpf_payment_operation" do
|
2
|
+
let(:params) do
|
3
|
+
{
|
4
|
+
merchant_site: 123,
|
5
|
+
merchant_uid: 321
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
subject { described_class.new credentials, params }
|
10
|
+
|
11
|
+
describe '#params' do
|
12
|
+
it 'returns hash of params for html form' do
|
13
|
+
res = subject.params
|
14
|
+
expect(res).to be_a Hash
|
15
|
+
expect(res[:method]).to eq :get
|
16
|
+
expect(res[:url]).to eq 'https://pay.qiwi.com/paypage/initial'
|
17
|
+
expect(res[:opcode]).to eq described_class.opcode.to_s
|
18
|
+
params.each do |k, v|
|
19
|
+
expect(res[k].to_s).to eq v.to_s
|
20
|
+
end
|
21
|
+
expect(res).to have_key :sign
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#url' do
|
26
|
+
it 'returns QiwiPay form url' do
|
27
|
+
url = subject.url
|
28
|
+
expect(url).to start_with 'https://pay.qiwi.com/paypage/initial?'
|
29
|
+
expect(url).to include "opcode=#{described_class.opcode}"
|
30
|
+
expect(url).to include 'merchant_site=123'
|
31
|
+
expect(url).to include 'merchant_uid=321'
|
32
|
+
expect(url).to include '&sign='
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'qiwi-pay'
|
2
|
+
require_relative 'support/external_requests'
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Enable flags like --only-failures and --next-failure
|
6
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
7
|
+
|
8
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
9
|
+
config.disable_monkey_patching!
|
10
|
+
|
11
|
+
config.expect_with :rspec do |c|
|
12
|
+
c.syntax = :expect
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def credentials
|
17
|
+
QiwiPay::Credentials.new secret: :secret,
|
18
|
+
cert: OpenSSL::X509::Certificate.new,
|
19
|
+
key: OpenSSL::PKey::RSA.new
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'webmock/rspec'
|
2
|
+
|
3
|
+
WebMock.disable_net_connect!(allow_localhost: true)
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.before(:each) do
|
7
|
+
mock_qiwi_pay_api_request
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def mock_qiwi_pay_api_request
|
12
|
+
WebMock.stub_request(:post, %r{\Ahttps://acquiring\.qiwi\.com.+})
|
13
|
+
.to_return(status: 200,
|
14
|
+
body: '{"txn_id":123, "txn_status":3, "txn_type":3,'\
|
15
|
+
'"txn_date": "2017-03-09T17:16:06+00:00",'\
|
16
|
+
'"error_code":0}')
|
17
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qiwi-pay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Klimenko
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -103,15 +103,12 @@ dependencies:
|
|
103
103
|
description: Provides support for payment operations using QiwiPay WPF and API services
|
104
104
|
email:
|
105
105
|
- mklimenko@onlinetours.ru
|
106
|
-
executables:
|
106
|
+
executables:
|
107
|
+
- console
|
108
|
+
- setup
|
107
109
|
extensions: []
|
108
110
|
extra_rdoc_files: []
|
109
111
|
files:
|
110
|
-
- ".gitignore"
|
111
|
-
- ".rspec"
|
112
|
-
- ".rubocop.yml"
|
113
|
-
- ".ruby-version"
|
114
|
-
- ".travis.yml"
|
115
112
|
- Gemfile
|
116
113
|
- Gemfile.lock
|
117
114
|
- LICENSE
|
@@ -136,7 +133,22 @@ files:
|
|
136
133
|
- lib/qiwi-pay/wpf/auth_operation.rb
|
137
134
|
- lib/qiwi-pay/wpf/payment_operation.rb
|
138
135
|
- lib/qiwi-pay/wpf/sale_operation.rb
|
139
|
-
- qiwi-pay.
|
136
|
+
- spec/qiwi-pay/api/capture_operation_spec.rb
|
137
|
+
- spec/qiwi-pay/api/refund_operation_spec.rb
|
138
|
+
- spec/qiwi-pay/api/response_spec.rb
|
139
|
+
- spec/qiwi-pay/api/reversal_operation_spec.rb
|
140
|
+
- spec/qiwi-pay/api/status_operation_spec.rb
|
141
|
+
- spec/qiwi-pay/cheque_spec.rb
|
142
|
+
- spec/qiwi-pay/confirmation_spec.rb
|
143
|
+
- spec/qiwi-pay/qiwi_pay_spec.rb
|
144
|
+
- spec/qiwi-pay/signature_spec.rb
|
145
|
+
- spec/qiwi-pay/wpf/auth_operation_spec.rb
|
146
|
+
- spec/qiwi-pay/wpf/sale_operation_spec.rb
|
147
|
+
- spec/shared/api_payment_operation.rb
|
148
|
+
- spec/shared/payment_operation.rb
|
149
|
+
- spec/shared/wpf_payment_operation.rb
|
150
|
+
- spec/spec_helper.rb
|
151
|
+
- spec/support/external_requests.rb
|
140
152
|
homepage: https://github.com/OnlinetoursGit/qiwi-pay
|
141
153
|
licenses:
|
142
154
|
- MIT
|
@@ -162,4 +174,20 @@ rubygems_version: 2.7.6
|
|
162
174
|
signing_key:
|
163
175
|
specification_version: 4
|
164
176
|
summary: QiwiPay WPF/API binding for Ruby
|
165
|
-
test_files:
|
177
|
+
test_files:
|
178
|
+
- spec/qiwi-pay/api/capture_operation_spec.rb
|
179
|
+
- spec/qiwi-pay/api/refund_operation_spec.rb
|
180
|
+
- spec/qiwi-pay/api/response_spec.rb
|
181
|
+
- spec/qiwi-pay/api/reversal_operation_spec.rb
|
182
|
+
- spec/qiwi-pay/api/status_operation_spec.rb
|
183
|
+
- spec/qiwi-pay/cheque_spec.rb
|
184
|
+
- spec/qiwi-pay/confirmation_spec.rb
|
185
|
+
- spec/qiwi-pay/qiwi_pay_spec.rb
|
186
|
+
- spec/qiwi-pay/signature_spec.rb
|
187
|
+
- spec/qiwi-pay/wpf/auth_operation_spec.rb
|
188
|
+
- spec/qiwi-pay/wpf/sale_operation_spec.rb
|
189
|
+
- spec/shared/api_payment_operation.rb
|
190
|
+
- spec/shared/payment_operation.rb
|
191
|
+
- spec/shared/wpf_payment_operation.rb
|
192
|
+
- spec/spec_helper.rb
|
193
|
+
- spec/support/external_requests.rb
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rubocop.yml
DELETED
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.3.5
|
data/.travis.yml
DELETED
data/qiwi-pay.gemspec
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'qiwi-pay/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = 'qiwi-pay'
|
8
|
-
spec.version = QiwiPay::VERSION
|
9
|
-
spec.authors = ['Michael Klimenko']
|
10
|
-
spec.email = ['mklimenko@onlinetours.ru']
|
11
|
-
|
12
|
-
spec.summary = 'QiwiPay WPF/API binding for Ruby'
|
13
|
-
spec.description = 'Provides support for payment operations using QiwiPay WPF and API services'
|
14
|
-
spec.homepage = 'https://github.com/OnlinetoursGit/qiwi-pay'
|
15
|
-
spec.license = 'MIT'
|
16
|
-
|
17
|
-
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
-
if spec.respond_to?(:metadata)
|
20
|
-
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
21
|
-
else
|
22
|
-
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
23
|
-
'public gem pushes.'
|
24
|
-
end
|
25
|
-
|
26
|
-
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
-
f.match(%r{^(test|spec|features)/})
|
28
|
-
end
|
29
|
-
spec.bindir = 'exe'
|
30
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
-
spec.require_paths = ['lib']
|
32
|
-
|
33
|
-
spec.add_dependency 'rest-client', ['>= 1.8.0', '< 2.1']
|
34
|
-
|
35
|
-
spec.add_development_dependency 'bundler', '~> 1.16'
|
36
|
-
spec.add_development_dependency 'luhn', '~> 1.0'
|
37
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
38
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
39
|
-
spec.add_development_dependency 'webmock', '~> 2'
|
40
|
-
end
|