xapo_sdk 0.0.1.pre.1 → 0.2.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.
- 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
|