diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd819b3..9b68ffc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,8 +5,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
## [Unreleased]
-- First testing version of pmtservice for Xero accounting is running
-
### Added
- Added new service for Xero integration
@@ -20,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Added
- Convenience buttons on checkout for wallets that are not ZIP-321-compliant
+- PmtService Component first alpha version ready for testing
### Fixed
diff --git a/src/app/invoice/invoice.component.ts b/src/app/invoice/invoice.component.ts
index 75e91ed..85fbebc 100644
--- a/src/app/invoice/invoice.component.ts
+++ b/src/app/invoice/invoice.component.ts
@@ -66,6 +66,7 @@ export class InvoiceComponent implements OnInit {
logoHeight: 50,
correctLevel: QRCode.CorrectLevel.H
});
+ this.error = false;
} else {
this.error = true;
this.codeString = 'Test';
diff --git a/src/app/pmtservice/pmtservice.component.css b/src/app/pmtservice/pmtservice.component.css
index f018ed3..ef2d460 100644
--- a/src/app/pmtservice/pmtservice.component.css
+++ b/src/app/pmtservice/pmtservice.component.css
@@ -22,3 +22,90 @@
background: #ff5722;
}
+.invoiceDetail {
+ font-family: Roboto Mono !important;
+ padding: 10px;
+ max-width: 600px;
+}
+
+.invoiceHdrTxt1 {
+ font-family: Spartan !important;
+ text-align: center;
+ font-size: 30px;
+ font-weight: 700;
+}
+
+.invoiceHdrTxt2 {
+ font-family: Spartan !important;
+ text-align: center;
+ font-size: 16px;
+ font-weight: 400;
+}
+
+.invoiceHdrTxt3 {
+ font-family: Spartan !important;
+ text-align: center;
+ font-size: 12px;
+ font-weight: 300;
+}
+
+.detailTitle1 {
+ border-top: solid 2px;
+ border-bottom: solid 2px;
+ border-color: navy;
+ text-align: left;
+}
+
+.detailTitle2 {
+ border-top: solid 2px;
+ border-bottom: solid 2px;
+ border-color: navy;
+ text-align: right;
+}
+
+.detailLineRight {
+ border-top: solid 2px;
+ border-bottom: solid 2px;
+ border-color: navy;
+ text-align: right;
+}
+
+.detailLineLeft {
+ border-top: solid 2px;
+ border-bottom: solid 2px;
+ border-color: navy;
+ text-align: right;
+}
+
+.invoice-title {
+ font-size: 16px;
+ font-weight: 700;
+ background: lightcyan;
+ line-height: 30px;
+ padding: 5px;
+}
+
+.invoice-detail {
+ line-height: 20px;
+ font-size: 16px;
+ font-weight: 400;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+.invoice-total {
+ margin-top: 40px;
+}
+
+.qrcode {
+ display: flex;
+ float: right;
+}
+
+.zecData {
+ width: auto;
+ font-family: Spartan !important;
+ font-size: 16px;
+ font-weight: 700;
+ text-align: right;
+}
diff --git a/src/app/pmtservice/pmtservice.component.html b/src/app/pmtservice/pmtservice.component.html
index 9b2cb25..4f5e5d4 100644
--- a/src/app/pmtservice/pmtservice.component.html
+++ b/src/app/pmtservice/pmtservice.component.html
@@ -128,36 +128,100 @@
+
+
Invoice
+
Order ID: {{orderId}}
+
Date:{{order.timestamp | date}}
+
+
+
Zcash Price: {{order.price | number: '1.02' | currency: order.currency.toUpperCase()}}
+
+
Total:
{{order.totalZec | number: '1.08'}}
+
+
+
+
+
+
+ Item
+ |
+
+ Qty.
+ |
+
+ Price ({{order.currency.toUpperCase()}})
+ |
+
+
+
+ {{item.name}}
+ |
+
+ {{item.qty}}
+ |
+
+ {{( item.qty * item.cost ) | number : '1.02' | currency: order.currency.toUpperCase()}}
+ |
+
+
+
+ Invoice Total:
+ |
+
-
-
-
-
- Invoice Goes here!!!
-
-
-
- Payment request was not processed!!
-
-
-
+ |
+
+ {{ order.total | currency: order.currency.toUpperCase()}}
+ |
+
+
+
+
+
+
+
+ Payment confirmed
+
+ Payment pending!!
+ |
+
+
+ |
+
+
+
+
+ Scan the QR code with your wallet to make payment
+
+
+
+
-
\ No newline at end of file
diff --git a/src/app/pmtservice/pmtservice.component.ts b/src/app/pmtservice/pmtservice.component.ts
index a4569f0..25ff5ec 100644
--- a/src/app/pmtservice/pmtservice.component.ts
+++ b/src/app/pmtservice/pmtservice.component.ts
@@ -4,13 +4,15 @@ import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http";
import { PmtData } from "./pmtservice.model";
import { XeroInvoice } from "./xeroinvoice.model";
import { Owner } from '../owner.model';
-import { Item } from '../items/item.model'
+// import { Item } from '../items/item.model'
import { Order } from '../order/order.model'
import { ConfigData } from '../configdata';
+import { faCheck, faHourglass } from '@fortawesome/free-solid-svg-icons';
+var QRCode = require('easyqrcodejs');
+var URLSafeBase64 = require('urlsafe-base64');
var Buffer = require('buffer/').Buffer;
-
@Component({
selector: 'app-pmtservice',
templateUrl: './pmtservice.component.html',
@@ -19,6 +21,9 @@ var Buffer = require('buffer/').Buffer;
export class PmtserviceComponent implements OnInit {
+ faCheck = faCheck;
+ faHourglass = faHourglass;
+
beUrl = ConfigData.Be_URL;
private reqHeaders: HttpHeaders = new HttpHeaders();
@@ -45,6 +50,7 @@ export class PmtserviceComponent implements OnInit {
};
public owner: Owner = {
+ _id: '',
address: '',
name: '',
currency: 'usd',
@@ -69,12 +75,41 @@ export class PmtserviceComponent implements OnInit {
payconf: false,
viewkey: ''
};
+
+public order: Order = {
+ _id : '',
+ address: '',
+ session: '',
+ timestamp: '',
+ closed: false,
+ currency: '',
+ price: 0,
+ total: 0,
+ totalZec: 0,
+ paid: false,
+ externalInvoice: '',
+ shortCode: '',
+ lines: [
+ {
+ qty: 1,
+ name: '',
+ cost:0
+ }
+ ]
+ };
+
private invData_raw : string = '';
private invData_buff : any = null;
- public reportType = 0;
+ public reportType = 1000;
public Status = 0;
+ zPrice: number = 1.0;
+ name: string = '';
+ error: boolean = false;
+ codeString: string = 'Test';
+ orderId : string = '';
+
constructor(private activatedRoute : ActivatedRoute,
private http : HttpClient ) {}
@@ -87,7 +122,7 @@ export class PmtserviceComponent implements OnInit {
this.pmtData.amount = params["amount"];
this.pmtData.currency = params["currency"];
this.pmtData.shortcode = params["shortCode"];
- console.log(this.pmtData);
+// console.log(this.pmtData);
this.getInvoiceData( this.pmtData );
@@ -101,7 +136,8 @@ export class PmtserviceComponent implements OnInit {
// Verify owner id ( Status = 1 if not exists )
// ( Status = 2 if service not available for user )
//
- console.log('getOwner -> ', reqData.ownerId);
+// console.log('getOwner -> '+ reqData.ownerId);
+// console.log('received amount -> ' + reqData.amount);
const ownParams = new HttpParams().append('id', reqData.ownerId);
let obs = this.http.get<{message:string, owner: any}>
( this.beUrl+'api/ownerid',
@@ -117,11 +153,6 @@ export class PmtserviceComponent implements OnInit {
// ==> remove "== false" for production enviroment
//
if ( this.owner.payconf == false) {
- // verifiy if an order for requested invoice
- // already exist, If exists, delete it and create
- // a new one if it has not been paid in ZGo
- // otherwise report payment
-
// process data
console.log("Owner check passed!!!");
this.getXeroInvoiceData( reqData );
@@ -140,71 +171,159 @@ export class PmtserviceComponent implements OnInit {
getXeroInvoiceData( reqData : PmtData ) {
- // Call Xero API
+/*
+ // Call test Xero API
let url : string = "http://localhost:3000/xero/" + reqData.invoice;
this.http
.get(url)
- .subscribe( data => {
- console.log('Data >>> ' + data);
- this.invData_raw = data.message.replaceAll("'",'"');
- this.invData_buff = JSON.parse(this.invData_raw);
- console.log('Invoice : >> ' + this.invData_raw);
- this.invData.inv_Type = this.invData_buff.type;
- this.invData.inv_Id = this.invData_buff.invoiceID;
- this.invData.inv_No = this.invData_buff.invoiceNumber;
- this.invData.inv_Contact = this.invData_buff.contact.name;
- this.invData.inv_Currency = this.invData_buff.currencyCode;
- this.invData.inv_CurrencyRate = this.invData_buff.currencyRate;
- this.invData.inv_Total = this.invData_buff.total;
- this.invData.inv_Status = this.invData_buff.status;
- this.invData.inv_Date = new Date(this.invData_buff.date);
- this.invData.inv_shortCode = reqData.shortcode;
- // invoice number found, test if it's type is correct
- if ( this.invData.inv_Type == 'ACCREC' ) {
- console.log('Invoice type is correct!!');
- // Test if invoice is not already paid
- if ( this.invData.inv_Status == 'AUTHORISED') {
- console.log('invoice is payable');
- // Test if Invoice's currency is supported
- if ( this.invData.inv_Currency == reqData.currency ) {
- console.log('Invoice currency supported');
- // Test if requested amount is as reported by Xero
- if ( this.invData.inv_Total == reqData.amount ) {
- console.log('Invoice amount Ok - create Order');
-//
-// =====> Create order here
-//
+*/
+ console.log('>> find current zcash price');
+ this.getPrice(this.owner.currency);
+
+ console.log('get Invoice -> ' + reqData.invoice);
+ let invParams = new HttpParams();
+ invParams = invParams.append('address', this.owner.address);
+ invParams = invParams.append('inv', reqData.invoice);
+ let inv = this.http.get<{message:string, invData: any}>
+ ( this.beUrl+'api/invdata',
+ { headers: this.reqHeaders,
+ params: invParams,
+ observe: 'response'});
+ inv.subscribe( invDataResponse => {
+// console.log('Response from ZGo-Xero');
+// console.log(invDataResponse.status);
+ this.invData_buff = invDataResponse.body;
+ this.invData.inv_Type = this.invData_buff.invdata.inv_Type;
+ this.invData.inv_Id = this.invData_buff.invdata.inv_Id;
+ this.invData.inv_No = this.invData_buff.invdata.inv_No;
+ this.invData.inv_Contact = this.invData_buff.invdata.inv_Contact;
+ this.invData.inv_Currency = this.invData_buff.invdata.inv_Currency;
+ this.invData.inv_CurrencyRate = this.invData_buff.invdata.inv_CurrencyRate;
+ this.invData.inv_Total = this.invData_buff.invdata.inv_Total;
+ this.invData.inv_Status = this.invData_buff.invdata.inv_Status;
+ this.invData.inv_Date = this.invData_buff.invdata.inv_Date;
+ this.invData.inv_shortCode = reqData.shortcode;
+ /*
+ console.log('>>> inv_Type -> ' + this.invData.inv_Type);
+ console.log('>>> inv_Id -> ' + this.invData.inv_Id);
+ console.log('>>> inv_No -> ' + this.invData.inv_No);
+ console.log('>>> inv_Contact -> ' + this.invData.inv_Contact);
+ console.log('>>> inv_Currency-> ' + this.invData.inv_Currency);
+ console.log('>>> inv_CurrencyRate -> ' + this.invData.inv_CurrencyRate);
+ console.log('>>> inv_Total -> ' + this.invData.inv_Total);
+ console.log('>>> inv_Status-> ' + this.invData.inv_Status);
+ console.log('>>> inv_Date -> ' + this.invData.inv_Date);
+*/
+ if ( this.invData.inv_Type == 'ACCREC' ) {
+ console.log('Invoice type is correct!!');
+ // Test if invoice is not already paid
+ if ( this.invData.inv_Status == 'AUTHORISED') {
+ console.log('invoice is payable');
+ // Test if Invoice's currency is supported
+ if ( this.invData.inv_Currency == reqData.currency ) {
+ console.log('Invoice currency supported');
+ // Test if requested amount is as reported by Xero
+ if ( this.invData.inv_Total == reqData.amount ) {
+ console.log('Invoice amount Ok - create Order');
+ // =====> Create order here
+ this.createOrder();
+ //
+ } else {
+ console.log('Invoice amount does not match')
+ this.reportType = 8;
+ }
} else {
- console.log('Invoice amount does not match')
- this.reportType = 8;
+ console.log('Invoice currency not supported');
+ this.reportType = 7;
}
} else {
- console.log('Invoice currency not supported');
- this.reportType = 7;
+ console.log('Invoice already paid');
+ this.reportType = 6;
}
} else {
- console.log('Invoice already paid');
- this.reportType = 6;
+ console.log('Invoice type is invalid' );
+ this.reportType = 5;
}
- } else {
- console.log('Invoice type is invalid' );
- this.reportType = 5;
- }
- // Save invData in database
- },
- error => {
- if ( error.status == 404 ) {
- this.reportType = 4;
- console.log('Invoice not found (' + JSON.stringify(error) +')' );
- } else {
- this.reportType = 3;
- console.log('Xero server inaccesible! (' + JSON.stringify(error) + ')');
- }
- return 2;
- },
- () => {
- console.log("Request complete")
- });
+ }, error => {
+ console.log("Error while getting invData!!!");
+ console.log(error);
+ });
}
-}
+
+ createOrder() {
+ this.reportType = 0;
+// console.log('Starting order generation');
+// console.log('>> find current zcash price');
+
+ this.order = {
+ _id: '',
+ address: this.owner.address,
+ session: 'Xero-' + this.owner._id,
+ currency: this.owner.currency,
+ timestamp: new Date(Date.now()).toISOString(),
+ closed: true,
+ totalZec: this.invData.inv_Total/this.zPrice,
+ price: this.zPrice,
+ total: this.invData.inv_Total,
+ paid: false,
+ externalInvoice: this.invData.inv_No,
+ shortCode: this.invData.inv_shortCode,
+ lines: [{qty: 1,
+ name: 'Invoice from ' + this.owner.name + '[' + this.invData.inv_No + ']',
+ cost: this.invData.inv_Total}]
+ };
+
+ let obs = this.http.post<{message: string, order: Order}>
+ (this.beUrl+'api/orderx',
+ {payload: this.order},
+ { headers: this.reqHeaders }
+ );
+ obs.subscribe((orderData) => {
+// console.log('Order created');
+
+// console.log(orderData.order);
+ this.order = orderData.order
+ console.log('>> order -> ' + JSON.stringify(this.order));
+ this.orderId = String(this.order._id);
+
+// console.log('Generating QRCode....')
+
+ this.codeString = `zcash:${this.order.address}?amount=${this.order.totalZec.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGo Order::'.concat(this.orderId)))}`;
+
+ var qrcode = new QRCode(document.getElementById("payment-qr"), {
+ text: this.codeString,
+ logo: "/assets/zcash.png",
+ width: 180,
+ height: 180,
+ logoWidth: 50,
+ logoHeight: 50,
+ correctLevel: QRCode.CorrectLevel.H
+ });
+
+ });
+ }
+
+ getIconStyle(order : Order) {
+ if( order.paid )
+ return "font-size: 14px; color: #72cc50; margin-bottom: -2px;";
+ return "color: #FB4F14; margin-bottom: -2px; cursor: pointer;";
+
+ }
+
+ getPrice(currency: string){
+ //var currency = 'usd';
+ const params = new HttpParams().append('currency', currency);
+ let obs = this.http.get<{message: string, price: any}>(this.beUrl+'api/price', { headers:this.reqHeaders, params: params, observe: 'response'});
+ obs.subscribe((PriceData) => {
+ if (PriceData.status == 200) {
+ this.zPrice = PriceData.body!.price.price;
+ console.log("price", this.zPrice);
+ } else {
+ console.log('No price found for currency', currency);
+ this.zPrice = 1.0;
+ }
+ });
+ return obs;
+ }
+}
\ No newline at end of file
diff --git a/src/app/pmtservice/url.txt b/src/app/pmtservice/url.txt
index 7e07097..595f557 100644
--- a/src/app/pmtservice/url.txt
+++ b/src/app/pmtservice/url.txt
@@ -1 +1,3 @@
-http://localhost:4200/pmtservice?ownerid=62cca13f5530331e2a97c78e&invoiceNo=INV-0034¤cy=USD&amount=753.95&shortCode=!w8T62
\ No newline at end of file
+http://localhost:4200/pmtservice?ownerid=62cca13f5530331e2a97c78e&invoiceNo=INV-0034¤cy=USD&amount=753.95&shortCode=!w8T62
+
+https://test.zgo.cash/api/invdata?address=zs17faa6l5ma55s55exq9rnr32tu0wl8nmqg7xp3e6tz0m5ajn2a6yxlc09t03mqdmvyphavvf3sl8&inv=INV-0034
\ No newline at end of file
diff --git a/src/app/pmtservice/xeroinvoice.model.ts b/src/app/pmtservice/xeroinvoice.model.ts
index 5f0ed81..e906e34 100644
--- a/src/app/pmtservice/xeroinvoice.model.ts
+++ b/src/app/pmtservice/xeroinvoice.model.ts
@@ -1,13 +1,13 @@
export interface XeroInvoice {
- inv_Type : String;
- inv_Id : String;
- inv_No : String;
- inv_Contact : String;
- inv_Currency : String;
+ inv_Type : string;
+ inv_Id : string;
+ inv_No : string;
+ inv_Contact : string;
+ inv_Currency : string;
inv_CurrencyRate : number;
inv_Total : number;
- inv_Status : String;
+ inv_Status : string;
inv_Date : Date;
- inv_shortCode : String;
+ inv_shortCode : string;
inv_ProcDate : Date;
}
\ No newline at end of file