Skip to content

Commit

Permalink
Merge pull request #91 from open-template-hub/develop
Browse files Browse the repository at this point in the history
Release/notification update
  • Loading branch information
furknyavuz authored Apr 8, 2022
2 parents c9ac1d6 + de38e7e commit 0939bb9
Show file tree
Hide file tree
Showing 18 changed files with 216 additions and 101 deletions.
13 changes: 11 additions & 2 deletions .github/workflows/cron-dependency-checker-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,18 @@ jobs:
- name: Npm Outdated
run: npm run outdated

- name: Check for Changes
run: |
if git diff --exit-code; then
echo "changes_exist=false" >> $GITHUB_ENV
else
echo "changes_exist=true" >> $GITHUB_ENV
fi
- name: Git Commit and Push
if: ${{ env.changes_exist == 'true' }}
run: |
git config --global user.email "furknyavuz@gmail.com"
git config --global user.name "Furkan Yavuz"
git config --global user.email "[email protected].com"
git config --global user.name "OTH Service User"
git commit -am "Workflow/dependency check"
git push
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</p>

<h1 align="center">
Open Template Hub - Payment Server Template v3
Open Template Hub - Payment Server Template v4
</h1>

[![License](https://img.shields.io/github/license/open-template-hub/payment-server-template?color=43b043&style=for-the-badge)](LICENSE)
Expand Down
75 changes: 67 additions & 8 deletions app/controller/payment.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,30 @@
* @description holds payment controller
*/

import { MongoDbProvider, PostgreSqlProvider } from '@open-template-hub/common';
import {
BusinessLogicActionType,
MessageQueueChannelType,
MessageQueueProvider,
MongoDbProvider,
NotificationParams,
PostgreSqlProvider,
QueueMessage
} from '@open-template-hub/common';
import mongoose from 'mongoose';
import { Environment } from '../../environment';
import { ReceiptStatus } from '../constant';
import { PaymentConfigRepository } from '../repository/payment-config.repository';
import { ProductRepository } from '../repository/product.repository';
import { TransactionHistoryRepository } from '../repository/transaction-history.repository';
import { PaymentWrapper } from '../wrapper/payment.wrapper';

export class PaymentController {
constructor(
private environment = new Environment()
) {
// intentionally blank
}

/**
* initializes a payment
* @param mongodb_provider mongodb provider
Expand Down Expand Up @@ -103,13 +119,15 @@ export class PaymentController {
* returns refreshed transaction history
* @param mongodb_provider
* @param postgresql_provider
* @param message_queue_provider
* @param username
* @param payment_config_key
* @param transaction_history_id
*/
verifyPayment = async (
mongodb_provider: MongoDbProvider,
postgresql_provider: PostgreSqlProvider,
message_queue_provider: MessageQueueProvider,
username: string,
payment_config_key: string,
transaction_history_id: string
Expand All @@ -129,24 +147,24 @@ export class PaymentController {
const paymentWrapper = new PaymentWrapper( paymentConfig.payload.method );

if ( !mongoose.isValidObjectId( transaction_history_id ) ) {
throw new Error( 'transaction not found' )
throw new Error( 'transaction not found' );
}

const transactionHistoryRepository = await new TransactionHistoryRepository().initialize(
mongodb_provider.getConnection()
);

const transaction_history = await transactionHistoryRepository.findTransactionHistory( transaction_history_id )
const transaction_history = await transactionHistoryRepository.findTransactionHistory( transaction_history_id );

if ( !transaction_history ) {
throw new Error( 'transaction not found' )
throw new Error( 'transaction not found' );
}

if ( transaction_history.username !== username ) {
throw new Error( 'Bad request' );
}

// if current status is succeeded, do not check it again from payment provider
// If current status is succeeded, do not check it again from payment provider
if ( transaction_history.payload.transaction_history.status === paymentWrapper.paymentMethod?.getSuccessStatus() ) {
return;
}
Expand All @@ -162,15 +180,23 @@ export class PaymentController {
refreshed_transaction_history
);

await paymentWrapper.receiptStatusUpdate(
const status = await paymentWrapper.receiptStatusUpdate(
postgresql_provider,
paymentConfig,
transaction_history.external_transaction_id,
updated_transaction_history
);

if ( status && ReceiptStatus.SUCCESS === status ) {
await this.sendPaymentSuccessNotificationToQueue( message_queue_provider, {
timestamp: new Date().getTime(),
username: updated_transaction_history.username,
message: 'Product paid successfully'
} );
}

if ( updated_transaction_history.payload.transaction_history.status !== paymentWrapper.paymentMethod?.getSuccessStatus() ) {
throw new Error( 'Payment not found' )
throw new Error( 'Payment not found' );
}

} catch ( error ) {
Expand Down Expand Up @@ -219,12 +245,14 @@ export class PaymentController {
* refreshes transaction history
* @param mongodb_provider mongodb provider
* @param postgresql_provider postgresql provider
* @param message_queue_provider
* @param payment_config_key payment config key
* @param external_transaction_id external transaction id
*/
refreshTransactionHistory = async (
mongodb_provider: MongoDbProvider,
postgresql_provider: PostgreSqlProvider,
message_queue_provider: MessageQueueProvider,
payment_config_key: string,
external_transaction_id: string
) => {
Expand Down Expand Up @@ -256,12 +284,21 @@ export class PaymentController {
transaction_history
);

await paymentWrapper.receiptStatusUpdate(
const status: string = await paymentWrapper.receiptStatusUpdate(
postgresql_provider,
paymentConfig,
external_transaction_id,
updated_transaction_history
);

if ( status && ReceiptStatus.SUCCESS === status ) {
await this.sendPaymentSuccessNotificationToQueue(message_queue_provider, {
timestamp: new Date().getTime(),
username: updated_transaction_history.username,
message: 'Product paid successfully'
});
}

} catch ( error ) {
console.error( '> refreshTransactionHistory error: ', error );
throw error;
Expand Down Expand Up @@ -305,4 +342,26 @@ export class PaymentController {
throw error;
}
};

private async sendPaymentSuccessNotificationToQueue(
messageQueueProvider: MessageQueueProvider,
notificationParams: NotificationParams
) {
const orchestrationChannelTag = this.environment.args().mqArgs?.orchestrationServerMessageQueueChannel;

const message = {
sender: MessageQueueChannelType.PAYMENT,
receiver: MessageQueueChannelType.BUSINESS_LOGIC,
message: {
notification: {
params: notificationParams
}
} as BusinessLogicActionType,
} as QueueMessage;

await messageQueueProvider.publish(
message,
orchestrationChannelTag as string
);
}
}
2 changes: 1 addition & 1 deletion app/controller/receipt.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class ReceiptController {
* @param product_id product id
* @returns successful receipts
*/
getSuccesfulReceipts = async (
getSuccessfulReceipts = async (
postgresql_provider: PostgreSqlProvider,
username: string,
product_id: string
Expand Down
2 changes: 1 addition & 1 deletion app/interface/payment-method.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface PaymentMethod {
paymentConfig: PaymentConfig,
external_transaction_id: string,
updated_transaction_history: any
): Promise<void>;
): Promise<string>;

/**
* creates a product
Expand Down
10 changes: 8 additions & 2 deletions app/provider/coinbase-payment.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export class CoinbasePayment implements PaymentMethod {
paymentConfig: PaymentConfig,
external_transaction_id: string,
updated_transaction_history: any
) => {
): Promise<string> => {
if (
updated_transaction_history &&
updated_transaction_history.payload.transaction_history &&
Expand Down Expand Up @@ -180,6 +180,8 @@ export class CoinbasePayment implements PaymentMethod {
.local.currency
);

const success = ReceiptStatus.SUCCESS;

await receiptRepository.createReceipt( {
username: updated_transaction_history.username,
external_transaction_id,
Expand All @@ -188,12 +190,16 @@ export class CoinbasePayment implements PaymentMethod {
created_time: new Date(),
total_amount: amount,
currency_code,
status: ReceiptStatus.SUCCESS
status: success
}
);

return success;
}
}
}

return '';
};

/**
Expand Down
3 changes: 2 additions & 1 deletion app/provider/google-payment.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ export class GooglePayment implements PaymentMethod {
paymentConfig: PaymentConfig,
external_transaction_id: string,
updated_transaction_history: any
) => {
): Promise<string> => {
// Todo: Implement
return '';
};

/**
Expand Down
12 changes: 9 additions & 3 deletions app/provider/paypal-payment.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ export class PayPalPayment implements PaymentMethod {
paymentConfig: PaymentConfig,
external_transaction_id: string,
updated_transaction_history: any
) => {
console.log( 'receiptStatusUpdate: ' );
): Promise<string> => {

if (
updated_transaction_history &&
updated_transaction_history.payload.transaction_history &&
Expand Down Expand Up @@ -193,6 +193,8 @@ export class PayPalPayment implements PaymentMethod {
}
);

const success = ReceiptStatus.SUCCESS;

await receiptRepository.createReceipt(
{
username: updated_transaction_history.username,
Expand All @@ -202,11 +204,15 @@ export class PayPalPayment implements PaymentMethod {
created_time: new Date(),
total_amount: amount,
currency_code,
status: ReceiptStatus.SUCCESS
status: success
}
);

return success;
}
}

return '';
};

/**
Expand Down
9 changes: 8 additions & 1 deletion app/provider/stripe-payment.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ export class StripePayment implements PaymentMethod {
paymentConfig: PaymentConfig,
external_transaction_id: string,
updated_transaction_history: any
) => {
): Promise<string> => {

if ( updated_transaction_history?.payload?.transaction_history?.status === this.SUCCESS_STATUS ) {

const receiptRepository = new ReceiptRepository( dbConn );
Expand All @@ -157,6 +158,8 @@ export class StripePayment implements PaymentMethod {
updated_transaction_history.payload.transaction_history.currency
);

const success = ReceiptStatus.SUCCESS;

await receiptRepository.createReceipt( {
username: updated_transaction_history.username,
external_transaction_id,
Expand All @@ -167,8 +170,12 @@ export class StripePayment implements PaymentMethod {
currency_code,
status: ReceiptStatus.SUCCESS
} );

return success;
}
}

return '';
};

/**
Expand Down
2 changes: 1 addition & 1 deletion app/repository/transaction-history.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export class TransactionHistoryRepository {

/**
* finds transaction history using document_id
* @param id
* @param _id
*/
findTransactionHistory = async (
_id: string
Expand Down
11 changes: 9 additions & 2 deletions app/route/payment.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ const subRoutes = {

export const router = Router();

const paymentController = new PaymentController();

router.post(
subRoutes.root,
authorizedBy([UserRole.ADMIN, UserRole.DEFAULT]),
async (req: Request, res: Response) => {
// Create new payment session
const context = res.locals.ctx;

const paymentController = new PaymentController();

let paymentSession = await paymentController.initPayment(
context.mongodb_provider,
context.username,
Expand All @@ -46,9 +46,12 @@ router.post(
async (req: Request, res: Response) => {
const context = res.locals.ctx;

const paymentController = new PaymentController();

await paymentController.verifyPayment(
context.mongodb_provider,
context.postgresql_provider,
context.message_queue_provider,
context.username,
req.body.payment_config_key,
req.body.transaction_history_id
Expand All @@ -65,6 +68,8 @@ router.post(
// Create new payment session
const context = res.locals.ctx;

const paymentController = new PaymentController();

let external_transaction_id = await paymentController.confirmPayment(
context.mongodb_provider,
req.body.payment_config_key,
Expand All @@ -82,6 +87,8 @@ router.post(
// Init payment with external transaction id
const context = res.locals.ctx;

const paymentController = new PaymentController();

let paymentSession =
await paymentController.initPaymentWithExternalTransactionId(
context.mongodb_provider,
Expand Down
2 changes: 1 addition & 1 deletion app/route/receipt.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ router.get(
// gets successful receipts
const context = res.locals.ctx;

const successful_receipts = await receiptController.getSuccesfulReceipts(
const successful_receipts = await receiptController.getSuccessfulReceipts(
context.postgresql_provider,
context.username,
req.query.product_id as string
Expand Down
Loading

0 comments on commit 0939bb9

Please sign in to comment.