payments/server.js

import pick from 'lodash/pick'
import { JsonApiServer } from '../json_api'

/**
 * Facilitates interaction with the wallet server.
 *
 * @class
 */
export class PaymentServer extends JsonApiServer {
  /**
   * Create a new wallet server instance.
   *
   * @constructor
   * @param {ShelfNetwork} sdk Parent SDK instance.
   * @param {string} serverUrl wallet server URL.
   * @param {Object} opts
   * @param {boolean} [opts.allowHttp] Allow connecting to http servers, default: `false`. This must be set to false in production deployments!
   * @param {Object} [opts.proxy] Proxy configuration. Look [axios docs](https://github.com/axios/axios#request-config) for more info
   * @param {Object} [opts.httpBasicAuth] HTTP basic auth credentials. Look [axios docs](https://github.com/axios/axios#request-config) for more info.
   * @param {Object} [opts.customHeaders] Custom headers for request.
   * @param {boolean} [opts.withCredentials] Indicates whether or not cross-site Access-Control requests should be made using credentials.
   * @param {string} [opts.responseType='json'] Indicates the type of data that the server will respond with options are 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'.
   */
  constructor (sdk, serverUrl, opts = {}) {
    opts.alias = 'payments'
    super(sdk, serverUrl, opts)
  }

  /**
   * Preauthorize a transaction.
   *
   * @param {object} opts Payment details.
   * @param {string} opts.currency Payment currency.
   * @param {string} opts.amount Payment amount in cents.
   * @param {string} opts.description Payment description.
   * @param {string} opts.purpose Payment purpose.
   * @param {string} [opts.invoiceId] Invoice id.
   * @param {string} [opts.redirect] Custom redirect.
   *
   * @return {Promise.<JsonApiResponse>} Payment server response.
   */
  create (opts) {
    return this._makeTransactionsCallBuilder()
      .post({
        data: {
          type: 'transactions',
          attributes: pick(opts, [
            'currency',
            'amount',
            'description',
            'purpose',
            'invoiceId',
            'redirect'
          ])
        }
      })
  }

  /**
   * Confirm a transaction.
   *
   * @param {object} opts Payment details.
   * @param {string} opts.transactionId Transaction ID.
   *
   * @return {Promise.<JsonApiResponse>} Payment server response.
   */
  confirm (transactionId) {
    return this._makeCallBuilder()
      .appendUrlSegment('confirmations')
      .withCredentials()
      .post({
        data: {
          type: 'transactions',
          id: transactionId
        }
      })
  }

  /**
   * Reverse a transaction.
   *
   * @param {object} opts Payment details.
   * @param {string} opts.transactionId Transaction ID.
   *
   * @return {Promise.<JsonApiResponse>} Payment server response.
   */
  reverse (transactionId) {
    return this._makeCallBuilder()
      .appendUrlSegment('reversals')
      .withCredentials()
      .post({
        data: {
          type: 'transactions',
          id: transactionId
        }
      })
  }

  /**
   * Get a transaction ID.
   *
   * @param {string} transactionId Transaction ID.
   * @return {Promise.<JsonApiResponse>} Payment server response.
   */
  get (transactionId) {
    return this._makeTransactionsCallBuilder()
      .appendUrlSegment(transactionId, { base64: true })
      .get()
  }

  /**
   * Get a page of transactions.
   *
   * @param {object} [query] Request options.
   * @param {Number} [query.page.cursor] Pagination cursor.
   * @param {Number} [query.page.limit] Page size.
   * @param {string[]} [query.sort] Sorting params.
   * @param {string} [query.accountId] Filter by account ID.
   * @param {string} [query.status] Filter by payment status.
   * @param {string} [query.purpose] Filter by payment purpose.
   * @param {string} [query.invoiceId] Filter by invoice ID.
   *
   * @return {Promise.<JsonApiResponse>} Payment server response.
   */
  getPage (query) {
    return this._makeTransactionsCallBuilder().get(query)
  }

  _makeTransactionsCallBuilder () {
    return this._makeCallBuilder()
      .appendUrlSegment('transactions')
      .withOptionalCredentials()
  }
}