Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ test/test-results.xml

# Bower stuff.
bower_components/
dist/paydunya-node.debug.js
dist/paydunya-node.debug.js
__tests__/.env.local
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/
156 changes: 80 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,88 @@ PAYDUNYA NodeJS API Client
======================================
The [Node.JS](http://nodejs.org) library for [PAYDUNYA (paydunya.com)](https://paydunya.com).

Built on the PAYDUNYA HTTP API (beta).
✅ Fully supports Typescript.

Built on the PAYDUNYA HTTP API.

## Installation

```javascript
```typescript
npm install --save paydunya
```

## API configuration

Setup paydunya API keys.

```javascript
var setup = new paydunya.Setup({
masterKey: 'wQzk9ZwR-Qq9m-0hD0-zpud-je5coGC3FHKW',
privateKey: 'test_private_rMIdJM3PLLhLjyArx9tF3VURAF5',
publicKey: 'test_public_kb9Wo0Qpn8vNWMvMZOwwpvuTUja-OSDNhUqKoaTI4wc',
token: 'IivOiOxGJuWhc5znlIiK',
mode: 'test' // optional. use in sandbox mode.
});
```typescript
import { PaydunyaClient, PaydunyaEnvironment } from "paydunya"

let client = PaydunyaClient.fromCredentials({
masterKey: "your-master-key",
privateKey: "your-private-key",
publicKey: "your-public-key",
token: "your-token",
mode: PaydunyaEnvironment.TEST // or PaydunyaEnvironment.LIVE
})
```

It might usually be suitable to put your API configuration in environment variables. In that case you can initialize `paydunya.Setup` without passing configuration parameters.
The library will automatically detect the environment variables and use them.
Auto-detected environment variables: `PAYDUNYA_MASTER_KEY`, `PAYDUNYA_PRIVATE_KEY`, `PAYDUNYA_PUBLIC_KEY`, `PAYDUNYA_TOKEN`
### Auto-Detection
It might be suitable for you to put your API configuration in environment variables.
In that case, instantiate your client with these parameters.

```typescript
import { PaydunyaClient, PaydunyaEnvironment } from "paydunya"

// if you want automatic environment detection
let client = PaydunyaClient.autoDetect()
// if you want manual environment configuration
let client = PaydunyaClient.autoDetect(PaydunyaEnvironment.LIVE) // Or PaydunyaEnvironment.TEST
```

In that case please pass the following keys in your environment:
- `PAYDUNYA_MASTER_KEY`: the master key of your account,
- `PAYDUNYA_PRIVATE_KEY`: your private key
- `PAYDUNYA_PUBLIC_KEY`: your public key
- `PAYDUNYA_TOKEN`: your paydunya token,
- `PAYDUNYA_MODE`: your current environment. `test` or `live`.


## Checkout Store Configuration

```javascript
var store = new paydunya.Store({
name: 'Magasin Chez Sandra', // only name is required
tagline: "L'élégance n'a pas de prix",
phoneNumber: '336530583',
postalAddress: 'Dakar Plateau - Etablissement kheweul',
logoURL: 'http://www.chez-sandra.sn/logo.png'
```typescript
import { Store } from "paydunya"
let store = new Store({
name: 'Magasin Chez Sandra', // only name is required
tagline: "L'élégance n'a pas de prix",
phone_number: '336530583',
postal_address: 'Dakar Plateau - Etablissement kheweul',
logo_url: 'http://www.chez-sandra.sn/logo.png'
});
```

## Initialize Checkout Invoice

```javascript
var invoice = new paydunya.CheckoutInvoice(setup, store);
```typescript
let invoice = client.checkoutInvoiceInstance();
```

## Initialize Onsite Invoice

```javascript
var invoice = new paydunya.OnsiteInvoice(setup, store);
```typescript
let invoice = client.onsiteInvoiceInstance();
```

## Add Invoice Items & Description

```javascript
```typescript
invoice.addItem('Ordinateur Lenovo L440', 1, 400000, 400000); // name, quantity, unit price, total price
invoice.description = 'Lenovo Product'
```

## Setting Total Amount Chargeable

```javascript
```typescript
invoice.totalAmount = 400000;
```

Expand All @@ -71,11 +92,11 @@ After setting total amount and adding items to your invoice you can create a che

```javascript
invoice.create()
.then(function (){
invoice.status;
invoice.token; // invoice token
invoice.responseText;
invoice.url; // PAYDUNYA redirect checkout url
.then(function (result){
result.status;
result.token; // invoice token
result.responseText;
result.url; // PAYDUNYA redirect checkout url
})
.catch(function (e) {
console.log(e);
Expand All @@ -85,12 +106,12 @@ invoice.create()
## Onsite Payment Request (OPR): Step 1 - Token request
After setting total amount and adding items to your invoice get the paydunya customer's username or phone number and start an OPR request.

```javascript
```typescript
invoice.create('alioune@gmail.com')
.then(function(){
invoice.oprToken; // You need to pass the OPR Token on Step 2
invoice.token; // invoice token
invoice.responseText;
.then((result){
result.oprToken; // You need to pass the OPR Token on Step 2
result.token; // invoice token
result.responseText;
})
.catch(function (e) {
console.log(e);
Expand All @@ -101,13 +122,13 @@ invoice.create('alioune@gmail.com')
## Onsite Payment Request (OPR): Step 2 - Charge
To successfully complete an OPR charge, you need both your OPR Token & the Confirmation code sent to the customer. After a successfull charge you can programatically access the receipt url, customer information and more.

```javascript
```typescript
invoice.charge('oprToken', '0000')
.then(function (){
invoice.status;
invoice.responseText;
invoice.receiptURL;
invoice.customer; // {name: 'Alioune Badara', phone: '773830279', email: 'alioune@gmail.com'}
.then((result){
result.status;
result.responseText;
result.receiptURL;
result.customer; // {name: 'Alioune Badara', phone: '773830279', email: 'alioune@gmail.com'}
})
.catch(function (e) {
console.log(e);
Expand All @@ -119,7 +140,7 @@ invoice.charge('oprToken', '0000')
### Adding Tax Information
You may include tax information on on the checkout page. This information will be available on the invoice & receipt printouts and PDF downloads.

```javascript
```typescript
invoice.addTax('VAT (18%)', 3000);
invoice.addTax('Autre taxe (5%)', 200);
```
Expand All @@ -128,7 +149,7 @@ invoice.addTax('Autre taxe (5%)', 200);
There are times when you may need to add an extra load of data with the checkout information for later use. paydunya allows saving of custom data on their servers which are persisted even after successful payment.
Note: Custom data is not displayed anywhere on the checkout page, invoice/receipt download & printouts.

```javascript
```typescript
invoice.addCustomData('CartID', 32393);
invoice.addCustomData('Plan', 'NOEL');
```
Expand All @@ -138,9 +159,9 @@ You can optionally set the URL where your customers will be redirected to after
Note: There are two options as to how the cancel URL is set, one is to set it globally using the checkout setup information and the other is set it as per checkout invoice.
Setting the cancel URL directly on the invoice instance will overwrite the global settings if already set.

```javascript
```typescript
// Globally
var store = new paydunya.Store({
let store = new Store({
name: 'Magasin chez Sandra',
cancelURL: 'http://www.ma-super-boutique.com/'
});
Expand All @@ -153,9 +174,9 @@ invoice.cancelURL = 'http://www.ma-super-boutique.com/';
PAYDUNYA does a good job of managing receipt downloads and printouts after your customer successfuly makes payment. However there may be cases where you may descide to redirect your customers to another URL after successfully making payment. Return URL guarantees this action.
Note: PAYDUNYA will append `?token=INVOICE_TOKEN` to your URL.

```javascript
```typescript
// Globally
var store = new paydunya.Store({
let store = new Store({
name: 'Magasin chez Sandra',
returnURL: 'http://www.ma-super-boutique.com/confirm'
});
Expand All @@ -167,35 +188,18 @@ invoice.returnURL = 'http://www.ma-super-boutique.com/confirm';
### Confirming a Checkout Programatically
The API allows you to check on the status of any checkout using the checkout token key. You have access to all the data including the receipt download link & customer information in cases where the checkout has been confirmed as completed.

```javascript
var token = 'odaff0a023';

var invoice = new paydunya.CheckoutInvoice(setup, store);
```typescript
let token = 'odaff0a023';
let invoice = client.checkoutInvoiceInstance();

invoice.confirm(token)
.then(function (){
invoice.status; // completed, pending, canceled or fail
invoice.responseText;
.then(function (result){
result.status; // completed, pending, canceled or fail
result.responseText;

// available if status == 'completed'
invoice.customer; // {name: 'Alioune Badara', phone: '772639273', email: 'alioune@gmail.com'}
invoice.receiptURL; // 'https://app.paydunya.com/sandbox-checkout/receipt/pdf/test_44a6fef19a.pdf'
})
.catch(function (e) {
console.log(e);
});
```

## DirectPay
You can pay any paydunya account directly via your third party apps. This is particularly excellent for implementing your own Adaptive payment solutions on top of paydunya.

```javascript
var directPay = new paydunya.DirectPay(setup);
directPay.creditAccount('alioune@gmail.com', 5000)
.then(function (){
directPay.description;
directPay.responseText;
directPay.transactionID;
result.customer; // {name: 'Alioune Badara', phone: '772639273', email: 'alioune@gmail.com'}
result.receiptURL; // 'https://app.paydunya.com/sandbox-checkout/receipt/pdf/test_44a6fef19a.pdf'
})
.catch(function (e) {
console.log(e);
Expand All @@ -205,11 +209,11 @@ directPay.creditAccount('alioune@gmail.com', 5000)
# Running Tests
To run tests just setup the API configuration environment variables. An internet connection is required for some of the tests to pass.

```javascript
npm install -g mocha
```typescript
npm install
```
Then
`npm test` or `mocha`
`npm test`

## License
MIT
4 changes: 4 additions & 0 deletions __tests__/.env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PAYDUNYA_MASTER_KEY=
PAYDUNYA_PRIVATE_KEY=
PAYDUNYA_PUBLIC_KEY=
PAYDUNYA_TOKEN=
51 changes: 51 additions & 0 deletions __tests__/checkout-invoice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { PaydunyaClient } from '../src/lib';
import { Store } from '../src/lib/store';
import { PaydunyaEnvironment } from '../src/lib/credentials';
import { config } from 'dotenv';
import { join } from 'path';

config({ path: join(__dirname, ".env.local") })

describe('CheckoutInvoice', function () {

let token = '';

it('should work with valid initialization and total amount', function (done) {
const client = PaydunyaClient.autoDetect(PaydunyaEnvironment.TEST)
client.store = new Store({ name: "Magasin Chez Sandra" })
const invoice = client.checkoutInvoiceInstance();
invoice.totalAmount = 1000;

invoice.create()
.then((output) => {
expect(output.url).toBeTruthy()
expect(output.token).toBeTruthy()
token = output.token || "";
done();
})
.catch(done);
});

it('should confirm completed token', function (done) {

const client = PaydunyaClient.fromCredentials({
mode: PaydunyaEnvironment.TEST,
privateKey: process.env.PAYDUNYA_PRIVATE_KEY || "",
publicKey: process.env.PAYDUNYA_PUBLIC_KEY || "",
masterKey: process.env.PAYDUNYA_MASTER_KEY || "",
token: process.env.PAYDUNYA_TOKEN || ""
});

client.store = new Store({ name: "Magasin Chez Sandra" })
const invoice = client.checkoutInvoiceInstance();

invoice.getTokenStatus(token)
.then((result) => {
expect(result.status).toBeTruthy();
expect(result.hash).toBeTruthy();
expect(result.status).toBe("pending");
done();
})
.catch(done);
});
});
25 changes: 25 additions & 0 deletions __tests__/direct-pay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PaydunyaClient } from '../src/lib';
import { PaydunyaEnvironment } from '../src/lib/credentials';
import { config } from 'dotenv';
import { join } from 'path';

config({ path: join(__dirname, ".env.local") })

/**
* Direct Pay endpoint seems to be deprecated. endpoint not found on the server
*/
describe('DirectPay', function () {
let client = PaydunyaClient.autoDetect(PaydunyaEnvironment.TEST);
let directPay = client.directpayInstance();

it('should credit account if initialized correctly', function (done) {
directPay.creditAccount('maximiliencomlan05@gmail.com', 2000)
.then(function () {
expect(directPay.description).toBeTruthy();
expect(directPay.transactionID).toBeTruthy();
expect(directPay.responseText).toBeTruthy();
done();
});
});

});
Loading