Skip to content

Commit

Permalink
Merge pull request #20 from xendit/story/API-767
Browse files Browse the repository at this point in the history
Ewallets endpoints
  • Loading branch information
stanleynguyen authored Jan 3, 2020
2 parents 9195808 + ce3e5de commit fb9d75e
Show file tree
Hide file tree
Showing 10 changed files with 488 additions and 0 deletions.
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# CHANGELOG

## 2019-12-29

- [#16](https://github.com/xendit/xendit-node/pull/16) (feature) Recurring Payments
- [#18](https://github.com/xendit/xendit-node/pull/18) (feature) Payouts
- [#20](https://github.com/xendit/xendit-node/pull/20) (feature) EWallets

## 2019-12-28

- [#19](https://github.com/xendit/xendit-node/pull/19) Add linting for ts files

## 2019-12-26

- [#15](https://github.com/xendit/xendit-node/pull/15) Remove tokenization & authentication from Card

## 2019-12-16

- [#13](https://github.com/xendit/xendit-node/pull/13) Add integration tests

## 2019-11-28

- (feature) Invoices

## 2019-11-26

- (bugfix) `createdFixedVA` on nil expirationDate
- (bugfix) `updateFixedVA` on nul expirationDate

## 2019-11-03

- (feature) Credit Cards
- (feature) Virtual Accounts
- (feature) Disbursements
- (feature) Batch Disbursements
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ For PCI compliance to be maintained, tokenization of credt cards info should be
+ [Methods](#methods-4)
* [Payout Services](#payout-services)
+ [Methods](#methods-5)
* [EWallet Services](#ewallet-services)
+ [Methods](#methods-6)
- [Contributing](#contributing)

<!-- tocstop -->
Expand Down Expand Up @@ -516,6 +518,60 @@ p.getPayout(data: { id: string })
p.voidPayout(data: { id: string })
```

### EWallet Services

Instanitiate EWallet service using constructor that has been injected with Xendit keys

```js
const { EWallet } = x;
const ewalletSpecificOptions = {};
const ew = new EWallet(ewalletSpecificOptions);
```

Example: Create an ewallet payment

```js
ew.createPayment({
externalID: 'my-ovo-payment',
amount: 1,
phone: '081234567890',
ewalletType: EWallet.Type.OVO,
})
.then(r => {
console.log('create ewallet payment detail:', r);
return r;
})
```

#### Methods

- Create an ewallet payment
```ts
ew.createPayment(data: {
externalID: string;
amount: number;
phone?: string;
expirationDate?: Date;
callbackURL?: string;
redirectURL?: string;
items?: Array<{
id: string;
name: string;
price: number;
quantity: number;
}>;
ewalletType: CreateSupportWalletTypes;
})
```

- Get an ewallet Payment Status
```ts
ew.getPayment(data: {
externalID: string:
ewalletType: GetSupportWalletTypes;
})
```

## Contributing

Running test suite
Expand Down
29 changes: 29 additions & 0 deletions examples/ewallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const x = require('./xendit');

const EWallet = x.EWallet;
const ew = new EWallet({});

ew.createPayment({
externalID: new Date(),
amount: 1,
phone: '081234567890',
ewalletType: EWallet.Type.OVO,
})
.then(r => {
console.log('create payment detail:', r); // eslint-disable-line no-console
return r;
})
.then(({ external_id, ewallet_type }) =>
ew.ovo.getPaymentStatusByExtID({
externalID: external_id,
ewalletType: ewallet_type,
}),
)
.then(r => {
console.log('EWallet payment detail:', r); // eslint-disable-line no-console
return r;
})
.catch(e => {
console.error(e); // eslint-disable-line no-console
process.exit(1);
});
45 changes: 45 additions & 0 deletions src/ewallet/ewallet.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { XenditOptions } from '../xendit_opts';

enum CreateSupportWalletTypes {
OVO = 'OVO',
Dana = 'DANA',
Linkaja = 'LINKAJA',
}

enum GetSupportWalletTypes {
OVO = 'OVO',
Dana = 'DANA',
}

interface PaymentItem {
id: string;
name: string;
price: number;
quantity: number;
}

export = class EWallet {
constructor({});
static _constructorWithInjectedXenditOpts: (
opts: XenditOptions,
) => typeof EWallet;
static Type: {
OVO: string;
Dana: string;
LinkAja: string;
};
createPayment(data: {
externalID: string;
amount: number;
phone?: string;
expirationDate?: Date;
callbackURL?: string;
redirectURL?: string;
items?: PaymentItem[];
ewalletType: CreateSupportWalletTypes;
}): Promise<object>;
getPayment(data: {
externalID: string;
ewalletType: GetSupportWalletTypes;
}): Promise<object>;
};
117 changes: 117 additions & 0 deletions src/ewallet/ewallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const {
promWithJsErr,
Auth,
Validate,
fetchWithHTTPErr,
queryStringWithoutUndefined,
} = require('../utils');
const errors = require('../errors');

const EWALLET_PATH = '/ewallets';

function EWallet(options) {
let aggOpts = options;
if (EWallet._injectedOpts && Object.keys(EWallet._injectedOpts).length > 0) {
aggOpts = Object.assign({}, options, EWallet._injectedOpts);
}

this.opts = aggOpts;
this.API_ENDPOINT = this.opts.xenditURL + EWALLET_PATH;
}

EWallet._injectedOpts = {};
EWallet._constructorWithInjectedXenditOpts = function(options) {
EWallet._injectedOpts = options;
return EWallet;
};
EWallet.Type = {
OVO: 'OVO',
Dana: 'DANA',
LinkAja: 'LINKAJA',
};

EWallet.prototype.createPayment = function(data) {
return promWithJsErr((resolve, reject) => {
let compulsoryFields = ['ewalletType'];

if (data.ewalletType) {
switch (data.ewalletType) {
case EWallet.Type.OVO:
compulsoryFields = ['externalID', 'amount', 'phone', 'ewalletType'];
break;
case EWallet.Type.Dana:
compulsoryFields = [
'externalID',
'amount',
'callbackURL',
'redirectURL',
'ewalletType',
];
break;
case EWallet.Type.LinkAja:
compulsoryFields = [
'externalID',
'phone',
'amount',
'items',
'callbackURL',
'redirectURL',
'ewalletType',
];
break;
default:
reject({
status: 400,
code: errors.API_VALIDATION_ERROR,
message: 'Invalid EWallet Type',
});
}
}

Validate.rejectOnMissingFields(compulsoryFields, data, reject);

fetchWithHTTPErr(this.API_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: Auth.basicAuthHeader(this.opts.secretKey),
},
body: JSON.stringify({
external_id: data.externalID,
amount: data.amount,
phone: data.phone,
expiration_date: data.expirationDate,
callback_url: data.callbackURL,
redirect_url: data.redirectURL,
items: data.items,
ewallet_type: data.ewalletType,
}),
})
.then(resolve)
.catch(reject);
});
};

EWallet.prototype.getPayment = function(data) {
return promWithJsErr((resolve, reject) => {
Validate.rejectOnMissingFields(['externalID', 'ewalletType'], data, reject);

const queryStr = data
? queryStringWithoutUndefined({
external_id: data.externalID,
ewallet_type: data.ewalletType,
})
: '';

fetchWithHTTPErr(`${this.API_ENDPOINT}?${queryStr}`, {
method: 'GET',
headers: {
Authorization: Auth.basicAuthHeader(this.opts.secretKey),
},
})
.then(resolve)
.catch(reject);
});
};

module.exports = EWallet;
3 changes: 3 additions & 0 deletions src/ewallet/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const EWalletService = require('./ewallet');

module.exports = { EWalletService };
2 changes: 2 additions & 0 deletions src/xendit.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { InvoiceService } from './invoice';
import { PayoutService } from './payout';
import { RecurringPayment } from './recurring';
import { XenditOptions } from './xendit_opts';
import { EWalletService } from './ewallet';

export = class Xendit {
constructor(opts: XenditOptions);
Expand All @@ -16,4 +17,5 @@ export = class Xendit {
Invoice: typeof InvoiceService;
Payout: typeof PayoutService;
RecurringPayment: typeof RecurringPayment;
EWallet: typeof EWalletService;
};
2 changes: 2 additions & 0 deletions src/xendit.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { DisbursementService } = require('./disbursement');
const { InvoiceService } = require('./invoice');
const { PayoutService } = require('./payout');
const { RecurringPayment } = require('./recurring');
const { EWalletService } = require('./ewallet');
const Errors = require('./errors');

function Xendit(options) {
Expand All @@ -27,6 +28,7 @@ function Xendit(options) {
this.RecurringPayment = RecurringPayment._constructorWithInjectedXenditOpts(
this.opts,
);
this.EWallet = EWalletService._constructorWithInjectedXenditOpts(this.opts);
}

Xendit.Errors = Errors;
Expand Down
54 changes: 54 additions & 0 deletions test/ewallet/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const OVO_EWALLET_TYPE = 'OVO';
const DANA_EWALLET_TYPE = 'DANA';
const LINKAJA_EWALLET_TYPE = 'LINKAJA';

const EXT_ID = '123';
const PHONE = '081234567890';
const AMOUNT = 10000;
const CALLBACK_URL = 'https://yourwebsite.com/callback';
const REDIRECT_URL = 'https://yourwebsite.com/order/123';
const ITEMS = [
{
id: '123123',
name: 'Phone Case',
price: 100000,
quantity: 1,
},
{
id: '345678',
name: 'Powerbank',
price: 200000,
quantity: 1,
},
];

const VALID_CREATE_OVO_RESPONSE = {
transaction_date: String(new Date()),
amount: AMOUNT,
external_id: EXT_ID,
ewallet_type: OVO_EWALLET_TYPE,
business_id: '12121212',
};

const VALID_GET_OVO_PAYMENT_STATUS_RESPONSE = {
external_id: EXT_ID,
amount: AMOUNT,
transaction_date: String(new Date()),
business_id: '12121212',
ewallet_type: OVO_EWALLET_TYPE,
status: 'COMPLETED',
};

module.exports = {
OVO_EWALLET_TYPE,
DANA_EWALLET_TYPE,
LINKAJA_EWALLET_TYPE,
EXT_ID,
PHONE,
AMOUNT,
CALLBACK_URL,
REDIRECT_URL,
ITEMS,
VALID_CREATE_OVO_RESPONSE,
VALID_GET_OVO_PAYMENT_STATUS_RESPONSE,
};
Loading

0 comments on commit fb9d75e

Please sign in to comment.