qiwi-pay 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "qiwi-pay"
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(__FILE__)
@@ -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,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QiwiPay
4
+ # Web Payment Form interface interaction implementation
5
+ # @see https://developer.qiwi.com/ru/qiwipay/index.html?php#qiwipay-wpf
6
+ module Wpf
7
+ # QiwiPay WPF host
8
+ ENDPOINT_HOST = 'pay.qiwi.com'
9
+
10
+ # QiwiPay WPF endpoint
11
+ ENDPOINT_PATH = '/paypage/initial'
12
+ end
13
+
14
+ # JSON API interaction implementation
15
+ # @see https://developer.qiwi.com/ru/qiwipay/index.html?json#section-6
16
+ module Api
17
+ # QiwiPay API host
18
+ ENDPOINT_HOST = 'acquiring.qiwi.com'
19
+
20
+ # QiwiPay API endpoint
21
+ ENDPOINT_PATH = '/merchant/direct'
22
+ end
23
+ end
24
+
25
+ require "qiwi-pay/version"
26
+ require "qiwi-pay/messages_for_codes"
27
+ require "qiwi-pay/payment_operation"
28
+ require "qiwi-pay/cheque"
29
+ require "qiwi-pay/credentials"
30
+ require "qiwi-pay/signature"
31
+ require "qiwi-pay/confirmation"
32
+
33
+ require "qiwi-pay/wpf/payment_operation"
34
+ require "qiwi-pay/wpf/sale_operation"
35
+ require "qiwi-pay/wpf/auth_operation"
36
+
37
+ require "qiwi-pay/api/payment_operation"
38
+ require "qiwi-pay/api/capture_operation"
39
+ require "qiwi-pay/api/refund_operation"
40
+ require "qiwi-pay/api/reversal_operation"
41
+ require "qiwi-pay/api/status_operation"
42
+ require "qiwi-pay/api/response"
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QiwiPay::Api
4
+ # Подтверждение авторизации в случае двухшагового сценария оплаты
5
+ #
6
+ # @note Параметры запроса
7
+ # merchant_site Обязательно integer Идентификатор сайта ТСП
8
+ # txn_id Обязательно integer Идентификатор транзакции
9
+ # cheque Опционально string Данные для кассового чека по 54-ФЗ
10
+ #
11
+ # @example Запрос
12
+ # {
13
+ # "opcode": 5,
14
+ # "merchant_site": 99,
15
+ # "txn_id": "172001",
16
+ # "sign": "bb5c48ea540035e6b7c03c8184f74f09d26e9286a9b8f34b236b1bf2587e4268"
17
+ # }
18
+ #
19
+ # @example Ответ
20
+ # {
21
+ # "txn_id":172001,
22
+ # "txn_status":3,
23
+ # "txn_type":2,
24
+ # "txn_date": "2017-03-09T17:16:06+00:00",
25
+ # "error_code":0
26
+ # }
27
+ class CaptureOperation < PaymentOperation
28
+ # Код операции sale
29
+ def self.opcode
30
+ 5
31
+ end
32
+
33
+ # Описание операции
34
+ def self.description
35
+ 'Подтверждение авторизации в случае двухшагового сценария оплаты'
36
+ end
37
+
38
+ private
39
+
40
+ def self.in_params
41
+ %i[merchant_site txn_id cheque].freeze
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest_client'
4
+
5
+ module QiwiPay::Api
6
+ # General QiwiPay API payment operation request
7
+ class PaymentOperation < QiwiPay::PaymentOperation
8
+ # @return [Response]
9
+ def perform
10
+ res = RestClient::Resource.new(
11
+ url,
12
+ ssl_client_cert: credentials.certificate,
13
+ ssl_client_key: credentials.key,
14
+ verify_ssl: OpenSSL::SSL::VERIFY_PEER
15
+ ).post(request_params.to_json)
16
+
17
+ Response.new res.code, res.body
18
+ end
19
+
20
+ private
21
+
22
+ def url
23
+ URI::HTTPS.build(
24
+ host: ENDPOINT_HOST,
25
+ path: ENDPOINT_PATH
26
+ ).to_s
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QiwiPay::Api
4
+ # Операция возврата платежа (средства возвращаются в течение 30 дней)
5
+ #
6
+ # @note Параметры запроса
7
+ # merchant_site Обязательно integer Идентификатор сайта ТСП
8
+ # txn_id Обязательно integer Идентификатор транзакции
9
+ # amount Опционально string(20) Сумма операции
10
+ # cheque Опционально string Данные для кассового чека по 54-ФЗ
11
+ #
12
+ # @example Запрос
13
+ # {
14
+ # "opcode":7,
15
+ # "merchant_site": 99,
16
+ # "txn_id": 181001,
17
+ # "amount": "700",
18
+ # "sign": "bb5c48ea540035e6b7c03c8184f74f09d26e9286a9b8f34b236b1bf2587e4268"
19
+ # }
20
+ #
21
+ # @example Ответ
22
+ # {
23
+ # "txn_id":182001,
24
+ # "txn_status":3,
25
+ # "txn_type":3,
26
+ # "txn_date": "2017-03-09T17:16:06+00:00",
27
+ # "error_code":0,
28
+ # "amount": 700
29
+ # }
30
+ class RefundOperation < PaymentOperation
31
+ # Код операции sale
32
+ def self.opcode
33
+ 7
34
+ end
35
+
36
+ # Описание операции
37
+ def self.description
38
+ 'Возврат платежа'
39
+ end
40
+
41
+ private
42
+
43
+ def self.in_params
44
+ %i[merchant_site txn_id amount cheque].freeze
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'ostruct'
5
+
6
+ module QiwiPay::Api
7
+ # QiwiPay API response
8
+ class Response < OpenStruct
9
+ include QiwiPay::MessagesForCodes
10
+
11
+ # Parameters of integer type
12
+ INTEGER_PARAMS = %w[
13
+ txn_id
14
+ txn_status
15
+ txn_type
16
+ error_code
17
+ currency
18
+ ]
19
+
20
+ # @param response_code [Integer] HTTP response status code
21
+ # @param response_body [String] Response body in JSON
22
+ def initialize(response_code, response_body)
23
+ params = JSON.parse(response_body)
24
+ (INTEGER_PARAMS & params.keys).each do |p|
25
+ params[p] = params[p] && params[p].to_i
26
+ end
27
+ super params
28
+ send(:http_code=, response_code)
29
+ end
30
+
31
+ def success?
32
+ http_code == 200 && error_code == 0
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QiwiPay::Api
4
+ # Операция отмены платежа (средства расхолдируются практически сразу)
5
+ #
6
+ # @note Параметры запроса
7
+ # merchant_site Обязательно integer Идентификатор сайта ТСП
8
+ # txn_id Обязательно integer Идентификатор транзакции
9
+ # amount Опционально string(20) Сумма операции
10
+ # cheque Опционально string Данные для кассового чека по 54-ФЗ
11
+ #
12
+ # @example Запрос
13
+ # {
14
+ # "opcode":6,
15
+ # "merchant_site": 99,
16
+ # "txn_id": 181001,
17
+ # "amount": "700",
18
+ # "sign": "bb5c48ea540035e6b7c03c8184f74f09d26e9286a9b8f34b236b1bf2587e4268"
19
+ # }
20
+ #
21
+ # @example Ответ
22
+ # {
23
+ # "txn_id":182001,
24
+ # "txn_status":3,
25
+ # "txn_type":4,
26
+ # "txn_date": "2017-03-09T17:16:06+00:00",
27
+ # "error_code":0,
28
+ # "amount": 700
29
+ # }
30
+ class ReversalOperation < PaymentOperation
31
+ # Код операции sale
32
+ def self.opcode
33
+ 6
34
+ end
35
+
36
+ # Описание операции
37
+ def self.description
38
+ 'Отмена платежа'
39
+ end
40
+
41
+ private
42
+
43
+ def self.in_params
44
+ %i[merchant_site txn_id amount cheque].freeze
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QiwiPay::Api
4
+ # Запрос статуса операции
5
+ #
6
+ # @note Параметры запроса
7
+ # merchant_site Обязательно integer Идентификатор сайта ТСП
8
+ # txn_id Опционально integer Идентификатор транзакции
9
+ # order_id Опционально string(256) Уникальный номер заказа в системе ТСП
10
+ #
11
+ # @example Запрос
12
+ # {
13
+ # "opcode":30,
14
+ # "merchant_site": 99,
15
+ # "order_id": "41324123412342",
16
+ # "sign": "bb5c48ea540035e6b7c03c8184f74f09d26e9286a9b8f34b236b1bf2587e4268"
17
+ # }
18
+ #
19
+ # @example Ответ
20
+ # {
21
+ # "transactions": [
22
+ # {
23
+ # "error_code": 0,
24
+ # "txn_id": 3666050,
25
+ # "txn_status": 2,
26
+ # "txn_type": 2,
27
+ # "txn_date": "2017-03-09T17:16:06+00:00",
28
+ # "pan": "400000******0002",
29
+ # "amount": 10000,
30
+ # "currency": 643,
31
+ # "auth_code": "181218",
32
+ # "merchant_site": 99,
33
+ # "card_name": "cardholder name",
34
+ # "card_bank": "",
35
+ # "order_id": "41324123412342"
36
+ # },
37
+ # {
38
+ # "error_code": 0,
39
+ # "txn_id": 3684050,
40
+ # "txn_status": 3,
41
+ # "txn_type": 4,
42
+ # "txn_date": "2017-03-09T17:16:09+00:00",
43
+ # "pan": "400000******0002",
44
+ # "amount": 100,
45
+ # "currency": 643,
46
+ # "merchant_site": 99,
47
+ # "card_name": "cardholder name",
48
+ # "card_bank": ""
49
+ # },
50
+ # {
51
+ # "error_code": 0,
52
+ # "txn_id": 3685050,
53
+ # "txn_status": 3,
54
+ # "txn_type": 4,
55
+ # "txn_date": "2017-03-19T17:16:06+00:00",
56
+ # "pan": "400000******0002",
57
+ # "amount": 100,
58
+ # "currency": 643,
59
+ # "merchant_site": 99,
60
+ # "card_name": "cardholder name",
61
+ # "card_bank": ""
62
+ # }
63
+ # ],
64
+ # "error_code": 0
65
+ # }
66
+ class StatusOperation < PaymentOperation
67
+ # Код операции sale
68
+ def self.opcode
69
+ 30
70
+ end
71
+
72
+ # Описание операции
73
+ def self.description
74
+ 'Запрос статуса операции'
75
+ end
76
+
77
+ private
78
+
79
+ def self.in_params
80
+ %i[merchant_site txn_id order_id].freeze
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+ require 'base64'
3
+ require 'zlib'
4
+ require 'json'
5
+
6
+ module QiwiPay
7
+ # Чек 54-ФЗ
8
+ class Cheque
9
+ # Возможные значения НДС
10
+ module VAT
11
+ # не облагается НДС
12
+ NONE = 6
13
+ # облагается НДС по ставке 0%
14
+ VAT_0 = 5
15
+ # облагается НДС по ставке 10%
16
+ VAT_10 = 2
17
+ # облагается НДС по ставке 18%
18
+ VAT_18 = 1
19
+ # облагается НДС по ставке 10/110
20
+ VAT_110 = 4
21
+ # облагается НДС по ставке 18/118
22
+ VAT_118 = 3
23
+ end
24
+
25
+ # Возможные значения системы налогообложения
26
+ module TaxMode
27
+ # 0 — Общая система налогообложения
28
+ OSN = 0
29
+ # 1 — Упрощенная система налогообложения (Доход)
30
+ USN_D = 1
31
+ # 2 — Упрощенная СН (Доход минус Расход)
32
+ USN_DR = 2
33
+ # 3 — Единый налог на вмененный доход
34
+ ENVD = 3
35
+ # 4 — Единый сельскохозяйственный налог
36
+ ESHD = 4
37
+ # 5 — Патентная система налогообложения
38
+ PSN = 5
39
+ end
40
+
41
+ # Возможные значения типов чеков
42
+ module Type
43
+ # Приход
44
+ INFLOW = 1
45
+ # Возврат прихода
46
+ INFLOW_REVERSE = 2
47
+ # Расход
48
+ OUTFLOW = 3
49
+ # Возврат расхода
50
+ OUTFLOW_REVERSE = 4
51
+ end
52
+
53
+ # @option params seller_id [Integer] ИНН организации, для которой пробивается чек
54
+ # @option params cheque_type [Integer] Признак расчета (тэг 1054):
55
+ # 1. Приход
56
+ # 2. Возврат прихода
57
+ # 3. Расход
58
+ # 4. Возврат расхода
59
+ # @option params customer_contact [String] Телефон или электронный адрес покупателя (тэг 1008)
60
+ # @option params tax_system [Integer] Система налогообложения (тэг 1055):
61
+ # 0 – Общая, ОСН
62
+ # 1 – Упрощенная доход, УСН доход
63
+ # 2 – Упрощенная доход минус расход, УСН доход - расход
64
+ # 3 – Единый налог на вмененный доход, ЕНВД
65
+ # 4 – Единый сельскохозяйственный налог, ЕСН
66
+ # 5 – Патентная система налогообложения, Патент
67
+ # @option params positions [Array<Hash>] Массив товаров
68
+ def initialize(params)
69
+ @json = JSON.fast_generate params
70
+ end
71
+
72
+ # @return [String] cheque as JSON
73
+ # @example
74
+ # {
75
+ # "seller_id" : 3123011520,
76
+ # "cheque_type" : 1,
77
+ # "customer_contact" : "foo@domain.tld",
78
+ # "tax_system" : 1,
79
+ # "positions" : [
80
+ # {
81
+ # "quantity" : 2,
82
+ # "price" : 322.94,
83
+ # "tax" : 4,
84
+ # "description" : "Товар/Услуга 1"
85
+ # },
86
+ # {
87
+ # "quantity" : 1,
88
+ # "price" : 500,
89
+ # "tax" : 4,
90
+ # "description" : "Товар/Услуга 2"
91
+ # }
92
+ # ]
93
+ # }
94
+ def to_json
95
+ @json
96
+ end
97
+
98
+ # @return [String] Encoded cheque
99
+ def encode
100
+ Base64.strict_encode64(Zlib::Deflate.deflate(to_json))
101
+ end
102
+ end
103
+ end