---
# System prepended metadata

title: 'CardUp API :rocket:'

---

# CardUp API :rocket:
This is CardUp API. CardUp’s APIs enable businesses & financial institutions to make & collect card payments, where cards aren't accepted. Using this other organizations/companies can integrate cardup functionalities into their platform rather than coming to CardUp platform.

# Documentaion
All the documentation is present [here](https://api-docs.cardup.global/#documents)
# Major dependencies
- Ruby: 2.6.6
- Rails: 6.X
- DBMS: MySQL

# Setting up Development environment
1. Setup SSH and clone the code
2. Ask for database.yml and credentials from colleagues.
3. All three apps Core, Admin, and this API use the same database whose migrations are spread among admin and core. So no need to run `Migration` here but only `seeds`.

Alternative: Ask for colleagues database dump.

4. Setup all the secrets keys in code. Ask colleagues for secrets.
 Alternative: One can find existing secrets by running `EDITOR=vi rails credentials:show` on exsting machine.

5. Create credentials for any environment
 To create credentials for any environment, we can run the following command:
 `EDITOR=vi bin/rails credentials:edit`

The above command does the following:
 1. Creates config/credentials/<environment>.key if missing. Don’t commit this file.
 2. Creates config/credentials/<environment>.yml.enc if missing. Commit this file.
 3. Decrypts and opens the production credentials file in the default editor.

6. Edit you `credentials` by running this command on terminal `EDITOR=vi rails credentials:edit`
 1. Add those secrets into this file and save this. You got from your colleagues `(Refer ponit 4)`.

7. Run `bundle install` at root of the directory
8. Run `rails s` to run the server. The API server should be running now. But in order to use these APIs we need API key and ID which we will get from core app.
9. Run Core app and sign-up as `Business` owner. Scope of setting up and running core is out of this Readme.
10. Allow `api_access` from Admin Panel. Else one can use `rails console` to give API access to your user. At time of writing this, following is the way to do it:


```ruby
user = User.find_by(email: <your email>)
user.company.company_feature.update!(api_access: true)
```

11. Ask these keys from colleagues
```
vgs:
 vault:
 js_link:
 outbound_proxy:

```

1. Ask `cert.pem` from colleagues and put in the root of `core` repository.
 1. `cert.pem` is for solving the `OpenSSL::X509::StoreError (system lib)` error. Read more about `OpenSSL` [here](https://ruby-doc.org/stdlib-2.4.0/libdoc/openssl/rdoc/OpenSSL/X509/Certificate.html)

2. Ask `NGROK` `authtoken` from colleagues.
 1. `NGROK` is being used here to verify `JsonWebToken`.

3. Install `NGROK` and use the `authtoken` you got from point no `(Refer point 13)`.
4. Now start `NGROK` for `CORE` at `cuapi-dev.in.ngrok.io`

Now if you navigate to "My Account" > "API keys" on core you can see your API Key and API ID. These are used to create access token which is required with every request, even on development environment.In following steps we will create create access token from these keys.

1. Create base64 encoded string from your API ID and Key.
```bash
echo -n <Your API Key>:<Your API Secret> | openssl base64
```

### Postman setup
Every API call needs authentication token, even in the development environment. This token is valid for 1 hour. Making token at every hour while doing development is tedious task so we have automated this process. We use a pre-request script functionality of Postman to generate the token automatically before every call.

This is just a way. You are free to follow your own custom setup. Incase you want to follow the above setup, then following are the steps:

1. Make a [Collection](https://learning.postman.com/docs/sending-requests/intro-to-collections/) in the postman.
2. Make a [Pre-request](https://learning.postman.com/docs/writing-scripts/pre-request-scripts/) on the collection you created above with following code:

```javascript
var authServiceUrl = pm.collectionVariables.get('authService');
var authorization = pm.collectionVariables.get('authorization');
var sdk = require('postman-collection');
var tokenRequest = new sdk.Request({
url: authServiceUrl,
method: 'POST',
header: [
    new sdk.Header({
        key: 'content-type',
        value: 'application/x-www-form-urlencoded'
    }),
    new sdk.Header({
        key: 'authorization',
        value: authorization
    }),
],
body: {
    mode: 'raw',
    raw: "grant_type=client_credentials"
} 
});
pm.sendRequest(tokenRequest, function (err, response) {
    if (err) {
        throw err;
    }
    if (response.code !== 200) {
        throw new Error('Could not log in.');
    }
    data = response.json()
    token = data['access_token']
    pm.collectionVariables.set("bearer_token", token);
    console.log(`New token has been set: ${token}`);
});
```
3. Make the following [varibales](https://learning.postman.com/docs/sending-requests/variables/) on Collection level.

```
authService: https://login.cardup.co/oauth2/token
authorization: Basic <Your access token, which you generated in step 7 above>
```

4. Now in every Postman request we can use `bearer_token` variable which our script (in step 3) would create. Inside request tab open `Authorization` and choose type as `Bearer Token`. We will use our variable as it's value here. So write ```{{bearer_token}}``` in it's value.

# Contribution Guidelines
## Testing
In order to setup and test database, please do the following steps:

1. From [Core](https://github.com/CardUp/cardup.co) repo run the migration
```ruby
RAILS_ENV=test rails db:migrate
```
2. Come back to API repo and run the seeds.
```ruby
RAILS_ENV=test rails db:seed
```
3. Now we can run the tests by RSpec command
```ruby
rspec  # to run the complete suite
rspec ./spec/<path to file> # to run a specific file
```

### Ideology

We would like to minimise the database operations as much as possible to keep the test suite fast. For the same we have removed the RSpec configuration to run Database cleaner every time test suite start. Rather we can test our logic by observing delta change in data via test.


# Deployment
## Production Infra
TODO: Small intro to our Production infra
## How we deploy
TODO: Small description on how we deploy this app 