qiwi-pay 0.1.0

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.
@@ -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