You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+13-15Lines changed: 13 additions & 15 deletions
Original file line number
Diff line number
Diff line change
@@ -2,31 +2,29 @@
2
2
Kvasir (Vas-eer) is a support dashboard meant for WePay partners to be able to provide their end-users with basic support.
3
3
It will perform:
4
4
5
-
- account lookups
5
+
- Account Lookups
6
6
- Get the status of a merchant's account
7
-
8
7
- Get a merchant's withdrawal info including their bank info and when the next withdrawal will take place
9
-
10
-
- user lookups
11
-
12
-
- resending user confirmation
13
-
14
-
- refunding checkouts
15
-
8
+
- Merchant (User) Lookups
9
+
- Resending merchant confirmation
10
+
- Refunding Checkouts
16
11
- Both full and partial refunds are possible
12
+
- Payment Method Lookups
13
+
- Get the information that a given *payment_method_id* represents
14
+
15
+
## Full Documentation
16
+
This README only contains a brief outline of what Kvasir is and what it is capable of. To view the whole documentation, head to http://jalepeno112.github.io/Kvasir/index.html
17
17
18
18
## Functionality
19
-
All of the functionality has been tested, but there may be some cases that I missed. The WePay API isn't always predicatable, so if you run into an error, be sure to report it as an issue so that I can investigate furhter. Giving me the original call information (without your client_secret or any access tokens) is extremely helpful so that I can try and reproduce the error.
19
+
All of the functionality has been tested, but there may be some cases that we missed. The WePay API isn't always predictable, so if you run into an error, be sure to report it as an issue so that we can investigate further. Giving me the original call information (without your client_secret or any access tokens as those are sensitive pieces of information you shouldn't share with anyone) is extremely helpful so that I can try and reproduce the error.
20
20
21
21
To see how the framework behaves in action go to: https://nameless-hollows-55554.herokuapp.com/
22
22
23
-
The test cases are found in the "test" directory.
24
-
25
-
## More Info
26
-
To see more info and the full documentation on Kvasir's specs and what's required to use Kvasir, checkout the full documentation: https://wedemoapp.gitlab.io/kvasir/index.html
23
+
## Test Cases
24
+
The test cases are found in the "test" directory. They test the backend functionality and Kvasir's ability to interact with your middleware.
27
25
28
26
## Why Kvasir?
29
-
`Kvasir is a Norse god of wisdom <http://norse-mythology.org/kvasir/>`_. In fact he's considered the wisest of all of them. He was killed by dwarves and his blood became the Mead of Poetry which was used to inspire poets and scholars. Basically, he's the personification of alcohol. Given that we were drinking when we came up with the idea for Kvasir, it only made sense.
27
+
Kvasir is a Norse god of wisdom <http://norse-mythology.org/kvasir/>. He was killed by dwarves and his blood became the Mead of Poetry which was used to inspire poets and scholars. Basically, he's the personification of alcohol. Given that we were drinking when we came up with the idea for Kvasir, it only made sense.
30
28
31
29
## Who is this mystical "we" all over the documentation?
Copy file name to clipboardExpand all lines: docs/architecture.rst
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
Kvasir's Architecture
4
4
=========================
5
-
This page details Kvasir's architecture. It explains in detail why each architecture decision was made.
5
+
This page details Kvasir's architecture. We do this so that you have a better idea for why certain decisions are made in the :ref:`back-end <kvasirbackend>` and :ref:`front-end <kvasirfrontend>`.
6
6
7
7
A Brief History
8
8
-------------------
@@ -15,14 +15,14 @@ On the security side, many of the WePay API calls that we need to make required
15
15
16
16
While exposing access tokens to the front-end was considered a deal breaker, being able to get tokens to the front-end in the first place was also a challenge. No two database configurations are the same, and we wanted this solution to be available to any company that currently integrates with WePay. Normally, data makes up the fundamental building block of a web-application, but here we were presented with the unusual problem of having absolutely no control over the underlying database. Not only that, but many databases would likely not be optimized for use with Kvasir, so we could make no assumptions about how certain pieces of data were connected or about the presence of data.
17
17
18
-
A pure SPA with no attached back-end fell of the table pretty quickly, but we wanted to try and hold on to many of the benefits that come with a SPA such as:
18
+
A SPA with no attached back-end fell of the table pretty quickly, but we wanted to try and hold on to many of the benefits that come with a SPA such as:
19
19
1) **Being back-end agnostic**. Someone could simply take our front-end, and redesign the lower pieces and it should work just as well (if not better)
20
20
2) **Easy setup and deployment**. One of the nice parts of an SPA is that all of the logic and external calls are contained in the app running in a user's browser. It only requires a small static server to push the necessary files forward, but the burden of the work falls on the user's machine.
21
21
22
22
23
23
Architecture
24
24
-----------------
25
-
With all of these considerations in mind, we decided to stick with a SPA but provide it a sturdy back-end server for managing external API calls and database connections.
25
+
With all of these considerations in mind, we decided to stick with a SPA design but provide it a sturdy back-end server for managing external API calls and database connections.
@@ -43,7 +43,7 @@ In order to achieve this, we came up with this idea of a :ref:`"middleware compo
43
43
This middleware can be provided in any language that the developer chooses, using any structure that they want. As long as it can receive and send back information in the way that Kvasir expects, the rest is up to the developer. The information that Kvasir requests may be spread out across three or four tables for one developer, but be completed contained in a single table for another. This middleware piece allows Kvasir to be apathetic towards a developer's underlying database. This provides us with the necessary flexibility to be able to provide this as a solution to all platforms currently using WePay, not just a handful.
44
44
45
45
46
-
Integration Environment with Kvasir
46
+
How to Host Kvasir
47
47
----------------------------------------
48
48
The entire architectural model assumes that Kvasir and your middleware are running on your company's internal network. Kvasir does not come with any sort of authentication and there are *no plans for it*. Similarly to database configurations, there are a plethora of authentication systems out there that we cannot provide mechanisms to interact with all of them.
Copy file name to clipboardExpand all lines: docs/frontend.rst
+13-9Lines changed: 13 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ React and Redux apps are comprised of 3 parts:
25
25
Holding onto the idea that our application is really taking a user on a walk through their internal database, we have a set of "objects" or "models", each of which have their own set of actions, reducers and components.
26
26
27
27
These objects are:
28
-
- :ref:`User <user_object>`
28
+
- :ref:`User <user_object>`
29
29
* represents a given *merchant*.
30
30
* A merchant can have multiple accounts.
31
31
@@ -55,12 +55,14 @@ If you look at these objects, you might recognize that all of these *except for
55
55
56
56
The *components* are responsible for handling user actions and then dispatching the associated Redux actions. They are also responsible for subscribing to all of the necessary state information and formatting that data. While all actions are globally published, not every component relies on all of that info (and they shouldn't).
57
57
58
-
For example, when an account is clicked in the account component, the account component registers that the click happened, manipulates the table, and then dispatches the *searchedAccounts*, *fetchWithdrawalsIfNeeded* and *fetchCheckoutsIfNeeded* actions. Some of these actions will directly impact the action component causing it to re-render with new info, while others will impact other components forcing them to re-render with the new information, but the *User* objects is not impacted at all. Actions to accounts do not affect the User who owns them.
58
+
For example, when an account is clicked in the account component, the account component registers that the click happened, manipulates the table, and then dispatches the *searchedAccounts*, *fetchWithdrawalsIfNeeded* and *fetchCheckoutsIfNeeded* actions. Some of these actions will directly impact the action component causing it to re-render with new info, while others will impact other components forcing them to re-render with new info as well. On the other hand, the *User* objects is not impacted at all. Actions to accounts do not affect the User who owns them so we do not see the user component re-render.
59
59
60
60
General Object Implementation
61
61
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62
62
All of the objects are different in the sense that they require different search requirements (user_id, account_id, etc.); however, they are all implemented in very similar ways.
63
63
64
+
Actions
65
+
^^^^^^^^^^
64
66
All of the objects require a handful of actions:
65
67
1) Search
66
68
- Notify all components the object is being *searched* for and what exactly we are searching for
@@ -82,7 +84,7 @@ But not all of these actions are directly accessible. For example, request and
82
84
In general, these are the public functions that each object has for dispatching actions:
83
85
1) .. function:: search(id)
84
86
85
-
Will cause the associated reducer to update its state with the information the user passed in order to search the object.
87
+
Will cause the associated reducer to update its state with the information the user passed in order to search the object. This is necessary so that we can verify that the info coming back is actually the info we requested.
86
88
87
89
:param id: some unique id of the object that we just looked up. For example, for user's this is an email address; accounts use an account_id
88
90
@@ -94,6 +96,8 @@ In general, these are the public functions that each object has for dispatching
94
96
95
97
:param id: some unique id of the object that we just looked up. For example, for user's this is an email address; accounts use an account_id
96
98
99
+
Reducers
100
+
^^^^^^^^^^^^
97
101
The reducers that take these actions are also very similar.
98
102
Each reducer is actually composed of two smaller functions - a *searched* function and a *base* function.
99
103
We do this because of the asynchronous nature of Redux actions mixed with the POST requests to our back-end. If someone searches a user, but then realizes they searched the wrong email and changes the search parameter, we need a way to handle that.
@@ -128,7 +132,7 @@ Going back to the earlier example, if someone were to search a user with one ema
128
132
.. _user_object:
129
133
130
134
User Object
131
-
~~~~~~~~~~~~
135
+
------------
132
136
The user objects represents a WePay merchant accessible through the :wepay:`user` endpoint.
133
137
This is the primary building block for all other information that we gather.
134
138
@@ -149,7 +153,7 @@ The state of the user is important because if the user is not in the *registered
149
153
.. _account_object:
150
154
151
155
Account Object
152
-
~~~~~~~~~~~~~~~~
156
+
----------------
153
157
As soon we have a user's access token, we can also get a list of all of their merchant accounts tied to the app_id that the access token is associated with via the :wepay:`account find` call.
154
158
155
159
A user could have multiple accounts, so each account is displayed as a row in a larger table. Clicking on a row of the table will cause the row to become highlighted, and will dispatch actions to fetch more information about that specific account. This information includes withdrawals, reserves, and checkouts.
@@ -171,7 +175,7 @@ The account table itself includes:
171
175
.. _withdrawal_object:
172
176
173
177
Withdrawal Object
174
-
~~~~~~~~~~~~~~~~~~~~~
178
+
------------------
175
179
The withdrawal object represents information gained from the :wepay:`withdrawal` endpoint.
176
180
This includes information about where a merchant's money is being withdrawn too, when it's being withdrawn, and how much is being withdrawn.
177
181
@@ -182,7 +186,7 @@ These tables will render the 50 most recent withdrawals/reserves for a merchant.
182
186
.. _checkouts_object:
183
187
184
188
Checkouts Object
185
-
~~~~~~~~~~~~~~~~~~~
189
+
------------------
186
190
The checkout object is one of the more intensive objects. Since it is the heart of many operations that a platform performs, there are also several actions tied to any given checkout.
187
191
188
192
The checkout component renders a table of information gathered from a :wepay:`checkout find` call which includes:
@@ -214,7 +218,7 @@ The checkout component is also currently responsible for rendering the informati
214
218
.. _credit_card_object:
215
219
216
220
Credit Card Object
217
-
~~~~~~~~~~~~~~~~~~~
221
+
--------------------
218
222
The credit_card object represents information gathered by a :wepay:`credit_card` call. One of the benefits of WePay is the ability to tokenize payment information and simply store a token instead of all the payer's info. Storing all payer info requires a higher level of PCI compliance than just the token.
219
223
220
224
However, a platform may want to lookup information associated with a tokenized card at any point in time. The *Payment Method ID* column in the checkout object contains the tokenized id. Clicking on one of them (they are all hyperlinks) will dispatch actions to fetch more information about the card and render it in a table.
@@ -233,7 +237,7 @@ This table includes:
233
237
.. _payer_object:
234
238
235
239
Payer Object
236
-
~~~~~~~~~~~~~~~~
240
+
-------------------
237
241
As mentioned earlier the Payer object is the only one that doesn't tie directly back to a WePay endpoint. This is because the WePay API does not provide any way to search by a payer's information. All you can search by is a tokenized credit card ID.
238
242
239
243
However, if a payer comes to a platform's customer support and requests a refund, they likely don't know the token associated with their purchase. Storing payer information falls squarely onto the platform.
Copy file name to clipboardExpand all lines: docs/index.rst
+8-1Lines changed: 8 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -32,8 +32,15 @@ These actions include:
32
32
- Withdrawal Lookups
33
33
* Gather information about where a merchant's funds have been withdrawn to and when the next withdrawal should take place
34
34
* This also includes being able to get reserve details for accounts that have money in reserve
35
-
- Credit Card Token Lookup
35
+
- Payment Method Lookups
36
36
* Given a tokenized credit card, Kvasir can gather the original information used to create the token
37
+
* Given a preapproval id, Kvasir can gather the original information used to create the token and provide a link where the conditions of the preapproval can be updated
Copy file name to clipboardExpand all lines: logs/README.rst
+2Lines changed: 2 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -2,3 +2,5 @@ Logging Directory
2
2
------------------
3
3
4
4
This directory holds all of the log files generated by the application.
5
+
6
+
Logs are saved in JSON format. Express.js packages the requests and responses objects in a JSON format and writes them one per line. So each line is a different request or response. Looking at the status code lets you know what was and wasn't successful.
0 commit comments