t2_airtime 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +83 -0
- data/Rakefile +6 -0
- data/lib/t2_airtime/api.rb +290 -0
- data/lib/t2_airtime/base.rb +26 -0
- data/lib/t2_airtime/errors.rb +89 -0
- data/lib/t2_airtime/reply.rb +58 -0
- data/lib/t2_airtime/request.rb +73 -0
- data/lib/t2_airtime/rest.rb +67 -0
- data/lib/t2_airtime/test.rb +21 -0
- data/lib/t2_airtime/url.rb +6 -0
- data/lib/t2_airtime/version.rb +3 -0
- data/lib/t2_airtime.rb +16 -0
- data/t2_airtime.gemspec +31 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c6e8d1b5cfa93a9f398cc58bd1089bfc128a0dd0
|
4
|
+
data.tar.gz: e75396f390b165e992e87e37d75557fb82a7c427
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ae9a53249041d93c36146080f8cefa03052c5d90b32afe117d097f0333b68c835672a0aad09aefe1bdf0a61204a328371c52331a6bb1eb1010569aee16c2ff1d
|
7
|
+
data.tar.gz: 764234e7bfbfd290da1effb363c223ad7c21193df6e30c10ed5c200b674db654324ea18d2d2505cbf2e66adb5cf0032b9a3c0c50abc1e7b8ff010d82d8b40f99
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at TODO: Write your email address. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 matteolc
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# TransferTo Airtime API
|
2
|
+
|
3
|
+
TransferTo helps businesses offer airtime top-ups, goods and services, and mobile money around the world in real time.
|
4
|
+
This API enables developers to integrate TransferTo Top-up service into their system. If you are building
|
5
|
+
application that leverages international recharge services, then this is the API for you.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 't2_airtime'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install t2_airtime
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
### Retrieve your API Token
|
26
|
+
Once you have received your account credentials (login, password) to access the TransferTo web
|
27
|
+
interface, you must log in and retrieve your API token to be used with the TransferTo API.
|
28
|
+
To activate access to your API account, enable Two Factor Authentication (2FA).
|
29
|
+
|
30
|
+
TSHOP_USER=
|
31
|
+
TSHOP_SECRET=
|
32
|
+
|
33
|
+
## Test
|
34
|
+
|
35
|
+
Execute:
|
36
|
+
|
37
|
+
$ rspec
|
38
|
+
|
39
|
+
T2Airtime
|
40
|
+
has a version number
|
41
|
+
has the correct API URL
|
42
|
+
has 7 test numbers
|
43
|
+
responds to ping
|
44
|
+
checks wallet
|
45
|
+
checks number information
|
46
|
+
reserves a transaction id
|
47
|
+
returns a countries list
|
48
|
+
returns a country operators
|
49
|
+
returns an operator products
|
50
|
+
returns error code 0 for PIN based Top-up (successful transaction)
|
51
|
+
returns error code 0 for PIN less Top-up (successful transaction)
|
52
|
+
returns error code 204 (destination number is not a valid prepaid phone number) (FAILED - 1)
|
53
|
+
returns error code 301 (input value out of range or invalid product) (FAILED - 2)
|
54
|
+
returns error code 214 (transaction refused by the operator) (FAILED - 3)
|
55
|
+
returns error code 998 (system not available, please retry later) (FAILED - 4)
|
56
|
+
returns error code 999 (unknown error, please contact support) (FAILED - 5)
|
57
|
+
returns a transaction list
|
58
|
+
|
59
|
+
Failed examples:
|
60
|
+
|
61
|
+
rspec ./spec/t2_airtime_spec.rb:99 # T2Airtime returns error code 204 (destination number is not a valid prepaid phone number)
|
62
|
+
rspec ./spec/t2_airtime_spec.rb:108 # T2Airtime returns error code 301 (input value out of range or invalid product)
|
63
|
+
rspec ./spec/t2_airtime_spec.rb:117 # T2Airtime returns error code 214 (transaction refused by the operator)
|
64
|
+
rspec ./spec/t2_airtime_spec.rb:126 # T2Airtime returns error code 998 (system not available, please retry later)
|
65
|
+
rspec ./spec/t2_airtime_spec.rb:135 # T2Airtime returns error code 999 (unknown error, please contact support)
|
66
|
+
|
67
|
+
## Development
|
68
|
+
|
69
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
70
|
+
|
71
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
72
|
+
|
73
|
+
## Contributing
|
74
|
+
|
75
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/t2_airtime. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
76
|
+
|
77
|
+
## License
|
78
|
+
|
79
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
80
|
+
|
81
|
+
## Code of Conduct
|
82
|
+
|
83
|
+
Everyone interacting in the T2Airtime project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/t2_airtime/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,290 @@
|
|
1
|
+
module T2Airtime
|
2
|
+
class API < Base
|
3
|
+
|
4
|
+
# Test the connection to the Airtime API. Can be used for keep-alive.
|
5
|
+
def ping
|
6
|
+
run_action :ping
|
7
|
+
end
|
8
|
+
|
9
|
+
# Returns the balance in your TransferTo account.
|
10
|
+
# This method shall not be used more than 24 times per day.
|
11
|
+
def check_wallet
|
12
|
+
run_action :check_wallet
|
13
|
+
end
|
14
|
+
|
15
|
+
# This method is used to recharge a destination number with a specified
|
16
|
+
# denomination (“product” field).
|
17
|
+
# This is the API’s most important action as it is required when sending
|
18
|
+
# a topup to a prepaid account phone numberin a live! environment.
|
19
|
+
#
|
20
|
+
# parameters
|
21
|
+
# ==========
|
22
|
+
# msisdn
|
23
|
+
# ------
|
24
|
+
# The international phone number of the user requesting to credit
|
25
|
+
# a TransferToAPI phone number. The format must contain the country code,
|
26
|
+
# and will be valid with or without the ‘+’ or ‘00’ placed before it. For
|
27
|
+
# example: “6012345678” or “+6012345678” or “006012345678” (Malaysia) are
|
28
|
+
# all valid.
|
29
|
+
#
|
30
|
+
# product
|
31
|
+
# -------
|
32
|
+
# This field is used to define the remote product(often, the same as the
|
33
|
+
# amount in destination currency) to use in the request.
|
34
|
+
#
|
35
|
+
# destination
|
36
|
+
# -----------
|
37
|
+
# This is the destination phone number that will be credited with the
|
38
|
+
# amount transferred. Format is similar to “msisdn”.
|
39
|
+
#
|
40
|
+
# operator_id
|
41
|
+
# -----------
|
42
|
+
# It defines the operator id of the destination MSISDN that must be used
|
43
|
+
# when treating the request. If set, the platform will be forced to use
|
44
|
+
# this operatorID and will not identify the operator of the destination
|
45
|
+
# MSISDN based on the numbering plan. It must be very useful in case of
|
46
|
+
# countries with number portability if you are able to know the destination
|
47
|
+
# operator.
|
48
|
+
|
49
|
+
# Most receiving operators (or carriers) are PIN less (direct top-up), meaning that the mobile phone of the
|
50
|
+
# recipient is recharged in real time. A few operators are however PIN based (mostly in the USA and UK).
|
51
|
+
# For these PIN based operators, a PIN code is sent by SMS to the recipient, who then has to manually
|
52
|
+
# complete the recharge process (usually by calling an IVR to redeem the PIN).
|
53
|
+
|
54
|
+
# Name Type Description
|
55
|
+
# pin_based String Returns “Yes” if PIN-based transactions. Else “No”.
|
56
|
+
# pin_option_1 String Additional information. For example, it can describe how to use
|
57
|
+
# the PIN directly from handset (by entering a dedicated USSD code).
|
58
|
+
# pin_option_2 String Additional information. For example, it can provide the operator refill website.
|
59
|
+
# pin_option_3 String Additional information. For example, it can provide the operator refill call center.
|
60
|
+
# pin_value Integer Value of the PIN.
|
61
|
+
# pin_code Alphanumeric String Code of the PIN.
|
62
|
+
# pin_ivr Integer IVR number of the PIN.
|
63
|
+
# pin_serial Alphanumeric String Serial number of the PIN.
|
64
|
+
# pin_validity String Validity of the PIN
|
65
|
+
|
66
|
+
# By default, an SMS notification is sent to the recipient after every successful Top-up.
|
67
|
+
# The default originating address for the SMS is “8888”.
|
68
|
+
# The following is the default SMS which is translated into local languages for most of recipient countries:
|
69
|
+
# Congratulations! You've received
|
70
|
+
# AMOUNT_CURRENCY from SENDER. Thank you for using
|
71
|
+
# TransferTo. FREE_TEXT.
|
72
|
+
# • AMOUNT CURRENCY is the amount that has
|
73
|
+
# been sent with the currency.
|
74
|
+
# • SENDER can be a name or a phone number.
|
75
|
+
# • FREE_TEXT is the content of the field named
|
76
|
+
# “sms” of the topup method.
|
77
|
+
|
78
|
+
def topup(msisdn, destination_msisdn, product, method='topup',
|
79
|
+
reserved_id=nil, send_sms=true, sms=nil, sender_text=nil, operator_id=nil,
|
80
|
+
return_service_fee=1, delivered_amount_info=1, return_timestamp=1, return_version=1,
|
81
|
+
return_promo=0)
|
82
|
+
|
83
|
+
@params = {
|
84
|
+
msisdn: msisdn,
|
85
|
+
destination_msisdn: destination_msisdn,
|
86
|
+
product: product
|
87
|
+
}
|
88
|
+
self.oid = operator_id
|
89
|
+
|
90
|
+
@params.merge({
|
91
|
+
cid1: "", cid2: "", cid3: "",
|
92
|
+
reserved_id: reserved_id,
|
93
|
+
sender_sms: (sender_text ? "yes" : "no"),
|
94
|
+
send_sms: (send_sms ? "yes" : "no"),
|
95
|
+
sms: sms,
|
96
|
+
sender_text: sender_text,
|
97
|
+
delivered_amount_info: delivered_amount_info,
|
98
|
+
return_service_fee: return_service_fee,
|
99
|
+
return_timestamp: return_timestamp,
|
100
|
+
return_version: return_version,
|
101
|
+
return_promo: return_promo
|
102
|
+
})
|
103
|
+
|
104
|
+
run_action method
|
105
|
+
#{
|
106
|
+
# requesting_msisdn: response[:msisdn],
|
107
|
+
# destination_msisdn: response[:destination_msisdn],
|
108
|
+
# product_sent: response[:actual_product_sent].to_i,
|
109
|
+
# local_amount: response[:local_info_amount],
|
110
|
+
# local_value: response[:local_info_value],
|
111
|
+
# local_currency_code: response[:local_info_currency],
|
112
|
+
# transaction_status: response[:error_txt],
|
113
|
+
# operation_result: response[:error_code],
|
114
|
+
# operation_info: response[:info_txt],
|
115
|
+
# transaction_api_id: response[:transactionid].to_i,
|
116
|
+
# country_api_id: response[:countryid].to_i,
|
117
|
+
# operator_api_id: response[:operatorid].to_i,
|
118
|
+
# product_api_id: response[:product_requested].to_i,
|
119
|
+
# originator_currency_code: response[:originating_currency],
|
120
|
+
# destination_currency_code: response[:destination_currency],
|
121
|
+
# wholesale_price: response[:wholesale_price],
|
122
|
+
# retail_price: response[:retail_price],
|
123
|
+
# service_fee: response[:service_fee]
|
124
|
+
#}
|
125
|
+
end
|
126
|
+
|
127
|
+
# This method is used to retrieve various information of a specific MSISDN
|
128
|
+
# (operator, country…) as well as the list of all products configured for
|
129
|
+
# your specific account and the destination operator of the MSISDN.
|
130
|
+
# Returns relevant information on a MSISDN (operator, country…) as well as the
|
131
|
+
# list of products configured for your account and the destination operator
|
132
|
+
# linked to that MSISDN. Allows to check if a MSISDN is subjected to a promotion
|
133
|
+
#
|
134
|
+
# destination_msisdn
|
135
|
+
# Destination MSISDN (usually recipient phone number). This is the destination phone number that will
|
136
|
+
# be credited with the amount transferred. Format is similar to “msisdn” and restricted to international phone number only.
|
137
|
+
# delivered_amount_info
|
138
|
+
# Setting this to “1” will return the fields local_info_amount_list,local_info_currency and local_info_value_list in the API response.
|
139
|
+
# Blank or “no” if you do not want this returned.
|
140
|
+
# return_service_fee
|
141
|
+
# Setting this to “1” will return the field service_fee_list in the API response. Blank or “0” if you do not want it returned.
|
142
|
+
# operatorid
|
143
|
+
# Operator ID of the receiving operator that must be used when treating the request. If
|
144
|
+
# set, the platform will be forced to use this operator ID and will not identify the operator of
|
145
|
+
# the destination MSISDN based on the numbering plan. It is very useful in case of countries with number
|
146
|
+
# portability if you are able to know the destination operator.
|
147
|
+
# return_promo
|
148
|
+
# Setting this to “1” will return the current promotion related to the transaction’s operator.
|
149
|
+
def msisdn_info(destination_msisdn, operator_id=nil,
|
150
|
+
delivered_amount_info=1, return_service_fee=1, return_promo=1)
|
151
|
+
@params = {
|
152
|
+
destination_msisdn: destination_msisdn,
|
153
|
+
delivered_amount_info: delivered_amount_info,
|
154
|
+
return_service_fee: return_service_fee,
|
155
|
+
return_promo: return_promo
|
156
|
+
}
|
157
|
+
self.oid = operator_id
|
158
|
+
run_action :msisdn_info
|
159
|
+
end
|
160
|
+
|
161
|
+
# Get information about a phone number
|
162
|
+
def phone_search(number, operator_id=nil)
|
163
|
+
information = msisdn_info(number, operator_id).information
|
164
|
+
information[:product_list] = information[:product_list].split(",")
|
165
|
+
information
|
166
|
+
end
|
167
|
+
|
168
|
+
# This method is used to reserve an ID in the system. This ID can then be
|
169
|
+
# used in the “topup” or “simulation” requests.
|
170
|
+
# This way, your system knows the ID of the transaction before sending the
|
171
|
+
# request to TransferTo (else it will only be displayed in the response).
|
172
|
+
def reserve_id
|
173
|
+
run_action :reserve_id
|
174
|
+
end
|
175
|
+
|
176
|
+
# This method is used to retrieve the list of transactions performed within
|
177
|
+
# the date range by the MSISDN if set. Note that both dates are included
|
178
|
+
# during the search.
|
179
|
+
#
|
180
|
+
# parameters
|
181
|
+
# ==========
|
182
|
+
# msisdn
|
183
|
+
# ------
|
184
|
+
# The format must be international with or without the ‘+’ or ‘00’:
|
185
|
+
# “6012345678” or “+6012345678” or “006012345678” (Malaysia)
|
186
|
+
#
|
187
|
+
# destination_msisdn
|
188
|
+
# ------------------
|
189
|
+
# The format must be international with or without the ‘+’ or ‘00’:
|
190
|
+
# “6012345678” or “+6012345678” or “006012345678” (Malaysia)
|
191
|
+
#
|
192
|
+
# code
|
193
|
+
# ----
|
194
|
+
# The error_code of the transactions to search for. E.g “0” to search for
|
195
|
+
# only all successful transactions. If left empty, all transactions will be
|
196
|
+
# returned(Failed and successful).
|
197
|
+
#
|
198
|
+
# start_date
|
199
|
+
# ----------
|
200
|
+
# Defines the start date of the search. Format must be YYYY-MM-DD.
|
201
|
+
#
|
202
|
+
# stop_date
|
203
|
+
# ---------
|
204
|
+
# Defines the end date of the search (included). Format must be YYYY-MM-DD.
|
205
|
+
def trans_list(start, stop, msisdn = nil, destination = nil, code = nil)
|
206
|
+
@params[:code] = code unless code
|
207
|
+
@params[:msisdn] = msisdn unless msisdn
|
208
|
+
@params[:stop_date] = to_yyyymmdd(stop)
|
209
|
+
@params[:start_date] = to_yyyymmdd(start)
|
210
|
+
@params[:destination_msisdn] = destination unless destination
|
211
|
+
run_action :trans_list
|
212
|
+
end
|
213
|
+
|
214
|
+
# Retrieve available information on a specific transaction. Please note that values of “input_value” and
|
215
|
+
# “debit_amount_validated” are rounded to 2 digits after the comma but are
|
216
|
+
# the same as the values returned in the fields “input_value” and
|
217
|
+
# “validated_input_value” of the “topup” method response.
|
218
|
+
def trans_info(id)
|
219
|
+
@params = { transactionid: id }
|
220
|
+
run_action :trans_info
|
221
|
+
end
|
222
|
+
|
223
|
+
# This method is used to retrieve the ID of a transaction previously
|
224
|
+
# performed based on the key used in the request at that time.
|
225
|
+
def get_id_from_key(key)
|
226
|
+
@params = { from_key: key }
|
227
|
+
run_action :get_id_from_key
|
228
|
+
end
|
229
|
+
|
230
|
+
# These methods are used to retrieve coverage and pricelist offered to you.
|
231
|
+
# parameters
|
232
|
+
# ==========
|
233
|
+
# info_type
|
234
|
+
# ---------
|
235
|
+
# i) “countries”: Returns a list of all countries offered to you
|
236
|
+
# ii) “country” : Returns a list of operators in the country
|
237
|
+
# iii) “operator” : Returns a list of wholesale and retail price for the operator
|
238
|
+
#
|
239
|
+
# content
|
240
|
+
# -------
|
241
|
+
# i) Not used if info_type = “countries”
|
242
|
+
# ii) countryid of the requested country if info_type = “country”
|
243
|
+
# iii) operatorid of the requested operator if info_type = “operator”
|
244
|
+
|
245
|
+
def price_list(info_type, content=nil)
|
246
|
+
@params[:info_type] = info_type
|
247
|
+
content && @params[:content] = content
|
248
|
+
run_action :pricelist
|
249
|
+
end
|
250
|
+
|
251
|
+
def country_list
|
252
|
+
price_list('countries')
|
253
|
+
end
|
254
|
+
|
255
|
+
def operator_list(country_api_id)
|
256
|
+
price_list('country', country_api_id)
|
257
|
+
end
|
258
|
+
|
259
|
+
def product_list(operator_api_id)
|
260
|
+
price_list('operator', operator_api_id)
|
261
|
+
end
|
262
|
+
|
263
|
+
# Operator Logo URL
|
264
|
+
def operator_logo_url(operator_id, size=1)
|
265
|
+
"#{T2Airtime::PROTOCOL}://#{T2Airtime::OPLOGO_DN}.#{T2Airtime::DOMAIN}/logo-#{operator_id}-#{size}.png"
|
266
|
+
end
|
267
|
+
|
268
|
+
private
|
269
|
+
|
270
|
+
def oid=(operator_id)
|
271
|
+
@params[:operatorid] = operator_id.to_i if operator_id.is_a?(Integer)
|
272
|
+
end
|
273
|
+
|
274
|
+
def to_time(time)
|
275
|
+
case time.class.name
|
276
|
+
when "String" then return Time.parse(time)
|
277
|
+
when "Integer" then return Time.at(time)
|
278
|
+
when "Time" then return time
|
279
|
+
else raise ArgumentError
|
280
|
+
end
|
281
|
+
rescue
|
282
|
+
Time.now
|
283
|
+
end
|
284
|
+
|
285
|
+
def to_yyyymmdd(time)
|
286
|
+
to_time(time).strftime("%Y-%m-%d")
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
290
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module T2Airtime
|
2
|
+
class Base
|
3
|
+
|
4
|
+
def initialize(user, password, url)
|
5
|
+
@user, @password, @url, @params = user, password, url, {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.api
|
9
|
+
@api ||= new(
|
10
|
+
ENV['T2_SHOP_USER'],
|
11
|
+
ENV['T2_AIRTIME_KEY'],
|
12
|
+
"https://#{T2Airtime::AIRTIME_DN}.#{T2Airtime::DOMAIN}/#{T2Airtime::ENDPOINT}"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def run_action(name, method=:get)
|
17
|
+
request = T2Airtime::Request.new(@user, @password, @url, name, @params)
|
18
|
+
request.run(method).on_complete do |reply|
|
19
|
+
reply = T2Airtime::Reply.new(reply)
|
20
|
+
#raise ::T2Airtime::Error.new @reply.error_code, @reply.error_message unless @reply.success?
|
21
|
+
return reply.data
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module T2Airtime
|
2
|
+
# 0 Transaction successful Indicates the Top-up was successfully delivered to the recipient.
|
3
|
+
# 101 Destination MSISDN out of range Numbering plan not recognized: the destination/recipient number was not identified as to belonging to any operators covered by TransferTo. Re-check recipient number and/or escalate the case to the TransferTo Support Team for further investigation.
|
4
|
+
# 104 MSISDN in blacklist Here MSISDN refers to both sender and recipient phone numbers which are blacklisted due to fraudulent activities.
|
5
|
+
# 105 Not enough credit on your account Transaction failed due to insufficient funds in your account's prepaid balance. Please reload balance and try again.
|
6
|
+
# 200 Transaction canceled by Customer
|
7
|
+
# 202 Transaction canceled by TransferTo
|
8
|
+
# 203 Transaction incomplete Transaction failed due to a technical issue. Please contact TransferTo Support Team for further investigation.
|
9
|
+
# 204 Destination Account is not prepaid or not valid Transaction refused by the operator because the recipient phone number is not a valid prepaid account.
|
10
|
+
# 207 Transaction amount limit exceeded Here limit refers to maximum amount defined for the destination MSISDN. There are some limitations set on the operator's side, not controlled by TransferTo. When one of these limits is reached, error code 207 will be returned. Some examples:
|
11
|
+
# • Indosat Indonesia operator's end, the customer must wait at least 5 mins before sending another transfer to the same recipient account.
|
12
|
+
# • Indian operators' end, the customer must wait 3 mins before sending another transfer of the same amount to the same recipient account.
|
13
|
+
# • Orange Africa, the recipient account is limited to a maximum rechargeable amount of 30 Euros per week and 60 Euros per month.
|
14
|
+
# 213 Duplicated transaction Transaction refused because it was submitted too closely after a preceding Top-up attempt.
|
15
|
+
# 214 Topup refused Transaction refused by the operator for a reason that was not specified. Common reasons for these types of failures are: Recipient number not valid for recharge. Service outage temporarily faced on the operator. Please try again at a later time and/or contact the TransferTo Support Team if the problem persists.
|
16
|
+
# 215 Service to this destination operator is Transaction failed due to an outage and/or connection issue with the operator. Please try again at a later time and/or contact the TransferTo Support Team if the problem persists.
|
17
|
+
# temporarily unavailable
|
18
|
+
# 216 Destination number not activated Transaction refused by the operator because the recipient number has not been activated.
|
19
|
+
# 217 Destination number expired Transaction refused by the operator because the recipient number is no longer an active account.
|
20
|
+
# 218 Request timeout Transaction timed-out and failed because of the long processing duration. Please try again at a later time and/or contact the TransferTo Support Team if the problem persists.
|
21
|
+
# 219 Key does not exist Request failed because the key provided does not exist (error returned for get_id_from_key method requests only).
|
22
|
+
# 221 Fraud suspicion Transaction refused and the recipient number flagged for suspicion of fraud, due to the number of consecutive Top-up requests within a short gap of time. The recipient phone number will be locked out from receiving any Top-up for a certain period of time, after which, the restriction will be automatically released.
|
23
|
+
# 222 Number barred from refill This error code is returned when the recipient has been blocked from refill directly by the recipient's operator. It prevents TransferTo system from reloading his account. Recipient must call the operator’s customer service to unblock it.
|
24
|
+
# 223 ID not reserved Transaction failed because the transaction ID specified in the request was not previously reserved.
|
25
|
+
# 224 Invalid length of destination MSISDN Transaction failed because the recipient number length does not match (shorter or longer) the mobile number format of the country.
|
26
|
+
# 230 Recipient reached maximum topup number This error is returned when a recipient reaches the maximum number of Top-up allowable in a certain gap of time.
|
27
|
+
# • 01 Day(s) => 10
|
28
|
+
# • 07 Day(s) => 15
|
29
|
+
# • 30 Day(s) => 40
|
30
|
+
# 231 Recipient reached maximum topup amount This error is returned when a recipient reaches the maximum amount (in USD) of Top-up allowable in a certain gap of time.
|
31
|
+
# • 01 Day(s) => max 100 USD
|
32
|
+
# • 07 Day(s) => max 150 USD
|
33
|
+
# • 30 Day(s) => max 200 USD
|
34
|
+
# 232 Account reached maximum topup number This error is returned when your account has reached its maximum number of Top-up allowable in a certain gap of time.
|
35
|
+
# 233 Account reached maximum topup amount This error is returned when your account has reached its maximum amount (in USD) of Top-up allowable in a certain gap of time.
|
36
|
+
# 241 Account reached maximum daily topup amount This error is returned when your account has reached its maximum amount (in USD) of Top-up allowable within a day.
|
37
|
+
# 242 Account reached maximum daily topup number This error is returned when your account has reached its maximum number of Top-up allowable within a day.
|
38
|
+
# 243 Account reached maximum weekly topup amount This error is returned when your account has reached its maximum amount (in USD) of Top-up allowable within a week.
|
39
|
+
# 244 Account reached maximum weekly topup number This error is returned when your account has reached its maximum number of Top-up allowable within a week.
|
40
|
+
# 245 Account reached maximum monthly topup amount This error is returned when your account has reached its maximum amount (in USD) of Top-up allowable within a month.
|
41
|
+
# 246 Account reached maximum monthly topup number This error is returned when your account has reached its maximum number of Top-up allowable within a month.
|
42
|
+
# 251 Sender reached maximum daily topup amount This error is returned when the sender has reached its maximum amount (in USD) of Top-up allowable within a day.
|
43
|
+
# 252 Sender reached maximum daily topup number This error is returned when the sender has reached its maximum number of Top-up allowable within a day.
|
44
|
+
# 253 Sender reached maximum weekly topup amount This error is returned when the sender has reached its maximum amount (in USD) of Top-up allowable within a week.
|
45
|
+
# 254 Sender reached maximum weekly topup number This error is returned when the sender has reached its maximum number of Top-up allowable within a week.
|
46
|
+
# 255 Sender reached maximum monthly topup amount This error is returned when the sender has reached its maximum amount (in USD) of Top-up allowable within a month.
|
47
|
+
# 256 Sender reached maximum monthly topup number This error is returned when the sender has reached its maximum number of Top-up allowable within a day month.
|
48
|
+
# 301 Denomination not available Denomination not available for this destination.
|
49
|
+
# 310 Denomination blocked Transaction failed because the Top-up is no longer available on the operator's offer or on the account.
|
50
|
+
# 320 Requested amount out of range Transaction failed because the Top-amount request was not within the range of valid amounts.
|
51
|
+
# 321 Requested currency not allowed for this account Transaction failed because the currency specified is not valid for the account.
|
52
|
+
# 401 Transaction ID not found or was not made No transaction was found with the ID specified (error returned for trans_info method requests only).
|
53
|
+
# by your account
|
54
|
+
# 777 Insufficient balance in your master account Transaction failed because there are not enough funds in your master account.
|
55
|
+
# 888 Insufficient balance in your subaccount Transaction failed because there are not enough funds in your sub-account.
|
56
|
+
# 900 Not enough information to process the topup Transaction failed because some of the required fields in your Top-up request are missing/empty.
|
57
|
+
# 901 Invalid action Transaction failed because the action specified in <action> field of the request is not valid.
|
58
|
+
# 902 Invalid input_currency
|
59
|
+
# 903 Invalid output_currency
|
60
|
+
# 904 Invalid input_value
|
61
|
+
# 905 Invalid start_date
|
62
|
+
# 906 Invalid stop_date
|
63
|
+
# 907 Invalid transaction ID Transaction ID specified in the <reserved_id> of the Top-up request is not valid.
|
64
|
+
# 908 Account not configured for this service Transaction failed because the account is not configured to carry out the requested action.
|
65
|
+
# 909 Invalid flag Transaction failed because the request included an invalid field/parameter.
|
66
|
+
# 919 All required argument not received Transaction failed because the request is missing a mandatory field/parameter.
|
67
|
+
# 921 Wrong MD5 encoding Transaction failed because the MD5 hash was not correct. Typically indicates that the password is incorrect.
|
68
|
+
# 922 Originating IP not allowed Transaction failed because the request originated from an IP that is not whitelisted for the account.
|
69
|
+
# 923 Key already used or invalid key value Transaction failed because the key value included in the request was not unique and greater than the previous key used.
|
70
|
+
# 926 Account not active Please contact your Account Manager.
|
71
|
+
# 995 Account not found Please enter and use a correct login.
|
72
|
+
# 998 System not available. Please retry later. Transaction failed due to technical issues. Please contact TransferTo Support Team for further investigation.
|
73
|
+
# 999 Unknown error To be escalated to the TransferTo Support Team for further investigation.
|
74
|
+
|
75
|
+
|
76
|
+
class Error < StandardError
|
77
|
+
|
78
|
+
attr_reader :code
|
79
|
+
|
80
|
+
def initialize(code, message=nil)
|
81
|
+
@code = code.to_i
|
82
|
+
super(message)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
class ConfigurationError < StandardError; end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module T2Airtime
|
2
|
+
class Reply
|
3
|
+
|
4
|
+
def initialize(reply)
|
5
|
+
@response = reply.to_hash
|
6
|
+
end
|
7
|
+
|
8
|
+
def data
|
9
|
+
hash = {}
|
10
|
+
@response[:body].lines.each do |line|
|
11
|
+
key, value = line.strip.split "="
|
12
|
+
hash[key.to_sym] = (key == "error_code") ? value.to_i : value
|
13
|
+
end; hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def status
|
17
|
+
@response[:status]
|
18
|
+
end
|
19
|
+
|
20
|
+
def error_code
|
21
|
+
data[:error_code]
|
22
|
+
end
|
23
|
+
|
24
|
+
def error_message
|
25
|
+
data[:error_txt]
|
26
|
+
end
|
27
|
+
|
28
|
+
def success?
|
29
|
+
status == 200 && error_code == 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def url
|
33
|
+
@response[:url].to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def information
|
37
|
+
data.reject do |key, value|
|
38
|
+
[:authentication_key, :error_code, :error_txt].include?(key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def message
|
43
|
+
information[:info_txt]
|
44
|
+
end
|
45
|
+
|
46
|
+
def auth_key
|
47
|
+
data[:authentication_key]
|
48
|
+
end
|
49
|
+
|
50
|
+
def headers
|
51
|
+
@response[:response_headers]
|
52
|
+
end
|
53
|
+
|
54
|
+
def raw
|
55
|
+
@response[:body]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module T2Airtime
|
2
|
+
class Request
|
3
|
+
|
4
|
+
def initialize(user, password, url, name, params)
|
5
|
+
@user = user
|
6
|
+
@pass = password
|
7
|
+
@conn = Faraday.new(url: url) do |faraday|
|
8
|
+
faraday.request :url_encoded
|
9
|
+
faraday.adapter :net_http
|
10
|
+
end
|
11
|
+
reset
|
12
|
+
@name = name
|
13
|
+
add_param :action, name
|
14
|
+
@params.merge!(params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def reset
|
18
|
+
@params = {}
|
19
|
+
authenticate
|
20
|
+
end
|
21
|
+
|
22
|
+
def authenticate
|
23
|
+
time = Time.now.to_i.to_s
|
24
|
+
add_param :key, time
|
25
|
+
add_param :md5, md5_hash(@user + @pass + time)
|
26
|
+
add_param :login, @user
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_param(key, value)
|
30
|
+
@params[key.to_sym] = value
|
31
|
+
end
|
32
|
+
|
33
|
+
def key
|
34
|
+
@params[:key]
|
35
|
+
end
|
36
|
+
|
37
|
+
def get?
|
38
|
+
@params[:method] == :get
|
39
|
+
end
|
40
|
+
|
41
|
+
def post?
|
42
|
+
@params[:method] == :post
|
43
|
+
end
|
44
|
+
|
45
|
+
# More than 99.5% of the transactions are currently processed within a few seconds.
|
46
|
+
# However, it may happen in some rare cases that a transaction takes longer to be processed by the receiving
|
47
|
+
# operator due to congested system on their end for instance.
|
48
|
+
# TransferTo guarantees that transactions not processed within 600 seconds will not be charged, whatever
|
49
|
+
# the final status of the transaction (successful or not). In addition, TransferTo is operating a real time system;
|
50
|
+
# therefore, the status returned in the Top-up response is final and will not change.
|
51
|
+
# To ensure that your system captures successfully the status of all transactions especially the longest
|
52
|
+
# ones, it is advised to either set up a high timeout value of 600seconds to be on the safe side (TCP connection
|
53
|
+
# could potentially be opened for a long time in this case) or to set up a mechanism to check on
|
54
|
+
# the status (to do so, you can call the trans_info method to retrieve the final status of a transaction).
|
55
|
+
# In case of timeout, both methods reserve_id and get_id_from_key of the API could be useful to identify
|
56
|
+
# the ID of the transaction (we recommend to either send a reserve_id request and to use the ID returned
|
57
|
+
# in the response in the subsequent top-up request so that you know in advance the ID of the transaction).
|
58
|
+
def run(method = :get)
|
59
|
+
add_param :method, method
|
60
|
+
@conn.send(method, "/#{T2Airtime::ENDPOINT}", @params) do |req|
|
61
|
+
req.options = { timeout: 600, open_timeout: 600 }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def md5_hash(str)
|
68
|
+
(Digest::MD5.new << str).to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module T2Airtime
|
2
|
+
|
3
|
+
class Country
|
4
|
+
|
5
|
+
def self.all
|
6
|
+
serialize_reply(T2Airtime::API.api.country_list)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.serialize_reply(reply)
|
10
|
+
names = reply[:country].split(",")
|
11
|
+
ids = reply[:countryid].split(",")
|
12
|
+
ids.each_with_index.map{|id, n| {
|
13
|
+
name: names[n],
|
14
|
+
aid: Integer(id)
|
15
|
+
}}
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class Operator
|
21
|
+
|
22
|
+
def self.all
|
23
|
+
countries = T2Airtime::Country.all
|
24
|
+
countries.flat_map{|country| serialize_reply(T2Airtime::API.api.operator_list(country[:aid]))}
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.serialize_reply(reply)
|
28
|
+
names = reply[:operator].split(",")
|
29
|
+
ids = reply[:operatorid].split(",")
|
30
|
+
ids.each_with_index.map{|id, n| {
|
31
|
+
country: reply[:country],
|
32
|
+
country_aid: Integer(reply[:countryid]),
|
33
|
+
name: names[n],
|
34
|
+
aid: Integer(id)
|
35
|
+
}}
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class Product
|
41
|
+
|
42
|
+
def self.all
|
43
|
+
operators = T2Airtime::Operator.all
|
44
|
+
operators.flat_map{|operator| serialize_reply(T2Airtime::API.api.product_list(operator[:aid]))}
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.serialize_reply(reply)
|
48
|
+
currency = reply[:destination_currency]
|
49
|
+
retail_prices = reply[:retail_price_list].split(",")
|
50
|
+
wholesale_prices = reply[:wholesale_price_list].split(",")
|
51
|
+
ids = reply[:product_list].split(",")
|
52
|
+
ids.each_with_index.map{|id, n| {
|
53
|
+
country: reply[:country],
|
54
|
+
country_aid: Integer(reply[:countryid]),
|
55
|
+
operator: reply[:operator],
|
56
|
+
operator_aid: Integer(reply[:operatorid]),
|
57
|
+
name: "#{id}#{currency}",
|
58
|
+
currency: currency,
|
59
|
+
retail_price: retail_prices[n],
|
60
|
+
wholesale_price: wholesale_prices[n],
|
61
|
+
aid: Integer(id)
|
62
|
+
}}
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module T2Airtime
|
2
|
+
class Test
|
3
|
+
|
4
|
+
# A few fake phone numbers in Indonesia have been created and set up with available products of IDR 5000, 10000, 20000, 50000 and 100000:
|
5
|
+
# 628123456710: error code 0 for PIN based Top-up (successful transaction).
|
6
|
+
# 628123456770: error code 0 for PIN less Top-up (successful transaction).
|
7
|
+
# 628123456780: error code 204 (destination number is not a valid prepaid phone number).
|
8
|
+
# 628123456781: error code 301 (input value out of range or invalid product).
|
9
|
+
# 628123456790: error code 214 (transaction refused by the operator).
|
10
|
+
# 628123456798: error code 998 (system not available, please retry later).
|
11
|
+
# 628123456799: error code 999 (unknown error, please contact support).
|
12
|
+
|
13
|
+
def self.numbers(num=0)
|
14
|
+
numbers = [ "628123456710", "628123456770", "628123456780",
|
15
|
+
"628123456781", "628123456790", "628123456798",
|
16
|
+
"628123456799" ]
|
17
|
+
num > 0 && num < 8 ? numbers[num-1] : numbers
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/t2_airtime.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'dotenv'
|
2
|
+
Dotenv.load
|
3
|
+
require "faraday"
|
4
|
+
require "net/http"
|
5
|
+
|
6
|
+
require "t2_airtime/version"
|
7
|
+
require "t2_airtime/url"
|
8
|
+
require "t2_airtime/errors"
|
9
|
+
require "t2_airtime/request"
|
10
|
+
require "t2_airtime/reply"
|
11
|
+
require "t2_airtime/base"
|
12
|
+
require "t2_airtime/api"
|
13
|
+
require "t2_airtime/test"
|
14
|
+
require "t2_airtime/rest"
|
15
|
+
|
16
|
+
module T2Airtime; end
|
data/t2_airtime.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "t2_airtime/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "t2_airtime"
|
8
|
+
spec.version = T2Airtime::VERSION
|
9
|
+
spec.authors = ["matteolc"]
|
10
|
+
spec.email = ["matteo@voxbox.io"]
|
11
|
+
|
12
|
+
spec.summary = "Wrapper methods to interface with [TransferTo](https://www.transfer-to.com/home) Airtime API"
|
13
|
+
spec.description = "Wrapper methods to interface with [TransferTo](https://www.transfer-to.com/home) Airtime API"
|
14
|
+
spec.homepage = "https://github.com/matteolc/t2_airtime"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
|
28
|
+
spec.add_runtime_dependency 'dotenv-rails', '~> 2.2', '>= 2.2.1'
|
29
|
+
spec.add_dependency "faraday", "0.9.1"
|
30
|
+
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: t2_airtime
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- matteolc
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-26 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.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
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: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dotenv-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.2'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 2.2.1
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '2.2'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.2.1
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: faraday
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 0.9.1
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.9.1
|
89
|
+
description: Wrapper methods to interface with [TransferTo](https://www.transfer-to.com/home)
|
90
|
+
Airtime API
|
91
|
+
email:
|
92
|
+
- matteo@voxbox.io
|
93
|
+
executables: []
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
97
|
+
- ".gitignore"
|
98
|
+
- ".rspec"
|
99
|
+
- ".travis.yml"
|
100
|
+
- CODE_OF_CONDUCT.md
|
101
|
+
- Gemfile
|
102
|
+
- LICENSE.txt
|
103
|
+
- README.md
|
104
|
+
- Rakefile
|
105
|
+
- lib/t2_airtime.rb
|
106
|
+
- lib/t2_airtime/api.rb
|
107
|
+
- lib/t2_airtime/base.rb
|
108
|
+
- lib/t2_airtime/errors.rb
|
109
|
+
- lib/t2_airtime/reply.rb
|
110
|
+
- lib/t2_airtime/request.rb
|
111
|
+
- lib/t2_airtime/rest.rb
|
112
|
+
- lib/t2_airtime/test.rb
|
113
|
+
- lib/t2_airtime/url.rb
|
114
|
+
- lib/t2_airtime/version.rb
|
115
|
+
- t2_airtime.gemspec
|
116
|
+
homepage: https://github.com/matteolc/t2_airtime
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.5.2
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: Wrapper methods to interface with [TransferTo](https://www.transfer-to.com/home)
|
140
|
+
Airtime API
|
141
|
+
test_files: []
|