npm package: @moneyspace.net/moneyspace-node-js-sdk
Description: MoneySpace NODE JS SDK
Latest version: 1.0.12

# MoneySpace NODE JS SDK

# Requirements

- Minimal NodeJS version `v10.x`

# Installation

```sh
yarn add @moneyspace.net/moneyspace-node-js-sdk
```

# Application templates

Check out [example/typescript/index.ts](https://bitbucket.org/MoneySpace/moneyspace-node-js-sdk/src/master/example/typescript/index.ts) or [example/nodejs/index.js](https://bitbucket.org/MoneySpace/moneyspace-node-js-sdk/src/master/example/nodejs/index.js)
templates for typescript/javascript application which uses minimal required configuration to create transaction requests.

Check out [example/typescript/template-qrnone.ts](https://bitbucket.org/MoneySpace/moneyspace-node-js-sdk/src/master/example/typescript/template-qrnone.ts) or [example/nodejs/template-qrnone.js](https://bitbucket.org/MoneySpace/moneyspace-node-js-sdk/src/master/example/nodejs/template-qrnone.js)
templates for typescript/javascript application for creation transaction QR Payments with minimalistic web interface.

# API

![API Architecture](https://bytebucket.org/MoneySpace/moneyspace-node-js-sdk/raw/92834fc9e878c1e0331b6ac902c27e41fc4f25f0/api-arch.png)

## Get MoneySpace API handle

```ts
import { createMoneySpace, createSimpleCredentialsProvider } from '@moneyspace.net/moneyspace-node-js-sdk';
const api = createMoneySpace({
   // Use simple credentials, you can use createFileCredentialsProvider as well
   credentials: {'secretId': '<secret id>', 'secretKey': '<secret key>'},
   // As payment success, it will redirect to this url.
   successUrl: 'https://www.moneyspace.net/merchantapi/paycardsuccess',
   // As payment cancelled, it will redirect to this url.
   cancelUrl: 'https://www.moneyspace.net?status=cancel',
   // As payment failed, it will redirect to this url.
   failUrl: 'https://www.moneyspace.net?status=fail',
   baseUrl:     // Optional. Base API endpoint. Default: https://www.moneyspace.net/merchantapi
   currency:    // Optional. Currency used. Default: 'THB'
   gatewayType: // Optional. Gateway type. Default: 'card'
   feeType:     // Optional
                //  include : Merchant pays transaction fees.
                //  exclude : Shopper pays transaction fees.
});
```

### Notes

- `credentials`:

  - `object`: `{'secretId': '<secret id>', 'secretKey': '<secret key>'}`
  - `function`: Credentials provider.
    For example JSON file credentials provider:
    `createFileCredentialsProvider('moneyspace_credentials.json');`

- `feeType`:

  - `include` Merchant pays transaction fees
  - `exclude` Shopper pays transaction fees

- `amount`: Order amount. It must be string with two decimal places
  after point and no comma in number.

- `customerOrderId`: Internal merchant order id.
  Order id must be unique over all merchant orders.
  Length can't be over 20 symbols. Can contain english and numbers only.

- `gatewayType`:
  - `card`: Payment by card
  - `qrnone`: Payment by qrcode. This mode can be in use with `include` feeType mode and non-empty `productDescription`.

## Create payment transaction

```ts
const resp = await api.merchantApi.sendPaymentTransaction({
  /**
   * Order amount. It must be string with
   * two decimal places after point and no comma in number.
   */
  amount: '<order amount>',
  /**
   * Internal merchant order id.
   * Order id must be unique over all merchant orders.
   * Length can't be over 20 symbols.
   * Can contain english and numbers only.
   */
  customerOrderId: '<order id>',
  firstName: '<shopper first name>',
  lastName: '<shopper last name>',
  currency:    // Optional. Currency used. Defaults from API configuration (above).
  gatewayType: // Optional. Gateway type. Defaults from API configuration.
  feeType:     // Optional.  Defaults from API configuration.
               //  include : Merchant pays transaction fees.
               //  exclude : Shopper pays transaction fees.
  message:     // Optional. Note to the seller. Up to 100 characters
  email:       // Optional. Shopper email address
  phone:       // Optional. Shopper phone number
  address:     // Optional. Shopper shipping address
  productDescription: // Optional: Product/service details description. Required fot gatewayType==`qrnone`
  successUrl: // Optional. Defaults from API configuration.
  failUrl: // Optional. Defaults from API configuration.
  cancelUrl: // Optional. Defaults from API configuration.
});
```

### Notes

Response of calling payment `sendPaymentTransaction`:

```js
 {
  orderId: '<merchant order od>',
  transactionId: '<moneyspace transaction id>',
  // As timestamp string: yyyyMMddHHmmss
  timeHash: '<transacton time hash>'
}
```

## Check payment transaction status

```ts
const resp = await api.checkPaymentTransaction({
  transactionId: '<transaction id>', // Either orderId or transactionId
  orderId: '<order id>' // Either orderId or transactionId
});
```

This function accepts `sendPaymentTransaction` response object or object where
you can specify `transactionId` or `orderId`. If `transactionId` not specified merchant
`orderId` will be used to check transaction status.

```ts
  const tx = await api.merchantApi.sendPaymentTransaction({...});
  const status = await api.checkPaymentTransaction(tx);
```

Returned value

```ts
{
  amount: '<order amount>',
  statusPayment: '<Transaction status>'
  transactionId: // Optional. Referenced transaction ID.
  orderId:       // Optional. Merchant order ID.
  description:   // Optional. Extra description.
}
```

## Get payment link for Shopper

```ts
  const tx = await api.merchantApi.sendPaymentTransaction({...});
  const linkUrl = await api.merchantApi.getPaymentLink(tx.transactionId);
```

Accepts `tranasctionId` and returns payment link for the shopper for payment.

If `gatewayType` is `qrnone`, then payment link shows QR code. QR code expires within 15 minutes.

## Get Merchant profile data

```ts
const profileData = await api.merchantApi.getMerchantProfile();
```

Profile data:

```js
  {
    stores: [
      {
        name: '<store name>',
        logo: '<optional link to merchant store image>',
        phone: '<optional merchant phone number>'
      },
      ...
    ]
  }
```

## WebHook integration

Merchant SDK provided WebHook integration in order to be notified about payment events.
Merchant SDK can be used in context of existing application webserver like [ExpressJS](https://expressjs.com)
as well in dedicated nodejs http/http webserver.

### WebHook in standalone NodeJS HTTP/HTTPS server

```ts
import * as http from 'http';
import { createMoneySpace } from '@moneyspace.net/moneyspace-node-js-sdk';

const api = createMoneySpace({....});

http
    .createServer(api.createWebHookRequestHandler())
    .on('error', function(err) {
      console.log(err);
    })
    .listen(
      {
        host: 'localhost',
        port: 8080
      },
      () => console.log('HTTP WebHook server running')
    );
```

### WebHook in ExpressJS server

```ts
import * as express from 'express';
import { createMoneySpace } from '@moneyspace.net/moneyspace-node-js-sdk';

const api = createMoneySpace({....});
const app = express();

app.post('/mywebhook', api.createWebHookRequestHandler());
app.listen(8080, function () {
  console.log('HTTP WebHook server running')
});
```

### Receiving payment transactions events

Once you have installed MoneySpace SDK WebHook
you can receive payment events for your store.

```ts
const ref = api.registerApiEventListener('*', (type, event) => {
  console.log('Got WebHook event: ', event);
  if (type == 'PaymentSuccess') {
    console.log(`Order: ${event.orderId} paid successfully`);
  }
});

// Later you can unregister event listener:
api.unregisterApiEventListener(ref);
```

#### Event types

- `*`: Listener will be subscribed to all API events
- `PaymentSent`: Payment transaction sent successfully
- `PaymentReceived`: MoneySpace server acknowledged what payment transaction received
- `PaymentPending`: Payment in progress
- `PaymentSuccess`: Payment completed successfully
- `PaymentFailed`: Payment failed
- `PaymentCancelled`: Payment cancelled.

Payment listener receives event object with the following structure:

```ts
{
  transactionId: '<transaction id>';
  orderId: '<order id>';
  amount: '<order amount>';
  timeHash: '<optional timestamp string: yyyyMMddHHmmss>';
}
```

# Development

## Run local tests

```sh
yarn install
yarn run test
```

## Run tests using real MoneySpace API

### Before run

Create json credentials configuration file: `${HOME}/.moneyspace-test-creds.json` with the following
content:

```json
{
  "secretId": "...",
  "secretKey": "..."
}
```

```sh
yarn install
yarn run test-manual
```