# Credify API doc OpenAPI Definition

## API clients and models

This repository automatically generates API clients and models based on OpenAPI Spec using [OpenAPITools/openapi-generator-cli](https://github.com/OpenAPITools/openapi-generator-cli).</br>
Please install the latest version with npm or yarn.

### Install

```shell script
// Generated API clients use `axios` as HTTP client.
yarn add -D @credify/api-docs axios@0.21.1

yarn install
``` 

### Usage

`index` contains all the definitions regarding API endpoints.</br>
`types` directory contains all the definitions regarding API request/response data.

```typescript
// By importing `@credify/api-docs/apiClients/v1`, you can use the API v1.
import { AuthApiFactory, CommonApiFactory, AccessTokenResponse, CommonResponse, Phone } from "@credify/api-docs/apiClients/v1";
// By importing `@credify/api-docs/apiClients/v2`, you can use the API v2.
import { OnboardingApiFactory } from "@credify/api-docs/apiClients/v2";
// By importing `@credify/api-docs/apiClients/integration`, you can use the API integration v1.
import { ClaimProviderApiFactory, EvaluatedOffersListResponse } from "@credify/api-docs/apiClients/integration";
// By importing `@credify/api-docs/apiClients/integration-v2`, you can use the API integration v2.
import { BNPLProviderApiFactory, GetCompletedBnplProviderList200Response } from "@credify/api-docs/apiClients/integration-v2";
// By importing `@credify/api-docs/apiClients/products`, you can use the API products.
import { BNPLApiFactory, BalanceCheckResponse } from "@credify/api-docs/apiClients/products";

/*
* Simple way to make a request is to create an API client with an API factory function.
* If you want to use the API with the Auth tag, you need to use the AuthApiFactory function.
* Named in this way - XXXApiFactory.
*  Organization -> OrganizationApiFactory
*  Offers       -> OffersApiFactory
* */
const apiClient = AuthApiFactory();
const response: AccessTokenResponse = await apiClient.generateAccessToken("X_API_KEY");


/*
* You can pass parameters, for example accessToken, with a Configuration object when initializing an API client.
*  1. Initialize a ConfigurationParameters with some basic properties.
*  2. Set additional information as a baseOptions property if needed, for example, accept-language.
*  3. Initialize a Configuration with the ConfigurationParameters.
*  4. Create an API client with a API factory function.
* 
* 
* The basePath can be changed for each environment.
* This needs to be handled by the user of the API client;
* You don't need to care about the API version in the path, like `/v1/~` or `/v2/~`.
* 
* in the case of the passport app, the getBaseUrl function can be used.
*   export const APP_API_BASE_URL = getBaseUrl();
*   export const getBaseUrl = (): string => {
*     let env = getEnvironment();
*     switch (env) {
*         case Environment.Dev:
*             return "https://dev-api.credify.ninja";
*         case Environment.SIT:
*             return "https://sit-api.credify.ninja";
*         case Environment.UAT:
*             return "https://uat-api.credify.dev";
*         case Environment.Sandbox:
*             return "https://sandbox-api.credify.dev";
*         case Environment.Prod:
*             return "https://api.credify.one";
*         default:
*             return "https://dev-api.credify.ninja";
*     }
*   };
* */ 

const configParameters: ConfigurationParameters = {
    "apiKey" : "X_API_KEY",
    "accessToken" : "ACCESS_TOKEN",
    "basePath" : "https://dev-api.credify.ninja",
};
// Set additional information in an HTTP request header.
const baseOptions = {};
const headers = {
    "Accept-Language": "accept language setting",
    "X-Custom-Header": "custom header value"
};
baseOptions["headers"] = headers;
configParameters["baseOptions"] = baseOptions;

const configuration = new Configuration(configParameters);
const commonApi = CommonApiFactory(configuration);
const response: PrivateKeyResponse = await commonApi.getKeyPairs();


// You can pass a payload when calling a function.
const phoneApi = PhoneNumberApiFactory(configuration);
const updatePhonePayload: Phone = {
    phone_number: "000000000000",
    country_code: "+84"
};
const response: CommonResponse = await phoneApi.updatePhoneNumber(updatePhonePayload);
```

### Deployment

Once you finish your changes on this repository, please merge a pull request named `Release for vX.X.X`.
GitHub Action will be kicked off to tag them, create releases, and deploy the latest package to [@credify/api-docs - npm](https://www.npmjs.com/package/@credify/api-docs).

GitHub Actions

`tagpr`
- This automatically creates and updates a pull request for unreleased items, tags them when they are merged, and create releases.
- This increases the patch version by default. To increase the minor/major version, please add the label `tagpr:major` or`tagpr:minor` to the pull request.

`npm`
- This builds and publish new package to [the npm repository](https://www.npmjs.com/package/@credify/api-docs).

---

## Working on your OpenAPI Definition

### Install

1. Install [Node JS](https://nodejs.org/).
2. Clone this repo and run `yarn` in the repo root.

### Usage

#### `yarn start`
Generate documentation previews for API definitions on your local machine.

#### `yarn build`
Combine separate API definition file into one. The generated file is located under the `dist` folder.

#### `yarn ts-build:v1` `yarn ts-build:v2` `yarn ts-build:integration-v1` `yarn ts-build:integration-v2` `yarn ts-build:products`
Build and generate API clients for each API definition file.

#### `yarn ts-build`
Build and generate API clients for all API definition files.

If you want to run ts-build command on your local machine, please make sure Java 8 or above is installed (Tips: run java -version to check the version), and export JAVA_HOME in order to use the supported Java version:
```shell script
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
export PATH=${JAVA_HOME}/bin:$PATH
```

## Contribution Guide

Below is a sample contribution guide. The tools 
in the repository don't restrict you to any 
specific structure. Adjust the contribution guide
to match your own structure. However, if you 
don't have a structure in mind, this is a
good place to start.

Update this contribution guide if you
adjust the file/folder organization.

The `.redocly.yaml` controls settings for various
tools including the lint tool and the reference
docs engine.  Open it to find examples and 
[read the docs](https://docs.redoc.ly/cli/configuration/)
for more information.


### Schemas

#### Adding Schemas

1. Navigate to the `docs/components/schemas` folder.
2. Add a file named as you wish to name the schema.
3. Define the schema.
4. Refer to the schema using the `$ref` (see example below).

##### Example Schema
This is a very simple schema example:
```yaml
type: string
description: The resource ID. Defaults to UUID v4
maxLength: 50
example: 4f6cf35x-2c4y-483z-a0a9-158621f77a21
```
This is a more complex schema example:
```yaml
type: object
properties:
  id:
    description: The customer identifier string
    readOnly: true
    allOf:
      - $ref: './ResourceId.yaml'
  websiteId:
    description: The website's ID
    allOf:
      - $ref: './ResourceId.yaml'
  paymentToken:
    type: string
    writeOnly: true
    description: |
      A write-only payment token; if supplied, it will be converted into a
      payment instrument and be set as the `defaultPaymentInstrument`. The
      value of this property will override the `defaultPaymentInstrument`
      in the case that both are supplied. The token may only be used once
      before it is expired.
  defaultPaymentInstrument:
    $ref: './PaymentInstrument.yaml'
  createdTime:
    description: The customer created time
    allOf:
      - $ref: './ServerTimestamp.yaml'
  updatedTime:
    description: The customer updated time
    allOf:
      - $ref: './ServerTimestamp.yaml'
  tags:
    description: A list of customer's tags
    readOnly: true
    type: array
    items:
      $ref: './Tags/Tag.yaml'
  revision:
    description: >
      The number of times the customer data has been modified.

      The revision is useful when analyzing webhook data to determine if the
      change takes precedence over the current representation.
    type: integer
    readOnly: true
  _links:
    type: array
    description: The links related to resource
    readOnly: true
    minItems: 3
    items:
      anyOf:
        - $ref: './Links/SelfLink.yaml'
        - $ref: './Links/NotesLink.yaml'
        - $ref: './Links/DefaultPaymentInstrumentLink.yaml'
        - $ref: './Links/LeadSourceLink.yaml'
        - $ref: './Links/WebsiteLink.yaml'
  _embedded:
    type: array
    description: >-
      Any embedded objects available that are requested by the `expand`
      querystring parameter.
    readOnly: true
    minItems: 1
    items:
      anyOf:
        - $ref: './Embeds/LeadSourceEmbed.yaml'

```

##### Using the `$ref`

Notice in the complex example above the schema definition itself has `$ref` links to other schemas defined.

Here is a small excerpt with an example:

```yaml
defaultPaymentInstrument:
  $ref: './PaymentInstrument.yaml'
```

The value of the `$ref` is the path to the other schema definition.

You may use `$ref`s to compose schema from other existing schema to avoid duplication.

You will use `$ref`s to reference schema from your path definitions.

#### Editing Schemas

1. Navigate to the `docs/components/schemas` folder.
2. Open the file you wish to edit.
3. Edit.

### Paths

#### Adding a Path

1. Navigate to the `docs/paths` folder.
2. Add a new YAML file named like your URL endpoint except replacing `/` with `@` and putting path parameters into curly braces like `{example}`.
3. Add the path and a ref to it inside of your `openapi.yaml` file inside of the `docs` folder.

Example addition to the `openapi.yaml` file:
```yaml
'/customers/{id}':
  $ref: './paths/customers@id@loans@loan-id.yaml'
```

Here is an example of a YAML file named `customers@{id}.yaml` in the `paths` folder:

```yaml
get:
  tags:
    - Customers
  summary: Retrieve a list of customers
  operationId: GetCustomerCollection
  description: |
    You can have a markdown description here.
  parameters:
    - $ref: '../components/parameters/collectionLimit.yaml'
    - $ref: '../components/parameters/collectionOffset.yaml'
    - $ref: '../components/parameters/collectionFilter.yaml'
    - $ref: '../components/parameters/collectionQuery.yaml'
    - $ref: '../components/parameters/collectionExpand.yaml'
    - $ref: '../components/parameters/collectionFields.yaml'
  responses:
    '200':
      description: A list of Customers was retrieved successfully
      headers:
        Rate-Limit-Limit:
          $ref: '../components/headers/Rate-Limit-Limit.yaml'
        Rate-Limit-Remaining:
          $ref: '../components/headers/Rate-Limit-Remaining.yaml'
        Rate-Limit-Reset:
          $ref: '../components/headers/Rate-Limit-Reset.yaml'
        Pagination-Total:
          $ref: '../components/headers/Pagination-Total.yaml'
        Pagination-Limit:
          $ref: '../components/headers/Pagination-Limit.yaml'
        Pagination-Offset:
          $ref: '../components/headers/Pagination-Offset.yaml'
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: '../components/schemas/Customer.yaml'
        text/csv:
          schema:
            type: array
            items:
              $ref: '../components/schemas/Customer.yaml'
    '401':
      $ref: '../components/responses/AccessForbidden.yaml'
  x-code-samples:
    - lang: PHP
      source:
        $ref: '../code_samples/PHP/customers/get.php'
post:
  tags:
    - Customers
  summary: Create a customer (without an ID)
  operationId: PostCustomer
  description: Another markdown description here.
  requestBody:
    $ref: '../components/requestBodies/Customer.yaml'
  responses:
    '201':
      $ref: '../components/responses/Customer.yaml'
    '401':
      $ref: '../components/responses/AccessForbidden.yaml'
    '409':
      $ref: '../components/responses/Conflict.yaml'
    '422':
      $ref: '../components/responses/InvalidDataError.yaml'
  x-code-samples:
    - lang: PHP
      source:
        $ref: '../code_samples/PHP/customers/post.php'
```

You'll see extensive usage of `$ref`s in this example to different types of components including schemas.

You'll also notice `$ref`s to code samples.

### Code samples

1. Navigate to the `docs/code_samples` folder.
2. Navigate to the `<language>` (e.g. PHP) sub-folder.
3. Navigate to the `path` folder, and add ref to the code sample.

You can add languages by adding new folders at the appropriate path level.

More details inside the `code_samples` folder README.
