# pagaris-node

Pagaris API client (i.e SDK) for Node

## Installation

```sh
npm install pagaris --save
# or
yarn add pagaris
```

## Usage

### Using `Promise`

Methods that perform HTTP requests to the API (e.g. `Order.prototype.create()`) return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) instead of using callbacks.


```javascript
async function () {
  let order = new Order({ amount: 5432 })

  await order.create()
    .then(() => {
      // Do something with the `order`, which is now persisted
    })
    .catch(err => {
      // Handle error (see 'Errors' section)
    })
}
```

### Configuration

> Warning: Never store your credentials in plaintext. We recommend using environment variables.

> Note: The private key you use in `Pagaris.private_key=` determines the current environment for all calls (i.e. sandbox or production calls).


```javascript
const { Pagaris, Order, Signature } = require('pagaris')

Pagaris.applicationId = process.env.PAGARIS_APPLICATION_ID
Pagaris.privateKey = process.env.PAGARIS_PRIVATE_KEY
```

### Creating an Order

```javascript
// NOTE: You can also call the static `Order.create()` method and pass the same
//  arguments
let order = new Order({
  amount: 8723.91,
  metadata: { internal_id: 192 }, // Optional
  products: [{ sku: '123', quantity: 3 }], // Optional
  redirect_url: 'https://some.url/for/redirect' // Optional, overrides app
})

await order.create().then(() => {
  console.log(order);
  /**
   * Order {
   *   amount: 8723.91,
   *   metadata: { internal_id: 192 },
   *   products: [{ sku: '123', quantity: 3 }],
   *   redirectUrl: 'https://some.url/for/redirect',
   *   id: 'a8e8615c-f4ad-4526-9123-ee1e06765ef5',
   *   fee: 100,
   *   payoutAmount: 8623.91,
   *   status: 'created',
   *   createdAt: 2020-05-06T21:05:46.892Z,
   *   updatedAt: 2020-05-06T21:05:46.909Z,
   *   url: 'https://pagaris.com/some_url_for_redirection'
   * }
   */
}).catch(err => {
  // Handle error. See 'Errors' section
})
```

### Getting an Order

```javascript
let order = await Order.get('2084f1bd-27ca-44ec-ae82-1be9e46a9f23')
```

### Getting all Orders

```javascript
let orders = await Order.all() // Returns an array of Orders
```

### Confirming an Order

```javascript
await order.confirm()
console.log(order.status) // 'confirmed'
```

### Cancelling an Order

```javascript
await order.cancel()
console.log(order.status) // 'cancelled'
```

### Errors

Any of the previous operations can raise one of the following errors. You can call `<Error>.prototype.response` on them to inspect what caused the error.

- `Errors.UnauthorizedError` - Credentials were not configured correctly or the request is impossible (e.g. trying to confirm an Order which can't be confirmed)
- `Errors.NotFoundError` - When fetching or trying to update an Order with an incorrect id (note the environment in which they were created)
- `Errors.UnprocessableEntityError` - When the parameters are invalid (e.g. creating an Order without an amount, or with an amount less than the minimum amount or greater than the maximum amount).
- `Errors.UnexpectedResponseError`
- `Errors.ServerError`

###### Example of handling errors

```javascript
await Order.create({ metadata: { we: 'did not pass an amount' } })
  .catch(err => {
    console.log(err.constructor.name) // UnprocessableEntityError
    console.log(err.response.data) // { error: { status: 422, detail: [Object] }}
  })
```

### Verifying webhook signatures

```javascript
// The value of the received `Authorization` header
let headerValue = 'Pagaris aaa:bbb:ccc'

// The path of your app in which this webhook was received
let path = '/pagaris_webhooks'

// The raw received body
let body = '{"some": "body"}'

Signature.validate(headerValue, path, body) // Returns `true` or `false`
```

## Development

To run all tests:

```sh
yarn install
yarn test
```

> Note: HTTP interactions are recorded via PollyJS (see test/recordings). If you'd like to actually hit the API, you can change the Polly mode and set `APPLICATION_ID` and `PRIVATE_KEY` environment variables in a .env file
