Credit Record Processing - v3

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

Credit Record Processing

When dealing with System to Instructor payments there are two types of systems involved:

 Database
 External Payment Gateway

These two systems are not coordinated and they do not participate in distributed transaction. Under
such circumstances we can have situation where money were transferred to target Instructor account
(PayPal) but the database tracking records were not updated. For example, Instructor Course CREDIT
Transaction was not updated as completed due to intermittent database failure. In this unhappy
scenario, the same CREDIT Instructor Course Transaction will be reprocessed and the same amount will
be transferred to the Instructor account (which is not desirable at all).

In order to deal with such scenario we shall process CREDIT transactions by separating the logic into
multiple successive database transactions. Before trying to pay with PayPal (or another payment
gateway), we must set the Instructor Course Transaction status to PROCESSING. After PayPal payment
operation has been finished the Instructor Course Transaction’s status shall be updated accordingly.

However if something unexpected happens and Instructor Course transaction remains in PROCESSING
state, we must always check with PayPal, based on the Payment’s Reference Id if that payment
succeeded or not.

Before processing Instructor Course instructions in INITIALIZED state, the system must check and
sanitize ALL CREDIT Instructor Course Transactions left in PROCESSING state because of:

1. PayPal communication error

2. Database was not available after PayPal response was received

This is system undetermined state and we need to query the payment gateway and check the status of
the payment (by its reference id or additional tokens).

If the system finds some Instructor Course transactions as completed, the credit process for those
transactions will be completed (amount deduced from Instructor Course and the statuses will be set to
COMPLETED). If some Instructor Course transactions were not completed at Pay Pal side, they will be re-
initialized for repetition by setting their status to INITIALIZED.

Algorithm CHECK_CREDIT_RECORD
BOOLEAN FUNCTION CHECK_CREDIT_RECORD

INPUT:

InstructorCourseTransaction (in PROCESSING state),

PaymentGatewayUnavailableMap

BEGIN

BEGIN TRANSACTION

//Load associated payment


Payment=LOAD_ASSOCIATED_PAYMENT

InstructorCourse=LOAD_INSTRUCTOR_COURSE

END TRANSACTION

IF PaymentGatewayUnavailableMap[Payment.PaymentGatewayType]=TRUE THEN

RETURN FALSE

END IF

PaymentGateway= Locate based on Payment.PaymentGatewayType

ReferenceId=Construct with concatenation on ‘IC’, Payment.ReferenceId, CreatedOn

TransferAmount=Payment.Amount (or InstructorCourseTransaction.Amount)

PaymentTransaction=NULL

TRY

PaymentTransaction =CHECK_PAYMENT_STATUS(ReferenceId)

CATCH EXCEPTION

//Communication error with the Payment Gateway

PaymentGatewayUnavailableMap[Payment.PaymentGatewayType]=TRUE

RETURN FALSE

END CATCH

IF PaymentTransaction.COMPLETED

BEGIN TRANSACTION

//use HQL

UPDATE InstructorCourse

SET Amount=Amount-TransferAmount

//use HQL

UPDATE Payment

SET Status=COMPLETED
SET ExternalPaymentGatewayId= PaymentTransaction.TransactionId

//use HQL

UPDATE InstructorCourseTransaction

SET Status=COMPLETED

END TRANSACTION

ELSE

PAYMENT_ERROR_LOG:

Payment Gateway Type

Payment Id
Payment Reference Id Type

Payment Reference Id

Payment Creation Time

Payment Update Time

PaymentTransaction.Status

PaymentTransaction.TransactionId

PaymentTransaction.Message

Action=NOTIFICATION

BEGIN TRANSACTION

//use HQL

UPDATE InstructorCourseTransaction

SET Status=INITIALIZED

//use HQL

UPDATE Payment

SET Status=CANCELED

END TRANSACTION

END IF

RETURN TRUE

END FUNCTION

Note: All exceptions thrown from the CHECK_PAYMENT_STATUS function will mark the Payment
Gateway as temporary unavailable. The function in that case returns FALSE which is Boolean marker for
(pending) postponed processing.

Algorithm CREDIT_RECORD
BOOLEAN FUNCTION CREDIT_RECORD

INPUT:

InstructorCourseTransaction

PaymentGatewayUnavailableMap

BEGIN

InstructorCourse= NULL

PaymentGateway =NULL

BEGIN TRANSACTION

PaymentGateway=OBTAIN_PAYMENT_GATEWAY_FOR_THE_INSTRUCTOR
END TRANSACTION

IF PaymentGateway IS NULL

//this is the case when instructor does not have valid payment gateway account

BEGIN TRANSACTION

UPDATE InstructorCourseTransaction

SET Status CANCELED

END TRANSACTION

RETURN TRUE

END IF

IF PaymentGatewayUnavailableMap[PaymentGateway.Type]=TRUE THEN

//Postpone processing for this record and move forward

RETURN FALSE;

END IF

InstructorCourse=LOAD_INSTRUCTOR_COURSE

Amount=InstructorCourse.AccruedAmmount

MaxAmount=PaymentGateway.maxTransferAmount

MinAmount=PaymentGateway.minTransferAmount

CurrentInstructorCourseTransaction=InstructorCourseTransaction

CurrentPayment=NULL

IF (Amount<=0) THEN

BEGIN TRANSACTION

UPDATE InstructorCourseTransaction

SET Status CANCELED

END TRANSACTION

RETURN TRUE

END IF

WHILE (Amount >0)

IF (Amount>MaxAmount)

TransferAmount=MaxAmount

ELSE

TransferAmount=Amount

END IF
Amount=Amount-TransferAmount

IF (TransferAmount <MinAmount)

IF CurrentInstructorTransaction IS NOT NULL

BEGIN TRANSACTION

//use update HQL (don’t merge and save)

UPDATE CurrentInstructorCourseTransaction

SET Amount=TransferAmount

SET Status=CANCELED

END TRANSACTION

END IF

//exit the while loop

BREAK

END IF

BEGIN TRANSACTION

CurrentPayment= GENERATE_PAYMENT

SET Amount=TransferAmount

SET CreatedOn=Current Date

SET UpdatedOn=Current Date

SET ReferenceIdType=’IC’

SET ReferenceId=Instructor Course’s ReferenceId

SET Status=PROCESSING

IF CurrentInstructorCourseTransaction IS NULL

//generate with status PROCESSING, TransferAmount and Payment reference

CurrentInstructorCourseTransaction=GENERATE_INSTRUCTOR_COURSE_INSTRUCTION

ELSE

//use HQL

UPDATE CurrentInstructorCourseTransaction

SET Amount=TransferAmount

SET Payment=CurrentPayment

SET Status=PROCESSING

END IF

END TRANSACTION
//the payment reference id used must be proper concatenation of the current
//payment attributes: IC_REFERENCE_ID_TIMESTAMP

PaymentTransaction=NULL

TRY

PaymentTransaction =PAY_WITH_EXTERNAL_PAYMENT_GATEWAY

CATCH EXCEPTION

PaymentGatewayUnavailableMap[PaymentGateway.Type]=TRUE

RETURN FALSE

END CATCH

IF PaymentTransaction.COMPLETED

BEGIN TRANSACTION

//use HQL

UPDATE InstructorCourse

SET Amount=Amount-TransferAmount

//use HQL

UPDATE CurrentPayment

SET Status=COMPLETED
SET ExternalPaymentGatewayId= PaymentTransaction.TransactionId

//use HQL

UPDATE CurrentInstructorCourseTransaction

SET Status=COMPLETED

END TRANSACTION

ELSE

PAYMENT_ERROR_LOG:

Payment Gateway Type

Payment Id

Payment Reference Id Type

Payment Reference Id

Payment Creation Time

Payment Update Time

PaymentTransaction.Status

PaymentTransaction.TransactionId

PaymentTransaction.Message

Action=NOTIFICATION

BEGIN TRANSACTION
//use HQL

UPDATE CurrentInstructorCourseTransaction

SET Status=CANCELED

//use HQL

UPDATE CurrentPayment

SET Status=CANCELED

END TRANSACTION

END IF

CurrentInstructorCourseTransaction=NULL

END WHILE

RETURN TRUE

END FUNCTION

Payment Error Log Procedure

Payment Error Log procedure shall obey to the following rules:

 Define Service Interface: PaymentErrorNotifierService with single method:


notify(PaymentError paymentError); this method shall not throw an error under no
circumstances.
 Create default implementation for the interface that will:
o Log comma separated values into separate SLF4j Logger (rolling appender, “payment-
error.log”_.
o Send notification e-mails to the administrator. The mail notification shall be configurable
in order to specify for which Reference Id Types the system shall send an e-mails.

The scheduled procedure for processing Instructor Course Transaction is the following:

PROCEDURE PROCESS_INSTRUCTOR_COURSE_TRANSACTIONS

INPUT: MaxPendingInterval, PaymentGateways

BEGIN

CommittedId=-1

TempId=CommitedId

PendingDate=NULL
PaymentGatewayUnavailableMap=[] //empty map

WHILE TRUE

IF (TempId=-1 OR

PendingDate <>NULL AND CurrentDate - PendingDate >=MaxPendingInterval) THEN

PendingDate=NULL

TempId=CommitedId

//empty the map with unavailable payment gateway markers

PaymentGatewayUnavailableMap=[]

ProcessingTransactions=Select InstructorCourseTransactions in ‘PROCESSING’ state

FOR EACH InstructorCourseTransaction IN ProcessingTransactions DO

Success=CHECK_CREDIT_RECORD(

InstructorCourseTransaction,

PaymentGatewayUnavailableMap)

IF Success=FALSE AND PendingDate=NULL THEN

PendingDate=CurrentDate

//If all gateways are unavailable, stop the processing

IF COUNT(PaymentGateways)=COUNT(PaymentGatewayUnavailableMap) THEN

RETURN

END IF

END IF

END FOR

END IF

InstructorCourseTransactions=

SELECT InstructorCourseTransactions in ‘INITIALIZED’ state WHERE Id>TempId

ORDER BY Id LIMIT N

IF InstructorCourseTransactions IS EMPTY THEN

//exit the procedure, it will repeated by the scheduler after that

RETURN
END IF

FOR EACH InstructorCourseTransaction in InstructorCourseTransactions

TempId=InstructorCourseTransaction.Id

IF InstructorCourseTransaction IS DEBIT THEN

DEBIT_RECORD (InstructorCourseTransaction)

ELSE

Success= CREDIT_RECORD(

InstructorCourseTransaction,

PaymentGatewayUnavailableMap)

IF Success=FALSE AND PendingDate=NULL THEN

PendingDate=CurrentDate

//If all gateways are unavailable, stop the processing

IF COUNT(PaymentGateways)=COUNT(PaymentGatewayUnavailableMap) THEN

RETURN

END IF

END IF

END

END FOR

IF PendingDate=NULL THEN

CommitedId=TempId

END IF

END WHILE

END PROCEDURE

Billing process, PUH and Instructor Course Transaction Processing

The billing process is created once in a month. Its first state is INITIALIZED. Once all CREDIT Instructor
Course transaction are generated its state shall go into SUBMITTED.

The whole billing process shall follow the steps outlined below.
PROCEDURE BILL

Get the latest billing record

IF billing status IS NOT COMPLETED THEN

Process PUH Payments

IF

There was no error during PUH processing (unavailable gateway)

AND

billing state is SUBMITTED THEN

Get the latest InstructorCourse CREDIT transaction (with max id)

IF instructorCourse transaction status is COMPLETED OR CANCELED THEN

//from this moment on, the system can generate another billing process

SET the billing’s status to COMPLETED

END IF

END IF

END IF

END IF

Process Instructor Course Transactions

END PROCEDURE

You might also like