Implementation Guide for Oracle Self-Service E-Billing > Customizing Payment >

About Recurring Payment Processing


The recurring payment feature is very complex, involving a great deal of business logic. This topic discusses the recurring payment processing in detail.

Recurring payments consist of actions at the front-end (UI) and back end (Command Center jobs). The UI allows a user to insert, update, and delete a recurring payment, and the back end pmtRecurPayment job makes the payment.

The changes to the information in the recurring_payments table are described in Table 69, showing how payment works.

Table 69. Changes in the Recurring Payments Table
Column Name
Comment

AMOUNT_TYPE and AMOUNT

These two columns record how the payment amount is generated. They are only updated through the UI and are used by back-end jobs to calculate how much to pay. The valid values of AMOUNT_TYPE are:

  • Fixed amount. Pay a fixed amount and the amount value is specified by AMOUNT column.
  • Amount due. Pay amount due on the bill and, AMOUNT column is not used (null).
  • Minimal due. Pay minimum amount due on the bill and AMOUNT column is not used (null).
  • Less due. Pay the amount due if it is less than the value of the AMOUNT column; otherwise, pay nothing and send email notification.
  • Upto amount. Pay the amount due if it is less than the value of the AMOUNT column; otherwise, pay the value of AMOUNT and send email notification.

PAY_INTERVAL DAY_OF_PAY_INTERVAL

MONTH_OF_PAY_INTERVAL

These three columns record how the payment date is generated. They are only updated through the UI, and are used by back-end jobs to calculate when to pay. Valid PAY_INTERVAL values are:

  • Weekly. User-specified to make payments weekly. The day of week is specified by DAY_OF_PAY_INTERVAL. The MONTH_OF_PAY_INTERVAL is irrelevant.
  • Monthly. User-specified to make payments monthly. The day of month is specified by DAY_OF_PAY_INTERVAL. The MONTH_OF_PAY_INTERVAL is irrelevant.
  • Quarterly. User-specified to make payments quarterly. The day of month is specified by DAY_OF_PAY_INTERVAL. The month of quarter is specified by MONTH_OF_PAY_INTERVAL (one of 1,2 or 3).

START_DATE

END_DATE

CURR_NUM_PAYMENTS

MAX_NUM_PAYMENTS

STATUS

These columns determine when to start the recurring payment and when to stop it. START_DATE, END_DATE and MAX_NUM_PAYMENTS can only be updated through the UI.

START_DATE is required, but you set only one of the END_DATE (end by that date) or MAX_NUM_PAYMENTS (end when this number of payments is made).

The recurring payment STATUS is active when it is created and it has not reached either END_DATE or MAX_NUM_PAYMENTS. When one of them is reached, the STATUS is changed to inactive and the recurring payment will never take effect again.

If END_DATE is chosen, NEXT_PAY_DATE (the pay date for the next bill to be paid) is greater than or equal to START_DATE and less then or equal to END_DATE, the bill will be paid. The STATUS is set to inactive if NEXT_PAY_DATE > END_DATE.

If MAX_NUM_PAYMENTS is chosen, the STATUS is changed to inactive when CURR_NUM_PAYMENTS reaches MAX_NUM_PAYMENTS.

LAST_PAY_DATE

This is the pay date of last bill. It is set to 01/07/1970 when recurring payment is created to indicate that there is valid information.

NEXT_PAY_DATE

This is the pay date of next bill. When the recurring payment job runs, it schedules a payment with a pay date of NEXT_PAY_DATE. Note, NEXT_PAY_DATE is calculated based on LAST_PAY_DATE and PAY_INTERNAL.

Recurring Payment UI

This topic discusses the actions of the recurring payment UI.

The UI sets up a recurring payment: the UI allows you to insert/update/delete a recurring payment and get back the list of recurring payments.

Figure 11 illustrates the objects involved in the process.

Figure 11. Objects Involved in the Recurring Payment User Interface

Retrieving and deleting recurring payments from the database is straightforward, so the next topics discuss what happens when a recurring payment is inserted or updated.

Insert Recurring Payment From UI

Figure 12 demonstrates what happens when a recurring payment is inserted into database using the UI.

Figure 12. Recurring Payment Inserted into the Database Using the User Interface
Click for full size image

The next topic explains RecurringPaymentUtil.calculateInternal(). This method calculates the next_pay_date and status of the recurring payment before it is being inserted into database.

This method calculates the internal states of recurring payment differently for insert and update. For the insert operation, this method performs the following tasks:

  1. Call init() method: this method sets some of the recurring payment fields.
    • If the user chooses to end recurring payment by maximum number of payments, set end_date to 01/01/3000 00:00:00.
    • If the user chooses to end recurring payments by a fixed date, set max_num_payments it java.lang.Integer.MAX_VALUE.
    • Set last_pay_date to 01/01/1970 00:00:00; this means no bill has been paid.
    • Set bill_scheduled to Y if the recurring payment is fixed amount and fixed date. Note, in this case, the flag is always true because whenever a payment is made, the next payment is calculated. It has the same effect as making the next bill available immediately.
    • Set last_process_time to start_date, which by default must be tomorrow or later. This means that any bills indexed through today (inclusive) will not be picked up by recurring payment. The recurring payment UI checks whether there are unpaid bills when a recurring payment is setup, and reminds the user to make a one-time payment to pay the outstanding bill.
  2. Call the checkSynchronization method: Checks whether any required information is missing from recurring payment before inserting it into the database.
  3. Check whether the recurring payment has expired by checking the current number of payments against maximum number of payments. Note, this check always return false for insert case.
  4. Calculate the next_pay_date by calling one of calculateMonthly(), calculateQuarterly(), calculateWeekly() or calculateBeforeDue() depending on whether pay_interval is "monthly", "quarterly" or "weekly" or "before_due" respectively.
    • Call calculateMonthly() when pay_interval is "monthly"

      This method calculates the next pay date, which is based on last_pay_date, start_date and day_of_pay_internal. Because last_pay_date is 01/01/1970, the next_pay_date is the nearest date with day_of_pay_internal after the start_date. If date_of_pay_internal is 29, 30 or 31 and there is no such date in that month, the last day of that month is used. After next_pay_date is calculated, it is checked against the end_date. If next_pay_date passes the end_date, the status of the recurring payment is set to "inactive".

      The following table displays some examples of how next_pay_date is calculated:

      Day_of_pay_interval
      Start_date
      Next_pay_date

      1

      Sep 10

      October 1

      10

      Sep 10

      September 10

      15

      Sep 10

      October 15

      31

      Sep 10

      September 30

    • Call calculateQuarterly() when pay_interval is "quarterly": works similar to "monthly"
    • Call calculateWeekly() when pay_interval is "weekly": works similar to "weekly".
    • Call calculateBeforeDue() when pay_interval is "before due": because there is no bill yet (bill due date is null), the recurring payment status is set to active and the next_pay_date is set to 01/01/3000.
Update Recurring Payment From the UI

This topic assumes that the UI prevents a user from updating a recurring payment from fixed date to before due date or conversely. If the UI is changed to allow a user to do so, the behavior of recurring payment is not tested.

Figure 13 demonstrates what happens when a recurring payment is updated using the UI into the database.

Figure 13. Recurring Payment Inserted into the Database Using the Database
Click for full size image

The RecurringPaymentUtil.calculateInternal() method calculates the next_pay_date and the status of the recurring payment before it is inserted into database. Note that this method is also used for update by the back-end job.

The following example shows how this method processes starting with iRecurringPaymentLog.update():

  1. Call IRecurringPaymentLog.update()
  2. Call RecurringPaymentUtil.calculateInternal()
  3. Call checkSynchronization() method to check whether the information required for recurring payment is present.
  4. If checkSynchronization() throws an exception indicating missed information, then:
    • Call synchronize() method to read the missed information from the database and populate the missing information into the recurring payment object.
    • Call checkSynchronization() again to make sure the required information has been populated.
    • Call init() method: unlike the insert operation, this method checks whether the recurring payment has started or not by checking the last_pay_date (01/01/1970 means not started yet) and then sets the last process time to the start_date of the recurring payment if the recurring payment has not been started. The last process time will not be updated if recurring payment has been started.
  5. Check whether the recurring payment has expired by checking the current number of payments against maximum number of payments. If true, set the recurring payment as inactive and return.
  6. Calculate next_pay_date and recurring payment status by calling one of calculateMonthly(), calculateQuarterly() or calculateWeekly() based on pay_interval of monthly, quarterly or weekly.
    1. Call calculateMonthly() when pay_interval is monthly, to calculate the next pay date.
    2. If the last_pay_date is 01/01/1970, then the next_pay_date is calculated based on the start_date and day_of_pay_interval. It is set to the nearest date with day_of_pay_interval as day of month after the start_date. This is the same as the insert case.
    3. If the last_pay_date is not 01/01/1970, that means that recurring payment has started, so the next_pay_date is calculated based on the last_pay_date and day_of_pay_interval. It is set to the date one month after the last_pay_date. The calculation does not depend on the current date. For example, if the recurring payment job runs today on October 1, the last_pay_date is Aug 30 and day_of_pay_interval is 30, the next_pay_date will be Sep 30 (not October 30 ) even though this date is in the past. In the case of fixed date and pay amount due, this can pose a problem if there is no bill for a certain month: the pay date will be in the past. To fix the problem, the recurring payment job will move the last_pay_date ahead by one month if there is no bill for that month. See following discussion for more details about the recurring payment job.
    4. If day_of_pay_interval is 29, 30 or 31 and there is no such date in that month, the last day of that month is used.

      After next_pay_date is calculated, it is checked against the end_date and if it passes the end_date, the status of the recurring payment is set to inactive.

    • Call calculateQuarterly() when pay_interval is quarterly, it works similarly to monthly.
    • Call calculateWeekly() when pay_interval is weekly, it works similar to weekly.
    • Call calculateBeforeDue() when pay_interval is before_due:

      First check whether the recurring payment has been synchronized (bill due date not null) and if so, set status to active and next pays date to 01/01/3000 and return.

      Calculate the proposed next pay date by current bill due date and day_of_internal.

      If the proposed next_pay_date is before start_date, set the status of recurring payment to active and next_pay_date to 01/01/3000 and return: the bill will not be paid in this case because it falls outside the effective period of the recurring payment.

      If the proposed next pay date is after end_date, set the status of recurring payment to inactive and set the next_pay_date to 01/01/3000 and return.

      Otherwise, set the status of the recurring payment to active and set its next_pay_date to the proposed next pay date.

Recurring Payment - Back-End Job

The pmtRecurringPayment job gets bills from the Command Center and then schedules payments. The first process is called synchronization and the second process is called scheduling.

Recurring Payment Synchronization

During the synchronization process, the job retrieves a list of recurring payments to be synchronized, and then tries to get the bills for the recurring payments from the Command Center. Figure 14 illustrates this process.

Figure 14. The Recurrent Payment Synchronization Process
Click for full size image

Figure 15 shows the synchronization.

Figure 15. Recurring Payment Synchronization
Click for full size image

Synchronization follows these steps:

  1. RecurPaymentTask.executeTask() is called when the job runs, which calls RecurringPaymentTask.synchronizeSummary().
  2. RecurringPaymentTask.synchronizeSummary() is called. This method does the real work of synchronization and following are the actions taken in this method.
  3. IRecurringPaymentLog.getRecurringPaymentsToBeSynchronized() is called to get a list of recurring payments to be synchronized. The query result is affected by the recurring payment job configuration parameter When to Synchronize Recurring Payment with Oracle. When this configuration is Whenever job runs, all the recurring payments are retrieved from the recurring_payments table with payee_id as the job DDN and status as active. If Only after current bill is scheduled is selected, then all payments with the payee_id as job DDN and status as active" and bill_scheduled as Y are retrieved from the recurring_payments table.
  4. For each recurring payment, IRecurringPaymentPlugIn.preGetLatestSummary() is called. This method allows the recurring payment plug-in code to decide whether to retrieve bills for a particular recurring payment based on biller-specific business rules.
  5. Call RecurPaymentTask.updateRecuringPaymentOnly() if the plug-in rejects this recurring payment by returning PRE_GET_LATEST_SUMMARY_REJECT. This method performs these functions:
    • Update last_process_time to the current time.
    • If the recurring payment pay date is fixed date (monthly/quarterly/weekly) and pay amount is based on (minimum) amount due, and no bill arrives for this pay period (bill_scheduled is Y and current time is after the current next_pay_date), the last_pay_date is updated to current next_pay_date. This ensures that if no bill arrives for this pay period; the next bill will be paid on the correct date.
    • Call IRecurringPayment.update(): this method calculates the next_pay_date based on the current last_pay_date.
  6. Call IBillDepot.getNewBillSummary(). This interface is implemented by com.edocs.payment.imported.eadirect.BillDepot. The BillDepot class retrieves the latest bill summary for the specified account.
    • BillDepot.getNewBillSummary() is called, which then calls BillDepot.getSummary().
    • BillDepot.getSummary() is called. This method calls IDataSource.getDocumentSummary() to get all the bills indexed for this account between the last_process_time of the recurring payment and the current job run time.
    • The returned bills are in the format of name value pairs with value of string. They are interpreted to retrieve due date, amount due and/or minimum amount due.
      • For each bill, if minimum amount due is not null, call BillDepot.preParseMinAmountDue() to give a child class of BillDepot (through the plug-in) a chance to manipulate the minimum amount due string before it is parsed, then it parses min amount due.
      • If the bill's amount due is not null, call BillDepot.preParseAmountDue() to give child class of BillDepot (through the plug-in) a chance to manipulate the amount due string before it is parsed, then it parses the amount due. If the amount due fails to parse, the bill is ignored.
      • If the bill has no amount due, or its amount due is set to null by preParseAmountDue(), or the amount due failed parsing, then the bill is ignored.
      • If the bill's due date is not null, call BillDepot.preParseDueDate() to give child class of BillDepot (through the plug-in) a chance to manipulate the due date string before it is parsed, then it parses the due date.
      • If the bill has no due date, or its due date is set to null by preParseAmountDue(), or the due date failed parsing, then the bill is ignored.
    • All the successfully parsed bills are compared with the bill summary associated with the current recurring payment, if the summary is not null. The following business rules are used to decide which bill is the latest one:

      The due dates of the bill summaries retrieved are compared and the one with latest due date is chosen.

      For rebill, multiple bills with the same due date can be retrieved. In this case, a rebill is chosen based on the following rules: the one with latest doc date and in case of the same doc date, the one with the larger IVN number. This assumes that a rebill is indexed after its original bill. A rebill will be ignored if its original bill has been paid (the bill_scheduled flag of recurring payment is Y).

    • BillDepot.Summary() returns the latest bill if there is one found, otherwise, it returns null.
Recurring Payment Scheduling

Recurring payment scheduling processes as follows:

  1. Call RecurPaymentTask.isValidBillSummar() to validate the latest retrieved bill summary. The latest bill summary could be ignored if it has no bill due date, or if the recurring payment is based on minimum amount due but the bill summary has no minimum amount due, or the recurring payment is based on amount due but the bill summary has no amount due.
  2. Now you have a valid bill summary. If the payment to the previous bill summary is still in scheduled status, it does the following:
    • Call RecurPaymentTask.cancelScheduledPayment() to cancel this payment. The reason to cancel it is that the new bill summary just retrieved must include the balance of this scheduled bill, cancel the payment so that it will not pay the same bill twice.
    • Call RecurPaymentTask.modifyLastPayDate(): If a recurring payment has a fixed pay date, but the amount is based on amount due or minimum amount due, it is necessary to back date the last pay date because the previous bill payment has been cancelled. Failing to do so will cause the current new bill being paid in next pay interval, not the current one. For example, assume that current bill cycle is October, the previous bill was retrieved on October 10 and is scheduled to pay on October 15. As a result, the last_pay_date and next_pay_date of the recurring payment are updated to October 15 and November 15, respectively. On October 11, a new bill is retrieved and the payment is scheduled. If Oracle Self-Service E-Billing does not back up the last_pay_date, the new bill will be scheduled to pay on November 15. But in this case, it is necessary to pay the bill on October 15 because it is still in the October billing cycle. To fulfill this goal, go back date the last_pay_date to Sep 15 so the next_pay_date will be calculated as October 15, which will be used as the pay date for the new bill.
  3. Call RecurPaymentTask.insertNewBillAndUpdateRecurring(), which inserts the retrieved new bill and updates recurring payment accordingly.
    • Call IRecurringPaymentPlugIn.preInsertLatestSummary() before inserting the bill summary in the payment_bill_summaries table.
    • If PRE_INSERT_LATEST_SUMMARY_REJECT is returned from the plug-in, call RecurPaymenTask.updateRecurringPaymentOnly() and return. See step 5 for details about what this method does.
    • Call IBillSummaryLog.insert() to insert this new bill summary.
    • If IBillSummaryLog.insert() throws DuplicateKeyException indicating that this bill is already in the database, so call RecurPaymenTask.updateRecurringPaymentOnly(). See step 5 for details about what this method does.
    • Set the bill_scheduled flag to N if the payment amount is not negative, or Y if it is negative. This means that no credit/reversal will be issued from recurring payment; the credit appears as part of the next bill.
    • Set the bill_id of the recurring payment to the one of the new bill summary.
    • Call IRecurringPaymentPlugIn.preUpdateSynchronizedRecurring().
    • If PRE_UPDATE_SYNCHRONIZED_RECURRING_REJECT is returned from the plug-in, call RecurPaymenTask.updateRecurringPaymentOnly() and return. See step 5 for details about what this method does.
    • Call IRecurringPaymentLog.update() to update the recurring payment. The following table lists the information being updated:
      Column
      Value

      last_pay_date

      In the case where the pay date is fixed, but amount is based on amount due, last_pay_date could be moved one pay_interval back if a scheduled payment is cancelled because a new bill arrives. Otherwise, last_pay_date will stay the same.

      next_pay_date

      Next_pay_date will be updated in RecurringPaymentUtil.calculateInternal(). In the case of fixed pay date, it will be updated based on last_pay_date; in case of before due, it will be updated based on the due date of the new bill. See Update Recurring Payment From the UI for more information.

      status

      Because next_pay_date is changed, the status could be changed to inactive if next_pay_date falls after end_date.

      bill_id

      It is set to the bill_id (doc ID) of the bill being inserted into the payment_bill_summaries table.

      bill_scheduled

      The bill_scheduled flag is set to N if the payment amount is not negative, Y if it is negative.

      last_process_time

      Set to the current time.

Recurring Payment Scheduling Workflow

Recurring Payment Scheduling Workflow schedules recurring payments for processing with the pmtRecurringPayment job. During scheduling processing, the pmtRecurringPayment job retrieves a list of recurring payments to be scheduled, and then schedules them, as shown in Figure 16.

Figure 16. Recurring Payment Scheduling Workflow
Click for full size image

Figure 17 shows the action sequence:

Figure 17. Recurring Payment Scheduling Action Sequence
Click for full size image

Workflow Description. This workflow performs the following actions:

  1. RecurPaymentTask.execute().
  2. RecurringPaymentTask.schedulePayments(). This step performs the scheduling work.
  3. IRecurringPaymentLog.getRecurringPaymentsToBeScheduled(). This step gets a list of recurring payments to be scheduled. The result is affected by the recurring payment job configuration parameter Number of days before pay date to schedule the payment, which is a number, N. The SQL query finds all the recurring payments where the payee_id is the job's DDN reference, bill_scheduled is N and next_pay_date is less than or equal to today plus N.
  4. IPayUserAccountAccessor.getPaymentAccount(). This step gets the current payment account information associated with this recurring payment. A sanity check is done on the retrieved payment account and different actions can be take based on the result:
    • If no payment account has been retrieved, which means it has been deleted from database, then the current recurring payment setup will be de-activated (IRecurringPaymentLog.update() is called to update status to inactive) and no payment is scheduled.
    • If the payment account is a check account, its status is cancelled, and the job configuration parameter "Cancel recurring payment if payment account is canceled?" is true, then the current recurring payment setup is de- activated (IRecurringPaymentLog.update() is called to update status to inactive) and no payment is scheduled.
    • If the payment account is a credit card account, it has expired, and the job configuration parameter Cancel recurring payment if payment account is canceled? is true, then the current recurring payment setup is de-activated (IRecurringPaymentLog.update() is called to update status to inactive) and no payment is scheduled.
  5. RecurPaymentTask.createPaymentTransaction(). This step creates a new payment transaction (either a check or a credit card) with status as scheduled and pay date and amount as specified by recurring payment setup.
  6. IRecurringPaymentPlugin.preSchedulePayment(). This step gives PS a change to customize the payment transaction before it is inserted into the database. If this method returns PRE_SCHEDUE_PAYMENT_REJECT, the payment will not be scheduled, and the program return to process next recurring payment. If not, the program will go to the next step to schedule the payment.
  7. ICheckPaymentLog.insert(). This step inserts a check or ICreditCardPaymentLog.insert() to insert a credit card if the amount of the payment is not negative (it will never be negative because the bill_scheduled will not be N if amount is negative. See job synchronization part for detail). The following table lists part of the payment information inserted into the payment tables:
    Column
    Value

    status

    6

    pay_date

    The next_pay_date (calculated during synchronization process) of the current recurring payment. Because recurring payment will be updated after this insert operation, this value is the same value as last_pay_date of the updated recurring payment.

    Amount

    This value is decided by amount_type and the amount of the recurring payment. It is calculated when RecurPaymentTask.createPaymentTransaction() is called. It must be the same as the amount column of the recurring payment if amount_type is Fixed. It must be the same as the amount_due or min_amount_due of the bill associated with current recurring payment if amount_type is amount due or minimal due, respectively. If amount_type is "less due", the payment amount is the amount due of the bill if amount due is less than or equal to the amount column value of the recurring payment. Otherwise, the payment amount value is 0. If amount_type is "upto amount", then the payment amount is the amount due of the bill if amount due is less than or equal to the amount column value of the recurring payment. Otherwise, the payment amount is the amount column value of the recurring payment.

    bill_id

    Same as the one from recurring_payment.

    Pid

    Same as the one from recurring_payment.

    payer_id

    Same as the one from recurring_payment.

    payer_acct_number

    Same as the one from recurring_payment.

  8. IRecurringPaymentLog.update(). This step updates the recurring payment. The following information of the recurring payment will be updated:
    Column
    Value

    Curr_num_payments

    Increased by 1

    Bill_scheduled

    N if pay date is on fixed date (monthly, quarterly or weekly) and pay amount is fixed amount, otherwise Y.

    Last_pay_date

    The last_pay_date is set to the current next_pay_date of the recurring payment.

    Next_pay_date

    After last_pay_date is set to the current next_pay_date, the next_pay_date is calculated again by RecurringPaymentUtil.calculateInternal(). If the payment is using a fixed pay date (weekly, quarterly or weekly), then next_pay_date is calculated and moved to the next pay date in the next pay interval. In case of before due date, the next pay date will be calculated based on the current due date (whose bill has been paid), so this next_pay_date has no meaning until the next bill is synchronized.

    Status

    Status is recalculated and will be changed to inactive if next_pay_date is after end_date, or curr_num_payments is greater than max_num_payments.

  9. IRecurringPaymentPlugIn.preSendEmail(). This step lets the plug-in customize the email being sent out. The email is not sent out if this method returns PRE_SEND_EMAIL_REJECT.
  10. Template.parse(). This step parses the email template and generates the content of email.
  11. PaymentMailer.send(). This step sends email.

Recurring Payment FAQ

This topic answers a few common questions about recurring payment.

  • Why is my current bill not paid by recurring payment after I set up my recurring payment?

    The recurring payment start date can only start from tomorrow, so the last_process_date is set to start from tomorrow. This means all the bills indexed before today will not be processed by the recurring payment. The reason is that, currently, there is no reliable way for recurring payment to know whether the current bill has been paid or not. The user might have paid it through a one-time payment or through paper check. To avoid paying the bill twice, recurring payment will only start processing bills indexed since tomorrow.

    When a recurring payment is created, the JSP page checks whether there are any indexed bills for the account. If so, Oracle Self-Service E-Billing retrieves the latest bill for the account. Oracle Self-Service E-Billing also checks whether the latest bill has been paid by checking its doc ID against the bill_id of Oracle Self-Service E-Billing Payment tables. If there is no match, it is reasonable to assume that the bill has not been paid, so Oracle Self-Service E-Billing prompts the user to make a one-time payment to pay that bill.

  • What assumptions does recurring payment make?

    Recurring payment assumes that the bill balances are accumulative; that is, the bill of this billing cycle includes the balance of the bill from previous billing cycle, and the later bill has a due date after that of the previous bill (the only situation where the same due date can happen is for a rebill).

    Recurring payment also assumes that each bill has a date indicating the chronological order of bills; this is usually the date when the bill arrives. For example, in the case of the Command Center, doc date can be used to indicate the chronological order of arriving bills. In the case of external billing software, other dates such as statement date can be used for this purpose. When recurring payment synchronizes with the Command Center or other billing software, it must retrieve the latest bill issued between the last_process_time and current time. This chronological date of bills (doc date or statement date) is used to guarantee that functionality.

  • Can recurring payment work with billing software other than the Command Center?

    Yes. Recurring payment assumes nothing specific to the Command Center and the only action to take is to reimplement the IBillDepot API. The billing software must meet assumptions stated in item 2.

  • Must the bills have due dates?

    Yes, if the recurring payment is not fixed date and fixed amount. The due date is used to decide which bill is the latest one to pay. For the Command Center, you must index the due date or some date equivalent to use as the due date.

  • What is the Rebill feature? How do I enable it?

    The Rebill feature lets you issue the same bill multiple times during one billing cycle to handle adjustments. All the rebills must have the same due dates. To decide which rebill is the latest bill to pay, the current IBillDepot implementation considers the latest one to be the one with latest doc date. If there is more than one bill with same doc date, the bill with highest IVN number is chosen. Note, this implementation assumes that a later rebill is always indexed after a previous rebill, and no rebills will be put together in one data file. This would cause the rebills to have same doc date and IVN number. If you want to consider other factor such as amount for making the decision, you must reimplement IBillDepot.

    The Rebill feature is enabled by job configuration parameter When to synchronize with Oracle. To use the Rebill feature, you must choose Whenever the job runs. If you do not use the Rebill feature, you can choose either Whenever the job runs, or Only after current bill is scheduled.

    Technically, there is not much difference between a regular bill and rebill. The major difference is the logic required to decide which rebill is the latest bill, which goes beyond checking bill due date. You can think about non rebill as a special case of rebill; rebill allows the same bill to appear more than once in a single billing period, but non rebill appears only once. The code and programming logic does not distinguish between these two cases.

  • When rebill is not involved, is there any difference between the job configuration options for the job configuration parameter When to Synchronize with Oracle?

    It must not affect functionality, and you can choose either of them. Consider the following two possibilities:

    • Performance can deteriorate if you choose Whenever the job runs because instead of waiting until current bill is scheduled, the job will try to synchronize with the Command Center for each recurring payment. This can be especially true if you are talking with billing software other than the Command Center that might have a slow connection.
    • A scheduled payment can be cancelled because of an unexpected early-arrival of next bill. Because the user only wants to pay the latest bill, the scheduled payment will be canceled and the new bill will be scheduled.
  • Why and when can a scheduled payment be cancelled by recurring payment job?

    The cancellation of a scheduled payment can only happen when the job configuration When to synchronize with Oracle is set to Whenever job runs.

    It can happen because of two reasons:

    • The first case is: (for rebill) after the original bill is scheduled, but before it is processed, the rebill arrives. In this case, the original payment will be cancelled, and the rebill will be scheduled.
    • Second, the bill of this billing cycle is still scheduled, but before it is processed, the bill of next billing cycle arrives (early). In this case, this bill's payment is cancelled and the next bill is scheduled.

      In case of fixed pay date and pay amount due, if a scheduled payment is cancelled, move the last_pay_date and next_pay_date back by the pay_interval before the next bill is scheduled. This ensures that the next bill is paid with the same pay date as the previous bill.

  • In the case of fixed pay date and pay amount due, what happens if there is no bill for this billing cycle?

    Recurring payment can never be triggered for a billing cycle if there is no bill, or if the bill's balance is negative (recurring payment does not issue credit). For example, a user sets to pay the bill's amount due on the 15th of each month, and current month is Oct. The next_pay_date will be set to October 15. However, if no bill arrives before October 15, then after October 15, the next_pay_date will be changed to November 15 to ensure that the bill arrives it will be paid in the next pay period. Otherwise, the user might end up paying the November bill with the October pay date.

  • Will recurring payment make a pay if the balance is negative?

    No. Instead, recurring payment assumes that this credit will roll into the balance of next bill. However, a zero dollar payment will be made if the balance is zero.

  • Can I set up a recurring payment to pay from multiple payment accounts?

    No, you can only pay from one payment account for each recurring payment.

  • Why does the default recurring payment update UI limit some options after the recurring payment is started? For example, it is not possible to switch from pay on fixed date to pay before due.

    The logic to calculate next pay date becomes extremely complicated, so it is disallowed. If a custom UI does allow such an update, the behavior is undefined.

  • What happens if my credit card account expires?

    The recurring payment does not schedule a payment. It is then de-activated and an email is sent to the users to indicate that they must update their credit card account information. In this case, the user must log in to cancel the inactive recurring payment and create a new one.

  • Why was my bill not scheduled?

    This is the most often asked question, but there can be many causes. Follow these steps to debug this problem. To start, review the recurring payment logic steps described previously.

    First, check whether this is a false alarm. A bill can be synchronized, but yet scheduled. Also check the next_pay_date to see whether it reflects the correct pay date for the bill.

    If the bill is not even synchronized, check whether it has been indexed;

    If indexed, check whether it falls into the synchronization period. Only bills whose doc date fall between last_process_time and the current time will be considered.

    Check whether this bill has valid information. For example, whether its due date, amount due are valid parse-able strings. A bill with invalid bill information or with negative balance will not be paid.

    Even though this is a valid bill, it might not still be paid because its due date is before the due date of the current bill associated with the recurring payment.

    Custom plug-ins might be a factor. The custom code might not have been thoroughly tested, so check the plug-in the code carefully. Especially if the custom plug-in is manipulating the bill's due date or amount due or recurring payment information directly.

    The bill cannot be scheduled because the payment account has been cancelled or deleted or de-activated.

  • Will a single recurring payment failure fail the whole recurring payment job?

    No. If it does, it is a bug. If this happens, create a service request (SR) on My Oracle Support. Alternatively, you can phone Oracle Global Customer Support directly to create a service request or get a status update on your current SR. Support phone numbers are listed on My Oracle Support.

  • What is bill ID?

    A unique ID used to identify each bill. In the Command Center, it is the doc ID.

  • What is last process time? What is it used for?

    The time when the last recurring payment job ran. It is used to ensure that a bill is only retrieved once from the Command Center. Oracle Self-Service E-Billing Payment only retrieves bills indexed between the last process time and the current time. That is, bills whose doc date is greater than or equal to the last process time and less than or equal to the current time. The last process time only contains date information (because the doc date only contains date information).

  • What happens if a bill is indexed twice?

    This is similar to rebill. The two bills have the same due dates, but the second indexing produces a later doc date, or a larger IVN, if they are indexed in the same day.

    If When to synchronize with is set to Whenever job runs, this is a true rebill case, and will be treated as a rebill.

    If When to synchronize with Oracle is set to After current bill is scheduled, the second indexed bill will be ignored during next round of synchronization.

Implementation Guide for Oracle Self-Service E-Billing Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices.