xapo_sdk 0.0.1.pre.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +15 -9
- data/lib/xapo_sdk/version.rb +1 -1
- data/lib/xapo_tools.rb +119 -65
- data/lib/xapo_utils.rb +18 -10
- data/test/test_xapo_tools.rb +80 -41
- data/test/test_xapo_utils.rb +21 -21
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66227ffeca0ea2c6c313df33e6bb6e959113b840
|
4
|
+
data.tar.gz: 94613eba6fca7265cea57c6acb86f88de9b025de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1290315d1ab8f2bb52f004969f572141488ddc1c8db05dd953a790cd9afff23b75781404f87e4fb444e7ddcb57a95e7329221f03775086119ef52afc2ade6774
|
7
|
+
data.tar.gz: 99208026f43d3b5efbc3abff53ad2e1e7a882f07ff7b3b59d655c7f10c970b92320173816affe1b66dbd49343c2bea75b9b296b8499d553dedbc70c2ae632725
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
0.2.0 / 2014-11-01
|
2
|
+
==================
|
3
|
+
|
4
|
+
* Having a TPA is not longer mandatory to provide a micro payments widget. Parameters 'app_id' and 'app_secret' are now optional.
|
5
|
+
|
6
|
+
0.0.1 / 2014-10-18
|
7
|
+
==================
|
8
|
+
|
9
|
+
* Initial commit
|
10
|
+
* Encryption library
|
11
|
+
* Micro payment `div` and `iframe`
|
data/README.md
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
|
5
5
|
---
|
6
6
|
|
7
|
+
[Changelog](CHANGELOG.md)
|
8
|
+
|
7
9
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
8
10
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
9
11
|
## Table of Contents
|
@@ -62,6 +64,8 @@ Micro payment widgets allow to dynamically get a HTML snippet pre-configured and
|
|
62
64
|
- **Pay Object's Id:** `[mandatory]` any unique identifier in the context of the TPA distinguishing the object of the payment.
|
63
65
|
- **Pay type:** `[optional]` any of Donate | Pay | Tip | Deposit.
|
64
66
|
|
67
|
+
Be aware that micro payments could be optionally configured with your own application id and secret (`app_id`/`app_secret`). Configuring the micro payment with your application credentials allows you to charge a transaction fee for example.
|
68
|
+
|
65
69
|
### IFrame Widget
|
66
70
|
```ruby
|
67
71
|
require 'xapo_tools'
|
@@ -69,9 +73,10 @@ require 'xapo_tools'
|
|
69
73
|
...
|
70
74
|
|
71
75
|
micro_payment = XapoTools::MicroPayment.new(
|
72
|
-
|
73
|
-
|
74
|
-
|
76
|
+
XAPO_URL,
|
77
|
+
APP_ID, # optional
|
78
|
+
APP_SECRET # optional
|
79
|
+
)
|
75
80
|
config = XapoTools.micro_payment_config
|
76
81
|
|
77
82
|
config[:sender_user_email] = "sender@xapo.com"
|
@@ -101,9 +106,10 @@ require 'xapo_tools'
|
|
101
106
|
...
|
102
107
|
|
103
108
|
micro_payment = XapoTools::MicroPayment.new(
|
104
|
-
|
105
|
-
|
106
|
-
|
109
|
+
XAPO_URL,
|
110
|
+
APP_ID, # optional
|
111
|
+
APP_SECRET # optional
|
112
|
+
)
|
107
113
|
config = XapoTools.micro_payment_config
|
108
114
|
|
109
115
|
config[:sender_user_email] = "sender@xapo.com"
|
@@ -154,7 +160,7 @@ See the example results in the [widgets gallery](#widgets-gallery).
|
|
154
160
|
## TODO
|
155
161
|
- ~~Fix style (https://github.com/bbatsov/ruby-style-guide#naming)~~
|
156
162
|
- ~~Add unit testing~~
|
157
|
-
- Document, document, ~~document
|
163
|
+
- Document, document, ~~document~~
|
158
164
|
- ~~Review naming and organization (with respect to Java & Python?)~~
|
159
|
-
- Review `gem` build infraestructure
|
160
|
-
- ...
|
165
|
+
- ~~Review `gem` build infraestructure~~
|
166
|
+
- ...
|
data/lib/xapo_sdk/version.rb
CHANGED
data/lib/xapo_tools.rb
CHANGED
@@ -7,75 +7,129 @@ require "yaml"
|
|
7
7
|
|
8
8
|
module XapoTools
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# Micro payment button configuration options.
|
13
|
+
#
|
14
|
+
# This function is intended to be a helper for creating empty micro
|
15
|
+
# payments buttons configuration but also serves for documenting. A
|
16
|
+
# hash with the intended fields would give the same results.
|
17
|
+
#
|
18
|
+
# Attributes:
|
19
|
+
# sender_user_id (str): The id of the user sending the payment.
|
20
|
+
# sender_user_email (str, optional): The email of the user sending
|
21
|
+
# the payment.
|
22
|
+
# sender_user_cellphone (str, optional): The celphone number of the user
|
23
|
+
# sending the payment.
|
24
|
+
# receiver_user_id (str): The id of the user receiving the payment.
|
25
|
+
# receiver_user_email (str): The email of the user receiving the payment.
|
26
|
+
# pay_object_id (str): A payment identifier in the TPA context.
|
27
|
+
# amount_BIT (float, optional): The amount of bitcoins to be payed by the
|
28
|
+
# widget. If not specified here, it must be entered on payment basis.
|
29
|
+
# pay_type (str): The string representing the type of operation
|
30
|
+
# ("Tip", "Pay", "Deposit" or "Donate").
|
31
|
+
def micro_payment_config
|
32
|
+
return Hash[:sender_user_id => "", :sender_user_email => "",
|
33
|
+
:sender_user_cellphone => "", :receiver_user_id => "",
|
34
|
+
:receiver_user_email => "", :pay_object_id => "",
|
35
|
+
:amount_BIT => 0, :timestamp => XapoUtils.timestamp,
|
36
|
+
:pay_type => ""]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Xapo's payment buttons snippet builder.
|
40
|
+
#
|
41
|
+
# This class allows the construction of 2 kind of widgets, *div* and
|
42
|
+
# *iframe*. The result is a HTML snippet that could be embedded in a
|
43
|
+
# web page for doing micro payments though a payment button.
|
44
|
+
#
|
45
|
+
# Attributes:
|
46
|
+
# service_url (str): The endpoint URL that returns the payment widget.
|
47
|
+
# app_id (str, optional): The id of the TPA for which the widget will be created.
|
48
|
+
# app_secret (str, optional): The TPA secret used to encrypt widget configuration.
|
49
|
+
class MicroPayment
|
50
|
+
def initialize(service_url, app_id=nil, app_secret=nil)
|
51
|
+
@service_url = service_url
|
52
|
+
@app_id = app_id
|
53
|
+
@app_secret = app_secret
|
18
54
|
end
|
19
55
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def build_iframe_widget(config)
|
42
|
-
widget_url = build_url(config)
|
43
|
-
|
44
|
-
snippet = YAML::load(<<-END)
|
45
|
-
|
|
46
|
-
<iframe id="tipButtonFrame" scrolling="no" frameborder="0"
|
47
|
-
style="border:none; overflow:hidden; height:22px;"
|
48
|
-
allowTransparency="true" src="#{widget_url}">
|
49
|
-
</iframe>
|
50
|
-
END
|
51
|
-
|
52
|
-
return snippet
|
53
|
-
end
|
54
|
-
|
55
|
-
def build_div_widget(config)
|
56
|
-
widget_url = build_url(config)
|
57
|
-
|
58
|
-
snippet = YAML::load(<<-END)
|
59
|
-
|
|
60
|
-
<div id="tipButtonDiv" class="tipButtonDiv"></div>
|
61
|
-
<div id="tipButtonPopup" class="tipButtonPopup"></div>
|
62
|
-
<script>
|
63
|
-
$(document).ready(function() {{
|
64
|
-
$("#tipButtonDiv").load("#{widget_url}");
|
65
|
-
}});
|
66
|
-
</script>
|
67
|
-
END
|
68
|
-
|
69
|
-
return snippet
|
70
|
-
end
|
71
|
-
|
72
|
-
private :build_url
|
56
|
+
def build_url(config)
|
57
|
+
json_config = JSON.generate(config)
|
58
|
+
|
59
|
+
if @app_secret == nil || @app_id == nil
|
60
|
+
query_str = URI.encode_www_form(
|
61
|
+
"payload" => json_config,
|
62
|
+
"customization" => JSON.generate({"button_text" => config[:pay_type]})
|
63
|
+
)
|
64
|
+
else
|
65
|
+
encrypted_config = XapoUtils.encrypt(json_config, @app_secret)
|
66
|
+
|
67
|
+
query_str = URI.encode_www_form(
|
68
|
+
"app_id" => @app_id,
|
69
|
+
"button_request" => encrypted_config,
|
70
|
+
"customization" => JSON.generate({"button_text" => config[:pay_type]})
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
widget_url = @service_url + "?" + query_str
|
75
|
+
|
76
|
+
return widget_url
|
73
77
|
end
|
78
|
+
|
79
|
+
# Build an iframe HTML snippet in order to be embedded in apps.
|
80
|
+
#
|
81
|
+
# Args:
|
82
|
+
# config (MicroPaymentConfig): The button configuration options.
|
83
|
+
# See @MicroPaymentConfig.
|
84
|
+
#
|
85
|
+
# Returns:
|
86
|
+
# string: the iframe HTML snippet ot be embedded in a page.
|
87
|
+
def build_iframe_widget(config)
|
88
|
+
widget_url = build_url(config)
|
89
|
+
|
90
|
+
snippet = YAML::load(<<-END)
|
91
|
+
|
|
92
|
+
<iframe id="tipButtonFrame" scrolling="no" frameborder="0"
|
93
|
+
style="border:none; overflow:hidden; height:22px;"
|
94
|
+
allowTransparency="true" src="#{widget_url}">
|
95
|
+
</iframe>
|
96
|
+
END
|
97
|
+
|
98
|
+
return snippet
|
99
|
+
end
|
100
|
+
|
101
|
+
# Build div HTML snippet in order to be embedded in apps.
|
102
|
+
#
|
103
|
+
# Args:
|
104
|
+
# config (MicroPaymentConfig): The button configuration options.
|
105
|
+
# See @MicroPaymentConfig.
|
106
|
+
#
|
107
|
+
# Returns:
|
108
|
+
# string: the div HTML snippet ot be embedded in a page.
|
109
|
+
def build_div_widget(config)
|
110
|
+
widget_url = build_url(config)
|
111
|
+
|
112
|
+
snippet = YAML::load(<<-END)
|
113
|
+
|
|
114
|
+
<div id="tipButtonDiv" class="tipButtonDiv"></div>
|
115
|
+
<div id="tipButtonPopup" class="tipButtonPopup"></div>
|
116
|
+
<script>
|
117
|
+
$(document).ready(function() {{
|
118
|
+
$("#tipButtonDiv").load("#{widget_url}");
|
119
|
+
}});
|
120
|
+
</script>
|
121
|
+
END
|
122
|
+
|
123
|
+
return snippet
|
124
|
+
end
|
125
|
+
|
126
|
+
private :build_url
|
127
|
+
end
|
74
128
|
end
|
75
129
|
|
76
130
|
module PayType
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
131
|
+
TIP = "Tip"
|
132
|
+
DONATE = "Donate"
|
133
|
+
PAY = "Pay"
|
134
|
+
DEPOSIT = "Deposit"
|
81
135
|
end
|
data/lib/xapo_utils.rb
CHANGED
@@ -3,17 +3,25 @@ require "base64"
|
|
3
3
|
|
4
4
|
module XapoUtils
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Do PKCS#7 padding and encrypting.
|
9
|
+
#
|
10
|
+
# Args:
|
11
|
+
# bytestring (str): The text to encode.
|
12
|
+
# k (int, optional): The padding block size. It defaults to k=16.
|
13
|
+
#
|
14
|
+
# Returns:
|
15
|
+
# str: The padded bytestring.
|
16
|
+
def encrypt(payload, secret)
|
17
|
+
cipher = OpenSSL::Cipher::AES.new("256-ECB")
|
18
|
+
cipher.encrypt
|
19
|
+
cipher.key = secret
|
12
20
|
|
13
|
-
|
21
|
+
encrypted = cipher.update(payload) + cipher.final
|
14
22
|
|
15
|
-
|
16
|
-
|
23
|
+
return Base64.encode64(encrypted)
|
24
|
+
end
|
17
25
|
|
18
|
-
|
26
|
+
def timestamp; (Time.now.to_f * 1000).to_i end
|
19
27
|
end
|
data/test/test_xapo_tools.rb
CHANGED
@@ -2,45 +2,84 @@ require "minitest/autorun"
|
|
2
2
|
require "xapo_tools"
|
3
3
|
|
4
4
|
class TestXapoTools < Minitest::Test
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
5
|
+
def setup
|
6
|
+
@xapo_tools = XapoTools::MicroPayment.new(
|
7
|
+
"http://dev.xapo.com:8089/pay_button/show",
|
8
|
+
"b91014cc28c94841",
|
9
|
+
"c533a6e606fb62ccb13e8baf8a95cbdc"
|
10
|
+
)
|
11
|
+
@xapo_tools_notpa = XapoTools::MicroPayment.new(
|
12
|
+
"http://dev.xapo.com:8089/pay_button/show"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_build_iframe_widget()
|
17
|
+
config = XapoTools.micro_payment_config
|
18
|
+
config[:sender_user_email] = "sender@xapo.com"
|
19
|
+
config[:sender_user_cellphone] = "+5491112341234"
|
20
|
+
config[:receiver_user_id] = "r0210"
|
21
|
+
config[:receiver_user_email] = "fernando.taboada@xapo.com"
|
22
|
+
config[:pay_object_id] = "to0210"
|
23
|
+
config[:amount_BIT] = 0.01
|
24
|
+
config[:pay_type] = PayType::DONATE
|
25
|
+
|
26
|
+
actual = @xapo_tools.build_iframe_widget(config)
|
27
|
+
|
28
|
+
assert_match(/<iframe(.*)button_request(.*)>(.*)<\/iframe>\n/m, actual)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_build_iframe_widget_notpa()
|
32
|
+
config = XapoTools.micro_payment_config
|
33
|
+
config[:sender_user_email] = "sender@xapo.com"
|
34
|
+
config[:sender_user_cellphone] = "+5491112341234"
|
35
|
+
config[:receiver_user_id] = "r0210"
|
36
|
+
config[:receiver_user_email] = "fernando.taboada@xapo.com"
|
37
|
+
config[:pay_object_id] = "to0210"
|
38
|
+
config[:amount_BIT] = 0.01
|
39
|
+
config[:pay_type] = PayType::DONATE
|
40
|
+
|
41
|
+
actual = @xapo_tools_notpa.build_iframe_widget(config)
|
42
|
+
|
43
|
+
assert_match(/<iframe(.*)payload(.*)>(.*)<\/iframe>\n/m, actual)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_build_div_widget()
|
47
|
+
config = XapoTools.micro_payment_config
|
48
|
+
config[:sender_user_email] = "sender@xapo.com"
|
49
|
+
config[:sender_user_cellphone] = "+5491112341234"
|
50
|
+
config[:receiver_user_id] = "r0210"
|
51
|
+
config[:receiver_user_email] = "fernando.taboada@xapo.com"
|
52
|
+
config[:pay_object_id] = "to0210"
|
53
|
+
config[:amount_BIT] = 0.01
|
54
|
+
config[:pay_type] = PayType::TIP
|
55
|
+
regex = /
|
56
|
+
<div\sid="tipButtonDiv"\sclass="tipButtonDiv"><\/div>\n
|
57
|
+
<div\sid="tipButtonPopup"\sclass="tipButtonPopup"><\/div>\n
|
58
|
+
<script>(.*)button_request(.*)<\/script>\n
|
59
|
+
/mx
|
60
|
+
|
61
|
+
actual = @xapo_tools.build_div_widget(config)
|
62
|
+
|
63
|
+
assert_match(regex, actual)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_build_div_widget_notpa()
|
67
|
+
config = XapoTools.micro_payment_config
|
68
|
+
config[:sender_user_email] = "sender@xapo.com"
|
69
|
+
config[:sender_user_cellphone] = "+5491112341234"
|
70
|
+
config[:receiver_user_id] = "r0210"
|
71
|
+
config[:receiver_user_email] = "fernando.taboada@xapo.com"
|
72
|
+
config[:pay_object_id] = "to0210"
|
73
|
+
config[:amount_BIT] = 0.01
|
74
|
+
config[:pay_type] = PayType::TIP
|
75
|
+
regex = /
|
76
|
+
<div\sid="tipButtonDiv"\sclass="tipButtonDiv"><\/div>\n
|
77
|
+
<div\sid="tipButtonPopup"\sclass="tipButtonPopup"><\/div>\n
|
78
|
+
<script>(.*)payload(.*)<\/script>\n
|
79
|
+
/mx
|
80
|
+
|
81
|
+
actual = @xapo_tools_notpa.build_div_widget(config)
|
82
|
+
|
83
|
+
assert_match(regex, actual)
|
84
|
+
end
|
46
85
|
end
|
data/test/test_xapo_utils.rb
CHANGED
@@ -2,27 +2,27 @@ require 'minitest/autorun'
|
|
2
2
|
require 'xapo_utils'
|
3
3
|
|
4
4
|
class TestXapoUtils < Minitest::Test
|
5
|
-
|
6
|
-
|
5
|
+
def setup
|
6
|
+
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
8
|
+
def test_encrypt()
|
9
|
+
json = '{"sender_user_id":"s160901",' +
|
10
|
+
'"sender_user_email":"fernando.taboada@gmail.com",' +
|
11
|
+
'"sender_user_cellphone":"",' +
|
12
|
+
'"receiver_user_id":"r160901",' +
|
13
|
+
'"receiver_user_email":"fernando.taboada@xapo.com",' +
|
14
|
+
'"tip_object_id":"to160901",' +
|
15
|
+
'"amount_SAT":"",' +
|
16
|
+
'"timestamp":1410973639125}'
|
17
|
+
expected = 'rjiFHpE3794U23dEKNyEz3ukF5rhVxtKzxEnZq8opuHoRH5eA' +
|
18
|
+
'/XOEbROEzf5AYmyQ5Yw6cQLSVMx/JgENrNKVK268n3o1kOIxEpupaha2wYX' +
|
19
|
+
'LqIqU8Ye7LFQz7NvQNPzfyOSPWnBQ/JUCSKsCiCz45VoK511B/RMz33mjJM' +
|
20
|
+
'F7s2a6FEk6YOwf3hrvYwFt1frXLDwxsAwMXKUutIdfnrM2c6MYOFXTSGqZc' +
|
21
|
+
'2gS8DXmwHyIrXKUFCt7Ax3DMk0ao7iAE8MiXWaSSSZRVBQ7d1a9JDRoNtzq' +
|
22
|
+
'GB++p7zK4NmOdrGEX9f+EwBjYuyKSsNez7kXPAWzwEvoi1o8gu4bxA1ng=='
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
actual = XapoUtils.encrypt(json, "bc4e142dc053407b0028accffc289c18").tr("\n","")
|
25
|
+
|
26
|
+
assert_equal(expected, actual)
|
27
|
+
end
|
28
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xapo_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Federico Repond
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -46,6 +46,7 @@ extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
48
|
- ".gitignore"
|
49
|
+
- CHANGELOG.md
|
49
50
|
- Gemfile
|
50
51
|
- LICENSE.txt
|
51
52
|
- README.md
|
@@ -71,9 +72,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
72
|
version: '0'
|
72
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
74
|
requirements:
|
74
|
-
- - "
|
75
|
+
- - ">="
|
75
76
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
77
|
+
version: '0'
|
77
78
|
requirements: []
|
78
79
|
rubyforge_project:
|
79
80
|
rubygems_version: 2.4.2
|